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 };
2104 /* The first 16 bytes of the video sample description are already
2105 * read in ff_mov_read_stsd_entries() */
2106 stsd_start = avio_tell(pb) - 16;
2108 avio_rb16(pb); /* version */
2109 avio_rb16(pb); /* revision level */
2110 avio_rb32(pb); /* vendor */
2111 avio_rb32(pb); /* temporal quality */
2112 avio_rb32(pb); /* spatial quality */
2114 st->codecpar->width = avio_rb16(pb); /* width */
2115 st->codecpar->height = avio_rb16(pb); /* height */
2117 avio_rb32(pb); /* horiz resolution */
2118 avio_rb32(pb); /* vert resolution */
2119 avio_rb32(pb); /* data size, always 0 */
2120 avio_rb16(pb); /* frames per samples */
2122 len = avio_r8(pb); /* codec name, pascal string */
2125 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2127 avio_skip(pb, 31 - len);
2130 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2132 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2133 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2134 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2135 st->codecpar->width &= ~1;
2136 st->codecpar->height &= ~1;
2138 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2139 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2140 !strncmp(codec_name, "Sorenson H263", 13))
2141 st->codecpar->codec_id = AV_CODEC_ID_FLV1;
2143 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2145 avio_seek(pb, stsd_start, SEEK_SET);
2147 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2148 st->codecpar->bits_per_coded_sample &= 0x1F;
2149 sc->has_palette = 1;
2153 static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
2154 AVStream *st, MOVStreamContext *sc)
2156 int bits_per_sample, flags;
2157 uint16_t version = avio_rb16(pb);
2158 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2160 avio_rb16(pb); /* revision level */
2161 avio_rb32(pb); /* vendor */
2163 st->codecpar->channels = avio_rb16(pb); /* channel count */
2164 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2165 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", st->codecpar->channels);
2167 sc->audio_cid = avio_rb16(pb);
2168 avio_rb16(pb); /* packet size = 0 */
2170 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2172 // Read QT version 1 fields. In version 0 these do not exist.
2173 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2175 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2176 (sc->stsd_version == 0 && version > 0)) {
2178 sc->samples_per_frame = avio_rb32(pb);
2179 avio_rb32(pb); /* bytes per packet */
2180 sc->bytes_per_frame = avio_rb32(pb);
2181 avio_rb32(pb); /* bytes per sample */
2182 } else if (version == 2) {
2183 avio_rb32(pb); /* sizeof struct only */
2184 st->codecpar->sample_rate = av_int2double(avio_rb64(pb));
2185 st->codecpar->channels = avio_rb32(pb);
2186 avio_rb32(pb); /* always 0x7F000000 */
2187 st->codecpar->bits_per_coded_sample = avio_rb32(pb);
2189 flags = avio_rb32(pb); /* lpcm format specific flag */
2190 sc->bytes_per_frame = avio_rb32(pb);
2191 sc->samples_per_frame = avio_rb32(pb);
2192 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2193 st->codecpar->codec_id =
2194 ff_mov_get_lpcm_codec_id(st->codecpar->bits_per_coded_sample,
2197 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2198 /* can't correctly handle variable sized packet as audio unit */
2199 switch (st->codecpar->codec_id) {
2200 case AV_CODEC_ID_MP2:
2201 case AV_CODEC_ID_MP3:
2202 st->need_parsing = AVSTREAM_PARSE_FULL;
2208 if (sc->format == 0) {
2209 if (st->codecpar->bits_per_coded_sample == 8)
2210 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2211 else if (st->codecpar->bits_per_coded_sample == 16)
2212 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2215 switch (st->codecpar->codec_id) {
2216 case AV_CODEC_ID_PCM_S8:
2217 case AV_CODEC_ID_PCM_U8:
2218 if (st->codecpar->bits_per_coded_sample == 16)
2219 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16BE;
2221 case AV_CODEC_ID_PCM_S16LE:
2222 case AV_CODEC_ID_PCM_S16BE:
2223 if (st->codecpar->bits_per_coded_sample == 8)
2224 st->codecpar->codec_id = AV_CODEC_ID_PCM_S8;
2225 else if (st->codecpar->bits_per_coded_sample == 24)
2226 st->codecpar->codec_id =
2227 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2228 AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
2229 else if (st->codecpar->bits_per_coded_sample == 32)
2230 st->codecpar->codec_id =
2231 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2232 AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
2234 /* set values for old format before stsd version 1 appeared */
2235 case AV_CODEC_ID_MACE3:
2236 sc->samples_per_frame = 6;
2237 sc->bytes_per_frame = 2 * st->codecpar->channels;
2239 case AV_CODEC_ID_MACE6:
2240 sc->samples_per_frame = 6;
2241 sc->bytes_per_frame = 1 * st->codecpar->channels;
2243 case AV_CODEC_ID_ADPCM_IMA_QT:
2244 sc->samples_per_frame = 64;
2245 sc->bytes_per_frame = 34 * st->codecpar->channels;
2247 case AV_CODEC_ID_GSM:
2248 sc->samples_per_frame = 160;
2249 sc->bytes_per_frame = 33;
2255 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2256 if (bits_per_sample) {
2257 st->codecpar->bits_per_coded_sample = bits_per_sample;
2258 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->channels;
2262 static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
2263 AVStream *st, MOVStreamContext *sc,
2266 // ttxt stsd contains display flags, justification, background
2267 // color, fonts, and default styles, so fake an atom to read it
2268 MOVAtom fake_atom = { .size = size };
2269 // mp4s contains a regular esds atom
2270 if (st->codecpar->codec_tag != AV_RL32("mp4s"))
2271 mov_read_glbl(c, pb, fake_atom);
2272 st->codecpar->width = sc->width;
2273 st->codecpar->height = sc->height;
2276 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2281 y = (ycbcr >> 16) & 0xFF;
2282 cr = (ycbcr >> 8) & 0xFF;
2285 b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
2286 g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
2287 r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
2289 return (r << 16) | (g << 8) | b;
2292 static int mov_rewrite_dvd_sub_extradata(AVStream *st)
2294 char buf[256] = {0};
2295 uint8_t *src = st->codecpar->extradata;
2298 if (st->codecpar->extradata_size != 64)
2301 if (st->codecpar->width > 0 && st->codecpar->height > 0)
2302 snprintf(buf, sizeof(buf), "size: %dx%d\n",
2303 st->codecpar->width, st->codecpar->height);
2304 av_strlcat(buf, "palette: ", sizeof(buf));
2306 for (i = 0; i < 16; i++) {
2307 uint32_t yuv = AV_RB32(src + i * 4);
2308 uint32_t rgba = yuv_to_rgba(yuv);
2310 av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2313 if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2316 ret = ff_alloc_extradata(st->codecpar, strlen(buf));
2319 memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2324 static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
2325 AVStream *st, MOVStreamContext *sc,
2330 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2331 if ((int)size != size)
2332 return AVERROR(ENOMEM);
2334 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2338 MOVStreamContext *tmcd_ctx = st->priv_data;
2340 val = AV_RB32(st->codecpar->extradata + 4);
2341 tmcd_ctx->tmcd_flags = val;
2342 st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2343 st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2344 #if FF_API_LAVF_AVCTX
2345 FF_DISABLE_DEPRECATION_WARNINGS
2346 st->codec->time_base = av_inv_q(st->avg_frame_rate);
2347 FF_ENABLE_DEPRECATION_WARNINGS
2349 /* adjust for per frame dur in counter mode */
2350 if (tmcd_ctx->tmcd_flags & 0x0008) {
2351 int timescale = AV_RB32(st->codecpar->extradata + 8);
2352 int framedur = AV_RB32(st->codecpar->extradata + 12);
2353 st->avg_frame_rate.num *= timescale;
2354 st->avg_frame_rate.den *= framedur;
2355 #if FF_API_LAVF_AVCTX
2356 FF_DISABLE_DEPRECATION_WARNINGS
2357 st->codec->time_base.den *= timescale;
2358 st->codec->time_base.num *= framedur;
2359 FF_ENABLE_DEPRECATION_WARNINGS
2363 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2364 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2365 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2366 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2367 if (str_size > 0 && size >= (int)str_size + 30 &&
2368 st->codecpar->extradata[30] /* Don't add empty string */) {
2369 char *reel_name = av_malloc(str_size + 1);
2371 return AVERROR(ENOMEM);
2372 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2373 reel_name[str_size] = 0; /* Add null terminator */
2374 av_dict_set(&st->metadata, "reel_name", reel_name,
2375 AV_DICT_DONT_STRDUP_VAL);
2381 /* other codec type, just skip (rtp, mp4s ...) */
2382 avio_skip(pb, size);
2387 static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
2388 AVStream *st, MOVStreamContext *sc)
2390 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2391 !st->codecpar->sample_rate && sc->time_scale > 1)
2392 st->codecpar->sample_rate = sc->time_scale;
2394 /* special codec parameters handling */
2395 switch (st->codecpar->codec_id) {
2396 #if CONFIG_DV_DEMUXER
2397 case AV_CODEC_ID_DVAUDIO:
2398 c->dv_fctx = avformat_alloc_context();
2400 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2401 return AVERROR(ENOMEM);
2403 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2405 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2406 return AVERROR(ENOMEM);
2408 sc->dv_audio_container = 1;
2409 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
2412 /* no ifdef since parameters are always those */
2413 case AV_CODEC_ID_QCELP:
2414 st->codecpar->channels = 1;
2415 // force sample rate for qcelp when not stored in mov
2416 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2417 st->codecpar->sample_rate = 8000;
2418 // FIXME: Why is the following needed for some files?
2419 sc->samples_per_frame = 160;
2420 if (!sc->bytes_per_frame)
2421 sc->bytes_per_frame = 35;
2423 case AV_CODEC_ID_AMR_NB:
2424 st->codecpar->channels = 1;
2425 /* force sample rate for amr, stsd in 3gp does not store sample rate */
2426 st->codecpar->sample_rate = 8000;
2428 case AV_CODEC_ID_AMR_WB:
2429 st->codecpar->channels = 1;
2430 st->codecpar->sample_rate = 16000;
2432 case AV_CODEC_ID_MP2:
2433 case AV_CODEC_ID_MP3:
2434 /* force type after stsd for m1a hdlr */
2435 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2437 case AV_CODEC_ID_GSM:
2438 case AV_CODEC_ID_ADPCM_MS:
2439 case AV_CODEC_ID_ADPCM_IMA_WAV:
2440 case AV_CODEC_ID_ILBC:
2441 case AV_CODEC_ID_MACE3:
2442 case AV_CODEC_ID_MACE6:
2443 case AV_CODEC_ID_QDM2:
2444 st->codecpar->block_align = sc->bytes_per_frame;
2446 case AV_CODEC_ID_ALAC:
2447 if (st->codecpar->extradata_size == 36) {
2448 st->codecpar->channels = AV_RB8 (st->codecpar->extradata + 21);
2449 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2452 case AV_CODEC_ID_AC3:
2453 case AV_CODEC_ID_EAC3:
2454 case AV_CODEC_ID_MPEG1VIDEO:
2455 case AV_CODEC_ID_VC1:
2456 case AV_CODEC_ID_VP8:
2457 case AV_CODEC_ID_VP9:
2458 st->need_parsing = AVSTREAM_PARSE_FULL;
2460 case AV_CODEC_ID_AV1:
2461 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2469 static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
2470 int codec_tag, int format,
2473 int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2476 (codec_tag != format &&
2477 // AVID 1:1 samples with differing data format and codec tag exist
2478 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
2479 // prores is allowed to have differing data format and codec tag
2480 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
2482 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
2483 (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id
2484 : codec_tag != MKTAG('j','p','e','g')))) {
2485 /* Multiple fourcc, we skip JPEG. This is not correct, we should
2486 * export it as a separate AVStream but this needs a few changes
2487 * in the MOV demuxer, patch welcome. */
2489 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
2490 avio_skip(pb, size);
2497 int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
2500 MOVStreamContext *sc;
2501 int pseudo_stream_id;
2503 av_assert0 (c->fc->nb_streams >= 1);
2504 st = c->fc->streams[c->fc->nb_streams-1];
2507 for (pseudo_stream_id = 0;
2508 pseudo_stream_id < entries && !pb->eof_reached;
2509 pseudo_stream_id++) {
2510 //Parsing Sample description table
2512 int ret, dref_id = 1;
2513 MOVAtom a = { AV_RL32("stsd") };
2514 int64_t start_pos = avio_tell(pb);
2515 int64_t size = avio_rb32(pb); /* size */
2516 uint32_t format = avio_rl32(pb); /* data format */
2519 avio_rb32(pb); /* reserved */
2520 avio_rb16(pb); /* reserved */
2521 dref_id = avio_rb16(pb);
2522 } else if (size <= 7) {
2523 av_log(c->fc, AV_LOG_ERROR,
2524 "invalid size %"PRId64" in stsd\n", size);
2525 return AVERROR_INVALIDDATA;
2528 if (mov_skip_multiple_stsd(c, pb, st->codecpar->codec_tag, format,
2529 size - (avio_tell(pb) - start_pos))) {
2534 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
2535 sc->dref_id= dref_id;
2536 sc->format = format;
2538 id = mov_codec_id(st, format);
2540 av_log(c->fc, AV_LOG_TRACE,
2541 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
2542 av_fourcc2str(format), st->codecpar->codec_type);
2544 st->codecpar->codec_id = id;
2545 if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) {
2546 mov_parse_stsd_video(c, pb, st, sc);
2547 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
2548 mov_parse_stsd_audio(c, pb, st, sc);
2549 if (st->codecpar->sample_rate < 0) {
2550 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
2551 return AVERROR_INVALIDDATA;
2553 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
2554 mov_parse_stsd_subtitle(c, pb, st, sc,
2555 size - (avio_tell(pb) - start_pos));
2557 ret = mov_parse_stsd_data(c, pb, st, sc,
2558 size - (avio_tell(pb) - start_pos));
2562 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
2563 a.size = size - (avio_tell(pb) - start_pos);
2565 if ((ret = mov_read_default(c, pb, a)) < 0)
2567 } else if (a.size > 0)
2568 avio_skip(pb, a.size);
2570 if (sc->extradata && st->codecpar->extradata) {
2571 int extra_size = st->codecpar->extradata_size;
2573 /* Move the current stream extradata to the stream context one. */
2574 sc->extradata_size[pseudo_stream_id] = extra_size;
2575 sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
2576 st->codecpar->extradata = NULL;
2577 st->codecpar->extradata_size = 0;
2582 if (pb->eof_reached) {
2583 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
2590 static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2593 MOVStreamContext *sc;
2596 if (c->fc->nb_streams < 1)
2598 st = c->fc->streams[c->fc->nb_streams - 1];
2601 sc->stsd_version = avio_r8(pb);
2602 avio_rb24(pb); /* flags */
2603 entries = avio_rb32(pb);
2605 /* Each entry contains a size (4 bytes) and format (4 bytes). */
2606 if (entries <= 0 || entries > atom.size / 8) {
2607 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
2608 return AVERROR_INVALIDDATA;
2611 if (sc->extradata) {
2612 av_log(c->fc, AV_LOG_ERROR,
2613 "Duplicate stsd found in this track.\n");
2614 return AVERROR_INVALIDDATA;
2617 /* Prepare space for hosting multiple extradata. */
2618 sc->extradata = av_mallocz_array(entries, sizeof(*sc->extradata));
2620 return AVERROR(ENOMEM);
2622 sc->extradata_size = av_mallocz_array(entries, sizeof(*sc->extradata_size));
2623 if (!sc->extradata_size) {
2624 ret = AVERROR(ENOMEM);
2628 ret = ff_mov_read_stsd_entries(c, pb, entries);
2632 /* Restore back the primary extradata. */
2633 av_freep(&st->codecpar->extradata);
2634 st->codecpar->extradata_size = sc->extradata_size[0];
2635 if (sc->extradata_size[0]) {
2636 st->codecpar->extradata = av_mallocz(sc->extradata_size[0] + AV_INPUT_BUFFER_PADDING_SIZE);
2637 if (!st->codecpar->extradata)
2638 return AVERROR(ENOMEM);
2639 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
2642 return mov_finalize_stsd_codec(c, pb, st, sc);
2644 if (sc->extradata) {
2646 for (j = 0; j < sc->stsd_count; j++)
2647 av_freep(&sc->extradata[j]);
2650 av_freep(&sc->extradata);
2651 av_freep(&sc->extradata_size);
2655 static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2658 MOVStreamContext *sc;
2659 unsigned int i, entries;
2661 if (c->fc->nb_streams < 1)
2663 st = c->fc->streams[c->fc->nb_streams-1];
2666 avio_r8(pb); /* version */
2667 avio_rb24(pb); /* flags */
2669 entries = avio_rb32(pb);
2670 if ((uint64_t)entries * 12 + 4 > atom.size)
2671 return AVERROR_INVALIDDATA;
2673 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
2678 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSC atom\n");
2679 av_free(sc->stsc_data);
2681 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
2683 return AVERROR(ENOMEM);
2685 for (i = 0; i < entries && !pb->eof_reached; i++) {
2686 sc->stsc_data[i].first = avio_rb32(pb);
2687 sc->stsc_data[i].count = avio_rb32(pb);
2688 sc->stsc_data[i].id = avio_rb32(pb);
2692 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
2693 int64_t first_min = i + 1;
2694 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
2695 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
2696 sc->stsc_data[i].first < first_min ||
2697 sc->stsc_data[i].count < 1 ||
2698 sc->stsc_data[i].id < 1) {
2699 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);
2700 if (i+1 >= sc->stsc_count) {
2701 if (sc->stsc_data[i].count == 0 && i > 0) {
2705 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
2706 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
2707 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
2708 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
2709 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
2712 av_assert0(sc->stsc_data[i+1].first >= 2);
2713 // We replace this entry by the next valid
2714 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
2715 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
2716 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
2720 if (pb->eof_reached) {
2721 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
2728 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
2730 return index < count - 1;
2733 /* Compute the samples value for the stsc entry at the given index. */
2734 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
2738 if (mov_stsc_index_valid(index, sc->stsc_count))
2739 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
2741 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
2742 av_assert0(sc->stsc_data[index].first <= sc->chunk_count);
2743 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
2746 return sc->stsc_data[index].count * (int64_t)chunk_count;
2749 static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2752 MOVStreamContext *sc;
2753 unsigned i, entries;
2755 if (c->fc->nb_streams < 1)
2757 st = c->fc->streams[c->fc->nb_streams-1];
2760 avio_rb32(pb); // version + flags
2762 entries = avio_rb32(pb);
2764 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
2765 av_free(sc->stps_data);
2767 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
2769 return AVERROR(ENOMEM);
2771 for (i = 0; i < entries && !pb->eof_reached; i++) {
2772 sc->stps_data[i] = avio_rb32(pb);
2777 if (pb->eof_reached) {
2778 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
2785 static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2788 MOVStreamContext *sc;
2789 unsigned int i, entries;
2791 if (c->fc->nb_streams < 1)
2793 st = c->fc->streams[c->fc->nb_streams-1];
2796 avio_r8(pb); /* version */
2797 avio_rb24(pb); /* flags */
2799 entries = avio_rb32(pb);
2801 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
2804 sc->keyframe_absent = 1;
2805 if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
2806 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2810 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
2811 if (entries >= UINT_MAX / sizeof(int))
2812 return AVERROR_INVALIDDATA;
2813 av_freep(&sc->keyframes);
2814 sc->keyframe_count = 0;
2815 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
2817 return AVERROR(ENOMEM);
2819 for (i = 0; i < entries && !pb->eof_reached; i++) {
2820 sc->keyframes[i] = avio_rb32(pb);
2823 sc->keyframe_count = i;
2825 if (pb->eof_reached) {
2826 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
2833 static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2836 MOVStreamContext *sc;
2837 unsigned int i, entries, sample_size, field_size, num_bytes;
2842 if (c->fc->nb_streams < 1)
2844 st = c->fc->streams[c->fc->nb_streams-1];
2847 avio_r8(pb); /* version */
2848 avio_rb24(pb); /* flags */
2850 if (atom.type == MKTAG('s','t','s','z')) {
2851 sample_size = avio_rb32(pb);
2852 if (!sc->sample_size) /* do not overwrite value computed in stsd */
2853 sc->sample_size = sample_size;
2854 sc->stsz_sample_size = sample_size;
2858 avio_rb24(pb); /* reserved */
2859 field_size = avio_r8(pb);
2861 entries = avio_rb32(pb);
2863 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
2865 sc->sample_count = entries;
2869 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
2870 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
2871 return AVERROR_INVALIDDATA;
2876 if (entries >= (UINT_MAX - 4) / field_size)
2877 return AVERROR_INVALIDDATA;
2878 if (sc->sample_sizes)
2879 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
2880 av_free(sc->sample_sizes);
2881 sc->sample_count = 0;
2882 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
2883 if (!sc->sample_sizes)
2884 return AVERROR(ENOMEM);
2886 num_bytes = (entries*field_size+4)>>3;
2888 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
2890 av_freep(&sc->sample_sizes);
2891 return AVERROR(ENOMEM);
2894 ret = ffio_read_size(pb, buf, num_bytes);
2896 av_freep(&sc->sample_sizes);
2898 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
2902 init_get_bits(&gb, buf, 8*num_bytes);
2904 for (i = 0; i < entries && !pb->eof_reached; i++) {
2905 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
2906 if (sc->sample_sizes[i] < 0) {
2908 av_log(c->fc, AV_LOG_ERROR, "Invalid sample size %d\n", sc->sample_sizes[i]);
2909 return AVERROR_INVALIDDATA;
2911 sc->data_size += sc->sample_sizes[i];
2914 sc->sample_count = i;
2918 if (pb->eof_reached) {
2919 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSZ atom\n");
2926 static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2929 MOVStreamContext *sc;
2930 unsigned int i, entries, alloc_size = 0;
2931 int64_t duration = 0;
2932 int64_t total_sample_count = 0;
2934 if (c->fc->nb_streams < 1)
2936 st = c->fc->streams[c->fc->nb_streams-1];
2939 avio_r8(pb); /* version */
2940 avio_rb24(pb); /* flags */
2941 entries = avio_rb32(pb);
2943 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
2944 c->fc->nb_streams-1, entries);
2947 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
2948 av_freep(&sc->stts_data);
2950 if (entries >= INT_MAX / sizeof(*sc->stts_data))
2951 return AVERROR(ENOMEM);
2953 for (i = 0; i < entries && !pb->eof_reached; i++) {
2954 int sample_duration;
2955 unsigned int sample_count;
2956 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
2957 MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
2958 min_entries * sizeof(*sc->stts_data));
2960 av_freep(&sc->stts_data);
2962 return AVERROR(ENOMEM);
2964 sc->stts_count = min_entries;
2965 sc->stts_data = stts_data;
2967 sample_count = avio_rb32(pb);
2968 sample_duration = avio_rb32(pb);
2970 sc->stts_data[i].count= sample_count;
2971 sc->stts_data[i].duration= sample_duration;
2973 av_log(c->fc, AV_LOG_TRACE, "sample_count=%d, sample_duration=%d\n",
2974 sample_count, sample_duration);
2976 duration+=(int64_t)sample_duration*(uint64_t)sample_count;
2977 total_sample_count+=sample_count;
2983 duration <= INT64_MAX - sc->duration_for_fps &&
2984 total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
2985 sc->duration_for_fps += duration;
2986 sc->nb_frames_for_fps += total_sample_count;
2989 if (pb->eof_reached) {
2990 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
2994 st->nb_frames= total_sample_count;
2996 st->duration= FFMIN(st->duration, duration);
2997 sc->track_end = duration;
3001 static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3004 MOVStreamContext *sc;
3007 if (c->fc->nb_streams < 1)
3009 st = c->fc->streams[c->fc->nb_streams - 1];
3012 avio_r8(pb); /* version */
3013 avio_rb24(pb); /* flags */
3014 entries = atom.size - 4;
3016 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3017 c->fc->nb_streams - 1, entries);
3020 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3021 av_freep(&sc->sdtp_data);
3024 sc->sdtp_data = av_mallocz(entries);
3026 return AVERROR(ENOMEM);
3028 for (i = 0; i < entries && !pb->eof_reached; i++)
3029 sc->sdtp_data[i] = avio_r8(pb);
3035 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3038 if (duration == INT_MIN) {
3039 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3042 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3046 static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3049 MOVStreamContext *sc;
3050 unsigned int i, entries, ctts_count = 0;
3052 if (c->fc->nb_streams < 1)
3054 st = c->fc->streams[c->fc->nb_streams-1];
3057 avio_r8(pb); /* version */
3058 avio_rb24(pb); /* flags */
3059 entries = avio_rb32(pb);
3061 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3065 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3066 return AVERROR_INVALIDDATA;
3067 av_freep(&sc->ctts_data);
3068 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3070 return AVERROR(ENOMEM);
3072 for (i = 0; i < entries && !pb->eof_reached; i++) {
3073 int count = avio_rb32(pb);
3074 int duration = avio_rb32(pb);
3077 av_log(c->fc, AV_LOG_TRACE,
3078 "ignoring CTTS entry with count=%d duration=%d\n",
3083 add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3086 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3089 if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3090 av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3091 av_freep(&sc->ctts_data);
3097 mov_update_dts_shift(sc, duration, c->fc);
3100 sc->ctts_count = ctts_count;
3102 if (pb->eof_reached) {
3103 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3107 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3112 static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3115 MOVStreamContext *sc;
3116 unsigned int i, entries;
3118 uint32_t grouping_type;
3120 if (c->fc->nb_streams < 1)
3122 st = c->fc->streams[c->fc->nb_streams-1];
3125 version = avio_r8(pb); /* version */
3126 avio_rb24(pb); /* flags */
3127 grouping_type = avio_rl32(pb);
3128 if (grouping_type != MKTAG( 'r','a','p',' '))
3129 return 0; /* only support 'rap ' grouping */
3131 avio_rb32(pb); /* grouping_type_parameter */
3133 entries = avio_rb32(pb);
3137 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP atom\n");
3138 av_free(sc->rap_group);
3139 sc->rap_group_count = 0;
3140 sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group));
3142 return AVERROR(ENOMEM);
3144 for (i = 0; i < entries && !pb->eof_reached; i++) {
3145 sc->rap_group[i].count = avio_rb32(pb); /* sample_count */
3146 sc->rap_group[i].index = avio_rb32(pb); /* group_description_index */
3149 sc->rap_group_count = i;
3151 if (pb->eof_reached) {
3152 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3160 * Get ith edit list entry (media time, duration).
3162 static int get_edit_list_entry(MOVContext *mov,
3163 const MOVStreamContext *msc,
3164 unsigned int edit_list_index,
3165 int64_t *edit_list_media_time,
3166 int64_t *edit_list_duration,
3167 int64_t global_timescale)
3169 if (edit_list_index == msc->elst_count) {
3172 *edit_list_media_time = msc->elst_data[edit_list_index].time;
3173 *edit_list_duration = msc->elst_data[edit_list_index].duration;
3175 /* duration is in global timescale units;convert to msc timescale */
3176 if (global_timescale == 0) {
3177 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3180 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3186 * Find the closest previous frame to the timestamp_pts, in e_old index
3187 * entries. Searching for just any frame / just key frames can be controlled by
3188 * last argument 'flag'.
3189 * Note that if ctts_data is not NULL, we will always search for a key frame
3190 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3191 * return the first frame of the video.
3193 * Here the timestamp_pts is considered to be a presentation timestamp and
3194 * the timestamp of index entries are considered to be decoding timestamps.
3196 * Returns 0 if successful in finding a frame, else returns -1.
3197 * Places the found index corresponding output arg.
3199 * If ctts_old is not NULL, then refines the searched entry by searching
3200 * backwards from the found timestamp, to find the frame with correct PTS.
3202 * Places the found ctts_index and ctts_sample in corresponding output args.
3204 static int find_prev_closest_index(AVStream *st,
3205 AVIndexEntry *e_old,
3209 int64_t timestamp_pts,
3212 int64_t* ctts_index,
3213 int64_t* ctts_sample)
3215 MOVStreamContext *msc = st->priv_data;
3216 AVIndexEntry *e_keep = st->internal->index_entries;
3217 int nb_keep = st->internal->nb_index_entries;
3219 int64_t index_ctts_count;
3223 // If dts_shift > 0, then all the index timestamps will have to be offset by
3224 // at least dts_shift amount to obtain PTS.
3225 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3226 if (msc->dts_shift > 0) {
3227 timestamp_pts -= msc->dts_shift;
3230 st->internal->index_entries = e_old;
3231 st->internal->nb_index_entries = nb_old;
3232 *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3234 // Keep going backwards in the index entries until the timestamp is the same.
3236 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3238 if ((flag & AVSEEK_FLAG_ANY) ||
3239 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3245 // If we have CTTS then refine the search, by searching backwards over PTS
3246 // computed by adding corresponding CTTS durations to index timestamps.
3247 if (ctts_data && *index >= 0) {
3248 av_assert0(ctts_index);
3249 av_assert0(ctts_sample);
3250 // Find out the ctts_index for the found frame.
3253 for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3254 if (*ctts_index < ctts_count) {
3256 if (ctts_data[*ctts_index].count == *ctts_sample) {
3263 while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3264 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3265 // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3266 // compensated by dts_shift above.
3267 if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3268 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3273 if (*ctts_sample == 0) {
3275 if (*ctts_index >= 0)
3276 *ctts_sample = ctts_data[*ctts_index].count - 1;
3283 /* restore AVStream state*/
3284 st->internal->index_entries = e_keep;
3285 st->internal->nb_index_entries = nb_keep;
3286 return *index >= 0 ? 0 : -1;
3290 * Add index entry with the given values, to the end of st->internal->index_entries.
3291 * Returns the new size st->internal->index_entries if successful, else returns -1.
3293 * This function is similar to ff_add_index_entry in libavformat/utils.c
3294 * except that here we are always unconditionally adding an index entry to
3295 * the end, instead of searching the entries list and skipping the add if
3296 * there is an existing entry with the same timestamp.
3297 * This is needed because the mov_fix_index calls this func with the same
3298 * unincremented timestamp for successive discarded frames.
3300 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3301 int size, int distance, int flags)
3303 AVIndexEntry *entries, *ie;
3305 const size_t min_size_needed = (st->internal->nb_index_entries + 1) * sizeof(AVIndexEntry);
3307 // Double the allocation each time, to lower memory fragmentation.
3308 // Another difference from ff_add_index_entry function.
3309 const size_t requested_size =
3310 min_size_needed > st->internal->index_entries_allocated_size ?
3311 FFMAX(min_size_needed, 2 * st->internal->index_entries_allocated_size) :
3314 if (st->internal->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
3317 entries = av_fast_realloc(st->internal->index_entries,
3318 &st->internal->index_entries_allocated_size,
3323 st->internal->index_entries= entries;
3325 index= st->internal->nb_index_entries++;
3326 ie= &entries[index];
3329 ie->timestamp = timestamp;
3330 ie->min_distance= distance;
3337 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3338 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3340 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3341 int64_t* frame_duration_buffer,
3342 int frame_duration_buffer_size) {
3344 av_assert0(end_index >= 0 && end_index <= st->internal->nb_index_entries);
3345 for (i = 0; i < frame_duration_buffer_size; i++) {
3346 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3347 st->internal->index_entries[end_index - 1 - i].timestamp = end_ts;
3352 * Append a new ctts entry to ctts_data.
3353 * Returns the new ctts_count if successful, else returns -1.
3355 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3356 int count, int duration)
3358 MOVStts *ctts_buf_new;
3359 const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVStts);
3360 const size_t requested_size =
3361 min_size_needed > *allocated_size ?
3362 FFMAX(min_size_needed, 2 * (*allocated_size)) :
3365 if ((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
3368 ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3373 *ctts_data = ctts_buf_new;
3375 ctts_buf_new[*ctts_count].count = count;
3376 ctts_buf_new[*ctts_count].duration = duration;
3378 *ctts_count = (*ctts_count) + 1;
3382 #define MAX_REORDER_DELAY 16
3383 static void mov_estimate_video_delay(MOVContext *c, AVStream* st)
3385 MOVStreamContext *msc = st->priv_data;
3388 int ctts_sample = 0;
3389 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3391 int j, r, num_swaps;
3393 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3394 pts_buf[j] = INT64_MIN;
3396 if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3397 st->codecpar->codec_id == AV_CODEC_ID_H264) {
3398 st->codecpar->video_delay = 0;
3399 for (ind = 0; ind < st->internal->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3400 // Point j to the last elem of the buffer and insert the current pts there.
3402 buf_start = (buf_start + 1);
3403 if (buf_start == MAX_REORDER_DELAY + 1)
3406 pts_buf[j] = st->internal->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3408 // The timestamps that are already in the sorted buffer, and are greater than the
3409 // current pts, are exactly the timestamps that need to be buffered to output PTS
3410 // in correct sorted order.
3411 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3412 // can be computed as the maximum no. of swaps any particular timestamp needs to
3413 // go through, to keep this buffer in sorted order.
3415 while (j != buf_start) {
3417 if (r < 0) r = MAX_REORDER_DELAY;
3418 if (pts_buf[j] < pts_buf[r]) {
3419 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3426 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3429 if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3434 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3435 st->codecpar->video_delay, st->index);
3439 static void mov_current_sample_inc(MOVStreamContext *sc)
3441 sc->current_sample++;
3442 sc->current_index++;
3443 if (sc->index_ranges &&
3444 sc->current_index >= sc->current_index_range->end &&
3445 sc->current_index_range->end) {
3446 sc->current_index_range++;
3447 sc->current_index = sc->current_index_range->start;
3451 static void mov_current_sample_dec(MOVStreamContext *sc)
3453 sc->current_sample--;
3454 sc->current_index--;
3455 if (sc->index_ranges &&
3456 sc->current_index < sc->current_index_range->start &&
3457 sc->current_index_range > sc->index_ranges) {
3458 sc->current_index_range--;
3459 sc->current_index = sc->current_index_range->end - 1;
3463 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3467 sc->current_sample = current_sample;
3468 sc->current_index = current_sample;
3469 if (!sc->index_ranges) {
3473 for (sc->current_index_range = sc->index_ranges;
3474 sc->current_index_range->end;
3475 sc->current_index_range++) {
3476 range_size = sc->current_index_range->end - sc->current_index_range->start;
3477 if (range_size > current_sample) {
3478 sc->current_index = sc->current_index_range->start + current_sample;
3481 current_sample -= range_size;
3486 * Fix st->internal->index_entries, so that it contains only the entries (and the entries
3487 * which are needed to decode them) that fall in the edit list time ranges.
3488 * Also fixes the timestamps of the index entries to match the timeline
3489 * specified the edit lists.
3491 static void mov_fix_index(MOVContext *mov, AVStream *st)
3493 MOVStreamContext *msc = st->priv_data;
3494 AVIndexEntry *e_old = st->internal->index_entries;
3495 int nb_old = st->internal->nb_index_entries;
3496 const AVIndexEntry *e_old_end = e_old + nb_old;
3497 const AVIndexEntry *current = NULL;
3498 MOVStts *ctts_data_old = msc->ctts_data;
3499 int64_t ctts_index_old = 0;
3500 int64_t ctts_sample_old = 0;
3501 int64_t ctts_count_old = msc->ctts_count;
3502 int64_t edit_list_media_time = 0;
3503 int64_t edit_list_duration = 0;
3504 int64_t frame_duration = 0;
3505 int64_t edit_list_dts_counter = 0;
3506 int64_t edit_list_dts_entry_end = 0;
3507 int64_t edit_list_start_ctts_sample = 0;
3509 int64_t curr_ctts = 0;
3510 int64_t empty_edits_sum_duration = 0;
3511 int64_t edit_list_index = 0;
3514 int64_t start_dts = 0;
3515 int64_t edit_list_start_encountered = 0;
3516 int64_t search_timestamp = 0;
3517 int64_t* frame_duration_buffer = NULL;
3518 int num_discarded_begin = 0;
3519 int first_non_zero_audio_edit = -1;
3520 int packet_skip_samples = 0;
3521 MOVIndexRange *current_index_range;
3523 int found_keyframe_after_edit = 0;
3524 int found_non_empty_edit = 0;
3526 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
3530 // allocate the index ranges array
3531 msc->index_ranges = av_malloc((msc->elst_count + 1) * sizeof(msc->index_ranges[0]));
3532 if (!msc->index_ranges) {
3533 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
3536 msc->current_index_range = msc->index_ranges;
3537 current_index_range = msc->index_ranges - 1;
3539 // Clean AVStream from traces of old index
3540 st->internal->index_entries = NULL;
3541 st->internal->index_entries_allocated_size = 0;
3542 st->internal->nb_index_entries = 0;
3544 // Clean ctts fields of MOVStreamContext
3545 msc->ctts_data = NULL;
3546 msc->ctts_count = 0;
3547 msc->ctts_index = 0;
3548 msc->ctts_sample = 0;
3549 msc->ctts_allocated_size = 0;
3551 // Reinitialize min_corrected_pts so that it can be computed again.
3552 msc->min_corrected_pts = -1;
3554 // If the dts_shift is positive (in case of negative ctts values in mov),
3555 // then negate the DTS by dts_shift
3556 if (msc->dts_shift > 0) {
3557 edit_list_dts_entry_end -= msc->dts_shift;
3558 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
3561 start_dts = edit_list_dts_entry_end;
3563 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
3564 &edit_list_duration, mov->time_scale)) {
3565 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
3566 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
3568 edit_list_dts_counter = edit_list_dts_entry_end;
3569 edit_list_dts_entry_end += edit_list_duration;
3570 num_discarded_begin = 0;
3571 if (!found_non_empty_edit && edit_list_media_time == -1) {
3572 empty_edits_sum_duration += edit_list_duration;
3575 found_non_empty_edit = 1;
3577 // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
3578 // according to the edit list below.
3579 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3580 if (first_non_zero_audio_edit < 0) {
3581 first_non_zero_audio_edit = 1;
3583 first_non_zero_audio_edit = 0;
3586 if (first_non_zero_audio_edit > 0)
3587 st->internal->skip_samples = msc->start_pad = 0;
3590 // While reordering frame index according to edit list we must handle properly
3591 // the scenario when edit list entry starts from none key frame.
3592 // We find closest previous key frame and preserve it and consequent frames in index.
3593 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
3594 search_timestamp = edit_list_media_time;
3595 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3596 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
3597 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
3598 // edit_list_media_time to cover the decoder delay.
3599 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
3602 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
3603 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3604 av_log(mov->fc, AV_LOG_WARNING,
3605 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
3606 st->index, edit_list_index, search_timestamp);
3607 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
3608 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3609 av_log(mov->fc, AV_LOG_WARNING,
3610 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
3611 st->index, edit_list_index, search_timestamp);
3614 ctts_sample_old = 0;
3617 current = e_old + index;
3618 edit_list_start_ctts_sample = ctts_sample_old;
3620 // Iterate over index and arrange it according to edit list
3621 edit_list_start_encountered = 0;
3622 found_keyframe_after_edit = 0;
3623 for (; current < e_old_end; current++, index++) {
3624 // check if frame outside edit list mark it for discard
3625 frame_duration = (current + 1 < e_old_end) ?
3626 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
3628 flags = current->flags;
3630 // frames (pts) before or after edit list
3631 curr_cts = current->timestamp + msc->dts_shift;
3634 if (ctts_data_old && ctts_index_old < ctts_count_old) {
3635 curr_ctts = ctts_data_old[ctts_index_old].duration;
3636 av_log(mov->fc, AV_LOG_DEBUG, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
3637 curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
3638 curr_cts += curr_ctts;
3640 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
3641 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3642 &msc->ctts_allocated_size,
3643 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3644 ctts_data_old[ctts_index_old].duration) == -1) {
3645 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3647 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3648 ctts_data_old[ctts_index_old].duration);
3652 ctts_sample_old = 0;
3653 edit_list_start_ctts_sample = 0;
3657 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
3658 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
3659 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
3660 first_non_zero_audio_edit > 0) {
3661 packet_skip_samples = edit_list_media_time - curr_cts;
3662 st->internal->skip_samples += packet_skip_samples;
3664 // Shift the index entry timestamp by packet_skip_samples to be correct.
3665 edit_list_dts_counter -= packet_skip_samples;
3666 if (edit_list_start_encountered == 0) {
3667 edit_list_start_encountered = 1;
3668 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
3669 // discarded packets.
3670 if (frame_duration_buffer) {
3671 fix_index_entry_timestamps(st, st->internal->nb_index_entries, edit_list_dts_counter,
3672 frame_duration_buffer, num_discarded_begin);
3673 av_freep(&frame_duration_buffer);
3677 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
3679 flags |= AVINDEX_DISCARD_FRAME;
3680 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
3682 if (edit_list_start_encountered == 0) {
3683 num_discarded_begin++;
3684 frame_duration_buffer = av_realloc(frame_duration_buffer,
3685 num_discarded_begin * sizeof(int64_t));
3686 if (!frame_duration_buffer) {
3687 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
3690 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
3692 // Increment skip_samples for the first non-zero audio edit list
3693 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3694 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
3695 st->internal->skip_samples += frame_duration;
3700 if (msc->min_corrected_pts < 0) {
3701 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
3703 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
3705 if (edit_list_start_encountered == 0) {
3706 edit_list_start_encountered = 1;
3707 // Make timestamps strictly monotonically increasing by rewriting timestamps for
3708 // discarded packets.
3709 if (frame_duration_buffer) {
3710 fix_index_entry_timestamps(st, st->internal->nb_index_entries, edit_list_dts_counter,
3711 frame_duration_buffer, num_discarded_begin);
3712 av_freep(&frame_duration_buffer);
3717 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
3718 current->min_distance, flags) == -1) {
3719 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
3723 // Update the index ranges array
3724 if (current_index_range < msc->index_ranges || index != current_index_range->end) {
3725 current_index_range++;
3726 current_index_range->start = index;
3728 current_index_range->end = index + 1;
3730 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
3731 if (edit_list_start_encountered > 0) {
3732 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
3735 // Break when found first key frame after edit entry completion
3736 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
3737 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
3738 if (ctts_data_old) {
3739 // If we have CTTS and this is the first keyframe after edit elist,
3740 // wait for one more, because there might be trailing B-frames after this I-frame
3741 // that do belong to the edit.
3742 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
3743 found_keyframe_after_edit = 1;
3746 if (ctts_sample_old != 0) {
3747 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3748 &msc->ctts_allocated_size,
3749 ctts_sample_old - edit_list_start_ctts_sample,
3750 ctts_data_old[ctts_index_old].duration) == -1) {
3751 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3752 ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
3753 ctts_data_old[ctts_index_old].duration);
3762 // If there are empty edits, then msc->min_corrected_pts might be positive
3763 // intentionally. So we subtract the sum duration of emtpy edits here.
3764 msc->min_corrected_pts -= empty_edits_sum_duration;
3766 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
3767 // dts by that amount to make the first pts zero.
3768 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
3769 if (msc->min_corrected_pts > 0) {
3770 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
3771 for (i = 0; i < st->internal->nb_index_entries; ++i) {
3772 st->internal->index_entries[i].timestamp -= msc->min_corrected_pts;
3776 // Start time should be equal to zero or the duration of any empty edits.
3777 st->start_time = empty_edits_sum_duration;
3779 // Update av stream length, if it ends up shorter than the track's media duration
3780 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
3781 msc->start_pad = st->internal->skip_samples;
3783 // Free the old index and the old CTTS structures
3785 av_free(ctts_data_old);
3786 av_freep(&frame_duration_buffer);
3788 // Null terminate the index ranges array
3789 current_index_range++;
3790 current_index_range->start = 0;
3791 current_index_range->end = 0;
3792 msc->current_index = msc->index_ranges[0].start;
3795 static void mov_build_index(MOVContext *mov, AVStream *st)
3797 MOVStreamContext *sc = st->priv_data;
3798 int64_t current_offset;
3799 int64_t current_dts = 0;
3800 unsigned int stts_index = 0;
3801 unsigned int stsc_index = 0;
3802 unsigned int stss_index = 0;
3803 unsigned int stps_index = 0;
3805 uint64_t stream_size = 0;
3806 MOVStts *ctts_data_old = sc->ctts_data;
3807 unsigned int ctts_count_old = sc->ctts_count;
3809 if (sc->elst_count) {
3810 int i, edit_start_index = 0, multiple_edits = 0;
3811 int64_t empty_duration = 0; // empty duration of the first edit list entry
3812 int64_t start_time = 0; // start time of the media
3814 for (i = 0; i < sc->elst_count; i++) {
3815 const MOVElst *e = &sc->elst_data[i];
3816 if (i == 0 && e->time == -1) {
3817 /* if empty, the first entry is the start time of the stream
3818 * relative to the presentation itself */
3819 empty_duration = e->duration;
3820 edit_start_index = 1;
3821 } else if (i == edit_start_index && e->time >= 0) {
3822 start_time = e->time;
3828 if (multiple_edits && !mov->advanced_editlist)
3829 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
3830 "Use -advanced_editlist to correctly decode otherwise "
3831 "a/v desync might occur\n");
3833 /* adjust first dts according to edit list */
3834 if ((empty_duration || start_time) && mov->time_scale > 0) {
3836 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
3837 sc->time_offset = start_time - empty_duration;
3838 sc->min_corrected_pts = start_time;
3839 if (!mov->advanced_editlist)
3840 current_dts = -sc->time_offset;
3843 if (!multiple_edits && !mov->advanced_editlist &&
3844 st->codecpar->codec_id == AV_CODEC_ID_AAC && start_time > 0)
3845 sc->start_pad = start_time;
3848 /* only use old uncompressed audio chunk demuxing when stts specifies it */
3849 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3850 sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
3851 unsigned int current_sample = 0;
3852 unsigned int stts_sample = 0;
3853 unsigned int sample_size;
3854 unsigned int distance = 0;
3855 unsigned int rap_group_index = 0;
3856 unsigned int rap_group_sample = 0;
3857 int64_t last_dts = 0;
3858 int64_t dts_correction = 0;
3859 int rap_group_present = sc->rap_group_count && sc->rap_group;
3860 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
3862 current_dts -= sc->dts_shift;
3863 last_dts = current_dts;
3865 if (!sc->sample_count || st->internal->nb_index_entries)
3867 if (sc->sample_count >= UINT_MAX / sizeof(*st->internal->index_entries) - st->internal->nb_index_entries)
3869 if (av_reallocp_array(&st->internal->index_entries,
3870 st->internal->nb_index_entries + sc->sample_count,
3871 sizeof(*st->internal->index_entries)) < 0) {
3872 st->internal->nb_index_entries = 0;
3875 st->internal->index_entries_allocated_size = (st->internal->nb_index_entries + sc->sample_count) * sizeof(*st->internal->index_entries);
3877 if (ctts_data_old) {
3878 // Expand ctts entries such that we have a 1-1 mapping with samples
3879 if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
3882 sc->ctts_allocated_size = 0;
3883 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size,
3884 sc->sample_count * sizeof(*sc->ctts_data));
3885 if (!sc->ctts_data) {
3886 av_free(ctts_data_old);
3890 memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
3892 for (i = 0; i < ctts_count_old &&
3893 sc->ctts_count < sc->sample_count; i++)
3894 for (j = 0; j < ctts_data_old[i].count &&
3895 sc->ctts_count < sc->sample_count; j++)
3896 add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
3897 &sc->ctts_allocated_size, 1,
3898 ctts_data_old[i].duration);
3899 av_free(ctts_data_old);
3902 for (i = 0; i < sc->chunk_count; i++) {
3903 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
3904 current_offset = sc->chunk_offsets[i];
3905 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3906 i + 1 == sc->stsc_data[stsc_index + 1].first)
3909 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
3910 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
3911 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
3912 sc->stsz_sample_size = sc->sample_size;
3914 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
3915 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
3916 sc->stsz_sample_size = sc->sample_size;
3919 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
3921 if (current_sample >= sc->sample_count) {
3922 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
3926 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
3928 if (stss_index + 1 < sc->keyframe_count)
3930 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
3932 if (stps_index + 1 < sc->stps_count)
3935 if (rap_group_present && rap_group_index < sc->rap_group_count) {
3936 if (sc->rap_group[rap_group_index].index > 0)
3938 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
3939 rap_group_sample = 0;
3943 if (sc->keyframe_absent
3945 && !rap_group_present
3946 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
3950 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
3951 if (sc->pseudo_stream_id == -1 ||
3952 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
3954 if (sample_size > 0x3FFFFFFF) {
3955 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
3958 e = &st->internal->index_entries[st->internal->nb_index_entries++];
3959 e->pos = current_offset;
3960 e->timestamp = current_dts;
3961 e->size = sample_size;
3962 e->min_distance = distance;
3963 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
3964 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
3965 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
3966 current_offset, current_dts, sample_size, distance, keyframe);
3967 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->internal->nb_index_entries < 100)
3968 ff_rfps_add_frame(mov->fc, st, current_dts);
3971 current_offset += sample_size;
3972 stream_size += sample_size;
3974 /* A negative sample duration is invalid based on the spec,
3975 * but some samples need it to correct the DTS. */
3976 if (sc->stts_data[stts_index].duration < 0) {
3977 av_log(mov->fc, AV_LOG_WARNING,
3978 "Invalid SampleDelta %d in STTS, at %d st:%d\n",
3979 sc->stts_data[stts_index].duration, stts_index,
3981 dts_correction += sc->stts_data[stts_index].duration - 1;
3982 sc->stts_data[stts_index].duration = 1;
3984 current_dts += sc->stts_data[stts_index].duration;
3985 if (!dts_correction || current_dts + dts_correction > last_dts) {
3986 current_dts += dts_correction;
3989 /* Avoid creating non-monotonous DTS */
3990 dts_correction += current_dts - last_dts - 1;
3991 current_dts = last_dts + 1;
3993 last_dts = current_dts;
3997 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
4003 if (st->duration > 0)
4004 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
4006 unsigned chunk_samples, total = 0;
4008 if (!sc->chunk_count)
4011 // compute total chunk count
4012 for (i = 0; i < sc->stsc_count; i++) {
4013 unsigned count, chunk_count;
4015 chunk_samples = sc->stsc_data[i].count;
4016 if (i != sc->stsc_count - 1 &&
4017 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
4018 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
4022 if (sc->samples_per_frame >= 160) { // gsm
4023 count = chunk_samples / sc->samples_per_frame;
4024 } else if (sc->samples_per_frame > 1) {
4025 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4026 count = (chunk_samples+samples-1) / samples;
4028 count = (chunk_samples+1023) / 1024;
4031 if (mov_stsc_index_valid(i, sc->stsc_count))
4032 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4034 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4035 total += chunk_count * count;
4038 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4039 if (total >= UINT_MAX / sizeof(*st->internal->index_entries) - st->internal->nb_index_entries)
4041 if (av_reallocp_array(&st->internal->index_entries,
4042 st->internal->nb_index_entries + total,
4043 sizeof(*st->internal->index_entries)) < 0) {
4044 st->internal->nb_index_entries = 0;
4047 st->internal->index_entries_allocated_size = (st->internal->nb_index_entries + total) * sizeof(*st->internal->index_entries);
4050 for (i = 0; i < sc->chunk_count; i++) {
4051 current_offset = sc->chunk_offsets[i];
4052 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4053 i + 1 == sc->stsc_data[stsc_index + 1].first)
4055 chunk_samples = sc->stsc_data[stsc_index].count;
4057 while (chunk_samples > 0) {
4059 unsigned size, samples;
4061 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4062 avpriv_request_sample(mov->fc,
4063 "Zero bytes per frame, but %d samples per frame",
4064 sc->samples_per_frame);
4068 if (sc->samples_per_frame >= 160) { // gsm
4069 samples = sc->samples_per_frame;
4070 size = sc->bytes_per_frame;
4072 if (sc->samples_per_frame > 1) {
4073 samples = FFMIN((1024 / sc->samples_per_frame)*
4074 sc->samples_per_frame, chunk_samples);
4075 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
4077 samples = FFMIN(1024, chunk_samples);
4078 size = samples * sc->sample_size;
4082 if (st->internal->nb_index_entries >= total) {
4083 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4086 if (size > 0x3FFFFFFF) {
4087 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4090 e = &st->internal->index_entries[st->internal->nb_index_entries++];
4091 e->pos = current_offset;
4092 e->timestamp = current_dts;
4094 e->min_distance = 0;
4095 e->flags = AVINDEX_KEYFRAME;
4096 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4097 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4100 current_offset += size;
4101 current_dts += samples;
4102 chunk_samples -= samples;
4107 if (!mov->ignore_editlist && mov->advanced_editlist) {
4108 // Fix index according to edit lists.
4109 mov_fix_index(mov, st);
4112 // Update start time of the stream.
4113 if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->internal->nb_index_entries > 0) {
4114 st->start_time = st->internal->index_entries[0].timestamp + sc->dts_shift;
4115 if (sc->ctts_data) {
4116 st->start_time += sc->ctts_data[0].duration;
4120 mov_estimate_video_delay(mov, st);
4123 static int test_same_origin(const char *src, const char *ref) {
4133 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4134 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4136 if (strlen(src) == 0) {
4138 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4139 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4140 strlen(src_host) + 1 >= sizeof(src_host) ||
4141 strlen(ref_host) + 1 >= sizeof(ref_host)) {
4143 } else if (strcmp(src_proto, ref_proto) ||
4144 strcmp(src_auth, ref_auth) ||
4145 strcmp(src_host, ref_host) ||
4146 src_port != ref_port) {
4152 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4154 /* try relative path, we do not try the absolute because it can leak information about our
4155 system to an attacker */
4156 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4157 char filename[1025];
4158 const char *src_path;
4161 /* find a source dir */
4162 src_path = strrchr(src, '/');
4168 /* find a next level down to target */
4169 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4170 if (ref->path[l] == '/') {
4171 if (i == ref->nlvl_to - 1)
4177 /* compose filename if next level down to target was found */
4178 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4179 memcpy(filename, src, src_path - src);
4180 filename[src_path - src] = 0;
4182 for (i = 1; i < ref->nlvl_from; i++)
4183 av_strlcat(filename, "../", sizeof(filename));
4185 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4186 if (!c->use_absolute_path) {
4187 int same_origin = test_same_origin(src, filename);
4190 av_log(c->fc, AV_LOG_ERROR,
4191 "Reference with mismatching origin, %s not tried for security reasons, "
4192 "set demuxer option use_absolute_path to allow it anyway\n",
4194 return AVERROR(ENOENT);
4197 if (strstr(ref->path + l + 1, "..") ||
4198 strstr(ref->path + l + 1, ":") ||
4199 (ref->nlvl_from > 1 && same_origin < 0) ||
4200 (filename[0] == '/' && src_path == src))
4201 return AVERROR(ENOENT);
4204 if (strlen(filename) + 1 == sizeof(filename))
4205 return AVERROR(ENOENT);
4206 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4209 } else if (c->use_absolute_path) {
4210 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4211 "this is a possible security issue\n");
4212 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4215 av_log(c->fc, AV_LOG_ERROR,
4216 "Absolute path %s not tried for security reasons, "
4217 "set demuxer option use_absolute_path to allow absolute paths\n",
4221 return AVERROR(ENOENT);
4224 static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
4226 if (sc->time_scale <= 0) {
4227 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4228 sc->time_scale = c->time_scale;
4229 if (sc->time_scale <= 0)
4234 static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4237 MOVStreamContext *sc;
4240 st = avformat_new_stream(c->fc, NULL);
4241 if (!st) return AVERROR(ENOMEM);
4243 sc = av_mallocz(sizeof(MOVStreamContext));
4244 if (!sc) return AVERROR(ENOMEM);
4247 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
4248 sc->ffindex = st->index;
4249 c->trak_index = st->index;
4251 if ((ret = mov_read_default(c, pb, atom)) < 0)
4256 // Here stsc refers to a chunk not described in stco. This is technically invalid,
4257 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4258 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4260 av_freep(&sc->stsc_data);
4264 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4265 (!sc->sample_size && !sc->sample_count))) ||
4266 (!sc->chunk_count && sc->sample_count)) {
4267 av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4271 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4272 av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4274 return AVERROR_INVALIDDATA;
4277 fix_timescale(c, sc);
4279 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4281 mov_build_index(c, st);
4283 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4284 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4285 if (c->enable_drefs) {
4286 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4287 av_log(c->fc, AV_LOG_ERROR,
4288 "stream %d, error opening alias: path='%s', dir='%s', "
4289 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4290 st->index, dref->path, dref->dir, dref->filename,
4291 dref->volume, dref->nlvl_from, dref->nlvl_to);
4293 av_log(c->fc, AV_LOG_WARNING,
4294 "Skipped opening external track: "
4295 "stream %d, alias: path='%s', dir='%s', "
4296 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4297 "Set enable_drefs to allow this.\n",
4298 st->index, dref->path, dref->dir, dref->filename,
4299 dref->volume, dref->nlvl_from, dref->nlvl_to);
4303 sc->pb_is_copied = 1;
4306 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4307 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4308 sc->height && sc->width &&
4309 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4310 st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4311 ((double)st->codecpar->width * sc->height), INT_MAX);
4314 #if FF_API_R_FRAME_RATE
4315 if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4316 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
4317 sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4321 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4322 if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4323 TAG_IS_AVCI(st->codecpar->codec_tag)) {
4324 ret = ff_generate_avci_extradata(st);
4329 switch (st->codecpar->codec_id) {
4330 #if CONFIG_H261_DECODER
4331 case AV_CODEC_ID_H261:
4333 #if CONFIG_H263_DECODER
4334 case AV_CODEC_ID_H263:
4336 #if CONFIG_MPEG4_DECODER
4337 case AV_CODEC_ID_MPEG4:
4339 st->codecpar->width = 0; /* let decoder init width/height */
4340 st->codecpar->height= 0;
4344 // If the duration of the mp3 packets is not constant, then they could need a parser
4345 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4346 && sc->stts_count > 3
4347 && sc->stts_count*10 > st->nb_frames
4348 && sc->time_scale == st->codecpar->sample_rate) {
4349 st->need_parsing = AVSTREAM_PARSE_FULL;
4351 /* Do not need those anymore. */
4352 av_freep(&sc->chunk_offsets);
4353 av_freep(&sc->sample_sizes);
4354 av_freep(&sc->keyframes);
4355 av_freep(&sc->stts_data);
4356 av_freep(&sc->stps_data);
4357 av_freep(&sc->elst_data);
4358 av_freep(&sc->rap_group);
4363 static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4366 c->itunes_metadata = 1;
4367 ret = mov_read_default(c, pb, atom);
4368 c->itunes_metadata = 0;
4372 static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4381 count = avio_rb32(pb);
4382 if (count > UINT_MAX / sizeof(*c->meta_keys) - 1) {
4383 av_log(c->fc, AV_LOG_ERROR,
4384 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
4385 return AVERROR_INVALIDDATA;
4388 c->meta_keys_count = count + 1;
4389 c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
4391 return AVERROR(ENOMEM);
4393 for (i = 1; i <= count; ++i) {
4394 uint32_t key_size = avio_rb32(pb);
4395 uint32_t type = avio_rl32(pb);
4397 av_log(c->fc, AV_LOG_ERROR,
4398 "The key# %"PRIu32" in meta has invalid size:"
4399 "%"PRIu32"\n", i, key_size);
4400 return AVERROR_INVALIDDATA;
4403 if (type != MKTAG('m','d','t','a')) {
4404 avio_skip(pb, key_size);
4406 c->meta_keys[i] = av_mallocz(key_size + 1);
4407 if (!c->meta_keys[i])
4408 return AVERROR(ENOMEM);
4409 avio_read(pb, c->meta_keys[i], key_size);
4415 static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4417 int64_t end = av_sat_add64(avio_tell(pb), atom.size);
4418 uint8_t *key = NULL, *val = NULL, *mean = NULL;
4422 MOVStreamContext *sc;
4424 if (c->fc->nb_streams < 1)
4426 st = c->fc->streams[c->fc->nb_streams-1];
4429 for (i = 0; i < 3; i++) {
4433 if (end - avio_tell(pb) <= 12)
4436 len = avio_rb32(pb);
4437 tag = avio_rl32(pb);
4438 avio_skip(pb, 4); // flags
4440 if (len < 12 || len - 12 > end - avio_tell(pb))
4444 if (tag == MKTAG('m', 'e', 'a', 'n'))
4446 else if (tag == MKTAG('n', 'a', 'm', 'e'))
4448 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
4458 *p = av_malloc(len + 1);
4460 ret = AVERROR(ENOMEM);
4463 ret = ffio_read_size(pb, *p, len);
4471 if (mean && key && val) {
4472 if (strcmp(key, "iTunSMPB") == 0) {
4473 int priming, remainder, samples;
4474 if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
4475 if(priming>0 && priming<16384)
4476 sc->start_pad = priming;
4479 if (strcmp(key, "cdec") != 0) {
4480 av_dict_set(&c->fc->metadata, key, val,
4481 AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
4485 av_log(c->fc, AV_LOG_VERBOSE,
4486 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
4489 avio_seek(pb, end, SEEK_SET);
4496 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4498 while (atom.size > 8) {
4502 tag = avio_rl32(pb);
4504 if (tag == MKTAG('h','d','l','r')) {
4505 avio_seek(pb, -8, SEEK_CUR);
4507 return mov_read_default(c, pb, atom);
4513 // return 1 when matrix is identity, 0 otherwise
4514 #define IS_MATRIX_IDENT(matrix) \
4515 ( (matrix)[0][0] == (1 << 16) && \
4516 (matrix)[1][1] == (1 << 16) && \
4517 (matrix)[2][2] == (1 << 30) && \
4518 !(matrix)[0][1] && !(matrix)[0][2] && \
4519 !(matrix)[1][0] && !(matrix)[1][2] && \
4520 !(matrix)[2][0] && !(matrix)[2][1])
4522 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4527 int display_matrix[3][3];
4528 int res_display_matrix[3][3] = { { 0 } };
4530 MOVStreamContext *sc;
4534 if (c->fc->nb_streams < 1)
4536 st = c->fc->streams[c->fc->nb_streams-1];
4539 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4540 // avoids corrupting AVStreams mapped to an earlier tkhd.
4542 return AVERROR_INVALIDDATA;
4544 version = avio_r8(pb);
4545 flags = avio_rb24(pb);
4546 st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
4552 avio_rb32(pb); /* creation time */
4553 avio_rb32(pb); /* modification time */
4555 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4556 avio_rb32(pb); /* reserved */
4558 /* highlevel (considering edits) duration in movie timebase */
4559 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4560 avio_rb32(pb); /* reserved */
4561 avio_rb32(pb); /* reserved */
4563 avio_rb16(pb); /* layer */
4564 avio_rb16(pb); /* alternate group */
4565 avio_rb16(pb); /* volume */
4566 avio_rb16(pb); /* reserved */
4568 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4569 // they're kept in fixed point format through all calculations
4570 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4571 // side data, but the scale factor is not needed to calculate aspect ratio
4572 for (i = 0; i < 3; i++) {
4573 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
4574 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
4575 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
4578 width = avio_rb32(pb); // 16.16 fixed point track width
4579 height = avio_rb32(pb); // 16.16 fixed point track height
4580 sc->width = width >> 16;
4581 sc->height = height >> 16;
4583 // apply the moov display matrix (after the tkhd one)
4584 for (i = 0; i < 3; i++) {
4585 const int sh[3] = { 16, 16, 30 };
4586 for (j = 0; j < 3; j++) {
4587 for (e = 0; e < 3; e++) {
4588 res_display_matrix[i][j] +=
4589 ((int64_t) display_matrix[i][e] *
4590 c->movie_display_matrix[e][j]) >> sh[e];
4595 // save the matrix when it is not the default identity
4596 if (!IS_MATRIX_IDENT(res_display_matrix)) {
4599 av_freep(&sc->display_matrix);
4600 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4601 if (!sc->display_matrix)
4602 return AVERROR(ENOMEM);
4604 for (i = 0; i < 3; i++)
4605 for (j = 0; j < 3; j++)
4606 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4608 #if FF_API_OLD_ROTATE_API
4609 rotate = av_display_rotation_get(sc->display_matrix);
4610 if (!isnan(rotate)) {
4611 char rotate_buf[64];
4613 if (rotate < 0) // for backward compatibility
4615 snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate);
4616 av_dict_set(&st->metadata, "rotate", rotate_buf, 0);
4621 // transform the display width/height according to the matrix
4622 // to keep the same scale, use [width height 1<<16]
4623 if (width && height && sc->display_matrix) {
4624 double disp_transform[2];
4626 for (i = 0; i < 2; i++)
4627 disp_transform[i] = hypot(sc->display_matrix[0 + i],
4628 sc->display_matrix[3 + i]);
4630 if (disp_transform[0] > 0 && disp_transform[1] > 0 &&
4631 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4632 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4633 st->sample_aspect_ratio = av_d2q(
4634 disp_transform[0] / disp_transform[1],
4640 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4642 MOVFragment *frag = &c->fragment;
4643 MOVTrackExt *trex = NULL;
4644 int flags, track_id, i;
4645 MOVFragmentStreamInfo * frag_stream_info;
4647 avio_r8(pb); /* version */
4648 flags = avio_rb24(pb);
4650 track_id = avio_rb32(pb);
4652 return AVERROR_INVALIDDATA;
4653 for (i = 0; i < c->trex_count; i++)
4654 if (c->trex_data[i].track_id == track_id) {
4655 trex = &c->trex_data[i];
4659 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4662 c->fragment.found_tfhd = 1;
4663 frag->track_id = track_id;
4664 set_frag_stream(&c->frag_index, track_id);
4666 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4667 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4668 frag->moof_offset : frag->implicit_offset;
4669 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4671 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4672 avio_rb32(pb) : trex->duration;
4673 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4674 avio_rb32(pb) : trex->size;
4675 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4676 avio_rb32(pb) : trex->flags;
4677 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4679 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4680 if (frag_stream_info)
4681 frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
4686 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4691 num = atom.size / 4;
4692 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4693 return AVERROR(ENOMEM);
4695 av_free(c->chapter_tracks);
4696 c->chapter_tracks = new_tracks;
4697 c->nb_chapter_tracks = num;
4699 for (i = 0; i < num && !pb->eof_reached; i++)
4700 c->chapter_tracks[i] = avio_rb32(pb);
4705 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4710 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4711 return AVERROR_INVALIDDATA;
4712 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4713 sizeof(*c->trex_data))) < 0) {
4718 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4720 trex = &c->trex_data[c->trex_count++];
4721 avio_r8(pb); /* version */
4722 avio_rb24(pb); /* flags */
4723 trex->track_id = avio_rb32(pb);
4724 trex->stsd_id = avio_rb32(pb);
4725 trex->duration = avio_rb32(pb);
4726 trex->size = avio_rb32(pb);
4727 trex->flags = avio_rb32(pb);
4731 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4733 MOVFragment *frag = &c->fragment;
4734 AVStream *st = NULL;
4735 MOVStreamContext *sc;
4737 MOVFragmentStreamInfo * frag_stream_info;
4738 int64_t base_media_decode_time;
4740 for (i = 0; i < c->fc->nb_streams; i++) {
4741 if (c->fc->streams[i]->id == frag->track_id) {
4742 st = c->fc->streams[i];
4747 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4751 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4753 version = avio_r8(pb);
4754 avio_rb24(pb); /* flags */
4756 base_media_decode_time = avio_rb64(pb);
4758 base_media_decode_time = avio_rb32(pb);
4761 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4762 if (frag_stream_info)
4763 frag_stream_info->tfdt_dts = base_media_decode_time;
4764 sc->track_end = base_media_decode_time;
4769 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4771 MOVFragment *frag = &c->fragment;
4772 AVStream *st = NULL;
4773 MOVStreamContext *sc;
4776 int64_t dts, pts = AV_NOPTS_VALUE;
4777 int data_offset = 0;
4778 unsigned entries, first_sample_flags = frag->flags;
4779 int flags, distance, i;
4780 int64_t prev_dts = AV_NOPTS_VALUE;
4781 int next_frag_index = -1, index_entry_pos;
4782 size_t requested_size;
4783 size_t old_ctts_allocated_size;
4784 AVIndexEntry *new_entries;
4785 MOVFragmentStreamInfo * frag_stream_info;
4787 if (!frag->found_tfhd) {
4788 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4789 return AVERROR_INVALIDDATA;
4792 for (i = 0; i < c->fc->nb_streams; i++) {
4793 if (c->fc->streams[i]->id == frag->track_id) {
4794 st = c->fc->streams[i];
4799 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4803 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4806 // Find the next frag_index index that has a valid index_entry for
4807 // the current track_id.
4809 // A valid index_entry means the trun for the fragment was read
4810 // and it's samples are in index_entries at the given position.
4811 // New index entries will be inserted before the index_entry found.
4812 index_entry_pos = st->internal->nb_index_entries;
4813 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4814 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4815 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4816 next_frag_index = i;
4817 index_entry_pos = frag_stream_info->index_entry;
4821 av_assert0(index_entry_pos <= st->internal->nb_index_entries);
4823 avio_r8(pb); /* version */
4824 flags = avio_rb24(pb);
4825 entries = avio_rb32(pb);
4826 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4828 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4829 return AVERROR_INVALIDDATA;
4830 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4831 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4833 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4834 if (frag_stream_info) {
4835 if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
4836 dts = frag_stream_info->next_trun_dts - sc->time_offset;
4837 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4838 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4839 pts = frag_stream_info->first_tfra_pts;
4840 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4841 ", using it for pts\n", pts);
4842 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4843 c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
4844 dts = frag_stream_info->first_tfra_pts;
4845 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4846 ", using it for dts\n", pts);
4847 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4848 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4849 // pts = frag_stream_info->sidx_pts;
4850 dts = frag_stream_info->sidx_pts - sc->time_offset;
4851 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4852 ", using it for pts\n", pts);
4853 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4854 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4855 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4856 ", using it for dts\n", dts);
4858 dts = sc->track_end - sc->time_offset;
4859 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4860 ", using it for dts\n", dts);
4863 dts = sc->track_end - sc->time_offset;
4864 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4865 ", using it for dts\n", dts);
4867 offset = frag->base_data_offset + data_offset;
4869 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4871 // realloc space for new index entries
4872 if((uint64_t)st->internal->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4873 entries = UINT_MAX / sizeof(AVIndexEntry) - st->internal->nb_index_entries;
4874 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4879 requested_size = (st->internal->nb_index_entries + entries) * sizeof(AVIndexEntry);
4880 new_entries = av_fast_realloc(st->internal->index_entries,
4881 &st->internal->index_entries_allocated_size,
4884 return AVERROR(ENOMEM);
4885 st->internal->index_entries= new_entries;
4887 requested_size = (st->internal->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4888 old_ctts_allocated_size = sc->ctts_allocated_size;
4889 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4892 return AVERROR(ENOMEM);
4893 sc->ctts_data = ctts_data;
4895 // In case there were samples without ctts entries, ensure they get
4896 // zero valued entries. This ensures clips which mix boxes with and
4897 // without ctts entries don't pickup uninitialized data.
4898 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4899 sc->ctts_allocated_size - old_ctts_allocated_size);
4901 if (index_entry_pos < st->internal->nb_index_entries) {
4902 // Make hole in index_entries and ctts_data for new samples
4903 memmove(st->internal->index_entries + index_entry_pos + entries,
4904 st->internal->index_entries + index_entry_pos,
4905 sizeof(*st->internal->index_entries) *
4906 (st->internal->nb_index_entries - index_entry_pos));
4907 memmove(sc->ctts_data + index_entry_pos + entries,
4908 sc->ctts_data + index_entry_pos,
4909 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4910 if (index_entry_pos < sc->current_sample) {
4911 sc->current_sample += entries;
4915 st->internal->nb_index_entries += entries;
4916 sc->ctts_count = st->internal->nb_index_entries;
4918 // Record the index_entry position in frag_index of this fragment
4919 if (frag_stream_info)
4920 frag_stream_info->index_entry = index_entry_pos;
4922 if (index_entry_pos > 0)
4923 prev_dts = st->internal->index_entries[index_entry_pos-1].timestamp;
4925 for (i = 0; i < entries && !pb->eof_reached; i++) {
4926 unsigned sample_size = frag->size;
4927 int sample_flags = i ? frag->flags : first_sample_flags;
4928 unsigned sample_duration = frag->duration;
4929 unsigned ctts_duration = 0;
4931 int index_entry_flags = 0;
4933 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4934 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4935 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4936 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4938 mov_update_dts_shift(sc, ctts_duration, c->fc);
4939 if (pts != AV_NOPTS_VALUE) {
4940 dts = pts - sc->dts_shift;
4941 if (flags & MOV_TRUN_SAMPLE_CTS) {
4942 dts -= ctts_duration;
4944 dts -= sc->time_offset;
4946 av_log(c->fc, AV_LOG_DEBUG,
4947 "pts %"PRId64" calculated dts %"PRId64
4948 " sc->dts_shift %d ctts.duration %d"
4949 " sc->time_offset %"PRId64
4950 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4952 sc->dts_shift, ctts_duration,
4953 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4954 pts = AV_NOPTS_VALUE;
4957 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4961 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4962 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4965 index_entry_flags |= AVINDEX_KEYFRAME;
4967 // Fragments can overlap in time. Discard overlapping frames after
4969 if (prev_dts >= dts)
4970 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4972 st->internal->index_entries[index_entry_pos].pos = offset;
4973 st->internal->index_entries[index_entry_pos].timestamp = dts;
4974 st->internal->index_entries[index_entry_pos].size= sample_size;
4975 st->internal->index_entries[index_entry_pos].min_distance= distance;
4976 st->internal->index_entries[index_entry_pos].flags = index_entry_flags;
4978 sc->ctts_data[index_entry_pos].count = 1;
4979 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4982 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4983 "size %u, distance %d, keyframe %d\n", st->index,
4984 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4986 dts += sample_duration;
4987 offset += sample_size;
4988 sc->data_size += sample_size;
4990 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4991 1 <= INT_MAX - sc->nb_frames_for_fps
4993 sc->duration_for_fps += sample_duration;
4994 sc->nb_frames_for_fps ++;
4997 if (frag_stream_info)
4998 frag_stream_info->next_trun_dts = dts + sc->time_offset;
5000 // EOF found before reading all entries. Fix the hole this would
5001 // leave in index_entries and ctts_data
5002 int gap = entries - i;
5003 memmove(st->internal->index_entries + index_entry_pos,
5004 st->internal->index_entries + index_entry_pos + gap,
5005 sizeof(*st->internal->index_entries) *
5006 (st->internal->nb_index_entries - (index_entry_pos + gap)));
5007 memmove(sc->ctts_data + index_entry_pos,
5008 sc->ctts_data + index_entry_pos + gap,
5009 sizeof(*sc->ctts_data) *
5010 (sc->ctts_count - (index_entry_pos + gap)));
5012 st->internal->nb_index_entries -= gap;
5013 sc->ctts_count -= gap;
5014 if (index_entry_pos < sc->current_sample) {
5015 sc->current_sample -= gap;
5020 // The end of this new fragment may overlap in time with the start
5021 // of the next fragment in index_entries. Mark the samples in the next
5022 // fragment that overlap with AVINDEX_DISCARD_FRAME
5023 prev_dts = AV_NOPTS_VALUE;
5024 if (index_entry_pos > 0)
5025 prev_dts = st->internal->index_entries[index_entry_pos-1].timestamp;
5026 for (i = index_entry_pos; i < st->internal->nb_index_entries; i++) {
5027 if (prev_dts < st->internal->index_entries[i].timestamp)
5029 st->internal->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
5032 // If a hole was created to insert the new index_entries into,
5033 // the index_entry recorded for all subsequent moof must
5034 // be incremented by the number of entries inserted.
5035 fix_frag_index_entries(&c->frag_index, next_frag_index,
5036 frag->track_id, entries);
5038 if (pb->eof_reached) {
5039 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
5043 frag->implicit_offset = offset;
5045 sc->track_end = dts + sc->time_offset;
5046 if (st->duration < sc->track_end)
5047 st->duration = sc->track_end;
5052 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5054 int64_t stream_size = avio_size(pb);
5055 int64_t offset = avio_tell(pb) + atom.size, pts, timestamp;
5056 uint8_t version, is_complete;
5057 unsigned i, j, track_id, item_count;
5058 AVStream *st = NULL;
5059 AVStream *ref_st = NULL;
5060 MOVStreamContext *sc, *ref_sc = NULL;
5061 AVRational timescale;
5063 version = avio_r8(pb);
5065 avpriv_request_sample(c->fc, "sidx version %u", version);
5069 avio_rb24(pb); // flags
5071 track_id = avio_rb32(pb); // Reference ID
5072 for (i = 0; i < c->fc->nb_streams; i++) {
5073 if (c->fc->streams[i]->id == track_id) {
5074 st = c->fc->streams[i];
5079 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5085 timescale = av_make_q(1, avio_rb32(pb));
5087 if (timescale.den <= 0) {
5088 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5089 return AVERROR_INVALIDDATA;
5093 pts = avio_rb32(pb);
5094 offset += avio_rb32(pb);
5096 pts = avio_rb64(pb);
5097 offset += avio_rb64(pb);
5100 avio_rb16(pb); // reserved
5102 item_count = avio_rb16(pb);
5104 for (i = 0; i < item_count; i++) {
5106 MOVFragmentStreamInfo * frag_stream_info;
5107 uint32_t size = avio_rb32(pb);
5108 uint32_t duration = avio_rb32(pb);
5109 if (size & 0x80000000) {
5110 avpriv_request_sample(c->fc, "sidx reference_type 1");
5111 return AVERROR_PATCHWELCOME;
5113 avio_rb32(pb); // sap_flags
5114 timestamp = av_rescale_q(pts, timescale, st->time_base);
5116 index = update_frag_index(c, offset);
5117 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5118 if (frag_stream_info)
5119 frag_stream_info->sidx_pts = timestamp;
5125 st->duration = sc->track_end = pts;
5129 // See if the remaining bytes are just an mfra which we can ignore.
5130 is_complete = offset == stream_size;
5131 if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL)) {
5133 int64_t original_pos = avio_tell(pb);
5134 if (!c->have_read_mfra_size) {
5135 if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
5137 c->mfra_size = avio_rb32(pb);
5138 c->have_read_mfra_size = 1;
5139 if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
5142 if (offset + c->mfra_size == stream_size)
5147 // Find first entry in fragment index that came from an sidx.
5148 // This will pretty much always be the first entry.
5149 for (i = 0; i < c->frag_index.nb_items; i++) {
5150 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5151 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5152 MOVFragmentStreamInfo * si;
5153 si = &item->stream_info[j];
5154 if (si->sidx_pts != AV_NOPTS_VALUE) {
5155 ref_st = c->fc->streams[j];
5156 ref_sc = ref_st->priv_data;
5161 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5162 st = c->fc->streams[i];
5164 if (!sc->has_sidx) {
5165 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5169 c->frag_index.complete = 1;
5175 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5176 /* like the files created with Adobe Premiere 5.0, for samples see */
5177 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5178 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5183 return 0; /* continue */
5184 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5185 avio_skip(pb, atom.size - 4);
5188 atom.type = avio_rl32(pb);
5190 if (atom.type != MKTAG('m','d','a','t')) {
5191 avio_skip(pb, atom.size);
5194 err = mov_read_mdat(c, pb, atom);
5198 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5203 uint8_t *moov_data; /* uncompressed data */
5204 long cmov_len, moov_len;
5207 avio_rb32(pb); /* dcom atom */
5208 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5209 return AVERROR_INVALIDDATA;
5210 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5211 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5212 return AVERROR_INVALIDDATA;
5214 avio_rb32(pb); /* cmvd atom */
5215 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5216 return AVERROR_INVALIDDATA;
5217 moov_len = avio_rb32(pb); /* uncompressed size */
5218 cmov_len = atom.size - 6 * 4;
5220 cmov_data = av_malloc(cmov_len);
5222 return AVERROR(ENOMEM);
5223 moov_data = av_malloc(moov_len);
5226 return AVERROR(ENOMEM);
5228 ret = ffio_read_size(pb, cmov_data, cmov_len);
5230 goto free_and_return;
5232 ret = AVERROR_INVALIDDATA;
5233 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5234 goto free_and_return;
5235 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5236 goto free_and_return;
5237 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5238 atom.type = MKTAG('m','o','o','v');
5239 atom.size = moov_len;
5240 ret = mov_read_default(c, &ctx, atom);
5246 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5247 return AVERROR(ENOSYS);
5251 /* edit list atom */
5252 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5254 MOVStreamContext *sc;
5255 int i, edit_count, version;
5256 int64_t elst_entry_size;
5258 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5260 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5262 version = avio_r8(pb); /* version */
5263 avio_rb24(pb); /* flags */
5264 edit_count = avio_rb32(pb); /* entries */
5267 elst_entry_size = version == 1 ? 20 : 12;
5268 if (atom.size != edit_count * elst_entry_size) {
5269 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5270 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5271 edit_count, atom.size + 8);
5272 return AVERROR_INVALIDDATA;
5274 edit_count = atom.size / elst_entry_size;
5275 if (edit_count * elst_entry_size != atom.size) {
5276 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
5284 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5285 av_free(sc->elst_data);
5287 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5289 return AVERROR(ENOMEM);
5291 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5292 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5293 MOVElst *e = &sc->elst_data[i];
5296 e->duration = avio_rb64(pb);
5297 e->time = avio_rb64(pb);
5300 e->duration = avio_rb32(pb); /* segment duration */
5301 e->time = (int32_t)avio_rb32(pb); /* media time */
5304 e->rate = avio_rb32(pb) / 65536.0;
5306 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5307 e->duration, e->time, e->rate);
5309 if (e->time < 0 && e->time != -1 &&
5310 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5311 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5312 c->fc->nb_streams-1, i, e->time);
5313 return AVERROR_INVALIDDATA;
5321 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5323 MOVStreamContext *sc;
5325 if (c->fc->nb_streams < 1)
5326 return AVERROR_INVALIDDATA;
5327 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5328 sc->timecode_track = avio_rb32(pb);
5332 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5337 if (c->fc->nb_streams < 1)
5339 st = c->fc->streams[c->fc->nb_streams - 1];
5341 if (atom.size < 4) {
5342 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5343 return AVERROR_INVALIDDATA;
5346 /* For now, propagate only the OBUs, if any. Once libavcodec is
5347 updated to handle isobmff style extradata this can be removed. */
5353 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5360 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5363 int version, color_range, color_primaries, color_trc, color_space;
5365 if (c->fc->nb_streams < 1)
5367 st = c->fc->streams[c->fc->nb_streams - 1];
5369 if (atom.size < 5) {
5370 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5371 return AVERROR_INVALIDDATA;
5374 version = avio_r8(pb);
5376 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5379 avio_skip(pb, 3); /* flags */
5381 avio_skip(pb, 2); /* profile + level */
5382 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5383 color_primaries = avio_r8(pb);
5384 color_trc = avio_r8(pb);
5385 color_space = avio_r8(pb);
5386 if (avio_rb16(pb)) /* codecIntializationDataSize */
5387 return AVERROR_INVALIDDATA;
5389 if (!av_color_primaries_name(color_primaries))
5390 color_primaries = AVCOL_PRI_UNSPECIFIED;
5391 if (!av_color_transfer_name(color_trc))
5392 color_trc = AVCOL_TRC_UNSPECIFIED;
5393 if (!av_color_space_name(color_space))
5394 color_space = AVCOL_SPC_UNSPECIFIED;
5396 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5397 st->codecpar->color_primaries = color_primaries;
5398 st->codecpar->color_trc = color_trc;
5399 st->codecpar->color_space = color_space;
5404 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5406 MOVStreamContext *sc;
5409 if (c->fc->nb_streams < 1)
5410 return AVERROR_INVALIDDATA;
5412 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5414 if (atom.size < 5) {
5415 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5416 return AVERROR_INVALIDDATA;
5419 version = avio_r8(pb);
5421 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5424 avio_skip(pb, 3); /* flags */
5426 sc->mastering = av_mastering_display_metadata_alloc();
5428 return AVERROR(ENOMEM);
5430 for (i = 0; i < 3; i++) {
5431 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5432 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5434 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5435 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5437 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5438 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5440 sc->mastering->has_primaries = 1;
5441 sc->mastering->has_luminance = 1;
5446 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5448 MOVStreamContext *sc;
5449 const int mapping[3] = {1, 2, 0};
5450 const int chroma_den = 50000;
5451 const int luma_den = 10000;
5454 if (c->fc->nb_streams < 1)
5455 return AVERROR_INVALIDDATA;
5457 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5459 if (atom.size < 24) {
5460 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5461 return AVERROR_INVALIDDATA;
5464 sc->mastering = av_mastering_display_metadata_alloc();
5466 return AVERROR(ENOMEM);
5468 for (i = 0; i < 3; i++) {
5469 const int j = mapping[i];
5470 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5471 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5473 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5474 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5476 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5477 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5479 sc->mastering->has_luminance = 1;
5480 sc->mastering->has_primaries = 1;
5485 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5487 MOVStreamContext *sc;
5490 if (c->fc->nb_streams < 1)
5491 return AVERROR_INVALIDDATA;
5493 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5495 if (atom.size < 5) {
5496 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5497 return AVERROR_INVALIDDATA;
5500 version = avio_r8(pb);
5502 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5505 avio_skip(pb, 3); /* flags */
5507 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5509 return AVERROR(ENOMEM);
5511 sc->coll->MaxCLL = avio_rb16(pb);
5512 sc->coll->MaxFALL = avio_rb16(pb);
5517 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5519 MOVStreamContext *sc;
5521 if (c->fc->nb_streams < 1)
5522 return AVERROR_INVALIDDATA;
5524 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5526 if (atom.size < 4) {
5527 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5528 return AVERROR_INVALIDDATA;
5531 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5533 return AVERROR(ENOMEM);
5535 sc->coll->MaxCLL = avio_rb16(pb);
5536 sc->coll->MaxFALL = avio_rb16(pb);
5541 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5544 MOVStreamContext *sc;
5545 enum AVStereo3DType type;
5548 if (c->fc->nb_streams < 1)
5551 st = c->fc->streams[c->fc->nb_streams - 1];
5554 if (atom.size < 5) {
5555 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5556 return AVERROR_INVALIDDATA;
5558 avio_skip(pb, 4); /* version + flags */
5563 type = AV_STEREO3D_2D;
5566 type = AV_STEREO3D_TOPBOTTOM;
5569 type = AV_STEREO3D_SIDEBYSIDE;
5572 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5576 sc->stereo3d = av_stereo3d_alloc();
5578 return AVERROR(ENOMEM);
5580 sc->stereo3d->type = type;
5584 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5587 MOVStreamContext *sc;
5588 int size, version, layout;
5589 int32_t yaw, pitch, roll;
5590 uint32_t l = 0, t = 0, r = 0, b = 0;
5591 uint32_t tag, padding = 0;
5592 enum AVSphericalProjection projection;
5594 if (c->fc->nb_streams < 1)
5597 st = c->fc->streams[c->fc->nb_streams - 1];
5600 if (atom.size < 8) {
5601 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5602 return AVERROR_INVALIDDATA;
5605 size = avio_rb32(pb);
5606 if (size <= 12 || size > atom.size)
5607 return AVERROR_INVALIDDATA;
5609 tag = avio_rl32(pb);
5610 if (tag != MKTAG('s','v','h','d')) {
5611 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5614 version = avio_r8(pb);
5616 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5620 avio_skip(pb, 3); /* flags */
5621 avio_skip(pb, size - 12); /* metadata_source */
5623 size = avio_rb32(pb);
5624 if (size > atom.size)
5625 return AVERROR_INVALIDDATA;
5627 tag = avio_rl32(pb);
5628 if (tag != MKTAG('p','r','o','j')) {
5629 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5633 size = avio_rb32(pb);
5634 if (size > atom.size)
5635 return AVERROR_INVALIDDATA;
5637 tag = avio_rl32(pb);
5638 if (tag != MKTAG('p','r','h','d')) {
5639 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5642 version = avio_r8(pb);
5644 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5648 avio_skip(pb, 3); /* flags */
5650 /* 16.16 fixed point */
5651 yaw = avio_rb32(pb);
5652 pitch = avio_rb32(pb);
5653 roll = avio_rb32(pb);
5655 size = avio_rb32(pb);
5656 if (size > atom.size)
5657 return AVERROR_INVALIDDATA;
5659 tag = avio_rl32(pb);
5660 version = avio_r8(pb);
5662 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5666 avio_skip(pb, 3); /* flags */
5668 case MKTAG('c','b','m','p'):
5669 layout = avio_rb32(pb);
5671 av_log(c->fc, AV_LOG_WARNING,
5672 "Unsupported cubemap layout %d\n", layout);
5675 projection = AV_SPHERICAL_CUBEMAP;
5676 padding = avio_rb32(pb);
5678 case MKTAG('e','q','u','i'):
5684 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5685 av_log(c->fc, AV_LOG_ERROR,
5686 "Invalid bounding rectangle coordinates "
5687 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5688 return AVERROR_INVALIDDATA;
5691 if (l || t || r || b)
5692 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5694 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5697 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5701 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5703 return AVERROR(ENOMEM);
5705 sc->spherical->projection = projection;
5707 sc->spherical->yaw = yaw;
5708 sc->spherical->pitch = pitch;
5709 sc->spherical->roll = roll;
5711 sc->spherical->padding = padding;
5713 sc->spherical->bound_left = l;
5714 sc->spherical->bound_top = t;
5715 sc->spherical->bound_right = r;
5716 sc->spherical->bound_bottom = b;
5721 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5724 uint8_t *buffer = av_malloc(len + 1);
5728 return AVERROR(ENOMEM);
5731 ret = ffio_read_size(pb, buffer, len);
5735 /* Check for mandatory keys and values, try to support XML as best-effort */
5736 if (!sc->spherical &&
5737 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5738 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5739 av_stristr(val, "true") &&
5740 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5741 av_stristr(val, "true") &&
5742 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5743 av_stristr(val, "equirectangular")) {
5744 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5748 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5750 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5751 enum AVStereo3DType mode;
5753 if (av_stristr(buffer, "left-right"))
5754 mode = AV_STEREO3D_SIDEBYSIDE;
5755 else if (av_stristr(buffer, "top-bottom"))
5756 mode = AV_STEREO3D_TOPBOTTOM;
5758 mode = AV_STEREO3D_2D;
5760 sc->stereo3d = av_stereo3d_alloc();
5764 sc->stereo3d->type = mode;
5768 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5770 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5771 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5773 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5774 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5776 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5784 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5787 MOVStreamContext *sc;
5790 static const uint8_t uuid_isml_manifest[] = {
5791 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5792 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5794 static const uint8_t uuid_xmp[] = {
5795 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5796 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5798 static const uint8_t uuid_spherical[] = {
5799 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5800 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5803 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5804 return AVERROR_INVALIDDATA;
5806 if (c->fc->nb_streams < 1)
5808 st = c->fc->streams[c->fc->nb_streams - 1];
5811 ret = ffio_read_size(pb, uuid, sizeof(uuid));
5814 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5815 uint8_t *buffer, *ptr;
5817 size_t len = atom.size - sizeof(uuid);
5820 return AVERROR_INVALIDDATA;
5822 ret = avio_skip(pb, 4); // zeroes
5825 buffer = av_mallocz(len + 1);
5827 return AVERROR(ENOMEM);
5829 ret = ffio_read_size(pb, buffer, len);
5836 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5837 ptr += sizeof("systemBitrate=\"") - 1;
5838 c->bitrates_count++;
5839 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5841 c->bitrates_count = 0;
5843 return AVERROR(ENOMEM);
5846 ret = strtol(ptr, &endptr, 10);
5847 if (ret < 0 || errno || *endptr != '"') {
5848 c->bitrates[c->bitrates_count - 1] = 0;
5850 c->bitrates[c->bitrates_count - 1] = ret;
5855 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5857 size_t len = atom.size - sizeof(uuid);
5858 if (c->export_xmp) {
5859 buffer = av_mallocz(len + 1);
5861 return AVERROR(ENOMEM);
5863 ret = ffio_read_size(pb, buffer, len);
5869 av_dict_set(&c->fc->metadata, "xmp",
5870 buffer, AV_DICT_DONT_STRDUP_VAL);
5872 // skip all uuid atom, which makes it fast for long uuid-xmp file
5873 ret = avio_skip(pb, len);
5877 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5878 size_t len = atom.size - sizeof(uuid);
5879 ret = mov_parse_uuid_spherical(sc, pb, len);
5883 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5889 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5892 uint8_t content[16];
5897 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5903 && !memcmp(content, "Anevia\x1A\x1A", 8)
5904 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5905 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5911 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5913 uint32_t format = avio_rl32(pb);
5914 MOVStreamContext *sc;
5918 if (c->fc->nb_streams < 1)
5920 st = c->fc->streams[c->fc->nb_streams - 1];
5925 case MKTAG('e','n','c','v'): // encrypted video
5926 case MKTAG('e','n','c','a'): // encrypted audio
5927 id = mov_codec_id(st, format);
5928 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5929 st->codecpar->codec_id != id) {
5930 av_log(c->fc, AV_LOG_WARNING,
5931 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5932 (char*)&format, st->codecpar->codec_id);
5936 st->codecpar->codec_id = id;
5937 sc->format = format;
5941 if (format != sc->format) {
5942 av_log(c->fc, AV_LOG_WARNING,
5943 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5944 (char*)&format, (char*)&sc->format);
5953 * Gets the current encryption info and associated current stream context. If
5954 * we are parsing a track fragment, this will return the specific encryption
5955 * info for this fragment; otherwise this will return the global encryption
5956 * info for the current stream.
5958 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5960 MOVFragmentStreamInfo *frag_stream_info;
5964 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5965 if (frag_stream_info) {
5966 for (i = 0; i < c->fc->nb_streams; i++) {
5967 if (c->fc->streams[i]->id == frag_stream_info->id) {
5968 st = c->fc->streams[i];
5972 if (i == c->fc->nb_streams)
5974 *sc = st->priv_data;
5976 if (!frag_stream_info->encryption_index) {
5977 // If this stream isn't encrypted, don't create the index.
5978 if (!(*sc)->cenc.default_encrypted_sample)
5980 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5981 if (!frag_stream_info->encryption_index)
5982 return AVERROR(ENOMEM);
5984 *encryption_index = frag_stream_info->encryption_index;
5987 // No current track fragment, using stream level encryption info.
5989 if (c->fc->nb_streams < 1)
5991 st = c->fc->streams[c->fc->nb_streams - 1];
5992 *sc = st->priv_data;
5994 if (!(*sc)->cenc.encryption_index) {
5995 // If this stream isn't encrypted, don't create the index.
5996 if (!(*sc)->cenc.default_encrypted_sample)
5998 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5999 if (!(*sc)->cenc.encryption_index)
6000 return AVERROR(ENOMEM);
6003 *encryption_index = (*sc)->cenc.encryption_index;
6008 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
6011 unsigned int subsample_count;
6012 AVSubsampleEncryptionInfo *subsamples;
6014 if (!sc->cenc.default_encrypted_sample) {
6015 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
6016 return AVERROR_INVALIDDATA;
6019 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
6021 return AVERROR(ENOMEM);
6023 if (sc->cenc.per_sample_iv_size != 0) {
6024 if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
6025 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
6026 av_encryption_info_free(*sample);
6032 if (use_subsamples) {
6033 subsample_count = avio_rb16(pb);
6034 av_free((*sample)->subsamples);
6035 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
6036 if (!(*sample)->subsamples) {
6037 av_encryption_info_free(*sample);
6039 return AVERROR(ENOMEM);
6042 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
6043 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
6044 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
6047 if (pb->eof_reached) {
6048 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
6049 av_encryption_info_free(*sample);
6051 return AVERROR_INVALIDDATA;
6053 (*sample)->subsample_count = subsample_count;
6059 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6061 AVEncryptionInfo **encrypted_samples;
6062 MOVEncryptionIndex *encryption_index;
6063 MOVStreamContext *sc;
6064 int use_subsamples, ret;
6065 unsigned int sample_count, i, alloc_size = 0;
6067 ret = get_current_encryption_info(c, &encryption_index, &sc);
6071 if (encryption_index->nb_encrypted_samples) {
6072 // This can happen if we have both saio/saiz and senc atoms.
6073 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6077 avio_r8(pb); /* version */
6078 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6080 sample_count = avio_rb32(pb);
6081 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6082 return AVERROR(ENOMEM);
6084 for (i = 0; i < sample_count; i++) {
6085 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6086 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6087 min_samples * sizeof(*encrypted_samples));
6088 if (encrypted_samples) {
6089 encryption_index->encrypted_samples = encrypted_samples;
6091 ret = mov_read_sample_encryption_info(
6092 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6094 ret = AVERROR(ENOMEM);
6096 if (pb->eof_reached) {
6097 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6098 ret = AVERROR_INVALIDDATA;
6103 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6104 av_freep(&encryption_index->encrypted_samples);
6108 encryption_index->nb_encrypted_samples = sample_count;
6113 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6115 AVEncryptionInfo **sample, **encrypted_samples;
6117 size_t sample_count, sample_info_size, i;
6119 unsigned int alloc_size = 0;
6121 if (encryption_index->nb_encrypted_samples)
6123 sample_count = encryption_index->auxiliary_info_sample_count;
6124 if (encryption_index->auxiliary_offsets_count != 1) {
6125 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6126 return AVERROR_PATCHWELCOME;
6128 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6129 return AVERROR(ENOMEM);
6131 prev_pos = avio_tell(pb);
6132 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6133 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6134 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6138 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6139 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6140 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6141 min_samples * sizeof(*encrypted_samples));
6142 if (!encrypted_samples) {
6143 ret = AVERROR(ENOMEM);
6146 encryption_index->encrypted_samples = encrypted_samples;
6148 sample = &encryption_index->encrypted_samples[i];
6149 sample_info_size = encryption_index->auxiliary_info_default_size
6150 ? encryption_index->auxiliary_info_default_size
6151 : encryption_index->auxiliary_info_sizes[i];
6153 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6157 if (pb->eof_reached) {
6158 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6159 ret = AVERROR_INVALIDDATA;
6161 encryption_index->nb_encrypted_samples = sample_count;
6165 avio_seek(pb, prev_pos, SEEK_SET);
6167 for (; i > 0; i--) {
6168 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6170 av_freep(&encryption_index->encrypted_samples);
6176 * Tries to read the given number of bytes from the stream and puts it in a
6177 * newly allocated buffer. This reads in small chunks to avoid allocating large
6178 * memory if the file contains an invalid/malicious size value.
6180 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6182 const unsigned int block_size = 1024 * 1024;
6183 uint8_t *buffer = NULL;
6184 unsigned int alloc_size = 0, offset = 0;
6185 while (offset < size) {
6186 unsigned int new_size =
6187 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6188 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6189 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6192 return AVERROR(ENOMEM);
6194 buffer = new_buffer;
6196 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6198 return AVERROR_INVALIDDATA;
6207 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6209 MOVEncryptionIndex *encryption_index;
6210 MOVStreamContext *sc;
6212 unsigned int sample_count, aux_info_type, aux_info_param;
6214 ret = get_current_encryption_info(c, &encryption_index, &sc);
6218 if (encryption_index->nb_encrypted_samples) {
6219 // This can happen if we have both saio/saiz and senc atoms.
6220 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6224 if (encryption_index->auxiliary_info_sample_count) {
6225 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6226 return AVERROR_INVALIDDATA;
6229 avio_r8(pb); /* version */
6230 if (avio_rb24(pb) & 0x01) { /* flags */
6231 aux_info_type = avio_rb32(pb);
6232 aux_info_param = avio_rb32(pb);
6233 if (sc->cenc.default_encrypted_sample) {
6234 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6235 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6238 if (aux_info_param != 0) {
6239 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6243 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6244 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6245 aux_info_type == MKBETAG('c','e','n','s') ||
6246 aux_info_type == MKBETAG('c','b','c','1') ||
6247 aux_info_type == MKBETAG('c','b','c','s')) &&
6248 aux_info_param == 0) {
6249 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6250 return AVERROR_INVALIDDATA;
6255 } else if (!sc->cenc.default_encrypted_sample) {
6256 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6260 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6261 sample_count = avio_rb32(pb);
6262 encryption_index->auxiliary_info_sample_count = sample_count;
6264 if (encryption_index->auxiliary_info_default_size == 0) {
6265 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6267 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6272 if (encryption_index->auxiliary_offsets_count) {
6273 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6279 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6281 uint64_t *auxiliary_offsets;
6282 MOVEncryptionIndex *encryption_index;
6283 MOVStreamContext *sc;
6285 unsigned int version, entry_count, aux_info_type, aux_info_param;
6286 unsigned int alloc_size = 0;
6288 ret = get_current_encryption_info(c, &encryption_index, &sc);
6292 if (encryption_index->nb_encrypted_samples) {
6293 // This can happen if we have both saio/saiz and senc atoms.
6294 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6298 if (encryption_index->auxiliary_offsets_count) {
6299 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6300 return AVERROR_INVALIDDATA;
6303 version = avio_r8(pb); /* version */
6304 if (avio_rb24(pb) & 0x01) { /* flags */
6305 aux_info_type = avio_rb32(pb);
6306 aux_info_param = avio_rb32(pb);
6307 if (sc->cenc.default_encrypted_sample) {
6308 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6309 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6312 if (aux_info_param != 0) {
6313 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6317 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6318 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6319 aux_info_type == MKBETAG('c','e','n','s') ||
6320 aux_info_type == MKBETAG('c','b','c','1') ||
6321 aux_info_type == MKBETAG('c','b','c','s')) &&
6322 aux_info_param == 0) {
6323 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6324 return AVERROR_INVALIDDATA;
6329 } else if (!sc->cenc.default_encrypted_sample) {
6330 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6334 entry_count = avio_rb32(pb);
6335 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6336 return AVERROR(ENOMEM);
6338 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6339 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6340 auxiliary_offsets = av_fast_realloc(
6341 encryption_index->auxiliary_offsets, &alloc_size,
6342 min_offsets * sizeof(*auxiliary_offsets));
6343 if (!auxiliary_offsets) {
6344 av_freep(&encryption_index->auxiliary_offsets);
6345 return AVERROR(ENOMEM);
6347 encryption_index->auxiliary_offsets = auxiliary_offsets;
6350 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6352 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6354 if (c->frag_index.current >= 0) {
6355 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6359 if (pb->eof_reached) {
6360 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6361 av_freep(&encryption_index->auxiliary_offsets);
6362 return AVERROR_INVALIDDATA;
6365 encryption_index->auxiliary_offsets_count = entry_count;
6367 if (encryption_index->auxiliary_info_sample_count) {
6368 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6374 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6376 AVEncryptionInitInfo *info, *old_init_info;
6379 uint8_t *side_data, *extra_data, *old_side_data;
6380 size_t side_data_size;
6381 int ret = 0, old_side_data_size;
6382 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6384 if (c->fc->nb_streams < 1)
6386 st = c->fc->streams[c->fc->nb_streams-1];
6388 version = avio_r8(pb); /* version */
6389 avio_rb24(pb); /* flags */
6391 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6392 /* key_id_size */ 16, /* data_size */ 0);
6394 return AVERROR(ENOMEM);
6396 if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
6397 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6402 kid_count = avio_rb32(pb);
6403 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
6404 ret = AVERROR(ENOMEM);
6408 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6409 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6410 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6411 min_kid_count * sizeof(*key_ids));
6413 ret = AVERROR(ENOMEM);
6416 info->key_ids = key_ids;
6418 info->key_ids[i] = av_mallocz(16);
6419 if (!info->key_ids[i]) {
6420 ret = AVERROR(ENOMEM);
6423 info->num_key_ids = i + 1;
6425 if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
6426 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6431 if (pb->eof_reached) {
6432 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6433 ret = AVERROR_INVALIDDATA;
6438 extra_data_size = avio_rb32(pb);
6439 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6443 av_freep(&info->data); // malloc(0) may still allocate something.
6444 info->data = extra_data;
6445 info->data_size = extra_data_size;
6447 // If there is existing initialization data, append to the list.
6448 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6449 if (old_side_data) {
6450 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6451 if (old_init_info) {
6452 // Append to the end of the list.
6453 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6459 info = old_init_info;
6461 // Assume existing side-data will be valid, so the only error we could get is OOM.
6462 ret = AVERROR(ENOMEM);
6467 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6469 ret = AVERROR(ENOMEM);
6472 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6473 side_data, side_data_size);
6478 av_encryption_init_info_free(info);
6482 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6485 MOVStreamContext *sc;
6487 if (c->fc->nb_streams < 1)
6489 st = c->fc->streams[c->fc->nb_streams-1];
6492 if (sc->pseudo_stream_id != 0) {
6493 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6494 return AVERROR_PATCHWELCOME;
6498 return AVERROR_INVALIDDATA;
6500 avio_rb32(pb); /* version and flags */
6502 if (!sc->cenc.default_encrypted_sample) {
6503 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6504 if (!sc->cenc.default_encrypted_sample) {
6505 return AVERROR(ENOMEM);
6509 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6513 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6516 MOVStreamContext *sc;
6517 unsigned int version, pattern, is_protected, iv_size;
6519 if (c->fc->nb_streams < 1)
6521 st = c->fc->streams[c->fc->nb_streams-1];
6524 if (sc->pseudo_stream_id != 0) {
6525 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6526 return AVERROR_PATCHWELCOME;
6529 if (!sc->cenc.default_encrypted_sample) {
6530 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6531 if (!sc->cenc.default_encrypted_sample) {
6532 return AVERROR(ENOMEM);
6537 return AVERROR_INVALIDDATA;
6539 version = avio_r8(pb); /* version */
6540 avio_rb24(pb); /* flags */
6542 avio_r8(pb); /* reserved */
6543 pattern = avio_r8(pb);
6546 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6547 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6550 is_protected = avio_r8(pb);
6551 if (is_protected && !sc->cenc.encryption_index) {
6552 // The whole stream should be by-default encrypted.
6553 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6554 if (!sc->cenc.encryption_index)
6555 return AVERROR(ENOMEM);
6557 sc->cenc.per_sample_iv_size = avio_r8(pb);
6558 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6559 sc->cenc.per_sample_iv_size != 16) {
6560 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6561 return AVERROR_INVALIDDATA;
6563 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6564 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6565 return AVERROR_INVALIDDATA;
6568 if (is_protected && !sc->cenc.per_sample_iv_size) {
6569 iv_size = avio_r8(pb);
6570 if (iv_size != 8 && iv_size != 16) {
6571 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6572 return AVERROR_INVALIDDATA;
6575 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6576 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6577 return AVERROR_INVALIDDATA;
6584 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6587 int last, type, size, ret;
6590 if (c->fc->nb_streams < 1)
6592 st = c->fc->streams[c->fc->nb_streams-1];
6594 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6595 return AVERROR_INVALIDDATA;
6597 /* Check FlacSpecificBox version. */
6598 if (avio_r8(pb) != 0)
6599 return AVERROR_INVALIDDATA;
6601 avio_rb24(pb); /* Flags */
6603 avio_read(pb, buf, sizeof(buf));
6604 flac_parse_block_header(buf, &last, &type, &size);
6606 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6607 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6608 return AVERROR_INVALIDDATA;
6611 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6616 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6621 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6625 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6626 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6627 return AVERROR_PATCHWELCOME;
6630 if (!sc->cenc.aes_ctr) {
6631 /* initialize the cipher */
6632 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6633 if (!sc->cenc.aes_ctr) {
6634 return AVERROR(ENOMEM);
6637 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6643 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6645 if (!sample->subsample_count) {
6646 /* decrypt the whole packet */
6647 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6651 for (i = 0; i < sample->subsample_count; i++) {
6652 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6653 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6654 return AVERROR_INVALIDDATA;
6657 /* skip the clear bytes */
6658 input += sample->subsamples[i].bytes_of_clear_data;
6659 size -= sample->subsamples[i].bytes_of_clear_data;
6661 /* decrypt the encrypted bytes */
6662 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6663 input += sample->subsamples[i].bytes_of_protected_data;
6664 size -= sample->subsamples[i].bytes_of_protected_data;
6668 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6669 return AVERROR_INVALIDDATA;
6675 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6677 MOVFragmentStreamInfo *frag_stream_info;
6678 MOVEncryptionIndex *encryption_index;
6679 AVEncryptionInfo *encrypted_sample;
6680 int encrypted_index, ret;
6682 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6683 encrypted_index = current_index;
6684 encryption_index = NULL;
6685 if (frag_stream_info) {
6686 // Note this only supports encryption info in the first sample descriptor.
6687 if (mov->fragment.stsd_id == 1) {
6688 if (frag_stream_info->encryption_index) {
6689 encrypted_index = current_index - frag_stream_info->index_entry;
6690 encryption_index = frag_stream_info->encryption_index;
6692 encryption_index = sc->cenc.encryption_index;
6696 encryption_index = sc->cenc.encryption_index;
6699 if (encryption_index) {
6700 if (encryption_index->auxiliary_info_sample_count &&
6701 !encryption_index->nb_encrypted_samples) {
6702 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6703 return AVERROR_INVALIDDATA;
6705 if (encryption_index->auxiliary_offsets_count &&
6706 !encryption_index->nb_encrypted_samples) {
6707 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6708 return AVERROR_INVALIDDATA;
6711 if (!encryption_index->nb_encrypted_samples) {
6712 // Full-sample encryption with default settings.
6713 encrypted_sample = sc->cenc.default_encrypted_sample;
6714 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6715 // Per-sample setting override.
6716 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6718 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6719 return AVERROR_INVALIDDATA;
6722 if (mov->decryption_key) {
6723 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6726 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6728 return AVERROR(ENOMEM);
6729 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6739 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6741 const int OPUS_SEEK_PREROLL_MS = 80;
6747 if (c->fc->nb_streams < 1)
6749 st = c->fc->streams[c->fc->nb_streams-1];
6751 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6752 return AVERROR_INVALIDDATA;
6754 /* Check OpusSpecificBox version. */
6755 if (avio_r8(pb) != 0) {
6756 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6757 return AVERROR_INVALIDDATA;
6760 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6761 size = atom.size + 8;
6763 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
6766 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6767 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6768 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6769 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6771 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6772 little-endian; aside from the preceeding magic and version they're
6773 otherwise currently identical. Data after output gain at offset 16
6774 doesn't need to be bytewapped. */
6775 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6776 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6777 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6778 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6780 st->codecpar->initial_padding = pre_skip;
6781 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6782 (AVRational){1, 1000},
6783 (AVRational){1, 48000});
6788 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6791 unsigned format_info;
6792 int channel_assignment, channel_assignment1, channel_assignment2;
6795 if (c->fc->nb_streams < 1)
6797 st = c->fc->streams[c->fc->nb_streams-1];
6800 return AVERROR_INVALIDDATA;
6802 format_info = avio_rb32(pb);
6804 ratebits = (format_info >> 28) & 0xF;
6805 channel_assignment1 = (format_info >> 15) & 0x1F;
6806 channel_assignment2 = format_info & 0x1FFF;
6807 if (channel_assignment2)
6808 channel_assignment = channel_assignment2;
6810 channel_assignment = channel_assignment1;
6812 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6813 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6814 st->codecpar->channels = truehd_channels(channel_assignment);
6815 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6820 static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6824 AVDOVIDecoderConfigurationRecord *dovi;
6828 if (c->fc->nb_streams < 1)
6830 st = c->fc->streams[c->fc->nb_streams-1];
6832 if ((uint64_t)atom.size > (1<<30) || atom.size < 4)
6833 return AVERROR_INVALIDDATA;
6835 dovi = av_dovi_alloc(&dovi_size);
6837 return AVERROR(ENOMEM);
6839 dovi->dv_version_major = avio_r8(pb);
6840 dovi->dv_version_minor = avio_r8(pb);
6842 buf = avio_rb16(pb);
6843 dovi->dv_profile = (buf >> 9) & 0x7f; // 7 bits
6844 dovi->dv_level = (buf >> 3) & 0x3f; // 6 bits
6845 dovi->rpu_present_flag = (buf >> 2) & 0x01; // 1 bit
6846 dovi->el_present_flag = (buf >> 1) & 0x01; // 1 bit
6847 dovi->bl_present_flag = buf & 0x01; // 1 bit
6848 if (atom.size >= 24) { // 4 + 4 + 4 * 4
6850 dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits
6852 // 0 stands for None
6853 // Dolby Vision V1.2.93 profiles and levels
6854 dovi->dv_bl_signal_compatibility_id = 0;
6857 ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF,
6858 (uint8_t *)dovi, dovi_size);
6864 av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC box, version: %d.%d, profile: %d, level: %d, "
6865 "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n",
6866 dovi->dv_version_major, dovi->dv_version_minor,
6867 dovi->dv_profile, dovi->dv_level,
6868 dovi->rpu_present_flag,
6869 dovi->el_present_flag,
6870 dovi->bl_present_flag,
6871 dovi->dv_bl_signal_compatibility_id
6877 static const MOVParseTableEntry mov_default_parse_table[] = {
6878 { MKTAG('A','C','L','R'), mov_read_aclr },
6879 { MKTAG('A','P','R','G'), mov_read_avid },
6880 { MKTAG('A','A','L','P'), mov_read_avid },
6881 { MKTAG('A','R','E','S'), mov_read_ares },
6882 { MKTAG('a','v','s','s'), mov_read_avss },
6883 { MKTAG('a','v','1','C'), mov_read_av1c },
6884 { MKTAG('c','h','p','l'), mov_read_chpl },
6885 { MKTAG('c','o','6','4'), mov_read_stco },
6886 { MKTAG('c','o','l','r'), mov_read_colr },
6887 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6888 { MKTAG('d','i','n','f'), mov_read_default },
6889 { MKTAG('D','p','x','E'), mov_read_dpxe },
6890 { MKTAG('d','r','e','f'), mov_read_dref },
6891 { MKTAG('e','d','t','s'), mov_read_default },
6892 { MKTAG('e','l','s','t'), mov_read_elst },
6893 { MKTAG('e','n','d','a'), mov_read_enda },
6894 { MKTAG('f','i','e','l'), mov_read_fiel },
6895 { MKTAG('a','d','r','m'), mov_read_adrm },
6896 { MKTAG('f','t','y','p'), mov_read_ftyp },
6897 { MKTAG('g','l','b','l'), mov_read_glbl },
6898 { MKTAG('h','d','l','r'), mov_read_hdlr },
6899 { MKTAG('i','l','s','t'), mov_read_ilst },
6900 { MKTAG('j','p','2','h'), mov_read_jp2h },
6901 { MKTAG('m','d','a','t'), mov_read_mdat },
6902 { MKTAG('m','d','h','d'), mov_read_mdhd },
6903 { MKTAG('m','d','i','a'), mov_read_default },
6904 { MKTAG('m','e','t','a'), mov_read_meta },
6905 { MKTAG('m','i','n','f'), mov_read_default },
6906 { MKTAG('m','o','o','f'), mov_read_moof },
6907 { MKTAG('m','o','o','v'), mov_read_moov },
6908 { MKTAG('m','v','e','x'), mov_read_default },
6909 { MKTAG('m','v','h','d'), mov_read_mvhd },
6910 { MKTAG('S','M','I',' '), mov_read_svq3 },
6911 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6912 { MKTAG('a','v','c','C'), mov_read_glbl },
6913 { MKTAG('p','a','s','p'), mov_read_pasp },
6914 { MKTAG('s','i','d','x'), mov_read_sidx },
6915 { MKTAG('s','t','b','l'), mov_read_default },
6916 { MKTAG('s','t','c','o'), mov_read_stco },
6917 { MKTAG('s','t','p','s'), mov_read_stps },
6918 { MKTAG('s','t','r','f'), mov_read_strf },
6919 { MKTAG('s','t','s','c'), mov_read_stsc },
6920 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6921 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6922 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6923 { MKTAG('s','t','t','s'), mov_read_stts },
6924 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6925 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
6926 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6927 { MKTAG('t','f','d','t'), mov_read_tfdt },
6928 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6929 { MKTAG('t','r','a','k'), mov_read_trak },
6930 { MKTAG('t','r','a','f'), mov_read_default },
6931 { MKTAG('t','r','e','f'), mov_read_default },
6932 { MKTAG('t','m','c','d'), mov_read_tmcd },
6933 { MKTAG('c','h','a','p'), mov_read_chap },
6934 { MKTAG('t','r','e','x'), mov_read_trex },
6935 { MKTAG('t','r','u','n'), mov_read_trun },
6936 { MKTAG('u','d','t','a'), mov_read_default },
6937 { MKTAG('w','a','v','e'), mov_read_wave },
6938 { MKTAG('e','s','d','s'), mov_read_esds },
6939 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6940 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6941 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6942 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6943 { MKTAG('w','f','e','x'), mov_read_wfex },
6944 { MKTAG('c','m','o','v'), mov_read_cmov },
6945 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6946 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6947 { MKTAG('s','b','g','p'), mov_read_sbgp },
6948 { MKTAG('h','v','c','C'), mov_read_glbl },
6949 { MKTAG('u','u','i','d'), mov_read_uuid },
6950 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6951 { MKTAG('f','r','e','e'), mov_read_free },
6952 { MKTAG('-','-','-','-'), mov_read_custom },
6953 { MKTAG('s','i','n','f'), mov_read_default },
6954 { MKTAG('f','r','m','a'), mov_read_frma },
6955 { MKTAG('s','e','n','c'), mov_read_senc },
6956 { MKTAG('s','a','i','z'), mov_read_saiz },
6957 { MKTAG('s','a','i','o'), mov_read_saio },
6958 { MKTAG('p','s','s','h'), mov_read_pssh },
6959 { MKTAG('s','c','h','m'), mov_read_schm },
6960 { MKTAG('s','c','h','i'), mov_read_default },
6961 { MKTAG('t','e','n','c'), mov_read_tenc },
6962 { MKTAG('d','f','L','a'), mov_read_dfla },
6963 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6964 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6965 { MKTAG('d','O','p','s'), mov_read_dops },
6966 { MKTAG('d','m','l','p'), mov_read_dmlp },
6967 { MKTAG('S','m','D','m'), mov_read_smdm },
6968 { MKTAG('C','o','L','L'), mov_read_coll },
6969 { MKTAG('v','p','c','C'), mov_read_vpcc },
6970 { MKTAG('m','d','c','v'), mov_read_mdcv },
6971 { MKTAG('c','l','l','i'), mov_read_clli },
6972 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
6973 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
6977 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6979 int64_t total_size = 0;
6983 if (c->atom_depth > 10) {
6984 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6985 return AVERROR_INVALIDDATA;
6990 atom.size = INT64_MAX;
6991 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6992 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
6995 if (atom.size >= 8) {
6996 a.size = avio_rb32(pb);
6997 a.type = avio_rl32(pb);
6998 if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
6999 a.type == MKTAG('h','o','o','v')) &&
7001 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
7004 type = avio_rl32(pb);
7005 avio_seek(pb, -8, SEEK_CUR);
7006 if (type == MKTAG('m','v','h','d') ||
7007 type == MKTAG('c','m','o','v')) {
7008 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
7009 a.type = MKTAG('m','o','o','v');
7012 if (atom.type != MKTAG('r','o','o','t') &&
7013 atom.type != MKTAG('m','o','o','v')) {
7014 if (a.type == MKTAG('t','r','a','k') ||
7015 a.type == MKTAG('m','d','a','t')) {
7016 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
7023 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
7024 a.size = avio_rb64(pb) - 8;
7028 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
7029 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
7031 a.size = atom.size - total_size + 8;
7036 a.size = FFMIN(a.size, atom.size - total_size);
7038 for (i = 0; mov_default_parse_table[i].type; i++)
7039 if (mov_default_parse_table[i].type == a.type) {
7040 parse = mov_default_parse_table[i].parse;
7044 // container is user data
7045 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
7046 atom.type == MKTAG('i','l','s','t')))
7047 parse = mov_read_udta_string;
7049 // Supports parsing the QuickTime Metadata Keys.
7050 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
7051 if (!parse && c->found_hdlr_mdta &&
7052 atom.type == MKTAG('m','e','t','a') &&
7053 a.type == MKTAG('k','e','y','s') &&
7054 c->meta_keys_count == 0) {
7055 parse = mov_read_keys;
7058 if (!parse) { /* skip leaf atoms data */
7059 avio_skip(pb, a.size);
7061 int64_t start_pos = avio_tell(pb);
7063 int err = parse(c, pb, a);
7068 if (c->found_moov && c->found_mdat &&
7069 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
7070 start_pos + a.size == avio_size(pb))) {
7071 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
7072 c->next_root_atom = start_pos + a.size;
7076 left = a.size - avio_tell(pb) + start_pos;
7077 if (left > 0) /* skip garbage at atom end */
7078 avio_skip(pb, left);
7079 else if (left < 0) {
7080 av_log(c->fc, AV_LOG_WARNING,
7081 "overread end of atom '%s' by %"PRId64" bytes\n",
7082 av_fourcc2str(a.type), -left);
7083 avio_seek(pb, left, SEEK_CUR);
7087 total_size += a.size;
7090 if (total_size < atom.size && atom.size < 0x7ffff)
7091 avio_skip(pb, atom.size - total_size);
7097 static int mov_probe(const AVProbeData *p)
7102 int moov_offset = -1;
7104 /* check file header */
7107 /* ignore invalid offset */
7108 if ((offset + 8) > (unsigned int)p->buf_size)
7110 tag = AV_RL32(p->buf + offset + 4);
7112 /* check for obvious tags */
7113 case MKTAG('m','o','o','v'):
7114 moov_offset = offset + 4;
7115 case MKTAG('m','d','a','t'):
7116 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
7117 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
7118 case MKTAG('f','t','y','p'):
7119 if (AV_RB32(p->buf+offset) < 8 &&
7120 (AV_RB32(p->buf+offset) != 1 ||
7121 offset + 12 > (unsigned int)p->buf_size ||
7122 AV_RB64(p->buf+offset + 8) == 0)) {
7123 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7124 } else if (tag == MKTAG('f','t','y','p') &&
7125 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
7126 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
7128 score = FFMAX(score, 5);
7130 score = AVPROBE_SCORE_MAX;
7132 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7134 /* those are more common words, so rate then a bit less */
7135 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
7136 case MKTAG('w','i','d','e'):
7137 case MKTAG('f','r','e','e'):
7138 case MKTAG('j','u','n','k'):
7139 case MKTAG('p','i','c','t'):
7140 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
7141 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7143 case MKTAG(0x82,0x82,0x7f,0x7d):
7144 case MKTAG('s','k','i','p'):
7145 case MKTAG('u','u','i','d'):
7146 case MKTAG('p','r','f','l'):
7147 /* if we only find those cause probedata is too small at least rate them */
7148 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7149 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7152 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7155 if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
7156 /* moov atom in the header - we should make sure that this is not a
7157 * MOV-packed MPEG-PS */
7158 offset = moov_offset;
7160 while (offset < (p->buf_size - 16)) { /* Sufficient space */
7161 /* We found an actual hdlr atom */
7162 if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7163 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7164 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
7165 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7166 /* We found a media handler reference atom describing an
7167 * MPEG-PS-in-MOV, return a
7168 * low score to force expanding the probe window until
7169 * mpegps_probe finds what it needs */
7181 // must be done after parsing all trak because there's no order requirement
7182 static void mov_read_chapters(AVFormatContext *s)
7184 MOVContext *mov = s->priv_data;
7186 MOVStreamContext *sc;
7191 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7192 chapter_track = mov->chapter_tracks[j];
7194 for (i = 0; i < s->nb_streams; i++)
7195 if (s->streams[i]->id == chapter_track) {
7200 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7205 cur_pos = avio_tell(sc->pb);
7207 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7208 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7209 if (st->internal->nb_index_entries) {
7210 // Retrieve the first frame, if possible
7211 AVIndexEntry *sample = &st->internal->index_entries[0];
7212 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7213 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7217 if (av_get_packet(sc->pb, &st->attached_pic, sample->size) < 0)
7220 st->attached_pic.stream_index = st->index;
7221 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
7224 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7225 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7226 st->discard = AVDISCARD_ALL;
7227 for (i = 0; i < st->internal->nb_index_entries; i++) {
7228 AVIndexEntry *sample = &st->internal->index_entries[i];
7229 int64_t end = i+1 < st->internal->nb_index_entries ? st->internal->index_entries[i+1].timestamp : st->duration;
7234 if (end < sample->timestamp) {
7235 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7236 end = AV_NOPTS_VALUE;
7239 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7240 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7244 // the first two bytes are the length of the title
7245 len = avio_rb16(sc->pb);
7246 if (len > sample->size-2)
7248 title_len = 2*len + 1;
7249 if (!(title = av_mallocz(title_len)))
7252 // The samples could theoretically be in any encoding if there's an encd
7253 // atom following, but in practice are only utf-8 or utf-16, distinguished
7254 // instead by the presence of a BOM
7258 ch = avio_rb16(sc->pb);
7260 avio_get_str16be(sc->pb, len, title, title_len);
7261 else if (ch == 0xfffe)
7262 avio_get_str16le(sc->pb, len, title, title_len);
7265 if (len == 1 || len == 2)
7268 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7272 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7277 avio_seek(sc->pb, cur_pos, SEEK_SET);
7281 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7282 uint32_t value, int flags)
7285 char buf[AV_TIMECODE_STR_SIZE];
7286 AVRational rate = st->avg_frame_rate;
7287 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7290 av_dict_set(&st->metadata, "timecode",
7291 av_timecode_make_string(&tc, buf, value), 0);
7295 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7297 MOVStreamContext *sc = st->priv_data;
7298 char buf[AV_TIMECODE_STR_SIZE];
7299 int64_t cur_pos = avio_tell(sc->pb);
7300 int hh, mm, ss, ff, drop;
7302 if (!st->internal->nb_index_entries)
7305 avio_seek(sc->pb, st->internal->index_entries->pos, SEEK_SET);
7306 avio_skip(s->pb, 13);
7307 hh = avio_r8(s->pb);
7308 mm = avio_r8(s->pb);
7309 ss = avio_r8(s->pb);
7310 drop = avio_r8(s->pb);
7311 ff = avio_r8(s->pb);
7312 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7313 hh, mm, ss, drop ? ';' : ':', ff);
7314 av_dict_set(&st->metadata, "timecode", buf, 0);
7316 avio_seek(sc->pb, cur_pos, SEEK_SET);
7320 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7322 MOVStreamContext *sc = st->priv_data;
7324 int64_t cur_pos = avio_tell(sc->pb);
7327 if (!st->internal->nb_index_entries)
7330 avio_seek(sc->pb, st->internal->index_entries->pos, SEEK_SET);
7331 value = avio_rb32(s->pb);
7333 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7334 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7335 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7337 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7338 * not the case) and thus assume "frame number format" instead of QT one.
7339 * No sample with tmcd track can be found with a QT timecode at the moment,
7340 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7342 parse_timecode_in_framenum_format(s, st, value, flags);
7344 avio_seek(sc->pb, cur_pos, SEEK_SET);
7348 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7350 if (!index || !*index) return;
7351 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7352 av_encryption_info_free((*index)->encrypted_samples[i]);
7354 av_freep(&(*index)->encrypted_samples);
7355 av_freep(&(*index)->auxiliary_info_sizes);
7356 av_freep(&(*index)->auxiliary_offsets);
7360 static int mov_read_close(AVFormatContext *s)
7362 MOVContext *mov = s->priv_data;
7365 for (i = 0; i < s->nb_streams; i++) {
7366 AVStream *st = s->streams[i];
7367 MOVStreamContext *sc = st->priv_data;
7372 av_freep(&sc->ctts_data);
7373 for (j = 0; j < sc->drefs_count; j++) {
7374 av_freep(&sc->drefs[j].path);
7375 av_freep(&sc->drefs[j].dir);
7377 av_freep(&sc->drefs);
7379 sc->drefs_count = 0;
7381 if (!sc->pb_is_copied)
7382 ff_format_io_close(s, &sc->pb);
7385 av_freep(&sc->chunk_offsets);
7386 av_freep(&sc->stsc_data);
7387 av_freep(&sc->sample_sizes);
7388 av_freep(&sc->keyframes);
7389 av_freep(&sc->stts_data);
7390 av_freep(&sc->sdtp_data);
7391 av_freep(&sc->stps_data);
7392 av_freep(&sc->elst_data);
7393 av_freep(&sc->rap_group);
7394 av_freep(&sc->display_matrix);
7395 av_freep(&sc->index_ranges);
7398 for (j = 0; j < sc->stsd_count; j++)
7399 av_free(sc->extradata[j]);
7400 av_freep(&sc->extradata);
7401 av_freep(&sc->extradata_size);
7403 mov_free_encryption_index(&sc->cenc.encryption_index);
7404 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7405 av_aes_ctr_free(sc->cenc.aes_ctr);
7407 av_freep(&sc->stereo3d);
7408 av_freep(&sc->spherical);
7409 av_freep(&sc->mastering);
7410 av_freep(&sc->coll);
7413 av_freep(&mov->dv_demux);
7414 avformat_free_context(mov->dv_fctx);
7415 mov->dv_fctx = NULL;
7417 if (mov->meta_keys) {
7418 for (i = 1; i < mov->meta_keys_count; i++) {
7419 av_freep(&mov->meta_keys[i]);
7421 av_freep(&mov->meta_keys);
7424 av_freep(&mov->trex_data);
7425 av_freep(&mov->bitrates);
7427 for (i = 0; i < mov->frag_index.nb_items; i++) {
7428 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7429 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7430 mov_free_encryption_index(&frag[j].encryption_index);
7432 av_freep(&mov->frag_index.item[i].stream_info);
7434 av_freep(&mov->frag_index.item);
7436 av_freep(&mov->aes_decrypt);
7437 av_freep(&mov->chapter_tracks);
7442 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7446 for (i = 0; i < s->nb_streams; i++) {
7447 AVStream *st = s->streams[i];
7448 MOVStreamContext *sc = st->priv_data;
7450 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7451 sc->timecode_track == tmcd_id)
7457 /* look for a tmcd track not referenced by any video track, and export it globally */
7458 static void export_orphan_timecode(AVFormatContext *s)
7462 for (i = 0; i < s->nb_streams; i++) {
7463 AVStream *st = s->streams[i];
7465 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7466 !tmcd_is_referenced(s, i + 1)) {
7467 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7469 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7476 static int read_tfra(MOVContext *mov, AVIOContext *f)
7478 int version, fieldlength, i, j;
7479 int64_t pos = avio_tell(f);
7480 uint32_t size = avio_rb32(f);
7481 unsigned track_id, item_count;
7483 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7486 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7488 version = avio_r8(f);
7490 track_id = avio_rb32(f);
7491 fieldlength = avio_rb32(f);
7492 item_count = avio_rb32(f);
7493 for (i = 0; i < item_count; i++) {
7494 int64_t time, offset;
7496 MOVFragmentStreamInfo * frag_stream_info;
7499 return AVERROR_INVALIDDATA;
7503 time = avio_rb64(f);
7504 offset = avio_rb64(f);
7506 time = avio_rb32(f);
7507 offset = avio_rb32(f);
7510 // The first sample of each stream in a fragment is always a random
7511 // access sample. So it's entry in the tfra can be used as the
7512 // initial PTS of the fragment.
7513 index = update_frag_index(mov, offset);
7514 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7515 if (frag_stream_info &&
7516 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7517 frag_stream_info->first_tfra_pts = time;
7519 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7521 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7523 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7527 avio_seek(f, pos + size, SEEK_SET);
7531 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7533 int64_t stream_size = avio_size(f);
7534 int64_t original_pos = avio_tell(f);
7537 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7541 c->mfra_size = avio_rb32(f);
7542 c->have_read_mfra_size = 1;
7543 if (!c->mfra_size || c->mfra_size > stream_size) {
7544 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7547 if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
7551 if (avio_rb32(f) != c->mfra_size) {
7552 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7555 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7556 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7559 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7561 ret = read_tfra(c, f);
7566 c->frag_index.complete = 1;
7568 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7570 av_log(c->fc, AV_LOG_ERROR,
7571 "failed to seek back after looking for mfra\n");
7577 static int mov_read_header(AVFormatContext *s)
7579 MOVContext *mov = s->priv_data;
7580 AVIOContext *pb = s->pb;
7582 MOVAtom atom = { AV_RL32("root") };
7585 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7586 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7587 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7588 return AVERROR(EINVAL);
7592 mov->trak_index = -1;
7593 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7594 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7595 atom.size = avio_size(pb);
7597 atom.size = INT64_MAX;
7599 /* check MOV header */
7601 if (mov->moov_retry)
7602 avio_seek(pb, 0, SEEK_SET);
7603 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7604 av_log(s, AV_LOG_ERROR, "error reading header\n");
7607 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7608 if (!mov->found_moov) {
7609 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7610 err = AVERROR_INVALIDDATA;
7613 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7615 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7616 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7617 mov_read_chapters(s);
7618 for (i = 0; i < s->nb_streams; i++)
7619 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7620 mov_read_timecode_track(s, s->streams[i]);
7621 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7622 mov_read_rtmd_track(s, s->streams[i]);
7626 /* copy timecode metadata from tmcd tracks to the related video streams */
7627 for (i = 0; i < s->nb_streams; i++) {
7628 AVStream *st = s->streams[i];
7629 MOVStreamContext *sc = st->priv_data;
7630 if (sc->timecode_track > 0) {
7631 AVDictionaryEntry *tcr;
7632 int tmcd_st_id = -1;
7634 for (j = 0; j < s->nb_streams; j++)
7635 if (s->streams[j]->id == sc->timecode_track)
7638 if (tmcd_st_id < 0 || tmcd_st_id == i)
7640 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7642 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7645 export_orphan_timecode(s);
7647 for (i = 0; i < s->nb_streams; i++) {
7648 AVStream *st = s->streams[i];
7649 MOVStreamContext *sc = st->priv_data;
7650 fix_timescale(mov, sc);
7651 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
7652 st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7653 st->internal->skip_samples = sc->start_pad;
7655 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7656 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7657 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7658 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7659 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7660 st->codecpar->width = sc->width;
7661 st->codecpar->height = sc->height;
7663 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7664 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7668 if (mov->handbrake_version &&
7669 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7670 st->codecpar->codec_id == AV_CODEC_ID_MP3) {
7671 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7672 st->need_parsing = AVSTREAM_PARSE_FULL;
7676 if (mov->trex_data) {
7677 for (i = 0; i < s->nb_streams; i++) {
7678 AVStream *st = s->streams[i];
7679 MOVStreamContext *sc = st->priv_data;
7680 if (st->duration > 0) {
7681 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7682 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7683 sc->data_size, sc->time_scale);
7684 err = AVERROR_INVALIDDATA;
7687 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7692 if (mov->use_mfra_for > 0) {
7693 for (i = 0; i < s->nb_streams; i++) {
7694 AVStream *st = s->streams[i];
7695 MOVStreamContext *sc = st->priv_data;
7696 if (sc->duration_for_fps > 0) {
7697 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7698 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7699 sc->data_size, sc->time_scale);
7700 err = AVERROR_INVALIDDATA;
7703 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7704 sc->duration_for_fps;
7709 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7710 if (mov->bitrates[i]) {
7711 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7715 ff_rfps_calculate(s);
7717 for (i = 0; i < s->nb_streams; i++) {
7718 AVStream *st = s->streams[i];
7719 MOVStreamContext *sc = st->priv_data;
7721 switch (st->codecpar->codec_type) {
7722 case AVMEDIA_TYPE_AUDIO:
7723 err = ff_replaygain_export(st, s->metadata);
7727 case AVMEDIA_TYPE_VIDEO:
7728 if (sc->display_matrix) {
7729 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7730 sizeof(int32_t) * 9);
7734 sc->display_matrix = NULL;
7737 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7738 (uint8_t *)sc->stereo3d,
7739 sizeof(*sc->stereo3d));
7743 sc->stereo3d = NULL;
7745 if (sc->spherical) {
7746 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7747 (uint8_t *)sc->spherical,
7748 sc->spherical_size);
7752 sc->spherical = NULL;
7754 if (sc->mastering) {
7755 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7756 (uint8_t *)sc->mastering,
7757 sizeof(*sc->mastering));
7761 sc->mastering = NULL;
7764 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7765 (uint8_t *)sc->coll,
7775 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7777 for (i = 0; i < mov->frag_index.nb_items; i++)
7778 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7779 mov->frag_index.item[i].headers_read = 1;
7787 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7789 AVIndexEntry *sample = NULL;
7790 int64_t best_dts = INT64_MAX;
7792 for (i = 0; i < s->nb_streams; i++) {
7793 AVStream *avst = s->streams[i];
7794 MOVStreamContext *msc = avst->priv_data;
7795 if (msc->pb && msc->current_sample < avst->internal->nb_index_entries) {
7796 AVIndexEntry *current_sample = &avst->internal->index_entries[msc->current_sample];
7797 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7798 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7799 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7800 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7801 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
7802 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7803 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7804 sample = current_sample;
7813 static int should_retry(AVIOContext *pb, int error_code) {
7814 if (error_code == AVERROR_EOF || avio_feof(pb))
7820 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7823 MOVContext *mov = s->priv_data;
7825 if (index >= 0 && index < mov->frag_index.nb_items)
7826 target = mov->frag_index.item[index].moof_offset;
7827 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7828 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7829 return AVERROR_INVALIDDATA;
7832 mov->next_root_atom = 0;
7833 if (index < 0 || index >= mov->frag_index.nb_items)
7834 index = search_frag_moof_offset(&mov->frag_index, target);
7835 if (index < mov->frag_index.nb_items &&
7836 mov->frag_index.item[index].moof_offset == target) {
7837 if (index + 1 < mov->frag_index.nb_items)
7838 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7839 if (mov->frag_index.item[index].headers_read)
7841 mov->frag_index.item[index].headers_read = 1;
7844 mov->found_mdat = 0;
7846 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7849 if (avio_feof(s->pb))
7851 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7856 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7858 uint8_t *side, *extradata;
7861 /* Save the current index. */
7862 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7864 /* Notify the decoder that extradata changed. */
7865 extradata_size = sc->extradata_size[sc->last_stsd_index];
7866 extradata = sc->extradata[sc->last_stsd_index];
7867 if (extradata_size > 0 && extradata) {
7868 side = av_packet_new_side_data(pkt,
7869 AV_PKT_DATA_NEW_EXTRADATA,
7872 return AVERROR(ENOMEM);
7873 memcpy(side, extradata, extradata_size);
7879 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int size)
7884 return AVERROR_INVALIDDATA;
7885 new_size = ((size - 8) / 2) * 3;
7886 ret = av_new_packet(pkt, new_size);
7891 for (int j = 0; j < new_size; j += 3) {
7892 pkt->data[j] = 0xFC;
7893 pkt->data[j+1] = avio_r8(pb);
7894 pkt->data[j+2] = avio_r8(pb);
7900 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7902 MOVContext *mov = s->priv_data;
7903 MOVStreamContext *sc;
7904 AVIndexEntry *sample;
7905 AVStream *st = NULL;
7906 int64_t current_index;
7910 sample = mov_find_next_sample(s, &st);
7911 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7912 if (!mov->next_root_atom)
7914 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7919 /* must be done just before reading, to avoid infinite loop on sample */
7920 current_index = sc->current_index;
7921 mov_current_sample_inc(sc);
7923 if (mov->next_root_atom) {
7924 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7925 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7928 if (st->discard != AVDISCARD_ALL) {
7929 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7930 if (ret64 != sample->pos) {
7931 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7932 sc->ffindex, sample->pos);
7933 if (should_retry(sc->pb, ret64)) {
7934 mov_current_sample_dec(sc);
7936 return AVERROR_INVALIDDATA;
7939 if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
7940 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7944 if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
7945 ret = get_eia608_packet(sc->pb, pkt, sample->size);
7947 ret = av_get_packet(sc->pb, pkt, sample->size);
7949 if (should_retry(sc->pb, ret)) {
7950 mov_current_sample_dec(sc);
7954 #if CONFIG_DV_DEMUXER
7955 if (mov->dv_demux && sc->dv_audio_container) {
7956 AVBufferRef *buf = pkt->buf;
7957 ret = avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7959 av_packet_unref(pkt);
7962 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7967 if (sc->has_palette) {
7970 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7972 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7974 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7975 sc->has_palette = 0;
7978 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7979 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7980 st->need_parsing = AVSTREAM_PARSE_FULL;
7984 pkt->stream_index = sc->ffindex;
7985 pkt->dts = sample->timestamp;
7986 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7987 pkt->flags |= AV_PKT_FLAG_DISCARD;
7989 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7990 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
7991 /* update ctts context */
7993 if (sc->ctts_index < sc->ctts_count &&
7994 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
7996 sc->ctts_sample = 0;
7999 int64_t next_dts = (sc->current_sample < st->internal->nb_index_entries) ?
8000 st->internal->index_entries[sc->current_sample].timestamp : st->duration;
8002 if (next_dts >= pkt->dts)
8003 pkt->duration = next_dts - pkt->dts;
8004 pkt->pts = pkt->dts;
8006 if (st->discard == AVDISCARD_ALL)
8008 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
8009 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
8010 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
8011 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
8013 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
8014 pkt->pos = sample->pos;
8016 /* Multiple stsd handling. */
8017 if (sc->stsc_data) {
8018 /* Keep track of the stsc index for the given sample, then check
8019 * if the stsd index is different from the last used one. */
8021 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
8022 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
8024 sc->stsc_sample = 0;
8025 /* Do not check indexes after a switch. */
8026 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
8027 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
8028 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
8029 ret = mov_change_extradata(sc, pkt);
8036 aax_filter(pkt->data, pkt->size, mov);
8038 ret = cenc_filter(mov, st, sc, pkt, current_index);
8046 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
8048 MOVContext *mov = s->priv_data;
8051 if (!mov->frag_index.complete)
8054 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
8057 if (!mov->frag_index.item[index].headers_read)
8058 return mov_switch_root(s, -1, index);
8059 if (index + 1 < mov->frag_index.nb_items)
8060 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
8065 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
8067 MOVStreamContext *sc = st->priv_data;
8068 int sample, time_sample, ret;
8071 // Here we consider timestamp to be PTS, hence try to offset it so that we
8072 // can search over the DTS timeline.
8073 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
8075 ret = mov_seek_fragment(s, st, timestamp);
8079 sample = av_index_search_timestamp(st, timestamp, flags);
8080 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
8081 if (sample < 0 && st->internal->nb_index_entries && timestamp < st->internal->index_entries[0].timestamp)
8083 if (sample < 0) /* not sure what to do */
8084 return AVERROR_INVALIDDATA;
8085 mov_current_sample_set(sc, sample);
8086 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
8087 /* adjust ctts index */
8088 if (sc->ctts_data) {
8090 for (i = 0; i < sc->ctts_count; i++) {
8091 int next = time_sample + sc->ctts_data[i].count;
8092 if (next > sc->current_sample) {
8094 sc->ctts_sample = sc->current_sample - time_sample;
8101 /* adjust stsd index */
8102 if (sc->chunk_count) {
8104 for (i = 0; i < sc->stsc_count; i++) {
8105 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
8106 if (next > sc->current_sample) {
8108 sc->stsc_sample = sc->current_sample - time_sample;
8111 av_assert0(next == (int)next);
8119 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
8121 MOVContext *mc = s->priv_data;
8126 if (stream_index >= s->nb_streams)
8127 return AVERROR_INVALIDDATA;
8129 st = s->streams[stream_index];
8130 sample = mov_seek_stream(s, st, sample_time, flags);
8134 if (mc->seek_individually) {
8135 /* adjust seek timestamp to found sample timestamp */
8136 int64_t seek_timestamp = st->internal->index_entries[sample].timestamp;
8138 for (i = 0; i < s->nb_streams; i++) {
8140 MOVStreamContext *sc = s->streams[i]->priv_data;
8142 st->internal->skip_samples = (sample_time <= 0) ? sc->start_pad : 0;
8144 if (stream_index == i)
8147 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
8148 mov_seek_stream(s, st, timestamp, flags);
8151 for (i = 0; i < s->nb_streams; i++) {
8152 MOVStreamContext *sc;
8155 mov_current_sample_set(sc, 0);
8158 MOVStreamContext *sc;
8159 AVIndexEntry *entry = mov_find_next_sample(s, &st);
8161 return AVERROR_INVALIDDATA;
8163 if (sc->ffindex == stream_index && sc->current_sample == sample)
8165 mov_current_sample_inc(sc);
8171 #define OFFSET(x) offsetof(MOVContext, x)
8172 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
8173 static const AVOption mov_options[] = {
8174 {"use_absolute_path",
8175 "allow using absolute path when opening alias, this is a possible security issue",
8176 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
8178 {"seek_streams_individually",
8179 "Seek each stream individually to the closest point",
8180 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
8182 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
8184 {"advanced_editlist",
8185 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
8186 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
8188 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8191 "use mfra for fragment timestamps",
8192 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8193 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8195 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8196 FLAGS, "use_mfra_for" },
8197 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8198 FLAGS, "use_mfra_for" },
8199 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8200 FLAGS, "use_mfra_for" },
8201 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8202 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8203 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8204 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8205 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8206 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8207 { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
8208 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8209 { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
8210 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8211 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8212 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8213 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8214 .flags = AV_OPT_FLAG_DECODING_PARAM },
8215 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8216 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8217 {.i64 = 0}, 0, 1, FLAGS },
8222 static const AVClass mov_class = {
8223 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8224 .item_name = av_default_item_name,
8225 .option = mov_options,
8226 .version = LIBAVUTIL_VERSION_INT,
8229 AVInputFormat ff_mov_demuxer = {
8230 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8231 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8232 .priv_class = &mov_class,
8233 .priv_data_size = sizeof(MOVContext),
8234 .extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
8235 .read_probe = mov_probe,
8236 .read_header = mov_read_header,
8237 .read_packet = mov_read_packet,
8238 .read_close = mov_read_close,
8239 .read_seek = mov_read_seek,
8240 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,