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
1515 c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale);
1516 avio_rb32(pb); /* preferred scale */
1518 avio_rb16(pb); /* preferred volume */
1520 avio_skip(pb, 10); /* reserved */
1522 /* movie display matrix, store it in main context and use it later on */
1523 for (i = 0; i < 3; i++) {
1524 c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1525 c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1526 c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1529 avio_rb32(pb); /* preview time */
1530 avio_rb32(pb); /* preview duration */
1531 avio_rb32(pb); /* poster time */
1532 avio_rb32(pb); /* selection time */
1533 avio_rb32(pb); /* selection duration */
1534 avio_rb32(pb); /* current time */
1535 avio_rb32(pb); /* next track ID */
1540 static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1545 if (c->fc->nb_streams < 1)
1547 st = c->fc->streams[c->fc->nb_streams-1];
1549 little_endian = avio_rb16(pb) & 0xFF;
1550 av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1551 if (little_endian == 1) {
1552 switch (st->codecpar->codec_id) {
1553 case AV_CODEC_ID_PCM_S24BE:
1554 st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE;
1556 case AV_CODEC_ID_PCM_S32BE:
1557 st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE;
1559 case AV_CODEC_ID_PCM_F32BE:
1560 st->codecpar->codec_id = AV_CODEC_ID_PCM_F32LE;
1562 case AV_CODEC_ID_PCM_F64BE:
1563 st->codecpar->codec_id = AV_CODEC_ID_PCM_F64LE;
1572 static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1575 uint8_t *icc_profile;
1576 char color_parameter_type[5] = { 0 };
1577 uint16_t color_primaries, color_trc, color_matrix;
1580 if (c->fc->nb_streams < 1)
1582 st = c->fc->streams[c->fc->nb_streams - 1];
1584 ret = ffio_read_size(pb, color_parameter_type, 4);
1587 if (strncmp(color_parameter_type, "nclx", 4) &&
1588 strncmp(color_parameter_type, "nclc", 4) &&
1589 strncmp(color_parameter_type, "prof", 4)) {
1590 av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
1591 color_parameter_type);
1595 if (!strncmp(color_parameter_type, "prof", 4)) {
1596 icc_profile = av_stream_new_side_data(st, AV_PKT_DATA_ICC_PROFILE, atom.size - 4);
1598 return AVERROR(ENOMEM);
1599 ret = ffio_read_size(pb, icc_profile, atom.size - 4);
1603 color_primaries = avio_rb16(pb);
1604 color_trc = avio_rb16(pb);
1605 color_matrix = avio_rb16(pb);
1607 av_log(c->fc, AV_LOG_TRACE,
1608 "%s: pri %d trc %d matrix %d",
1609 color_parameter_type, color_primaries, color_trc, color_matrix);
1611 if (!strncmp(color_parameter_type, "nclx", 4)) {
1612 uint8_t color_range = avio_r8(pb) >> 7;
1613 av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
1615 st->codecpar->color_range = AVCOL_RANGE_JPEG;
1617 st->codecpar->color_range = AVCOL_RANGE_MPEG;
1620 if (!av_color_primaries_name(color_primaries))
1621 color_primaries = AVCOL_PRI_UNSPECIFIED;
1622 if (!av_color_transfer_name(color_trc))
1623 color_trc = AVCOL_TRC_UNSPECIFIED;
1624 if (!av_color_space_name(color_matrix))
1625 color_matrix = AVCOL_SPC_UNSPECIFIED;
1627 st->codecpar->color_primaries = color_primaries;
1628 st->codecpar->color_trc = color_trc;
1629 st->codecpar->color_space = color_matrix;
1630 av_log(c->fc, AV_LOG_TRACE, "\n");
1635 static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1638 unsigned mov_field_order;
1639 enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
1641 if (c->fc->nb_streams < 1) // will happen with jp2 files
1643 st = c->fc->streams[c->fc->nb_streams-1];
1645 return AVERROR_INVALIDDATA;
1646 mov_field_order = avio_rb16(pb);
1647 if ((mov_field_order & 0xFF00) == 0x0100)
1648 decoded_field_order = AV_FIELD_PROGRESSIVE;
1649 else if ((mov_field_order & 0xFF00) == 0x0200) {
1650 switch (mov_field_order & 0xFF) {
1651 case 0x01: decoded_field_order = AV_FIELD_TT;
1653 case 0x06: decoded_field_order = AV_FIELD_BB;
1655 case 0x09: decoded_field_order = AV_FIELD_TB;
1657 case 0x0E: decoded_field_order = AV_FIELD_BT;
1661 if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
1662 av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
1664 st->codecpar->field_order = decoded_field_order;
1669 static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
1672 uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
1673 if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
1674 return AVERROR_INVALIDDATA;
1675 if ((err = av_reallocp(&par->extradata, size)) < 0) {
1676 par->extradata_size = 0;
1679 par->extradata_size = size - AV_INPUT_BUFFER_PADDING_SIZE;
1683 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
1684 static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1685 AVCodecParameters *par, uint8_t *buf)
1687 int64_t result = atom.size;
1690 AV_WB32(buf , atom.size + 8);
1691 AV_WL32(buf + 4, atom.type);
1692 err = ffio_read_size(pb, buf + 8, atom.size);
1694 par->extradata_size -= atom.size;
1696 } else if (err < atom.size) {
1697 av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
1698 par->extradata_size -= atom.size - err;
1701 memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1705 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
1706 static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1707 enum AVCodecID codec_id)
1710 uint64_t original_size;
1713 if (c->fc->nb_streams < 1) // will happen with jp2 files
1715 st = c->fc->streams[c->fc->nb_streams-1];
1717 if (st->codecpar->codec_id != codec_id)
1718 return 0; /* unexpected codec_id - don't mess with extradata */
1720 original_size = st->codecpar->extradata_size;
1721 err = mov_realloc_extradata(st->codecpar, atom);
1725 err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
1728 return 0; // Note: this is the original behavior to ignore truncation.
1731 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
1732 static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1734 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
1737 static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1739 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS);
1742 static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1744 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
1747 static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1749 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
1752 static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1754 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
1756 ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
1760 static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1762 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
1764 if (!ret && c->fc->nb_streams >= 1) {
1765 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1766 if (par->extradata_size >= 40) {
1767 par->height = AV_RB16(&par->extradata[36]);
1768 par->width = AV_RB16(&par->extradata[38]);
1774 static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1776 if (c->fc->nb_streams >= 1) {
1777 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1778 if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
1779 par->codec_id == AV_CODEC_ID_H264 &&
1783 cid = avio_rb16(pb);
1784 /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
1785 if (cid == 0xd4d || cid == 0xd4e)
1788 } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
1789 par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
1790 par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
1794 num = avio_rb32(pb);
1795 den = avio_rb32(pb);
1796 if (num <= 0 || den <= 0)
1798 switch (avio_rb32(pb)) {
1800 if (den >= INT_MAX / 2)
1804 c->fc->streams[c->fc->nb_streams-1]->internal->display_aspect_ratio.num = num;
1805 c->fc->streams[c->fc->nb_streams-1]->internal->display_aspect_ratio.den = den;
1812 return mov_read_avid(c, pb, atom);
1815 static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1819 uint64_t original_size;
1820 if (c->fc->nb_streams >= 1) {
1821 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1822 if (par->codec_id == AV_CODEC_ID_H264)
1824 if (atom.size == 16) {
1825 original_size = par->extradata_size;
1826 ret = mov_realloc_extradata(par, atom);
1828 length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
1829 if (length == atom.size) {
1830 const uint8_t range_value = par->extradata[original_size + 19];
1831 switch (range_value) {
1833 par->color_range = AVCOL_RANGE_MPEG;
1836 par->color_range = AVCOL_RANGE_JPEG;
1839 av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
1842 ff_dlog(c->fc, "color_range: %d\n", par->color_range);
1844 /* For some reason the whole atom was not added to the extradata */
1845 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
1848 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
1851 av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
1858 static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1860 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
1863 static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1868 if (c->fc->nb_streams < 1)
1870 st = c->fc->streams[c->fc->nb_streams-1];
1872 if ((uint64_t)atom.size > (1<<30))
1873 return AVERROR_INVALIDDATA;
1875 if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
1876 st->codecpar->codec_id == AV_CODEC_ID_QDMC ||
1877 st->codecpar->codec_id == AV_CODEC_ID_SPEEX) {
1878 // pass all frma atom to codec, needed at least for QDMC and QDM2
1879 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1882 } else if (atom.size > 8) { /* to read frma, esds atoms */
1883 if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
1885 ret = ffio_ensure_seekback(pb, 8);
1888 buffer = avio_rb64(pb);
1890 if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
1891 && buffer >> 32 <= atom.size
1892 && buffer >> 32 >= 8) {
1895 } else if (!st->codecpar->extradata_size) {
1896 #define ALAC_EXTRADATA_SIZE 36
1897 st->codecpar->extradata = av_mallocz(ALAC_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
1898 if (!st->codecpar->extradata)
1899 return AVERROR(ENOMEM);
1900 st->codecpar->extradata_size = ALAC_EXTRADATA_SIZE;
1901 AV_WB32(st->codecpar->extradata , ALAC_EXTRADATA_SIZE);
1902 AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
1903 AV_WB64(st->codecpar->extradata + 12, buffer);
1904 avio_read(pb, st->codecpar->extradata + 20, 16);
1905 avio_skip(pb, atom.size - 24);
1909 if ((ret = mov_read_default(c, pb, atom)) < 0)
1912 avio_skip(pb, atom.size);
1917 * This function reads atom content and puts data in extradata without tag
1918 * nor size unlike mov_read_extradata.
1920 static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1925 if (c->fc->nb_streams < 1)
1927 st = c->fc->streams[c->fc->nb_streams-1];
1929 if ((uint64_t)atom.size > (1<<30))
1930 return AVERROR_INVALIDDATA;
1932 if (atom.size >= 10) {
1933 // Broken files created by legacy versions of libavformat will
1934 // wrap a whole fiel atom inside of a glbl atom.
1935 unsigned size = avio_rb32(pb);
1936 unsigned type = avio_rl32(pb);
1937 avio_seek(pb, -8, SEEK_CUR);
1938 if (type == MKTAG('f','i','e','l') && size == atom.size)
1939 return mov_read_default(c, pb, atom);
1941 if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
1942 av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
1945 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1948 if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
1949 /* HEVC-based Dolby Vision derived from hvc1.
1950 Happens to match with an identifier
1951 previously utilized for DV. Thus, if we have
1952 the hvcC extradata box available as specified,
1953 set codec to HEVC */
1954 st->codecpar->codec_id = AV_CODEC_ID_HEVC;
1959 static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1962 uint8_t profile_level;
1965 if (c->fc->nb_streams < 1)
1967 st = c->fc->streams[c->fc->nb_streams-1];
1969 if (atom.size >= (1<<28) || atom.size < 7)
1970 return AVERROR_INVALIDDATA;
1972 profile_level = avio_r8(pb);
1973 if ((profile_level & 0xf0) != 0xc0)
1976 avio_seek(pb, 6, SEEK_CUR);
1977 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
1985 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
1986 * but can have extradata appended at the end after the 40 bytes belonging
1989 static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1994 if (c->fc->nb_streams < 1)
1996 if (atom.size <= 40)
1998 st = c->fc->streams[c->fc->nb_streams-1];
2000 if ((uint64_t)atom.size > (1<<30))
2001 return AVERROR_INVALIDDATA;
2004 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2011 static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2014 MOVStreamContext *sc;
2015 unsigned int i, entries;
2017 if (c->trak_index < 0) {
2018 av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2021 if (c->fc->nb_streams < 1)
2023 st = c->fc->streams[c->fc->nb_streams-1];
2026 avio_r8(pb); /* version */
2027 avio_rb24(pb); /* flags */
2029 entries = avio_rb32(pb);
2034 if (sc->chunk_offsets)
2035 av_log(c->fc, AV_LOG_WARNING, "Duplicated STCO atom\n");
2036 av_free(sc->chunk_offsets);
2037 sc->chunk_count = 0;
2038 sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2039 if (!sc->chunk_offsets)
2040 return AVERROR(ENOMEM);
2041 sc->chunk_count = entries;
2043 if (atom.type == MKTAG('s','t','c','o'))
2044 for (i = 0; i < entries && !pb->eof_reached; i++)
2045 sc->chunk_offsets[i] = avio_rb32(pb);
2046 else if (atom.type == MKTAG('c','o','6','4'))
2047 for (i = 0; i < entries && !pb->eof_reached; i++)
2048 sc->chunk_offsets[i] = avio_rb64(pb);
2050 return AVERROR_INVALIDDATA;
2052 sc->chunk_count = i;
2054 if (pb->eof_reached) {
2055 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2062 static int mov_codec_id(AVStream *st, uint32_t format)
2064 int id = ff_codec_get_id(ff_codec_movaudio_tags, format);
2067 ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2068 (format & 0xFFFF) == 'T' + ('S' << 8)))
2069 id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format) & 0xFFFF);
2071 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2072 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2073 } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2074 /* skip old ASF MPEG-4 tag */
2075 format && format != MKTAG('m','p','4','s')) {
2076 id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2078 id = ff_codec_get_id(ff_codec_bmp_tags, format);
2080 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
2081 else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2082 (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE &&
2083 st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2084 id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
2086 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
2088 id = ff_codec_get_id(ff_codec_movdata_tags, format);
2092 st->codecpar->codec_tag = format;
2097 static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
2098 AVStream *st, MOVStreamContext *sc)
2100 uint8_t codec_name[32] = { 0 };
2105 /* The first 16 bytes of the video sample description are already
2106 * read in ff_mov_read_stsd_entries() */
2107 stsd_start = avio_tell(pb) - 16;
2109 avio_rb16(pb); /* version */
2110 avio_rb16(pb); /* revision level */
2111 id = avio_rl32(pb); /* vendor */
2112 av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2113 avio_rb32(pb); /* temporal quality */
2114 avio_rb32(pb); /* spatial quality */
2116 st->codecpar->width = avio_rb16(pb); /* width */
2117 st->codecpar->height = avio_rb16(pb); /* height */
2119 avio_rb32(pb); /* horiz resolution */
2120 avio_rb32(pb); /* vert resolution */
2121 avio_rb32(pb); /* data size, always 0 */
2122 avio_rb16(pb); /* frames per samples */
2124 len = avio_r8(pb); /* codec name, pascal string */
2127 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2129 avio_skip(pb, 31 - len);
2132 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2134 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2135 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2136 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2137 st->codecpar->width &= ~1;
2138 st->codecpar->height &= ~1;
2140 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2141 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2142 !strncmp(codec_name, "Sorenson H263", 13))
2143 st->codecpar->codec_id = AV_CODEC_ID_FLV1;
2145 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2147 avio_seek(pb, stsd_start, SEEK_SET);
2149 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2150 st->codecpar->bits_per_coded_sample &= 0x1F;
2151 sc->has_palette = 1;
2155 static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
2156 AVStream *st, MOVStreamContext *sc)
2158 int bits_per_sample, flags;
2159 uint16_t version = avio_rb16(pb);
2161 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2163 avio_rb16(pb); /* revision level */
2164 id = avio_rl32(pb); /* vendor */
2165 av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2167 st->codecpar->channels = avio_rb16(pb); /* channel count */
2168 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2169 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", st->codecpar->channels);
2171 sc->audio_cid = avio_rb16(pb);
2172 avio_rb16(pb); /* packet size = 0 */
2174 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2176 // Read QT version 1 fields. In version 0 these do not exist.
2177 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2179 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2180 (sc->stsd_version == 0 && version > 0)) {
2182 sc->samples_per_frame = avio_rb32(pb);
2183 avio_rb32(pb); /* bytes per packet */
2184 sc->bytes_per_frame = avio_rb32(pb);
2185 avio_rb32(pb); /* bytes per sample */
2186 } else if (version == 2) {
2187 avio_rb32(pb); /* sizeof struct only */
2188 st->codecpar->sample_rate = av_int2double(avio_rb64(pb));
2189 st->codecpar->channels = avio_rb32(pb);
2190 avio_rb32(pb); /* always 0x7F000000 */
2191 st->codecpar->bits_per_coded_sample = avio_rb32(pb);
2193 flags = avio_rb32(pb); /* lpcm format specific flag */
2194 sc->bytes_per_frame = avio_rb32(pb);
2195 sc->samples_per_frame = avio_rb32(pb);
2196 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2197 st->codecpar->codec_id =
2198 ff_mov_get_lpcm_codec_id(st->codecpar->bits_per_coded_sample,
2201 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2202 /* can't correctly handle variable sized packet as audio unit */
2203 switch (st->codecpar->codec_id) {
2204 case AV_CODEC_ID_MP2:
2205 case AV_CODEC_ID_MP3:
2206 st->need_parsing = AVSTREAM_PARSE_FULL;
2212 if (sc->format == 0) {
2213 if (st->codecpar->bits_per_coded_sample == 8)
2214 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2215 else if (st->codecpar->bits_per_coded_sample == 16)
2216 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2219 switch (st->codecpar->codec_id) {
2220 case AV_CODEC_ID_PCM_S8:
2221 case AV_CODEC_ID_PCM_U8:
2222 if (st->codecpar->bits_per_coded_sample == 16)
2223 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16BE;
2225 case AV_CODEC_ID_PCM_S16LE:
2226 case AV_CODEC_ID_PCM_S16BE:
2227 if (st->codecpar->bits_per_coded_sample == 8)
2228 st->codecpar->codec_id = AV_CODEC_ID_PCM_S8;
2229 else if (st->codecpar->bits_per_coded_sample == 24)
2230 st->codecpar->codec_id =
2231 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2232 AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
2233 else if (st->codecpar->bits_per_coded_sample == 32)
2234 st->codecpar->codec_id =
2235 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2236 AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
2238 /* set values for old format before stsd version 1 appeared */
2239 case AV_CODEC_ID_MACE3:
2240 sc->samples_per_frame = 6;
2241 sc->bytes_per_frame = 2 * st->codecpar->channels;
2243 case AV_CODEC_ID_MACE6:
2244 sc->samples_per_frame = 6;
2245 sc->bytes_per_frame = 1 * st->codecpar->channels;
2247 case AV_CODEC_ID_ADPCM_IMA_QT:
2248 sc->samples_per_frame = 64;
2249 sc->bytes_per_frame = 34 * st->codecpar->channels;
2251 case AV_CODEC_ID_GSM:
2252 sc->samples_per_frame = 160;
2253 sc->bytes_per_frame = 33;
2259 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2260 if (bits_per_sample) {
2261 st->codecpar->bits_per_coded_sample = bits_per_sample;
2262 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->channels;
2266 static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
2267 AVStream *st, MOVStreamContext *sc,
2270 // ttxt stsd contains display flags, justification, background
2271 // color, fonts, and default styles, so fake an atom to read it
2272 MOVAtom fake_atom = { .size = size };
2273 // mp4s contains a regular esds atom
2274 if (st->codecpar->codec_tag != AV_RL32("mp4s"))
2275 mov_read_glbl(c, pb, fake_atom);
2276 st->codecpar->width = sc->width;
2277 st->codecpar->height = sc->height;
2280 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2285 y = (ycbcr >> 16) & 0xFF;
2286 cr = (ycbcr >> 8) & 0xFF;
2289 b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
2290 g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
2291 r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
2293 return (r << 16) | (g << 8) | b;
2296 static int mov_rewrite_dvd_sub_extradata(AVStream *st)
2298 char buf[256] = {0};
2299 uint8_t *src = st->codecpar->extradata;
2302 if (st->codecpar->extradata_size != 64)
2305 if (st->codecpar->width > 0 && st->codecpar->height > 0)
2306 snprintf(buf, sizeof(buf), "size: %dx%d\n",
2307 st->codecpar->width, st->codecpar->height);
2308 av_strlcat(buf, "palette: ", sizeof(buf));
2310 for (i = 0; i < 16; i++) {
2311 uint32_t yuv = AV_RB32(src + i * 4);
2312 uint32_t rgba = yuv_to_rgba(yuv);
2314 av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2317 if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2320 ret = ff_alloc_extradata(st->codecpar, strlen(buf));
2323 memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2328 static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
2329 AVStream *st, MOVStreamContext *sc,
2334 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2335 if ((int)size != size)
2336 return AVERROR(ENOMEM);
2338 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2342 MOVStreamContext *tmcd_ctx = st->priv_data;
2344 val = AV_RB32(st->codecpar->extradata + 4);
2345 tmcd_ctx->tmcd_flags = val;
2346 st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2347 st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2348 #if FF_API_LAVF_AVCTX
2349 FF_DISABLE_DEPRECATION_WARNINGS
2350 st->codec->time_base = av_inv_q(st->avg_frame_rate);
2351 FF_ENABLE_DEPRECATION_WARNINGS
2353 /* adjust for per frame dur in counter mode */
2354 if (tmcd_ctx->tmcd_flags & 0x0008) {
2355 int timescale = AV_RB32(st->codecpar->extradata + 8);
2356 int framedur = AV_RB32(st->codecpar->extradata + 12);
2357 st->avg_frame_rate = av_mul_q(st->avg_frame_rate, (AVRational){timescale, framedur});
2358 #if FF_API_LAVF_AVCTX
2359 FF_DISABLE_DEPRECATION_WARNINGS
2360 st->codec->time_base = av_mul_q(st->codec->time_base , (AVRational){framedur, timescale});
2361 FF_ENABLE_DEPRECATION_WARNINGS
2365 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2366 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2367 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2368 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2369 if (str_size > 0 && size >= (int)str_size + 30 &&
2370 st->codecpar->extradata[30] /* Don't add empty string */) {
2371 char *reel_name = av_malloc(str_size + 1);
2373 return AVERROR(ENOMEM);
2374 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2375 reel_name[str_size] = 0; /* Add null terminator */
2376 av_dict_set(&st->metadata, "reel_name", reel_name,
2377 AV_DICT_DONT_STRDUP_VAL);
2383 /* other codec type, just skip (rtp, mp4s ...) */
2384 avio_skip(pb, size);
2389 static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
2390 AVStream *st, MOVStreamContext *sc)
2392 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2393 !st->codecpar->sample_rate && sc->time_scale > 1)
2394 st->codecpar->sample_rate = sc->time_scale;
2396 /* special codec parameters handling */
2397 switch (st->codecpar->codec_id) {
2398 #if CONFIG_DV_DEMUXER
2399 case AV_CODEC_ID_DVAUDIO:
2400 c->dv_fctx = avformat_alloc_context();
2402 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2403 return AVERROR(ENOMEM);
2405 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2407 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2408 return AVERROR(ENOMEM);
2410 sc->dv_audio_container = 1;
2411 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
2414 /* no ifdef since parameters are always those */
2415 case AV_CODEC_ID_QCELP:
2416 st->codecpar->channels = 1;
2417 // force sample rate for qcelp when not stored in mov
2418 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2419 st->codecpar->sample_rate = 8000;
2420 // FIXME: Why is the following needed for some files?
2421 sc->samples_per_frame = 160;
2422 if (!sc->bytes_per_frame)
2423 sc->bytes_per_frame = 35;
2425 case AV_CODEC_ID_AMR_NB:
2426 st->codecpar->channels = 1;
2427 /* force sample rate for amr, stsd in 3gp does not store sample rate */
2428 st->codecpar->sample_rate = 8000;
2430 case AV_CODEC_ID_AMR_WB:
2431 st->codecpar->channels = 1;
2432 st->codecpar->sample_rate = 16000;
2434 case AV_CODEC_ID_MP2:
2435 case AV_CODEC_ID_MP3:
2436 /* force type after stsd for m1a hdlr */
2437 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2439 case AV_CODEC_ID_GSM:
2440 case AV_CODEC_ID_ADPCM_MS:
2441 case AV_CODEC_ID_ADPCM_IMA_WAV:
2442 case AV_CODEC_ID_ILBC:
2443 case AV_CODEC_ID_MACE3:
2444 case AV_CODEC_ID_MACE6:
2445 case AV_CODEC_ID_QDM2:
2446 st->codecpar->block_align = sc->bytes_per_frame;
2448 case AV_CODEC_ID_ALAC:
2449 if (st->codecpar->extradata_size == 36) {
2450 st->codecpar->channels = AV_RB8 (st->codecpar->extradata + 21);
2451 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2454 case AV_CODEC_ID_AC3:
2455 case AV_CODEC_ID_EAC3:
2456 case AV_CODEC_ID_MPEG1VIDEO:
2457 case AV_CODEC_ID_VC1:
2458 case AV_CODEC_ID_VP8:
2459 case AV_CODEC_ID_VP9:
2460 st->need_parsing = AVSTREAM_PARSE_FULL;
2462 case AV_CODEC_ID_AV1:
2463 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2471 static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
2472 int codec_tag, int format,
2475 int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2478 (codec_tag != format &&
2479 // AVID 1:1 samples with differing data format and codec tag exist
2480 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
2481 // prores is allowed to have differing data format and codec tag
2482 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
2484 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
2485 (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id
2486 : codec_tag != MKTAG('j','p','e','g')))) {
2487 /* Multiple fourcc, we skip JPEG. This is not correct, we should
2488 * export it as a separate AVStream but this needs a few changes
2489 * in the MOV demuxer, patch welcome. */
2491 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
2492 avio_skip(pb, size);
2499 int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
2502 MOVStreamContext *sc;
2503 int pseudo_stream_id;
2505 av_assert0 (c->fc->nb_streams >= 1);
2506 st = c->fc->streams[c->fc->nb_streams-1];
2509 for (pseudo_stream_id = 0;
2510 pseudo_stream_id < entries && !pb->eof_reached;
2511 pseudo_stream_id++) {
2512 //Parsing Sample description table
2514 int ret, dref_id = 1;
2515 MOVAtom a = { AV_RL32("stsd") };
2516 int64_t start_pos = avio_tell(pb);
2517 int64_t size = avio_rb32(pb); /* size */
2518 uint32_t format = avio_rl32(pb); /* data format */
2521 avio_rb32(pb); /* reserved */
2522 avio_rb16(pb); /* reserved */
2523 dref_id = avio_rb16(pb);
2524 } else if (size <= 7) {
2525 av_log(c->fc, AV_LOG_ERROR,
2526 "invalid size %"PRId64" in stsd\n", size);
2527 return AVERROR_INVALIDDATA;
2530 if (mov_skip_multiple_stsd(c, pb, st->codecpar->codec_tag, format,
2531 size - (avio_tell(pb) - start_pos))) {
2536 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
2537 sc->dref_id= dref_id;
2538 sc->format = format;
2540 id = mov_codec_id(st, format);
2542 av_log(c->fc, AV_LOG_TRACE,
2543 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
2544 av_fourcc2str(format), st->codecpar->codec_type);
2546 st->codecpar->codec_id = id;
2547 if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) {
2548 mov_parse_stsd_video(c, pb, st, sc);
2549 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
2550 mov_parse_stsd_audio(c, pb, st, sc);
2551 if (st->codecpar->sample_rate < 0) {
2552 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
2553 return AVERROR_INVALIDDATA;
2555 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
2556 mov_parse_stsd_subtitle(c, pb, st, sc,
2557 size - (avio_tell(pb) - start_pos));
2559 ret = mov_parse_stsd_data(c, pb, st, sc,
2560 size - (avio_tell(pb) - start_pos));
2564 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
2565 a.size = size - (avio_tell(pb) - start_pos);
2567 if ((ret = mov_read_default(c, pb, a)) < 0)
2569 } else if (a.size > 0)
2570 avio_skip(pb, a.size);
2572 if (sc->extradata && st->codecpar->extradata) {
2573 int extra_size = st->codecpar->extradata_size;
2575 /* Move the current stream extradata to the stream context one. */
2576 sc->extradata_size[pseudo_stream_id] = extra_size;
2577 sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
2578 st->codecpar->extradata = NULL;
2579 st->codecpar->extradata_size = 0;
2584 if (pb->eof_reached) {
2585 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
2592 static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2595 MOVStreamContext *sc;
2598 if (c->fc->nb_streams < 1)
2600 st = c->fc->streams[c->fc->nb_streams - 1];
2603 sc->stsd_version = avio_r8(pb);
2604 avio_rb24(pb); /* flags */
2605 entries = avio_rb32(pb);
2607 /* Each entry contains a size (4 bytes) and format (4 bytes). */
2608 if (entries <= 0 || entries > atom.size / 8) {
2609 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
2610 return AVERROR_INVALIDDATA;
2613 if (sc->extradata) {
2614 av_log(c->fc, AV_LOG_ERROR,
2615 "Duplicate stsd found in this track.\n");
2616 return AVERROR_INVALIDDATA;
2619 /* Prepare space for hosting multiple extradata. */
2620 sc->extradata = av_mallocz_array(entries, sizeof(*sc->extradata));
2622 return AVERROR(ENOMEM);
2624 sc->extradata_size = av_mallocz_array(entries, sizeof(*sc->extradata_size));
2625 if (!sc->extradata_size) {
2626 ret = AVERROR(ENOMEM);
2630 ret = ff_mov_read_stsd_entries(c, pb, entries);
2634 /* Restore back the primary extradata. */
2635 av_freep(&st->codecpar->extradata);
2636 st->codecpar->extradata_size = sc->extradata_size[0];
2637 if (sc->extradata_size[0]) {
2638 st->codecpar->extradata = av_mallocz(sc->extradata_size[0] + AV_INPUT_BUFFER_PADDING_SIZE);
2639 if (!st->codecpar->extradata)
2640 return AVERROR(ENOMEM);
2641 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
2644 return mov_finalize_stsd_codec(c, pb, st, sc);
2646 if (sc->extradata) {
2648 for (j = 0; j < sc->stsd_count; j++)
2649 av_freep(&sc->extradata[j]);
2652 av_freep(&sc->extradata);
2653 av_freep(&sc->extradata_size);
2657 static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2660 MOVStreamContext *sc;
2661 unsigned int i, entries;
2663 if (c->fc->nb_streams < 1)
2665 st = c->fc->streams[c->fc->nb_streams-1];
2668 avio_r8(pb); /* version */
2669 avio_rb24(pb); /* flags */
2671 entries = avio_rb32(pb);
2672 if ((uint64_t)entries * 12 + 4 > atom.size)
2673 return AVERROR_INVALIDDATA;
2675 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
2680 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSC atom\n");
2681 av_free(sc->stsc_data);
2683 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
2685 return AVERROR(ENOMEM);
2687 for (i = 0; i < entries && !pb->eof_reached; i++) {
2688 sc->stsc_data[i].first = avio_rb32(pb);
2689 sc->stsc_data[i].count = avio_rb32(pb);
2690 sc->stsc_data[i].id = avio_rb32(pb);
2694 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
2695 int64_t first_min = i + 1;
2696 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
2697 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
2698 sc->stsc_data[i].first < first_min ||
2699 sc->stsc_data[i].count < 1 ||
2700 sc->stsc_data[i].id < 1) {
2701 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);
2702 if (i+1 >= sc->stsc_count) {
2703 if (sc->stsc_data[i].count == 0 && i > 0) {
2707 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
2708 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
2709 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
2710 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
2711 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
2714 av_assert0(sc->stsc_data[i+1].first >= 2);
2715 // We replace this entry by the next valid
2716 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
2717 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
2718 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
2722 if (pb->eof_reached) {
2723 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
2730 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
2732 return index < count - 1;
2735 /* Compute the samples value for the stsc entry at the given index. */
2736 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
2740 if (mov_stsc_index_valid(index, sc->stsc_count))
2741 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
2743 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
2744 av_assert0(sc->stsc_data[index].first <= sc->chunk_count);
2745 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
2748 return sc->stsc_data[index].count * (int64_t)chunk_count;
2751 static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2754 MOVStreamContext *sc;
2755 unsigned i, entries;
2757 if (c->fc->nb_streams < 1)
2759 st = c->fc->streams[c->fc->nb_streams-1];
2762 avio_rb32(pb); // version + flags
2764 entries = avio_rb32(pb);
2766 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
2767 av_free(sc->stps_data);
2769 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
2771 return AVERROR(ENOMEM);
2773 for (i = 0; i < entries && !pb->eof_reached; i++) {
2774 sc->stps_data[i] = avio_rb32(pb);
2779 if (pb->eof_reached) {
2780 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
2787 static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2790 MOVStreamContext *sc;
2791 unsigned int i, entries;
2793 if (c->fc->nb_streams < 1)
2795 st = c->fc->streams[c->fc->nb_streams-1];
2798 avio_r8(pb); /* version */
2799 avio_rb24(pb); /* flags */
2801 entries = avio_rb32(pb);
2803 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
2806 sc->keyframe_absent = 1;
2807 if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
2808 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2812 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
2813 if (entries >= UINT_MAX / sizeof(int))
2814 return AVERROR_INVALIDDATA;
2815 av_freep(&sc->keyframes);
2816 sc->keyframe_count = 0;
2817 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
2819 return AVERROR(ENOMEM);
2821 for (i = 0; i < entries && !pb->eof_reached; i++) {
2822 sc->keyframes[i] = avio_rb32(pb);
2825 sc->keyframe_count = i;
2827 if (pb->eof_reached) {
2828 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
2835 static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2838 MOVStreamContext *sc;
2839 unsigned int i, entries, sample_size, field_size, num_bytes;
2844 if (c->fc->nb_streams < 1)
2846 st = c->fc->streams[c->fc->nb_streams-1];
2849 avio_r8(pb); /* version */
2850 avio_rb24(pb); /* flags */
2852 if (atom.type == MKTAG('s','t','s','z')) {
2853 sample_size = avio_rb32(pb);
2854 if (!sc->sample_size) /* do not overwrite value computed in stsd */
2855 sc->sample_size = sample_size;
2856 sc->stsz_sample_size = sample_size;
2860 avio_rb24(pb); /* reserved */
2861 field_size = avio_r8(pb);
2863 entries = avio_rb32(pb);
2865 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
2867 sc->sample_count = entries;
2871 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
2872 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
2873 return AVERROR_INVALIDDATA;
2878 if (entries >= (UINT_MAX - 4) / field_size)
2879 return AVERROR_INVALIDDATA;
2880 if (sc->sample_sizes)
2881 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
2882 av_free(sc->sample_sizes);
2883 sc->sample_count = 0;
2884 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
2885 if (!sc->sample_sizes)
2886 return AVERROR(ENOMEM);
2888 num_bytes = (entries*field_size+4)>>3;
2890 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
2892 av_freep(&sc->sample_sizes);
2893 return AVERROR(ENOMEM);
2896 ret = ffio_read_size(pb, buf, num_bytes);
2898 av_freep(&sc->sample_sizes);
2900 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
2904 init_get_bits(&gb, buf, 8*num_bytes);
2906 for (i = 0; i < entries && !pb->eof_reached; i++) {
2907 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
2908 if (sc->sample_sizes[i] < 0) {
2910 av_log(c->fc, AV_LOG_ERROR, "Invalid sample size %d\n", sc->sample_sizes[i]);
2911 return AVERROR_INVALIDDATA;
2913 sc->data_size += sc->sample_sizes[i];
2916 sc->sample_count = i;
2920 if (pb->eof_reached) {
2921 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSZ atom\n");
2928 static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2931 MOVStreamContext *sc;
2932 unsigned int i, entries, alloc_size = 0;
2933 int64_t duration = 0;
2934 int64_t total_sample_count = 0;
2936 if (c->fc->nb_streams < 1)
2938 st = c->fc->streams[c->fc->nb_streams-1];
2941 avio_r8(pb); /* version */
2942 avio_rb24(pb); /* flags */
2943 entries = avio_rb32(pb);
2945 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
2946 c->fc->nb_streams-1, entries);
2949 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
2950 av_freep(&sc->stts_data);
2952 if (entries >= INT_MAX / sizeof(*sc->stts_data))
2953 return AVERROR(ENOMEM);
2955 for (i = 0; i < entries && !pb->eof_reached; i++) {
2956 int sample_duration;
2957 unsigned int sample_count;
2958 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
2959 MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
2960 min_entries * sizeof(*sc->stts_data));
2962 av_freep(&sc->stts_data);
2964 return AVERROR(ENOMEM);
2966 sc->stts_count = min_entries;
2967 sc->stts_data = stts_data;
2969 sample_count = avio_rb32(pb);
2970 sample_duration = avio_rb32(pb);
2972 sc->stts_data[i].count= sample_count;
2973 sc->stts_data[i].duration= sample_duration;
2975 av_log(c->fc, AV_LOG_TRACE, "sample_count=%d, sample_duration=%d\n",
2976 sample_count, sample_duration);
2978 duration+=(int64_t)sample_duration*(uint64_t)sample_count;
2979 total_sample_count+=sample_count;
2985 duration <= INT64_MAX - sc->duration_for_fps &&
2986 total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
2987 sc->duration_for_fps += duration;
2988 sc->nb_frames_for_fps += total_sample_count;
2991 if (pb->eof_reached) {
2992 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
2996 st->nb_frames= total_sample_count;
2998 st->duration= FFMIN(st->duration, duration);
2999 sc->track_end = duration;
3003 static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3006 MOVStreamContext *sc;
3009 if (c->fc->nb_streams < 1)
3011 st = c->fc->streams[c->fc->nb_streams - 1];
3014 avio_r8(pb); /* version */
3015 avio_rb24(pb); /* flags */
3016 entries = atom.size - 4;
3018 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3019 c->fc->nb_streams - 1, entries);
3022 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3023 av_freep(&sc->sdtp_data);
3026 sc->sdtp_data = av_mallocz(entries);
3028 return AVERROR(ENOMEM);
3030 for (i = 0; i < entries && !pb->eof_reached; i++)
3031 sc->sdtp_data[i] = avio_r8(pb);
3037 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3040 if (duration == INT_MIN) {
3041 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3044 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3048 static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3051 MOVStreamContext *sc;
3052 unsigned int i, entries, ctts_count = 0;
3054 if (c->fc->nb_streams < 1)
3056 st = c->fc->streams[c->fc->nb_streams-1];
3059 avio_r8(pb); /* version */
3060 avio_rb24(pb); /* flags */
3061 entries = avio_rb32(pb);
3063 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3067 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3068 return AVERROR_INVALIDDATA;
3069 av_freep(&sc->ctts_data);
3070 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3072 return AVERROR(ENOMEM);
3074 for (i = 0; i < entries && !pb->eof_reached; i++) {
3075 int count = avio_rb32(pb);
3076 int duration = avio_rb32(pb);
3079 av_log(c->fc, AV_LOG_TRACE,
3080 "ignoring CTTS entry with count=%d duration=%d\n",
3085 add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3088 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3091 if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3092 av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3093 av_freep(&sc->ctts_data);
3099 mov_update_dts_shift(sc, duration, c->fc);
3102 sc->ctts_count = ctts_count;
3104 if (pb->eof_reached) {
3105 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3109 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3114 static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3117 MOVStreamContext *sc;
3118 unsigned int i, entries;
3120 uint32_t grouping_type;
3122 if (c->fc->nb_streams < 1)
3124 st = c->fc->streams[c->fc->nb_streams-1];
3127 version = avio_r8(pb); /* version */
3128 avio_rb24(pb); /* flags */
3129 grouping_type = avio_rl32(pb);
3130 if (grouping_type != MKTAG( 'r','a','p',' '))
3131 return 0; /* only support 'rap ' grouping */
3133 avio_rb32(pb); /* grouping_type_parameter */
3135 entries = avio_rb32(pb);
3139 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP atom\n");
3140 av_free(sc->rap_group);
3141 sc->rap_group_count = 0;
3142 sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group));
3144 return AVERROR(ENOMEM);
3146 for (i = 0; i < entries && !pb->eof_reached; i++) {
3147 sc->rap_group[i].count = avio_rb32(pb); /* sample_count */
3148 sc->rap_group[i].index = avio_rb32(pb); /* group_description_index */
3151 sc->rap_group_count = i;
3153 if (pb->eof_reached) {
3154 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3162 * Get ith edit list entry (media time, duration).
3164 static int get_edit_list_entry(MOVContext *mov,
3165 const MOVStreamContext *msc,
3166 unsigned int edit_list_index,
3167 int64_t *edit_list_media_time,
3168 int64_t *edit_list_duration,
3169 int64_t global_timescale)
3171 if (edit_list_index == msc->elst_count) {
3174 *edit_list_media_time = msc->elst_data[edit_list_index].time;
3175 *edit_list_duration = msc->elst_data[edit_list_index].duration;
3177 /* duration is in global timescale units;convert to msc timescale */
3178 if (global_timescale == 0) {
3179 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3182 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3188 * Find the closest previous frame to the timestamp_pts, in e_old index
3189 * entries. Searching for just any frame / just key frames can be controlled by
3190 * last argument 'flag'.
3191 * Note that if ctts_data is not NULL, we will always search for a key frame
3192 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3193 * return the first frame of the video.
3195 * Here the timestamp_pts is considered to be a presentation timestamp and
3196 * the timestamp of index entries are considered to be decoding timestamps.
3198 * Returns 0 if successful in finding a frame, else returns -1.
3199 * Places the found index corresponding output arg.
3201 * If ctts_old is not NULL, then refines the searched entry by searching
3202 * backwards from the found timestamp, to find the frame with correct PTS.
3204 * Places the found ctts_index and ctts_sample in corresponding output args.
3206 static int find_prev_closest_index(AVStream *st,
3207 AVIndexEntry *e_old,
3211 int64_t timestamp_pts,
3214 int64_t* ctts_index,
3215 int64_t* ctts_sample)
3217 MOVStreamContext *msc = st->priv_data;
3218 AVIndexEntry *e_keep = st->internal->index_entries;
3219 int nb_keep = st->internal->nb_index_entries;
3221 int64_t index_ctts_count;
3225 // If dts_shift > 0, then all the index timestamps will have to be offset by
3226 // at least dts_shift amount to obtain PTS.
3227 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3228 if (msc->dts_shift > 0) {
3229 timestamp_pts -= msc->dts_shift;
3232 st->internal->index_entries = e_old;
3233 st->internal->nb_index_entries = nb_old;
3234 *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3236 // Keep going backwards in the index entries until the timestamp is the same.
3238 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3240 if ((flag & AVSEEK_FLAG_ANY) ||
3241 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3247 // If we have CTTS then refine the search, by searching backwards over PTS
3248 // computed by adding corresponding CTTS durations to index timestamps.
3249 if (ctts_data && *index >= 0) {
3250 av_assert0(ctts_index);
3251 av_assert0(ctts_sample);
3252 // Find out the ctts_index for the found frame.
3255 for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3256 if (*ctts_index < ctts_count) {
3258 if (ctts_data[*ctts_index].count == *ctts_sample) {
3265 while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3266 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3267 // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3268 // compensated by dts_shift above.
3269 if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3270 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3275 if (*ctts_sample == 0) {
3277 if (*ctts_index >= 0)
3278 *ctts_sample = ctts_data[*ctts_index].count - 1;
3285 /* restore AVStream state*/
3286 st->internal->index_entries = e_keep;
3287 st->internal->nb_index_entries = nb_keep;
3288 return *index >= 0 ? 0 : -1;
3292 * Add index entry with the given values, to the end of st->internal->index_entries.
3293 * Returns the new size st->internal->index_entries if successful, else returns -1.
3295 * This function is similar to ff_add_index_entry in libavformat/utils.c
3296 * except that here we are always unconditionally adding an index entry to
3297 * the end, instead of searching the entries list and skipping the add if
3298 * there is an existing entry with the same timestamp.
3299 * This is needed because the mov_fix_index calls this func with the same
3300 * unincremented timestamp for successive discarded frames.
3302 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3303 int size, int distance, int flags)
3305 AVIndexEntry *entries, *ie;
3307 const size_t min_size_needed = (st->internal->nb_index_entries + 1) * sizeof(AVIndexEntry);
3309 // Double the allocation each time, to lower memory fragmentation.
3310 // Another difference from ff_add_index_entry function.
3311 const size_t requested_size =
3312 min_size_needed > st->internal->index_entries_allocated_size ?
3313 FFMAX(min_size_needed, 2 * st->internal->index_entries_allocated_size) :
3316 if (st->internal->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
3319 entries = av_fast_realloc(st->internal->index_entries,
3320 &st->internal->index_entries_allocated_size,
3325 st->internal->index_entries= entries;
3327 index= st->internal->nb_index_entries++;
3328 ie= &entries[index];
3331 ie->timestamp = timestamp;
3332 ie->min_distance= distance;
3339 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3340 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3342 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3343 int64_t* frame_duration_buffer,
3344 int frame_duration_buffer_size) {
3346 av_assert0(end_index >= 0 && end_index <= st->internal->nb_index_entries);
3347 for (i = 0; i < frame_duration_buffer_size; i++) {
3348 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3349 st->internal->index_entries[end_index - 1 - i].timestamp = end_ts;
3354 * Append a new ctts entry to ctts_data.
3355 * Returns the new ctts_count if successful, else returns -1.
3357 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3358 int count, int duration)
3360 MOVStts *ctts_buf_new;
3361 const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVStts);
3362 const size_t requested_size =
3363 min_size_needed > *allocated_size ?
3364 FFMAX(min_size_needed, 2 * (*allocated_size)) :
3367 if ((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
3370 ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3375 *ctts_data = ctts_buf_new;
3377 ctts_buf_new[*ctts_count].count = count;
3378 ctts_buf_new[*ctts_count].duration = duration;
3380 *ctts_count = (*ctts_count) + 1;
3384 #define MAX_REORDER_DELAY 16
3385 static void mov_estimate_video_delay(MOVContext *c, AVStream* st)
3387 MOVStreamContext *msc = st->priv_data;
3390 int ctts_sample = 0;
3391 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3393 int j, r, num_swaps;
3395 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3396 pts_buf[j] = INT64_MIN;
3398 if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3399 st->codecpar->codec_id == AV_CODEC_ID_H264) {
3400 st->codecpar->video_delay = 0;
3401 for (ind = 0; ind < st->internal->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3402 // Point j to the last elem of the buffer and insert the current pts there.
3404 buf_start = (buf_start + 1);
3405 if (buf_start == MAX_REORDER_DELAY + 1)
3408 pts_buf[j] = st->internal->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3410 // The timestamps that are already in the sorted buffer, and are greater than the
3411 // current pts, are exactly the timestamps that need to be buffered to output PTS
3412 // in correct sorted order.
3413 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3414 // can be computed as the maximum no. of swaps any particular timestamp needs to
3415 // go through, to keep this buffer in sorted order.
3417 while (j != buf_start) {
3419 if (r < 0) r = MAX_REORDER_DELAY;
3420 if (pts_buf[j] < pts_buf[r]) {
3421 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3428 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3431 if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3436 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3437 st->codecpar->video_delay, st->index);
3441 static void mov_current_sample_inc(MOVStreamContext *sc)
3443 sc->current_sample++;
3444 sc->current_index++;
3445 if (sc->index_ranges &&
3446 sc->current_index >= sc->current_index_range->end &&
3447 sc->current_index_range->end) {
3448 sc->current_index_range++;
3449 sc->current_index = sc->current_index_range->start;
3453 static void mov_current_sample_dec(MOVStreamContext *sc)
3455 sc->current_sample--;
3456 sc->current_index--;
3457 if (sc->index_ranges &&
3458 sc->current_index < sc->current_index_range->start &&
3459 sc->current_index_range > sc->index_ranges) {
3460 sc->current_index_range--;
3461 sc->current_index = sc->current_index_range->end - 1;
3465 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3469 sc->current_sample = current_sample;
3470 sc->current_index = current_sample;
3471 if (!sc->index_ranges) {
3475 for (sc->current_index_range = sc->index_ranges;
3476 sc->current_index_range->end;
3477 sc->current_index_range++) {
3478 range_size = sc->current_index_range->end - sc->current_index_range->start;
3479 if (range_size > current_sample) {
3480 sc->current_index = sc->current_index_range->start + current_sample;
3483 current_sample -= range_size;
3488 * Fix st->internal->index_entries, so that it contains only the entries (and the entries
3489 * which are needed to decode them) that fall in the edit list time ranges.
3490 * Also fixes the timestamps of the index entries to match the timeline
3491 * specified the edit lists.
3493 static void mov_fix_index(MOVContext *mov, AVStream *st)
3495 MOVStreamContext *msc = st->priv_data;
3496 AVIndexEntry *e_old = st->internal->index_entries;
3497 int nb_old = st->internal->nb_index_entries;
3498 const AVIndexEntry *e_old_end = e_old + nb_old;
3499 const AVIndexEntry *current = NULL;
3500 MOVStts *ctts_data_old = msc->ctts_data;
3501 int64_t ctts_index_old = 0;
3502 int64_t ctts_sample_old = 0;
3503 int64_t ctts_count_old = msc->ctts_count;
3504 int64_t edit_list_media_time = 0;
3505 int64_t edit_list_duration = 0;
3506 int64_t frame_duration = 0;
3507 int64_t edit_list_dts_counter = 0;
3508 int64_t edit_list_dts_entry_end = 0;
3509 int64_t edit_list_start_ctts_sample = 0;
3511 int64_t curr_ctts = 0;
3512 int64_t empty_edits_sum_duration = 0;
3513 int64_t edit_list_index = 0;
3516 int64_t start_dts = 0;
3517 int64_t edit_list_start_encountered = 0;
3518 int64_t search_timestamp = 0;
3519 int64_t* frame_duration_buffer = NULL;
3520 int num_discarded_begin = 0;
3521 int first_non_zero_audio_edit = -1;
3522 int packet_skip_samples = 0;
3523 MOVIndexRange *current_index_range;
3525 int found_keyframe_after_edit = 0;
3526 int found_non_empty_edit = 0;
3528 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
3532 // allocate the index ranges array
3533 msc->index_ranges = av_malloc((msc->elst_count + 1) * sizeof(msc->index_ranges[0]));
3534 if (!msc->index_ranges) {
3535 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
3538 msc->current_index_range = msc->index_ranges;
3539 current_index_range = msc->index_ranges - 1;
3541 // Clean AVStream from traces of old index
3542 st->internal->index_entries = NULL;
3543 st->internal->index_entries_allocated_size = 0;
3544 st->internal->nb_index_entries = 0;
3546 // Clean ctts fields of MOVStreamContext
3547 msc->ctts_data = NULL;
3548 msc->ctts_count = 0;
3549 msc->ctts_index = 0;
3550 msc->ctts_sample = 0;
3551 msc->ctts_allocated_size = 0;
3553 // Reinitialize min_corrected_pts so that it can be computed again.
3554 msc->min_corrected_pts = -1;
3556 // If the dts_shift is positive (in case of negative ctts values in mov),
3557 // then negate the DTS by dts_shift
3558 if (msc->dts_shift > 0) {
3559 edit_list_dts_entry_end -= msc->dts_shift;
3560 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
3563 start_dts = edit_list_dts_entry_end;
3565 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
3566 &edit_list_duration, mov->time_scale)) {
3567 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
3568 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
3570 edit_list_dts_counter = edit_list_dts_entry_end;
3571 edit_list_dts_entry_end += edit_list_duration;
3572 num_discarded_begin = 0;
3573 if (!found_non_empty_edit && edit_list_media_time == -1) {
3574 empty_edits_sum_duration += edit_list_duration;
3577 found_non_empty_edit = 1;
3579 // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
3580 // according to the edit list below.
3581 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3582 if (first_non_zero_audio_edit < 0) {
3583 first_non_zero_audio_edit = 1;
3585 first_non_zero_audio_edit = 0;
3588 if (first_non_zero_audio_edit > 0)
3589 st->internal->skip_samples = msc->start_pad = 0;
3592 // While reordering frame index according to edit list we must handle properly
3593 // the scenario when edit list entry starts from none key frame.
3594 // We find closest previous key frame and preserve it and consequent frames in index.
3595 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
3596 search_timestamp = edit_list_media_time;
3597 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3598 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
3599 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
3600 // edit_list_media_time to cover the decoder delay.
3601 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
3604 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
3605 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3606 av_log(mov->fc, AV_LOG_WARNING,
3607 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
3608 st->index, edit_list_index, search_timestamp);
3609 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
3610 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3611 av_log(mov->fc, AV_LOG_WARNING,
3612 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
3613 st->index, edit_list_index, search_timestamp);
3616 ctts_sample_old = 0;
3619 current = e_old + index;
3620 edit_list_start_ctts_sample = ctts_sample_old;
3622 // Iterate over index and arrange it according to edit list
3623 edit_list_start_encountered = 0;
3624 found_keyframe_after_edit = 0;
3625 for (; current < e_old_end; current++, index++) {
3626 // check if frame outside edit list mark it for discard
3627 frame_duration = (current + 1 < e_old_end) ?
3628 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
3630 flags = current->flags;
3632 // frames (pts) before or after edit list
3633 curr_cts = current->timestamp + msc->dts_shift;
3636 if (ctts_data_old && ctts_index_old < ctts_count_old) {
3637 curr_ctts = ctts_data_old[ctts_index_old].duration;
3638 av_log(mov->fc, AV_LOG_DEBUG, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
3639 curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
3640 curr_cts += curr_ctts;
3642 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
3643 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3644 &msc->ctts_allocated_size,
3645 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3646 ctts_data_old[ctts_index_old].duration) == -1) {
3647 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3649 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3650 ctts_data_old[ctts_index_old].duration);
3654 ctts_sample_old = 0;
3655 edit_list_start_ctts_sample = 0;
3659 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
3660 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
3661 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
3662 first_non_zero_audio_edit > 0) {
3663 packet_skip_samples = edit_list_media_time - curr_cts;
3664 st->internal->skip_samples += packet_skip_samples;
3666 // Shift the index entry timestamp by packet_skip_samples to be correct.
3667 edit_list_dts_counter -= packet_skip_samples;
3668 if (edit_list_start_encountered == 0) {
3669 edit_list_start_encountered = 1;
3670 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
3671 // discarded packets.
3672 if (frame_duration_buffer) {
3673 fix_index_entry_timestamps(st, st->internal->nb_index_entries, edit_list_dts_counter,
3674 frame_duration_buffer, num_discarded_begin);
3675 av_freep(&frame_duration_buffer);
3679 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
3681 flags |= AVINDEX_DISCARD_FRAME;
3682 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
3684 if (edit_list_start_encountered == 0) {
3685 num_discarded_begin++;
3686 frame_duration_buffer = av_realloc(frame_duration_buffer,
3687 num_discarded_begin * sizeof(int64_t));
3688 if (!frame_duration_buffer) {
3689 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
3692 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
3694 // Increment skip_samples for the first non-zero audio edit list
3695 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3696 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
3697 st->internal->skip_samples += frame_duration;
3702 if (msc->min_corrected_pts < 0) {
3703 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
3705 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
3707 if (edit_list_start_encountered == 0) {
3708 edit_list_start_encountered = 1;
3709 // Make timestamps strictly monotonically increasing by rewriting timestamps for
3710 // discarded packets.
3711 if (frame_duration_buffer) {
3712 fix_index_entry_timestamps(st, st->internal->nb_index_entries, edit_list_dts_counter,
3713 frame_duration_buffer, num_discarded_begin);
3714 av_freep(&frame_duration_buffer);
3719 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
3720 current->min_distance, flags) == -1) {
3721 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
3725 // Update the index ranges array
3726 if (current_index_range < msc->index_ranges || index != current_index_range->end) {
3727 current_index_range++;
3728 current_index_range->start = index;
3730 current_index_range->end = index + 1;
3732 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
3733 if (edit_list_start_encountered > 0) {
3734 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
3737 // Break when found first key frame after edit entry completion
3738 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
3739 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
3740 if (ctts_data_old) {
3741 // If we have CTTS and this is the first keyframe after edit elist,
3742 // wait for one more, because there might be trailing B-frames after this I-frame
3743 // that do belong to the edit.
3744 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
3745 found_keyframe_after_edit = 1;
3748 if (ctts_sample_old != 0) {
3749 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3750 &msc->ctts_allocated_size,
3751 ctts_sample_old - edit_list_start_ctts_sample,
3752 ctts_data_old[ctts_index_old].duration) == -1) {
3753 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3754 ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
3755 ctts_data_old[ctts_index_old].duration);
3764 // If there are empty edits, then msc->min_corrected_pts might be positive
3765 // intentionally. So we subtract the sum duration of emtpy edits here.
3766 msc->min_corrected_pts -= empty_edits_sum_duration;
3768 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
3769 // dts by that amount to make the first pts zero.
3770 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
3771 if (msc->min_corrected_pts > 0) {
3772 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
3773 for (i = 0; i < st->internal->nb_index_entries; ++i) {
3774 st->internal->index_entries[i].timestamp -= msc->min_corrected_pts;
3778 // Start time should be equal to zero or the duration of any empty edits.
3779 st->start_time = empty_edits_sum_duration;
3781 // Update av stream length, if it ends up shorter than the track's media duration
3782 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
3783 msc->start_pad = st->internal->skip_samples;
3785 // Free the old index and the old CTTS structures
3787 av_free(ctts_data_old);
3788 av_freep(&frame_duration_buffer);
3790 // Null terminate the index ranges array
3791 current_index_range++;
3792 current_index_range->start = 0;
3793 current_index_range->end = 0;
3794 msc->current_index = msc->index_ranges[0].start;
3797 static void mov_build_index(MOVContext *mov, AVStream *st)
3799 MOVStreamContext *sc = st->priv_data;
3800 int64_t current_offset;
3801 int64_t current_dts = 0;
3802 unsigned int stts_index = 0;
3803 unsigned int stsc_index = 0;
3804 unsigned int stss_index = 0;
3805 unsigned int stps_index = 0;
3807 uint64_t stream_size = 0;
3808 MOVStts *ctts_data_old = sc->ctts_data;
3809 unsigned int ctts_count_old = sc->ctts_count;
3811 if (sc->elst_count) {
3812 int i, edit_start_index = 0, multiple_edits = 0;
3813 int64_t empty_duration = 0; // empty duration of the first edit list entry
3814 int64_t start_time = 0; // start time of the media
3816 for (i = 0; i < sc->elst_count; i++) {
3817 const MOVElst *e = &sc->elst_data[i];
3818 if (i == 0 && e->time == -1) {
3819 /* if empty, the first entry is the start time of the stream
3820 * relative to the presentation itself */
3821 empty_duration = e->duration;
3822 edit_start_index = 1;
3823 } else if (i == edit_start_index && e->time >= 0) {
3824 start_time = e->time;
3830 if (multiple_edits && !mov->advanced_editlist)
3831 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
3832 "Use -advanced_editlist to correctly decode otherwise "
3833 "a/v desync might occur\n");
3835 /* adjust first dts according to edit list */
3836 if ((empty_duration || start_time) && mov->time_scale > 0) {
3838 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
3839 sc->time_offset = start_time - empty_duration;
3840 sc->min_corrected_pts = start_time;
3841 if (!mov->advanced_editlist)
3842 current_dts = -sc->time_offset;
3845 if (!multiple_edits && !mov->advanced_editlist &&
3846 st->codecpar->codec_id == AV_CODEC_ID_AAC && start_time > 0)
3847 sc->start_pad = start_time;
3850 /* only use old uncompressed audio chunk demuxing when stts specifies it */
3851 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3852 sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
3853 unsigned int current_sample = 0;
3854 unsigned int stts_sample = 0;
3855 unsigned int sample_size;
3856 unsigned int distance = 0;
3857 unsigned int rap_group_index = 0;
3858 unsigned int rap_group_sample = 0;
3859 int64_t last_dts = 0;
3860 int64_t dts_correction = 0;
3861 int rap_group_present = sc->rap_group_count && sc->rap_group;
3862 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
3864 current_dts -= sc->dts_shift;
3865 last_dts = current_dts;
3867 if (!sc->sample_count || st->internal->nb_index_entries)
3869 if (sc->sample_count >= UINT_MAX / sizeof(*st->internal->index_entries) - st->internal->nb_index_entries)
3871 if (av_reallocp_array(&st->internal->index_entries,
3872 st->internal->nb_index_entries + sc->sample_count,
3873 sizeof(*st->internal->index_entries)) < 0) {
3874 st->internal->nb_index_entries = 0;
3877 st->internal->index_entries_allocated_size = (st->internal->nb_index_entries + sc->sample_count) * sizeof(*st->internal->index_entries);
3879 if (ctts_data_old) {
3880 // Expand ctts entries such that we have a 1-1 mapping with samples
3881 if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
3884 sc->ctts_allocated_size = 0;
3885 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size,
3886 sc->sample_count * sizeof(*sc->ctts_data));
3887 if (!sc->ctts_data) {
3888 av_free(ctts_data_old);
3892 memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
3894 for (i = 0; i < ctts_count_old &&
3895 sc->ctts_count < sc->sample_count; i++)
3896 for (j = 0; j < ctts_data_old[i].count &&
3897 sc->ctts_count < sc->sample_count; j++)
3898 add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
3899 &sc->ctts_allocated_size, 1,
3900 ctts_data_old[i].duration);
3901 av_free(ctts_data_old);
3904 for (i = 0; i < sc->chunk_count; i++) {
3905 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
3906 current_offset = sc->chunk_offsets[i];
3907 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3908 i + 1 == sc->stsc_data[stsc_index + 1].first)
3911 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
3912 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
3913 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
3914 sc->stsz_sample_size = sc->sample_size;
3916 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
3917 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
3918 sc->stsz_sample_size = sc->sample_size;
3921 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
3923 if (current_sample >= sc->sample_count) {
3924 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
3928 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
3930 if (stss_index + 1 < sc->keyframe_count)
3932 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
3934 if (stps_index + 1 < sc->stps_count)
3937 if (rap_group_present && rap_group_index < sc->rap_group_count) {
3938 if (sc->rap_group[rap_group_index].index > 0)
3940 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
3941 rap_group_sample = 0;
3945 if (sc->keyframe_absent
3947 && !rap_group_present
3948 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
3952 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
3953 if (sc->pseudo_stream_id == -1 ||
3954 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
3956 if (sample_size > 0x3FFFFFFF) {
3957 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
3960 e = &st->internal->index_entries[st->internal->nb_index_entries++];
3961 e->pos = current_offset;
3962 e->timestamp = current_dts;
3963 e->size = sample_size;
3964 e->min_distance = distance;
3965 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
3966 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
3967 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
3968 current_offset, current_dts, sample_size, distance, keyframe);
3969 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->internal->nb_index_entries < 100)
3970 ff_rfps_add_frame(mov->fc, st, current_dts);
3973 current_offset += sample_size;
3974 stream_size += sample_size;
3976 /* A negative sample duration is invalid based on the spec,
3977 * but some samples need it to correct the DTS. */
3978 if (sc->stts_data[stts_index].duration < 0) {
3979 av_log(mov->fc, AV_LOG_WARNING,
3980 "Invalid SampleDelta %d in STTS, at %d st:%d\n",
3981 sc->stts_data[stts_index].duration, stts_index,
3983 dts_correction += sc->stts_data[stts_index].duration - 1;
3984 sc->stts_data[stts_index].duration = 1;
3986 current_dts += sc->stts_data[stts_index].duration;
3987 if (!dts_correction || current_dts + dts_correction > last_dts) {
3988 current_dts += dts_correction;
3991 /* Avoid creating non-monotonous DTS */
3992 dts_correction += current_dts - last_dts - 1;
3993 current_dts = last_dts + 1;
3995 last_dts = current_dts;
3999 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
4005 if (st->duration > 0)
4006 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
4008 unsigned chunk_samples, total = 0;
4010 if (!sc->chunk_count)
4013 // compute total chunk count
4014 for (i = 0; i < sc->stsc_count; i++) {
4015 unsigned count, chunk_count;
4017 chunk_samples = sc->stsc_data[i].count;
4018 if (i != sc->stsc_count - 1 &&
4019 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
4020 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
4024 if (sc->samples_per_frame >= 160) { // gsm
4025 count = chunk_samples / sc->samples_per_frame;
4026 } else if (sc->samples_per_frame > 1) {
4027 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4028 count = (chunk_samples+samples-1) / samples;
4030 count = (chunk_samples+1023) / 1024;
4033 if (mov_stsc_index_valid(i, sc->stsc_count))
4034 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4036 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4037 total += chunk_count * count;
4040 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4041 if (total >= UINT_MAX / sizeof(*st->internal->index_entries) - st->internal->nb_index_entries)
4043 if (av_reallocp_array(&st->internal->index_entries,
4044 st->internal->nb_index_entries + total,
4045 sizeof(*st->internal->index_entries)) < 0) {
4046 st->internal->nb_index_entries = 0;
4049 st->internal->index_entries_allocated_size = (st->internal->nb_index_entries + total) * sizeof(*st->internal->index_entries);
4052 for (i = 0; i < sc->chunk_count; i++) {
4053 current_offset = sc->chunk_offsets[i];
4054 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4055 i + 1 == sc->stsc_data[stsc_index + 1].first)
4057 chunk_samples = sc->stsc_data[stsc_index].count;
4059 while (chunk_samples > 0) {
4061 unsigned size, samples;
4063 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4064 avpriv_request_sample(mov->fc,
4065 "Zero bytes per frame, but %d samples per frame",
4066 sc->samples_per_frame);
4070 if (sc->samples_per_frame >= 160) { // gsm
4071 samples = sc->samples_per_frame;
4072 size = sc->bytes_per_frame;
4074 if (sc->samples_per_frame > 1) {
4075 samples = FFMIN((1024 / sc->samples_per_frame)*
4076 sc->samples_per_frame, chunk_samples);
4077 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
4079 samples = FFMIN(1024, chunk_samples);
4080 size = samples * sc->sample_size;
4084 if (st->internal->nb_index_entries >= total) {
4085 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4088 if (size > 0x3FFFFFFF) {
4089 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4092 e = &st->internal->index_entries[st->internal->nb_index_entries++];
4093 e->pos = current_offset;
4094 e->timestamp = current_dts;
4096 e->min_distance = 0;
4097 e->flags = AVINDEX_KEYFRAME;
4098 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4099 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4102 current_offset += size;
4103 current_dts += samples;
4104 chunk_samples -= samples;
4109 if (!mov->ignore_editlist && mov->advanced_editlist) {
4110 // Fix index according to edit lists.
4111 mov_fix_index(mov, st);
4114 // Update start time of the stream.
4115 if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->internal->nb_index_entries > 0) {
4116 st->start_time = st->internal->index_entries[0].timestamp + sc->dts_shift;
4117 if (sc->ctts_data) {
4118 st->start_time += sc->ctts_data[0].duration;
4122 mov_estimate_video_delay(mov, st);
4125 static int test_same_origin(const char *src, const char *ref) {
4135 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4136 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4138 if (strlen(src) == 0) {
4140 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4141 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4142 strlen(src_host) + 1 >= sizeof(src_host) ||
4143 strlen(ref_host) + 1 >= sizeof(ref_host)) {
4145 } else if (strcmp(src_proto, ref_proto) ||
4146 strcmp(src_auth, ref_auth) ||
4147 strcmp(src_host, ref_host) ||
4148 src_port != ref_port) {
4154 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4156 /* try relative path, we do not try the absolute because it can leak information about our
4157 system to an attacker */
4158 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4159 char filename[1025];
4160 const char *src_path;
4163 /* find a source dir */
4164 src_path = strrchr(src, '/');
4170 /* find a next level down to target */
4171 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4172 if (ref->path[l] == '/') {
4173 if (i == ref->nlvl_to - 1)
4179 /* compose filename if next level down to target was found */
4180 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4181 memcpy(filename, src, src_path - src);
4182 filename[src_path - src] = 0;
4184 for (i = 1; i < ref->nlvl_from; i++)
4185 av_strlcat(filename, "../", sizeof(filename));
4187 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4188 if (!c->use_absolute_path) {
4189 int same_origin = test_same_origin(src, filename);
4192 av_log(c->fc, AV_LOG_ERROR,
4193 "Reference with mismatching origin, %s not tried for security reasons, "
4194 "set demuxer option use_absolute_path to allow it anyway\n",
4196 return AVERROR(ENOENT);
4199 if (strstr(ref->path + l + 1, "..") ||
4200 strstr(ref->path + l + 1, ":") ||
4201 (ref->nlvl_from > 1 && same_origin < 0) ||
4202 (filename[0] == '/' && src_path == src))
4203 return AVERROR(ENOENT);
4206 if (strlen(filename) + 1 == sizeof(filename))
4207 return AVERROR(ENOENT);
4208 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4211 } else if (c->use_absolute_path) {
4212 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4213 "this is a possible security issue\n");
4214 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4217 av_log(c->fc, AV_LOG_ERROR,
4218 "Absolute path %s not tried for security reasons, "
4219 "set demuxer option use_absolute_path to allow absolute paths\n",
4223 return AVERROR(ENOENT);
4226 static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
4228 if (sc->time_scale <= 0) {
4229 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4230 sc->time_scale = c->time_scale;
4231 if (sc->time_scale <= 0)
4236 static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4239 MOVStreamContext *sc;
4242 st = avformat_new_stream(c->fc, NULL);
4243 if (!st) return AVERROR(ENOMEM);
4245 sc = av_mallocz(sizeof(MOVStreamContext));
4246 if (!sc) return AVERROR(ENOMEM);
4249 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
4250 sc->ffindex = st->index;
4251 c->trak_index = st->index;
4253 if ((ret = mov_read_default(c, pb, atom)) < 0)
4258 // Here stsc refers to a chunk not described in stco. This is technically invalid,
4259 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4260 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4262 av_freep(&sc->stsc_data);
4266 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4267 (!sc->sample_size && !sc->sample_count))) ||
4268 (!sc->chunk_count && sc->sample_count)) {
4269 av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4273 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4274 av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4276 return AVERROR_INVALIDDATA;
4279 fix_timescale(c, sc);
4281 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4283 mov_build_index(c, st);
4285 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4286 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4287 if (c->enable_drefs) {
4288 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4289 av_log(c->fc, AV_LOG_ERROR,
4290 "stream %d, error opening alias: path='%s', dir='%s', "
4291 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4292 st->index, dref->path, dref->dir, dref->filename,
4293 dref->volume, dref->nlvl_from, dref->nlvl_to);
4295 av_log(c->fc, AV_LOG_WARNING,
4296 "Skipped opening external track: "
4297 "stream %d, alias: path='%s', dir='%s', "
4298 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4299 "Set enable_drefs to allow this.\n",
4300 st->index, dref->path, dref->dir, dref->filename,
4301 dref->volume, dref->nlvl_from, dref->nlvl_to);
4305 sc->pb_is_copied = 1;
4308 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4309 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4310 sc->height && sc->width &&
4311 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4312 st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4313 ((double)st->codecpar->width * sc->height), INT_MAX);
4316 #if FF_API_R_FRAME_RATE
4317 if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4318 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
4319 sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4323 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4324 if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4325 TAG_IS_AVCI(st->codecpar->codec_tag)) {
4326 ret = ff_generate_avci_extradata(st);
4331 switch (st->codecpar->codec_id) {
4332 #if CONFIG_H261_DECODER
4333 case AV_CODEC_ID_H261:
4335 #if CONFIG_H263_DECODER
4336 case AV_CODEC_ID_H263:
4338 #if CONFIG_MPEG4_DECODER
4339 case AV_CODEC_ID_MPEG4:
4341 st->codecpar->width = 0; /* let decoder init width/height */
4342 st->codecpar->height= 0;
4346 // If the duration of the mp3 packets is not constant, then they could need a parser
4347 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4348 && sc->stts_count > 3
4349 && sc->stts_count*10 > st->nb_frames
4350 && sc->time_scale == st->codecpar->sample_rate) {
4351 st->need_parsing = AVSTREAM_PARSE_FULL;
4353 /* Do not need those anymore. */
4354 av_freep(&sc->chunk_offsets);
4355 av_freep(&sc->sample_sizes);
4356 av_freep(&sc->keyframes);
4357 av_freep(&sc->stts_data);
4358 av_freep(&sc->stps_data);
4359 av_freep(&sc->elst_data);
4360 av_freep(&sc->rap_group);
4365 static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4368 c->itunes_metadata = 1;
4369 ret = mov_read_default(c, pb, atom);
4370 c->itunes_metadata = 0;
4374 static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4383 count = avio_rb32(pb);
4384 if (count > UINT_MAX / sizeof(*c->meta_keys) - 1) {
4385 av_log(c->fc, AV_LOG_ERROR,
4386 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
4387 return AVERROR_INVALIDDATA;
4390 c->meta_keys_count = count + 1;
4391 c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
4393 return AVERROR(ENOMEM);
4395 for (i = 1; i <= count; ++i) {
4396 uint32_t key_size = avio_rb32(pb);
4397 uint32_t type = avio_rl32(pb);
4399 av_log(c->fc, AV_LOG_ERROR,
4400 "The key# %"PRIu32" in meta has invalid size:"
4401 "%"PRIu32"\n", i, key_size);
4402 return AVERROR_INVALIDDATA;
4405 if (type != MKTAG('m','d','t','a')) {
4406 avio_skip(pb, key_size);
4408 c->meta_keys[i] = av_mallocz(key_size + 1);
4409 if (!c->meta_keys[i])
4410 return AVERROR(ENOMEM);
4411 avio_read(pb, c->meta_keys[i], key_size);
4417 static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4419 int64_t end = av_sat_add64(avio_tell(pb), atom.size);
4420 uint8_t *key = NULL, *val = NULL, *mean = NULL;
4424 MOVStreamContext *sc;
4426 if (c->fc->nb_streams < 1)
4428 st = c->fc->streams[c->fc->nb_streams-1];
4431 for (i = 0; i < 3; i++) {
4435 if (end - avio_tell(pb) <= 12)
4438 len = avio_rb32(pb);
4439 tag = avio_rl32(pb);
4440 avio_skip(pb, 4); // flags
4442 if (len < 12 || len - 12 > end - avio_tell(pb))
4446 if (tag == MKTAG('m', 'e', 'a', 'n'))
4448 else if (tag == MKTAG('n', 'a', 'm', 'e'))
4450 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
4460 *p = av_malloc(len + 1);
4462 ret = AVERROR(ENOMEM);
4465 ret = ffio_read_size(pb, *p, len);
4473 if (mean && key && val) {
4474 if (strcmp(key, "iTunSMPB") == 0) {
4475 int priming, remainder, samples;
4476 if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
4477 if(priming>0 && priming<16384)
4478 sc->start_pad = priming;
4481 if (strcmp(key, "cdec") != 0) {
4482 av_dict_set(&c->fc->metadata, key, val,
4483 AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
4487 av_log(c->fc, AV_LOG_VERBOSE,
4488 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
4491 avio_seek(pb, end, SEEK_SET);
4498 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4500 while (atom.size > 8) {
4504 tag = avio_rl32(pb);
4506 if (tag == MKTAG('h','d','l','r')) {
4507 avio_seek(pb, -8, SEEK_CUR);
4509 return mov_read_default(c, pb, atom);
4515 // return 1 when matrix is identity, 0 otherwise
4516 #define IS_MATRIX_IDENT(matrix) \
4517 ( (matrix)[0][0] == (1 << 16) && \
4518 (matrix)[1][1] == (1 << 16) && \
4519 (matrix)[2][2] == (1 << 30) && \
4520 !(matrix)[0][1] && !(matrix)[0][2] && \
4521 !(matrix)[1][0] && !(matrix)[1][2] && \
4522 !(matrix)[2][0] && !(matrix)[2][1])
4524 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4529 int display_matrix[3][3];
4530 int res_display_matrix[3][3] = { { 0 } };
4532 MOVStreamContext *sc;
4536 if (c->fc->nb_streams < 1)
4538 st = c->fc->streams[c->fc->nb_streams-1];
4541 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4542 // avoids corrupting AVStreams mapped to an earlier tkhd.
4544 return AVERROR_INVALIDDATA;
4546 version = avio_r8(pb);
4547 flags = avio_rb24(pb);
4548 st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
4554 avio_rb32(pb); /* creation time */
4555 avio_rb32(pb); /* modification time */
4557 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4558 avio_rb32(pb); /* reserved */
4560 /* highlevel (considering edits) duration in movie timebase */
4561 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4562 avio_rb32(pb); /* reserved */
4563 avio_rb32(pb); /* reserved */
4565 avio_rb16(pb); /* layer */
4566 avio_rb16(pb); /* alternate group */
4567 avio_rb16(pb); /* volume */
4568 avio_rb16(pb); /* reserved */
4570 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4571 // they're kept in fixed point format through all calculations
4572 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4573 // side data, but the scale factor is not needed to calculate aspect ratio
4574 for (i = 0; i < 3; i++) {
4575 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
4576 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
4577 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
4580 width = avio_rb32(pb); // 16.16 fixed point track width
4581 height = avio_rb32(pb); // 16.16 fixed point track height
4582 sc->width = width >> 16;
4583 sc->height = height >> 16;
4585 // apply the moov display matrix (after the tkhd one)
4586 for (i = 0; i < 3; i++) {
4587 const int sh[3] = { 16, 16, 30 };
4588 for (j = 0; j < 3; j++) {
4589 for (e = 0; e < 3; e++) {
4590 res_display_matrix[i][j] +=
4591 ((int64_t) display_matrix[i][e] *
4592 c->movie_display_matrix[e][j]) >> sh[e];
4597 // save the matrix when it is not the default identity
4598 if (!IS_MATRIX_IDENT(res_display_matrix)) {
4601 av_freep(&sc->display_matrix);
4602 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4603 if (!sc->display_matrix)
4604 return AVERROR(ENOMEM);
4606 for (i = 0; i < 3; i++)
4607 for (j = 0; j < 3; j++)
4608 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4610 #if FF_API_OLD_ROTATE_API
4611 rotate = av_display_rotation_get(sc->display_matrix);
4612 if (!isnan(rotate)) {
4613 char rotate_buf[64];
4615 if (rotate < 0) // for backward compatibility
4617 snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate);
4618 av_dict_set(&st->metadata, "rotate", rotate_buf, 0);
4623 // transform the display width/height according to the matrix
4624 // to keep the same scale, use [width height 1<<16]
4625 if (width && height && sc->display_matrix) {
4626 double disp_transform[2];
4628 for (i = 0; i < 2; i++)
4629 disp_transform[i] = hypot(sc->display_matrix[0 + i],
4630 sc->display_matrix[3 + i]);
4632 if (disp_transform[0] > 0 && disp_transform[1] > 0 &&
4633 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4634 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4635 st->sample_aspect_ratio = av_d2q(
4636 disp_transform[0] / disp_transform[1],
4642 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4644 MOVFragment *frag = &c->fragment;
4645 MOVTrackExt *trex = NULL;
4646 int flags, track_id, i;
4647 MOVFragmentStreamInfo * frag_stream_info;
4649 avio_r8(pb); /* version */
4650 flags = avio_rb24(pb);
4652 track_id = avio_rb32(pb);
4654 return AVERROR_INVALIDDATA;
4655 for (i = 0; i < c->trex_count; i++)
4656 if (c->trex_data[i].track_id == track_id) {
4657 trex = &c->trex_data[i];
4661 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4664 c->fragment.found_tfhd = 1;
4665 frag->track_id = track_id;
4666 set_frag_stream(&c->frag_index, track_id);
4668 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4669 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4670 frag->moof_offset : frag->implicit_offset;
4671 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4673 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4674 avio_rb32(pb) : trex->duration;
4675 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4676 avio_rb32(pb) : trex->size;
4677 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4678 avio_rb32(pb) : trex->flags;
4679 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4681 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4682 if (frag_stream_info)
4683 frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
4688 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4693 num = atom.size / 4;
4694 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4695 return AVERROR(ENOMEM);
4697 av_free(c->chapter_tracks);
4698 c->chapter_tracks = new_tracks;
4699 c->nb_chapter_tracks = num;
4701 for (i = 0; i < num && !pb->eof_reached; i++)
4702 c->chapter_tracks[i] = avio_rb32(pb);
4707 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4712 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4713 return AVERROR_INVALIDDATA;
4714 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4715 sizeof(*c->trex_data))) < 0) {
4720 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4722 trex = &c->trex_data[c->trex_count++];
4723 avio_r8(pb); /* version */
4724 avio_rb24(pb); /* flags */
4725 trex->track_id = avio_rb32(pb);
4726 trex->stsd_id = avio_rb32(pb);
4727 trex->duration = avio_rb32(pb);
4728 trex->size = avio_rb32(pb);
4729 trex->flags = avio_rb32(pb);
4733 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4735 MOVFragment *frag = &c->fragment;
4736 AVStream *st = NULL;
4737 MOVStreamContext *sc;
4739 MOVFragmentStreamInfo * frag_stream_info;
4740 int64_t base_media_decode_time;
4742 for (i = 0; i < c->fc->nb_streams; i++) {
4743 if (c->fc->streams[i]->id == frag->track_id) {
4744 st = c->fc->streams[i];
4749 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4753 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4755 version = avio_r8(pb);
4756 avio_rb24(pb); /* flags */
4758 base_media_decode_time = avio_rb64(pb);
4760 base_media_decode_time = avio_rb32(pb);
4763 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4764 if (frag_stream_info)
4765 frag_stream_info->tfdt_dts = base_media_decode_time;
4766 sc->track_end = base_media_decode_time;
4771 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4773 MOVFragment *frag = &c->fragment;
4774 AVStream *st = NULL;
4775 MOVStreamContext *sc;
4778 int64_t dts, pts = AV_NOPTS_VALUE;
4779 int data_offset = 0;
4780 unsigned entries, first_sample_flags = frag->flags;
4781 int flags, distance, i;
4782 int64_t prev_dts = AV_NOPTS_VALUE;
4783 int next_frag_index = -1, index_entry_pos;
4784 size_t requested_size;
4785 size_t old_ctts_allocated_size;
4786 AVIndexEntry *new_entries;
4787 MOVFragmentStreamInfo * frag_stream_info;
4789 if (!frag->found_tfhd) {
4790 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4791 return AVERROR_INVALIDDATA;
4794 for (i = 0; i < c->fc->nb_streams; i++) {
4795 if (c->fc->streams[i]->id == frag->track_id) {
4796 st = c->fc->streams[i];
4801 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4805 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4808 // Find the next frag_index index that has a valid index_entry for
4809 // the current track_id.
4811 // A valid index_entry means the trun for the fragment was read
4812 // and it's samples are in index_entries at the given position.
4813 // New index entries will be inserted before the index_entry found.
4814 index_entry_pos = st->internal->nb_index_entries;
4815 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4816 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4817 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4818 next_frag_index = i;
4819 index_entry_pos = frag_stream_info->index_entry;
4823 av_assert0(index_entry_pos <= st->internal->nb_index_entries);
4825 avio_r8(pb); /* version */
4826 flags = avio_rb24(pb);
4827 entries = avio_rb32(pb);
4828 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4830 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4831 return AVERROR_INVALIDDATA;
4832 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4833 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4835 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4836 if (frag_stream_info) {
4837 if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
4838 dts = frag_stream_info->next_trun_dts - sc->time_offset;
4839 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4840 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4841 pts = frag_stream_info->first_tfra_pts;
4842 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4843 ", using it for pts\n", pts);
4844 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4845 c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
4846 dts = frag_stream_info->first_tfra_pts;
4847 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4848 ", using it for dts\n", pts);
4849 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4850 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4851 // pts = frag_stream_info->sidx_pts;
4852 dts = frag_stream_info->sidx_pts - sc->time_offset;
4853 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4854 ", using it for pts\n", pts);
4855 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4856 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4857 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4858 ", using it for dts\n", dts);
4860 dts = sc->track_end - sc->time_offset;
4861 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4862 ", using it for dts\n", dts);
4865 dts = sc->track_end - sc->time_offset;
4866 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4867 ", using it for dts\n", dts);
4869 offset = frag->base_data_offset + data_offset;
4871 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4873 // realloc space for new index entries
4874 if((uint64_t)st->internal->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4875 entries = UINT_MAX / sizeof(AVIndexEntry) - st->internal->nb_index_entries;
4876 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4881 requested_size = (st->internal->nb_index_entries + entries) * sizeof(AVIndexEntry);
4882 new_entries = av_fast_realloc(st->internal->index_entries,
4883 &st->internal->index_entries_allocated_size,
4886 return AVERROR(ENOMEM);
4887 st->internal->index_entries= new_entries;
4889 requested_size = (st->internal->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4890 old_ctts_allocated_size = sc->ctts_allocated_size;
4891 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4894 return AVERROR(ENOMEM);
4895 sc->ctts_data = ctts_data;
4897 // In case there were samples without ctts entries, ensure they get
4898 // zero valued entries. This ensures clips which mix boxes with and
4899 // without ctts entries don't pickup uninitialized data.
4900 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4901 sc->ctts_allocated_size - old_ctts_allocated_size);
4903 if (index_entry_pos < st->internal->nb_index_entries) {
4904 // Make hole in index_entries and ctts_data for new samples
4905 memmove(st->internal->index_entries + index_entry_pos + entries,
4906 st->internal->index_entries + index_entry_pos,
4907 sizeof(*st->internal->index_entries) *
4908 (st->internal->nb_index_entries - index_entry_pos));
4909 memmove(sc->ctts_data + index_entry_pos + entries,
4910 sc->ctts_data + index_entry_pos,
4911 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4912 if (index_entry_pos < sc->current_sample) {
4913 sc->current_sample += entries;
4917 st->internal->nb_index_entries += entries;
4918 sc->ctts_count = st->internal->nb_index_entries;
4920 // Record the index_entry position in frag_index of this fragment
4921 if (frag_stream_info)
4922 frag_stream_info->index_entry = index_entry_pos;
4924 if (index_entry_pos > 0)
4925 prev_dts = st->internal->index_entries[index_entry_pos-1].timestamp;
4927 for (i = 0; i < entries && !pb->eof_reached; i++) {
4928 unsigned sample_size = frag->size;
4929 int sample_flags = i ? frag->flags : first_sample_flags;
4930 unsigned sample_duration = frag->duration;
4931 unsigned ctts_duration = 0;
4933 int index_entry_flags = 0;
4935 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4936 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4937 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4938 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4940 mov_update_dts_shift(sc, ctts_duration, c->fc);
4941 if (pts != AV_NOPTS_VALUE) {
4942 dts = pts - sc->dts_shift;
4943 if (flags & MOV_TRUN_SAMPLE_CTS) {
4944 dts -= ctts_duration;
4946 dts -= sc->time_offset;
4948 av_log(c->fc, AV_LOG_DEBUG,
4949 "pts %"PRId64" calculated dts %"PRId64
4950 " sc->dts_shift %d ctts.duration %d"
4951 " sc->time_offset %"PRId64
4952 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4954 sc->dts_shift, ctts_duration,
4955 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4956 pts = AV_NOPTS_VALUE;
4959 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4963 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4964 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4967 index_entry_flags |= AVINDEX_KEYFRAME;
4969 // Fragments can overlap in time. Discard overlapping frames after
4971 if (prev_dts >= dts)
4972 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4974 st->internal->index_entries[index_entry_pos].pos = offset;
4975 st->internal->index_entries[index_entry_pos].timestamp = dts;
4976 st->internal->index_entries[index_entry_pos].size= sample_size;
4977 st->internal->index_entries[index_entry_pos].min_distance= distance;
4978 st->internal->index_entries[index_entry_pos].flags = index_entry_flags;
4980 sc->ctts_data[index_entry_pos].count = 1;
4981 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4984 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4985 "size %u, distance %d, keyframe %d\n", st->index,
4986 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4988 dts += sample_duration;
4989 offset += sample_size;
4990 sc->data_size += sample_size;
4992 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4993 1 <= INT_MAX - sc->nb_frames_for_fps
4995 sc->duration_for_fps += sample_duration;
4996 sc->nb_frames_for_fps ++;
4999 if (frag_stream_info)
5000 frag_stream_info->next_trun_dts = dts + sc->time_offset;
5002 // EOF found before reading all entries. Fix the hole this would
5003 // leave in index_entries and ctts_data
5004 int gap = entries - i;
5005 memmove(st->internal->index_entries + index_entry_pos,
5006 st->internal->index_entries + index_entry_pos + gap,
5007 sizeof(*st->internal->index_entries) *
5008 (st->internal->nb_index_entries - (index_entry_pos + gap)));
5009 memmove(sc->ctts_data + index_entry_pos,
5010 sc->ctts_data + index_entry_pos + gap,
5011 sizeof(*sc->ctts_data) *
5012 (sc->ctts_count - (index_entry_pos + gap)));
5014 st->internal->nb_index_entries -= gap;
5015 sc->ctts_count -= gap;
5016 if (index_entry_pos < sc->current_sample) {
5017 sc->current_sample -= gap;
5022 // The end of this new fragment may overlap in time with the start
5023 // of the next fragment in index_entries. Mark the samples in the next
5024 // fragment that overlap with AVINDEX_DISCARD_FRAME
5025 prev_dts = AV_NOPTS_VALUE;
5026 if (index_entry_pos > 0)
5027 prev_dts = st->internal->index_entries[index_entry_pos-1].timestamp;
5028 for (i = index_entry_pos; i < st->internal->nb_index_entries; i++) {
5029 if (prev_dts < st->internal->index_entries[i].timestamp)
5031 st->internal->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
5034 // If a hole was created to insert the new index_entries into,
5035 // the index_entry recorded for all subsequent moof must
5036 // be incremented by the number of entries inserted.
5037 fix_frag_index_entries(&c->frag_index, next_frag_index,
5038 frag->track_id, entries);
5040 if (pb->eof_reached) {
5041 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
5045 frag->implicit_offset = offset;
5047 sc->track_end = dts + sc->time_offset;
5048 if (st->duration < sc->track_end)
5049 st->duration = sc->track_end;
5054 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5056 int64_t stream_size = avio_size(pb);
5057 int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
5058 uint8_t version, is_complete;
5059 unsigned i, j, track_id, item_count;
5060 AVStream *st = NULL;
5061 AVStream *ref_st = NULL;
5062 MOVStreamContext *sc, *ref_sc = NULL;
5063 AVRational timescale;
5065 version = avio_r8(pb);
5067 avpriv_request_sample(c->fc, "sidx version %u", version);
5071 avio_rb24(pb); // flags
5073 track_id = avio_rb32(pb); // Reference ID
5074 for (i = 0; i < c->fc->nb_streams; i++) {
5075 if (c->fc->streams[i]->id == track_id) {
5076 st = c->fc->streams[i];
5081 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5087 timescale = av_make_q(1, avio_rb32(pb));
5089 if (timescale.den <= 0) {
5090 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5091 return AVERROR_INVALIDDATA;
5095 pts = avio_rb32(pb);
5096 offset += avio_rb32(pb);
5098 pts = avio_rb64(pb);
5099 offset += avio_rb64(pb);
5102 avio_rb16(pb); // reserved
5104 item_count = avio_rb16(pb);
5106 for (i = 0; i < item_count; i++) {
5108 MOVFragmentStreamInfo * frag_stream_info;
5109 uint32_t size = avio_rb32(pb);
5110 uint32_t duration = avio_rb32(pb);
5111 if (size & 0x80000000) {
5112 avpriv_request_sample(c->fc, "sidx reference_type 1");
5113 return AVERROR_PATCHWELCOME;
5115 avio_rb32(pb); // sap_flags
5116 timestamp = av_rescale_q(pts, timescale, st->time_base);
5118 index = update_frag_index(c, offset);
5119 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5120 if (frag_stream_info)
5121 frag_stream_info->sidx_pts = timestamp;
5127 st->duration = sc->track_end = pts;
5131 // See if the remaining bytes are just an mfra which we can ignore.
5132 is_complete = offset == stream_size;
5133 if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL)) {
5135 int64_t original_pos = avio_tell(pb);
5136 if (!c->have_read_mfra_size) {
5137 if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
5139 c->mfra_size = avio_rb32(pb);
5140 c->have_read_mfra_size = 1;
5141 if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
5144 if (offset + c->mfra_size == stream_size)
5149 // Find first entry in fragment index that came from an sidx.
5150 // This will pretty much always be the first entry.
5151 for (i = 0; i < c->frag_index.nb_items; i++) {
5152 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5153 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5154 MOVFragmentStreamInfo * si;
5155 si = &item->stream_info[j];
5156 if (si->sidx_pts != AV_NOPTS_VALUE) {
5157 ref_st = c->fc->streams[j];
5158 ref_sc = ref_st->priv_data;
5163 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5164 st = c->fc->streams[i];
5166 if (!sc->has_sidx) {
5167 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5171 c->frag_index.complete = 1;
5177 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5178 /* like the files created with Adobe Premiere 5.0, for samples see */
5179 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5180 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5185 return 0; /* continue */
5186 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5187 avio_skip(pb, atom.size - 4);
5190 atom.type = avio_rl32(pb);
5192 if (atom.type != MKTAG('m','d','a','t')) {
5193 avio_skip(pb, atom.size);
5196 err = mov_read_mdat(c, pb, atom);
5200 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5205 uint8_t *moov_data; /* uncompressed data */
5206 long cmov_len, moov_len;
5209 avio_rb32(pb); /* dcom atom */
5210 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5211 return AVERROR_INVALIDDATA;
5212 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5213 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5214 return AVERROR_INVALIDDATA;
5216 avio_rb32(pb); /* cmvd atom */
5217 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5218 return AVERROR_INVALIDDATA;
5219 moov_len = avio_rb32(pb); /* uncompressed size */
5220 cmov_len = atom.size - 6 * 4;
5222 cmov_data = av_malloc(cmov_len);
5224 return AVERROR(ENOMEM);
5225 moov_data = av_malloc(moov_len);
5228 return AVERROR(ENOMEM);
5230 ret = ffio_read_size(pb, cmov_data, cmov_len);
5232 goto free_and_return;
5234 ret = AVERROR_INVALIDDATA;
5235 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5236 goto free_and_return;
5237 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5238 goto free_and_return;
5239 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5240 atom.type = MKTAG('m','o','o','v');
5241 atom.size = moov_len;
5242 ret = mov_read_default(c, &ctx, atom);
5248 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5249 return AVERROR(ENOSYS);
5253 /* edit list atom */
5254 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5256 MOVStreamContext *sc;
5257 int i, edit_count, version;
5258 int64_t elst_entry_size;
5260 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5262 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5264 version = avio_r8(pb); /* version */
5265 avio_rb24(pb); /* flags */
5266 edit_count = avio_rb32(pb); /* entries */
5269 elst_entry_size = version == 1 ? 20 : 12;
5270 if (atom.size != edit_count * elst_entry_size) {
5271 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5272 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5273 edit_count, atom.size + 8);
5274 return AVERROR_INVALIDDATA;
5276 edit_count = atom.size / elst_entry_size;
5277 if (edit_count * elst_entry_size != atom.size) {
5278 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
5286 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5287 av_free(sc->elst_data);
5289 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5291 return AVERROR(ENOMEM);
5293 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5294 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5295 MOVElst *e = &sc->elst_data[i];
5298 e->duration = avio_rb64(pb);
5299 e->time = avio_rb64(pb);
5302 e->duration = avio_rb32(pb); /* segment duration */
5303 e->time = (int32_t)avio_rb32(pb); /* media time */
5306 e->rate = avio_rb32(pb) / 65536.0;
5308 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5309 e->duration, e->time, e->rate);
5311 if (e->time < 0 && e->time != -1 &&
5312 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5313 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5314 c->fc->nb_streams-1, i, e->time);
5315 return AVERROR_INVALIDDATA;
5323 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5325 MOVStreamContext *sc;
5327 if (c->fc->nb_streams < 1)
5328 return AVERROR_INVALIDDATA;
5329 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5330 sc->timecode_track = avio_rb32(pb);
5334 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5339 if (c->fc->nb_streams < 1)
5341 st = c->fc->streams[c->fc->nb_streams - 1];
5343 if (atom.size < 4) {
5344 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5345 return AVERROR_INVALIDDATA;
5348 /* For now, propagate only the OBUs, if any. Once libavcodec is
5349 updated to handle isobmff style extradata this can be removed. */
5355 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5362 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5365 int version, color_range, color_primaries, color_trc, color_space;
5367 if (c->fc->nb_streams < 1)
5369 st = c->fc->streams[c->fc->nb_streams - 1];
5371 if (atom.size < 5) {
5372 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5373 return AVERROR_INVALIDDATA;
5376 version = avio_r8(pb);
5378 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5381 avio_skip(pb, 3); /* flags */
5383 avio_skip(pb, 2); /* profile + level */
5384 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5385 color_primaries = avio_r8(pb);
5386 color_trc = avio_r8(pb);
5387 color_space = avio_r8(pb);
5388 if (avio_rb16(pb)) /* codecIntializationDataSize */
5389 return AVERROR_INVALIDDATA;
5391 if (!av_color_primaries_name(color_primaries))
5392 color_primaries = AVCOL_PRI_UNSPECIFIED;
5393 if (!av_color_transfer_name(color_trc))
5394 color_trc = AVCOL_TRC_UNSPECIFIED;
5395 if (!av_color_space_name(color_space))
5396 color_space = AVCOL_SPC_UNSPECIFIED;
5398 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5399 st->codecpar->color_primaries = color_primaries;
5400 st->codecpar->color_trc = color_trc;
5401 st->codecpar->color_space = color_space;
5406 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5408 MOVStreamContext *sc;
5411 if (c->fc->nb_streams < 1)
5412 return AVERROR_INVALIDDATA;
5414 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5416 if (atom.size < 5) {
5417 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5418 return AVERROR_INVALIDDATA;
5421 version = avio_r8(pb);
5423 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5426 avio_skip(pb, 3); /* flags */
5428 sc->mastering = av_mastering_display_metadata_alloc();
5430 return AVERROR(ENOMEM);
5432 for (i = 0; i < 3; i++) {
5433 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5434 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5436 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5437 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5439 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5440 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5442 sc->mastering->has_primaries = 1;
5443 sc->mastering->has_luminance = 1;
5448 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5450 MOVStreamContext *sc;
5451 const int mapping[3] = {1, 2, 0};
5452 const int chroma_den = 50000;
5453 const int luma_den = 10000;
5456 if (c->fc->nb_streams < 1)
5457 return AVERROR_INVALIDDATA;
5459 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5461 if (atom.size < 24) {
5462 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5463 return AVERROR_INVALIDDATA;
5466 sc->mastering = av_mastering_display_metadata_alloc();
5468 return AVERROR(ENOMEM);
5470 for (i = 0; i < 3; i++) {
5471 const int j = mapping[i];
5472 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5473 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5475 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5476 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5478 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5479 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5481 sc->mastering->has_luminance = 1;
5482 sc->mastering->has_primaries = 1;
5487 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5489 MOVStreamContext *sc;
5492 if (c->fc->nb_streams < 1)
5493 return AVERROR_INVALIDDATA;
5495 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5497 if (atom.size < 5) {
5498 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5499 return AVERROR_INVALIDDATA;
5502 version = avio_r8(pb);
5504 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5507 avio_skip(pb, 3); /* flags */
5509 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5511 return AVERROR(ENOMEM);
5513 sc->coll->MaxCLL = avio_rb16(pb);
5514 sc->coll->MaxFALL = avio_rb16(pb);
5519 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5521 MOVStreamContext *sc;
5523 if (c->fc->nb_streams < 1)
5524 return AVERROR_INVALIDDATA;
5526 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5528 if (atom.size < 4) {
5529 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5530 return AVERROR_INVALIDDATA;
5533 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5535 return AVERROR(ENOMEM);
5537 sc->coll->MaxCLL = avio_rb16(pb);
5538 sc->coll->MaxFALL = avio_rb16(pb);
5543 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5546 MOVStreamContext *sc;
5547 enum AVStereo3DType type;
5550 if (c->fc->nb_streams < 1)
5553 st = c->fc->streams[c->fc->nb_streams - 1];
5556 if (atom.size < 5) {
5557 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5558 return AVERROR_INVALIDDATA;
5562 return AVERROR_INVALIDDATA;
5564 avio_skip(pb, 4); /* version + flags */
5569 type = AV_STEREO3D_2D;
5572 type = AV_STEREO3D_TOPBOTTOM;
5575 type = AV_STEREO3D_SIDEBYSIDE;
5578 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5582 sc->stereo3d = av_stereo3d_alloc();
5584 return AVERROR(ENOMEM);
5586 sc->stereo3d->type = type;
5590 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5593 MOVStreamContext *sc;
5594 int size, version, layout;
5595 int32_t yaw, pitch, roll;
5596 uint32_t l = 0, t = 0, r = 0, b = 0;
5597 uint32_t tag, padding = 0;
5598 enum AVSphericalProjection projection;
5600 if (c->fc->nb_streams < 1)
5603 st = c->fc->streams[c->fc->nb_streams - 1];
5606 if (atom.size < 8) {
5607 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5608 return AVERROR_INVALIDDATA;
5611 size = avio_rb32(pb);
5612 if (size <= 12 || size > atom.size)
5613 return AVERROR_INVALIDDATA;
5615 tag = avio_rl32(pb);
5616 if (tag != MKTAG('s','v','h','d')) {
5617 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5620 version = avio_r8(pb);
5622 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5626 avio_skip(pb, 3); /* flags */
5627 avio_skip(pb, size - 12); /* metadata_source */
5629 size = avio_rb32(pb);
5630 if (size > atom.size)
5631 return AVERROR_INVALIDDATA;
5633 tag = avio_rl32(pb);
5634 if (tag != MKTAG('p','r','o','j')) {
5635 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5639 size = avio_rb32(pb);
5640 if (size > atom.size)
5641 return AVERROR_INVALIDDATA;
5643 tag = avio_rl32(pb);
5644 if (tag != MKTAG('p','r','h','d')) {
5645 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5648 version = avio_r8(pb);
5650 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5654 avio_skip(pb, 3); /* flags */
5656 /* 16.16 fixed point */
5657 yaw = avio_rb32(pb);
5658 pitch = avio_rb32(pb);
5659 roll = avio_rb32(pb);
5661 size = avio_rb32(pb);
5662 if (size > atom.size)
5663 return AVERROR_INVALIDDATA;
5665 tag = avio_rl32(pb);
5666 version = avio_r8(pb);
5668 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5672 avio_skip(pb, 3); /* flags */
5674 case MKTAG('c','b','m','p'):
5675 layout = avio_rb32(pb);
5677 av_log(c->fc, AV_LOG_WARNING,
5678 "Unsupported cubemap layout %d\n", layout);
5681 projection = AV_SPHERICAL_CUBEMAP;
5682 padding = avio_rb32(pb);
5684 case MKTAG('e','q','u','i'):
5690 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5691 av_log(c->fc, AV_LOG_ERROR,
5692 "Invalid bounding rectangle coordinates "
5693 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5694 return AVERROR_INVALIDDATA;
5697 if (l || t || r || b)
5698 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5700 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5703 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5707 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5709 return AVERROR(ENOMEM);
5711 sc->spherical->projection = projection;
5713 sc->spherical->yaw = yaw;
5714 sc->spherical->pitch = pitch;
5715 sc->spherical->roll = roll;
5717 sc->spherical->padding = padding;
5719 sc->spherical->bound_left = l;
5720 sc->spherical->bound_top = t;
5721 sc->spherical->bound_right = r;
5722 sc->spherical->bound_bottom = b;
5727 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5730 uint8_t *buffer = av_malloc(len + 1);
5734 return AVERROR(ENOMEM);
5737 ret = ffio_read_size(pb, buffer, len);
5741 /* Check for mandatory keys and values, try to support XML as best-effort */
5742 if (!sc->spherical &&
5743 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5744 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5745 av_stristr(val, "true") &&
5746 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5747 av_stristr(val, "true") &&
5748 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5749 av_stristr(val, "equirectangular")) {
5750 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5754 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5756 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5757 enum AVStereo3DType mode;
5759 if (av_stristr(buffer, "left-right"))
5760 mode = AV_STEREO3D_SIDEBYSIDE;
5761 else if (av_stristr(buffer, "top-bottom"))
5762 mode = AV_STEREO3D_TOPBOTTOM;
5764 mode = AV_STEREO3D_2D;
5766 sc->stereo3d = av_stereo3d_alloc();
5770 sc->stereo3d->type = mode;
5774 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5776 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5777 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5779 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5780 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5782 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5790 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5793 MOVStreamContext *sc;
5796 static const uint8_t uuid_isml_manifest[] = {
5797 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5798 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5800 static const uint8_t uuid_xmp[] = {
5801 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5802 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5804 static const uint8_t uuid_spherical[] = {
5805 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5806 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5809 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5810 return AVERROR_INVALIDDATA;
5812 if (c->fc->nb_streams < 1)
5814 st = c->fc->streams[c->fc->nb_streams - 1];
5817 ret = ffio_read_size(pb, uuid, sizeof(uuid));
5820 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5821 uint8_t *buffer, *ptr;
5823 size_t len = atom.size - sizeof(uuid);
5826 return AVERROR_INVALIDDATA;
5828 ret = avio_skip(pb, 4); // zeroes
5831 buffer = av_mallocz(len + 1);
5833 return AVERROR(ENOMEM);
5835 ret = ffio_read_size(pb, buffer, len);
5842 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5843 ptr += sizeof("systemBitrate=\"") - 1;
5844 c->bitrates_count++;
5845 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5847 c->bitrates_count = 0;
5849 return AVERROR(ENOMEM);
5852 ret = strtol(ptr, &endptr, 10);
5853 if (ret < 0 || errno || *endptr != '"') {
5854 c->bitrates[c->bitrates_count - 1] = 0;
5856 c->bitrates[c->bitrates_count - 1] = ret;
5861 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5863 size_t len = atom.size - sizeof(uuid);
5864 if (c->export_xmp) {
5865 buffer = av_mallocz(len + 1);
5867 return AVERROR(ENOMEM);
5869 ret = ffio_read_size(pb, buffer, len);
5875 av_dict_set(&c->fc->metadata, "xmp",
5876 buffer, AV_DICT_DONT_STRDUP_VAL);
5878 // skip all uuid atom, which makes it fast for long uuid-xmp file
5879 ret = avio_skip(pb, len);
5883 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5884 size_t len = atom.size - sizeof(uuid);
5885 ret = mov_parse_uuid_spherical(sc, pb, len);
5889 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5895 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5898 uint8_t content[16];
5903 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5909 && !memcmp(content, "Anevia\x1A\x1A", 8)
5910 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5911 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5917 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5919 uint32_t format = avio_rl32(pb);
5920 MOVStreamContext *sc;
5924 if (c->fc->nb_streams < 1)
5926 st = c->fc->streams[c->fc->nb_streams - 1];
5931 case MKTAG('e','n','c','v'): // encrypted video
5932 case MKTAG('e','n','c','a'): // encrypted audio
5933 id = mov_codec_id(st, format);
5934 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5935 st->codecpar->codec_id != id) {
5936 av_log(c->fc, AV_LOG_WARNING,
5937 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5938 (char*)&format, st->codecpar->codec_id);
5942 st->codecpar->codec_id = id;
5943 sc->format = format;
5947 if (format != sc->format) {
5948 av_log(c->fc, AV_LOG_WARNING,
5949 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5950 (char*)&format, (char*)&sc->format);
5959 * Gets the current encryption info and associated current stream context. If
5960 * we are parsing a track fragment, this will return the specific encryption
5961 * info for this fragment; otherwise this will return the global encryption
5962 * info for the current stream.
5964 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5966 MOVFragmentStreamInfo *frag_stream_info;
5970 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5971 if (frag_stream_info) {
5972 for (i = 0; i < c->fc->nb_streams; i++) {
5973 if (c->fc->streams[i]->id == frag_stream_info->id) {
5974 st = c->fc->streams[i];
5978 if (i == c->fc->nb_streams)
5980 *sc = st->priv_data;
5982 if (!frag_stream_info->encryption_index) {
5983 // If this stream isn't encrypted, don't create the index.
5984 if (!(*sc)->cenc.default_encrypted_sample)
5986 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5987 if (!frag_stream_info->encryption_index)
5988 return AVERROR(ENOMEM);
5990 *encryption_index = frag_stream_info->encryption_index;
5993 // No current track fragment, using stream level encryption info.
5995 if (c->fc->nb_streams < 1)
5997 st = c->fc->streams[c->fc->nb_streams - 1];
5998 *sc = st->priv_data;
6000 if (!(*sc)->cenc.encryption_index) {
6001 // If this stream isn't encrypted, don't create the index.
6002 if (!(*sc)->cenc.default_encrypted_sample)
6004 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
6005 if (!(*sc)->cenc.encryption_index)
6006 return AVERROR(ENOMEM);
6009 *encryption_index = (*sc)->cenc.encryption_index;
6014 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
6017 unsigned int subsample_count;
6018 AVSubsampleEncryptionInfo *subsamples;
6020 if (!sc->cenc.default_encrypted_sample) {
6021 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
6022 return AVERROR_INVALIDDATA;
6025 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
6027 return AVERROR(ENOMEM);
6029 if (sc->cenc.per_sample_iv_size != 0) {
6030 if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
6031 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
6032 av_encryption_info_free(*sample);
6038 if (use_subsamples) {
6039 subsample_count = avio_rb16(pb);
6040 av_free((*sample)->subsamples);
6041 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
6042 if (!(*sample)->subsamples) {
6043 av_encryption_info_free(*sample);
6045 return AVERROR(ENOMEM);
6048 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
6049 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
6050 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
6053 if (pb->eof_reached) {
6054 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
6055 av_encryption_info_free(*sample);
6057 return AVERROR_INVALIDDATA;
6059 (*sample)->subsample_count = subsample_count;
6065 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6067 AVEncryptionInfo **encrypted_samples;
6068 MOVEncryptionIndex *encryption_index;
6069 MOVStreamContext *sc;
6070 int use_subsamples, ret;
6071 unsigned int sample_count, i, alloc_size = 0;
6073 ret = get_current_encryption_info(c, &encryption_index, &sc);
6077 if (encryption_index->nb_encrypted_samples) {
6078 // This can happen if we have both saio/saiz and senc atoms.
6079 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6083 avio_r8(pb); /* version */
6084 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6086 sample_count = avio_rb32(pb);
6087 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6088 return AVERROR(ENOMEM);
6090 for (i = 0; i < sample_count; i++) {
6091 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6092 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6093 min_samples * sizeof(*encrypted_samples));
6094 if (encrypted_samples) {
6095 encryption_index->encrypted_samples = encrypted_samples;
6097 ret = mov_read_sample_encryption_info(
6098 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6100 ret = AVERROR(ENOMEM);
6102 if (pb->eof_reached) {
6103 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6104 ret = AVERROR_INVALIDDATA;
6109 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6110 av_freep(&encryption_index->encrypted_samples);
6114 encryption_index->nb_encrypted_samples = sample_count;
6119 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6121 AVEncryptionInfo **sample, **encrypted_samples;
6123 size_t sample_count, sample_info_size, i;
6125 unsigned int alloc_size = 0;
6127 if (encryption_index->nb_encrypted_samples)
6129 sample_count = encryption_index->auxiliary_info_sample_count;
6130 if (encryption_index->auxiliary_offsets_count != 1) {
6131 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6132 return AVERROR_PATCHWELCOME;
6134 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6135 return AVERROR(ENOMEM);
6137 prev_pos = avio_tell(pb);
6138 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6139 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6140 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6144 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6145 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6146 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6147 min_samples * sizeof(*encrypted_samples));
6148 if (!encrypted_samples) {
6149 ret = AVERROR(ENOMEM);
6152 encryption_index->encrypted_samples = encrypted_samples;
6154 sample = &encryption_index->encrypted_samples[i];
6155 sample_info_size = encryption_index->auxiliary_info_default_size
6156 ? encryption_index->auxiliary_info_default_size
6157 : encryption_index->auxiliary_info_sizes[i];
6159 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6163 if (pb->eof_reached) {
6164 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6165 ret = AVERROR_INVALIDDATA;
6167 encryption_index->nb_encrypted_samples = sample_count;
6171 avio_seek(pb, prev_pos, SEEK_SET);
6173 for (; i > 0; i--) {
6174 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6176 av_freep(&encryption_index->encrypted_samples);
6182 * Tries to read the given number of bytes from the stream and puts it in a
6183 * newly allocated buffer. This reads in small chunks to avoid allocating large
6184 * memory if the file contains an invalid/malicious size value.
6186 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6188 const unsigned int block_size = 1024 * 1024;
6189 uint8_t *buffer = NULL;
6190 unsigned int alloc_size = 0, offset = 0;
6191 while (offset < size) {
6192 unsigned int new_size =
6193 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6194 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6195 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6198 return AVERROR(ENOMEM);
6200 buffer = new_buffer;
6202 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6204 return AVERROR_INVALIDDATA;
6213 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6215 MOVEncryptionIndex *encryption_index;
6216 MOVStreamContext *sc;
6218 unsigned int sample_count, aux_info_type, aux_info_param;
6220 ret = get_current_encryption_info(c, &encryption_index, &sc);
6224 if (encryption_index->nb_encrypted_samples) {
6225 // This can happen if we have both saio/saiz and senc atoms.
6226 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6230 if (encryption_index->auxiliary_info_sample_count) {
6231 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6232 return AVERROR_INVALIDDATA;
6235 avio_r8(pb); /* version */
6236 if (avio_rb24(pb) & 0x01) { /* flags */
6237 aux_info_type = avio_rb32(pb);
6238 aux_info_param = avio_rb32(pb);
6239 if (sc->cenc.default_encrypted_sample) {
6240 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6241 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6244 if (aux_info_param != 0) {
6245 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6249 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6250 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6251 aux_info_type == MKBETAG('c','e','n','s') ||
6252 aux_info_type == MKBETAG('c','b','c','1') ||
6253 aux_info_type == MKBETAG('c','b','c','s')) &&
6254 aux_info_param == 0) {
6255 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6256 return AVERROR_INVALIDDATA;
6261 } else if (!sc->cenc.default_encrypted_sample) {
6262 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6266 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6267 sample_count = avio_rb32(pb);
6268 encryption_index->auxiliary_info_sample_count = sample_count;
6270 if (encryption_index->auxiliary_info_default_size == 0) {
6271 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6273 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6278 if (encryption_index->auxiliary_offsets_count) {
6279 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6285 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6287 uint64_t *auxiliary_offsets;
6288 MOVEncryptionIndex *encryption_index;
6289 MOVStreamContext *sc;
6291 unsigned int version, entry_count, aux_info_type, aux_info_param;
6292 unsigned int alloc_size = 0;
6294 ret = get_current_encryption_info(c, &encryption_index, &sc);
6298 if (encryption_index->nb_encrypted_samples) {
6299 // This can happen if we have both saio/saiz and senc atoms.
6300 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6304 if (encryption_index->auxiliary_offsets_count) {
6305 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6306 return AVERROR_INVALIDDATA;
6309 version = avio_r8(pb); /* version */
6310 if (avio_rb24(pb) & 0x01) { /* flags */
6311 aux_info_type = avio_rb32(pb);
6312 aux_info_param = avio_rb32(pb);
6313 if (sc->cenc.default_encrypted_sample) {
6314 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6315 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6318 if (aux_info_param != 0) {
6319 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6323 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6324 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6325 aux_info_type == MKBETAG('c','e','n','s') ||
6326 aux_info_type == MKBETAG('c','b','c','1') ||
6327 aux_info_type == MKBETAG('c','b','c','s')) &&
6328 aux_info_param == 0) {
6329 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6330 return AVERROR_INVALIDDATA;
6335 } else if (!sc->cenc.default_encrypted_sample) {
6336 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6340 entry_count = avio_rb32(pb);
6341 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6342 return AVERROR(ENOMEM);
6344 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6345 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6346 auxiliary_offsets = av_fast_realloc(
6347 encryption_index->auxiliary_offsets, &alloc_size,
6348 min_offsets * sizeof(*auxiliary_offsets));
6349 if (!auxiliary_offsets) {
6350 av_freep(&encryption_index->auxiliary_offsets);
6351 return AVERROR(ENOMEM);
6353 encryption_index->auxiliary_offsets = auxiliary_offsets;
6356 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6358 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6360 if (c->frag_index.current >= 0) {
6361 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6365 if (pb->eof_reached) {
6366 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6367 av_freep(&encryption_index->auxiliary_offsets);
6368 return AVERROR_INVALIDDATA;
6371 encryption_index->auxiliary_offsets_count = entry_count;
6373 if (encryption_index->auxiliary_info_sample_count) {
6374 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6380 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6382 AVEncryptionInitInfo *info, *old_init_info;
6385 uint8_t *side_data, *extra_data, *old_side_data;
6386 size_t side_data_size;
6387 int ret = 0, old_side_data_size;
6388 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6390 if (c->fc->nb_streams < 1)
6392 st = c->fc->streams[c->fc->nb_streams-1];
6394 version = avio_r8(pb); /* version */
6395 avio_rb24(pb); /* flags */
6397 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6398 /* key_id_size */ 16, /* data_size */ 0);
6400 return AVERROR(ENOMEM);
6402 if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
6403 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6408 kid_count = avio_rb32(pb);
6409 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
6410 ret = AVERROR(ENOMEM);
6414 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6415 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6416 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6417 min_kid_count * sizeof(*key_ids));
6419 ret = AVERROR(ENOMEM);
6422 info->key_ids = key_ids;
6424 info->key_ids[i] = av_mallocz(16);
6425 if (!info->key_ids[i]) {
6426 ret = AVERROR(ENOMEM);
6429 info->num_key_ids = i + 1;
6431 if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
6432 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6437 if (pb->eof_reached) {
6438 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6439 ret = AVERROR_INVALIDDATA;
6444 extra_data_size = avio_rb32(pb);
6445 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6449 av_freep(&info->data); // malloc(0) may still allocate something.
6450 info->data = extra_data;
6451 info->data_size = extra_data_size;
6453 // If there is existing initialization data, append to the list.
6454 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6455 if (old_side_data) {
6456 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6457 if (old_init_info) {
6458 // Append to the end of the list.
6459 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6465 info = old_init_info;
6467 // Assume existing side-data will be valid, so the only error we could get is OOM.
6468 ret = AVERROR(ENOMEM);
6473 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6475 ret = AVERROR(ENOMEM);
6478 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6479 side_data, side_data_size);
6484 av_encryption_init_info_free(info);
6488 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6491 MOVStreamContext *sc;
6493 if (c->fc->nb_streams < 1)
6495 st = c->fc->streams[c->fc->nb_streams-1];
6498 if (sc->pseudo_stream_id != 0) {
6499 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6500 return AVERROR_PATCHWELCOME;
6504 return AVERROR_INVALIDDATA;
6506 avio_rb32(pb); /* version and flags */
6508 if (!sc->cenc.default_encrypted_sample) {
6509 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6510 if (!sc->cenc.default_encrypted_sample) {
6511 return AVERROR(ENOMEM);
6515 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6519 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6522 MOVStreamContext *sc;
6523 unsigned int version, pattern, is_protected, iv_size;
6525 if (c->fc->nb_streams < 1)
6527 st = c->fc->streams[c->fc->nb_streams-1];
6530 if (sc->pseudo_stream_id != 0) {
6531 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6532 return AVERROR_PATCHWELCOME;
6535 if (!sc->cenc.default_encrypted_sample) {
6536 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6537 if (!sc->cenc.default_encrypted_sample) {
6538 return AVERROR(ENOMEM);
6543 return AVERROR_INVALIDDATA;
6545 version = avio_r8(pb); /* version */
6546 avio_rb24(pb); /* flags */
6548 avio_r8(pb); /* reserved */
6549 pattern = avio_r8(pb);
6552 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6553 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6556 is_protected = avio_r8(pb);
6557 if (is_protected && !sc->cenc.encryption_index) {
6558 // The whole stream should be by-default encrypted.
6559 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6560 if (!sc->cenc.encryption_index)
6561 return AVERROR(ENOMEM);
6563 sc->cenc.per_sample_iv_size = avio_r8(pb);
6564 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6565 sc->cenc.per_sample_iv_size != 16) {
6566 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6567 return AVERROR_INVALIDDATA;
6569 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6570 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6571 return AVERROR_INVALIDDATA;
6574 if (is_protected && !sc->cenc.per_sample_iv_size) {
6575 iv_size = avio_r8(pb);
6576 if (iv_size != 8 && iv_size != 16) {
6577 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6578 return AVERROR_INVALIDDATA;
6581 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6582 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6583 return AVERROR_INVALIDDATA;
6590 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6593 int last, type, size, ret;
6596 if (c->fc->nb_streams < 1)
6598 st = c->fc->streams[c->fc->nb_streams-1];
6600 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6601 return AVERROR_INVALIDDATA;
6603 /* Check FlacSpecificBox version. */
6604 if (avio_r8(pb) != 0)
6605 return AVERROR_INVALIDDATA;
6607 avio_rb24(pb); /* Flags */
6609 avio_read(pb, buf, sizeof(buf));
6610 flac_parse_block_header(buf, &last, &type, &size);
6612 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6613 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6614 return AVERROR_INVALIDDATA;
6617 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6622 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6627 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6631 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6632 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6633 return AVERROR_PATCHWELCOME;
6636 if (!sc->cenc.aes_ctr) {
6637 /* initialize the cipher */
6638 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6639 if (!sc->cenc.aes_ctr) {
6640 return AVERROR(ENOMEM);
6643 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6649 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6651 if (!sample->subsample_count) {
6652 /* decrypt the whole packet */
6653 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6657 for (i = 0; i < sample->subsample_count; i++) {
6658 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6659 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6660 return AVERROR_INVALIDDATA;
6663 /* skip the clear bytes */
6664 input += sample->subsamples[i].bytes_of_clear_data;
6665 size -= sample->subsamples[i].bytes_of_clear_data;
6667 /* decrypt the encrypted bytes */
6668 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6669 input += sample->subsamples[i].bytes_of_protected_data;
6670 size -= sample->subsamples[i].bytes_of_protected_data;
6674 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6675 return AVERROR_INVALIDDATA;
6681 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6683 MOVFragmentStreamInfo *frag_stream_info;
6684 MOVEncryptionIndex *encryption_index;
6685 AVEncryptionInfo *encrypted_sample;
6686 int encrypted_index, ret;
6688 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6689 encrypted_index = current_index;
6690 encryption_index = NULL;
6691 if (frag_stream_info) {
6692 // Note this only supports encryption info in the first sample descriptor.
6693 if (mov->fragment.stsd_id == 1) {
6694 if (frag_stream_info->encryption_index) {
6695 encrypted_index = current_index - frag_stream_info->index_entry;
6696 encryption_index = frag_stream_info->encryption_index;
6698 encryption_index = sc->cenc.encryption_index;
6702 encryption_index = sc->cenc.encryption_index;
6705 if (encryption_index) {
6706 if (encryption_index->auxiliary_info_sample_count &&
6707 !encryption_index->nb_encrypted_samples) {
6708 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6709 return AVERROR_INVALIDDATA;
6711 if (encryption_index->auxiliary_offsets_count &&
6712 !encryption_index->nb_encrypted_samples) {
6713 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6714 return AVERROR_INVALIDDATA;
6717 if (!encryption_index->nb_encrypted_samples) {
6718 // Full-sample encryption with default settings.
6719 encrypted_sample = sc->cenc.default_encrypted_sample;
6720 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6721 // Per-sample setting override.
6722 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6724 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6725 return AVERROR_INVALIDDATA;
6728 if (mov->decryption_key) {
6729 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6732 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6734 return AVERROR(ENOMEM);
6735 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6745 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6747 const int OPUS_SEEK_PREROLL_MS = 80;
6753 if (c->fc->nb_streams < 1)
6755 st = c->fc->streams[c->fc->nb_streams-1];
6757 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6758 return AVERROR_INVALIDDATA;
6760 /* Check OpusSpecificBox version. */
6761 if (avio_r8(pb) != 0) {
6762 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6763 return AVERROR_INVALIDDATA;
6766 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6767 size = atom.size + 8;
6769 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
6772 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6773 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6774 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6775 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6777 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6778 little-endian; aside from the preceeding magic and version they're
6779 otherwise currently identical. Data after output gain at offset 16
6780 doesn't need to be bytewapped. */
6781 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6782 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6783 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6784 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6786 st->codecpar->initial_padding = pre_skip;
6787 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6788 (AVRational){1, 1000},
6789 (AVRational){1, 48000});
6794 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6797 unsigned format_info;
6798 int channel_assignment, channel_assignment1, channel_assignment2;
6801 if (c->fc->nb_streams < 1)
6803 st = c->fc->streams[c->fc->nb_streams-1];
6806 return AVERROR_INVALIDDATA;
6808 format_info = avio_rb32(pb);
6810 ratebits = (format_info >> 28) & 0xF;
6811 channel_assignment1 = (format_info >> 15) & 0x1F;
6812 channel_assignment2 = format_info & 0x1FFF;
6813 if (channel_assignment2)
6814 channel_assignment = channel_assignment2;
6816 channel_assignment = channel_assignment1;
6818 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6819 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6820 st->codecpar->channels = truehd_channels(channel_assignment);
6821 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6826 static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6830 AVDOVIDecoderConfigurationRecord *dovi;
6834 if (c->fc->nb_streams < 1)
6836 st = c->fc->streams[c->fc->nb_streams-1];
6838 if ((uint64_t)atom.size > (1<<30) || atom.size < 4)
6839 return AVERROR_INVALIDDATA;
6841 dovi = av_dovi_alloc(&dovi_size);
6843 return AVERROR(ENOMEM);
6845 dovi->dv_version_major = avio_r8(pb);
6846 dovi->dv_version_minor = avio_r8(pb);
6848 buf = avio_rb16(pb);
6849 dovi->dv_profile = (buf >> 9) & 0x7f; // 7 bits
6850 dovi->dv_level = (buf >> 3) & 0x3f; // 6 bits
6851 dovi->rpu_present_flag = (buf >> 2) & 0x01; // 1 bit
6852 dovi->el_present_flag = (buf >> 1) & 0x01; // 1 bit
6853 dovi->bl_present_flag = buf & 0x01; // 1 bit
6854 if (atom.size >= 24) { // 4 + 4 + 4 * 4
6856 dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits
6858 // 0 stands for None
6859 // Dolby Vision V1.2.93 profiles and levels
6860 dovi->dv_bl_signal_compatibility_id = 0;
6863 ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF,
6864 (uint8_t *)dovi, dovi_size);
6870 av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC box, version: %d.%d, profile: %d, level: %d, "
6871 "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n",
6872 dovi->dv_version_major, dovi->dv_version_minor,
6873 dovi->dv_profile, dovi->dv_level,
6874 dovi->rpu_present_flag,
6875 dovi->el_present_flag,
6876 dovi->bl_present_flag,
6877 dovi->dv_bl_signal_compatibility_id
6883 static const MOVParseTableEntry mov_default_parse_table[] = {
6884 { MKTAG('A','C','L','R'), mov_read_aclr },
6885 { MKTAG('A','P','R','G'), mov_read_avid },
6886 { MKTAG('A','A','L','P'), mov_read_avid },
6887 { MKTAG('A','R','E','S'), mov_read_ares },
6888 { MKTAG('a','v','s','s'), mov_read_avss },
6889 { MKTAG('a','v','1','C'), mov_read_av1c },
6890 { MKTAG('c','h','p','l'), mov_read_chpl },
6891 { MKTAG('c','o','6','4'), mov_read_stco },
6892 { MKTAG('c','o','l','r'), mov_read_colr },
6893 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6894 { MKTAG('d','i','n','f'), mov_read_default },
6895 { MKTAG('D','p','x','E'), mov_read_dpxe },
6896 { MKTAG('d','r','e','f'), mov_read_dref },
6897 { MKTAG('e','d','t','s'), mov_read_default },
6898 { MKTAG('e','l','s','t'), mov_read_elst },
6899 { MKTAG('e','n','d','a'), mov_read_enda },
6900 { MKTAG('f','i','e','l'), mov_read_fiel },
6901 { MKTAG('a','d','r','m'), mov_read_adrm },
6902 { MKTAG('f','t','y','p'), mov_read_ftyp },
6903 { MKTAG('g','l','b','l'), mov_read_glbl },
6904 { MKTAG('h','d','l','r'), mov_read_hdlr },
6905 { MKTAG('i','l','s','t'), mov_read_ilst },
6906 { MKTAG('j','p','2','h'), mov_read_jp2h },
6907 { MKTAG('m','d','a','t'), mov_read_mdat },
6908 { MKTAG('m','d','h','d'), mov_read_mdhd },
6909 { MKTAG('m','d','i','a'), mov_read_default },
6910 { MKTAG('m','e','t','a'), mov_read_meta },
6911 { MKTAG('m','i','n','f'), mov_read_default },
6912 { MKTAG('m','o','o','f'), mov_read_moof },
6913 { MKTAG('m','o','o','v'), mov_read_moov },
6914 { MKTAG('m','v','e','x'), mov_read_default },
6915 { MKTAG('m','v','h','d'), mov_read_mvhd },
6916 { MKTAG('S','M','I',' '), mov_read_svq3 },
6917 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6918 { MKTAG('a','v','c','C'), mov_read_glbl },
6919 { MKTAG('p','a','s','p'), mov_read_pasp },
6920 { MKTAG('s','i','d','x'), mov_read_sidx },
6921 { MKTAG('s','t','b','l'), mov_read_default },
6922 { MKTAG('s','t','c','o'), mov_read_stco },
6923 { MKTAG('s','t','p','s'), mov_read_stps },
6924 { MKTAG('s','t','r','f'), mov_read_strf },
6925 { MKTAG('s','t','s','c'), mov_read_stsc },
6926 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6927 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6928 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6929 { MKTAG('s','t','t','s'), mov_read_stts },
6930 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6931 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
6932 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6933 { MKTAG('t','f','d','t'), mov_read_tfdt },
6934 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6935 { MKTAG('t','r','a','k'), mov_read_trak },
6936 { MKTAG('t','r','a','f'), mov_read_default },
6937 { MKTAG('t','r','e','f'), mov_read_default },
6938 { MKTAG('t','m','c','d'), mov_read_tmcd },
6939 { MKTAG('c','h','a','p'), mov_read_chap },
6940 { MKTAG('t','r','e','x'), mov_read_trex },
6941 { MKTAG('t','r','u','n'), mov_read_trun },
6942 { MKTAG('u','d','t','a'), mov_read_default },
6943 { MKTAG('w','a','v','e'), mov_read_wave },
6944 { MKTAG('e','s','d','s'), mov_read_esds },
6945 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6946 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6947 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6948 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6949 { MKTAG('w','f','e','x'), mov_read_wfex },
6950 { MKTAG('c','m','o','v'), mov_read_cmov },
6951 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6952 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6953 { MKTAG('s','b','g','p'), mov_read_sbgp },
6954 { MKTAG('h','v','c','C'), mov_read_glbl },
6955 { MKTAG('u','u','i','d'), mov_read_uuid },
6956 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6957 { MKTAG('f','r','e','e'), mov_read_free },
6958 { MKTAG('-','-','-','-'), mov_read_custom },
6959 { MKTAG('s','i','n','f'), mov_read_default },
6960 { MKTAG('f','r','m','a'), mov_read_frma },
6961 { MKTAG('s','e','n','c'), mov_read_senc },
6962 { MKTAG('s','a','i','z'), mov_read_saiz },
6963 { MKTAG('s','a','i','o'), mov_read_saio },
6964 { MKTAG('p','s','s','h'), mov_read_pssh },
6965 { MKTAG('s','c','h','m'), mov_read_schm },
6966 { MKTAG('s','c','h','i'), mov_read_default },
6967 { MKTAG('t','e','n','c'), mov_read_tenc },
6968 { MKTAG('d','f','L','a'), mov_read_dfla },
6969 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6970 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6971 { MKTAG('d','O','p','s'), mov_read_dops },
6972 { MKTAG('d','m','l','p'), mov_read_dmlp },
6973 { MKTAG('S','m','D','m'), mov_read_smdm },
6974 { MKTAG('C','o','L','L'), mov_read_coll },
6975 { MKTAG('v','p','c','C'), mov_read_vpcc },
6976 { MKTAG('m','d','c','v'), mov_read_mdcv },
6977 { MKTAG('c','l','l','i'), mov_read_clli },
6978 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
6979 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
6983 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6985 int64_t total_size = 0;
6989 if (c->atom_depth > 10) {
6990 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6991 return AVERROR_INVALIDDATA;
6996 atom.size = INT64_MAX;
6997 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6998 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
7001 if (atom.size >= 8) {
7002 a.size = avio_rb32(pb);
7003 a.type = avio_rl32(pb);
7004 if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
7005 a.type == MKTAG('h','o','o','v')) &&
7007 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
7010 type = avio_rl32(pb);
7013 avio_seek(pb, -8, SEEK_CUR);
7014 if (type == MKTAG('m','v','h','d') ||
7015 type == MKTAG('c','m','o','v')) {
7016 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
7017 a.type = MKTAG('m','o','o','v');
7020 if (atom.type != MKTAG('r','o','o','t') &&
7021 atom.type != MKTAG('m','o','o','v')) {
7022 if (a.type == MKTAG('t','r','a','k') ||
7023 a.type == MKTAG('m','d','a','t')) {
7024 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
7031 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
7032 a.size = avio_rb64(pb) - 8;
7036 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
7037 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
7039 a.size = atom.size - total_size + 8;
7044 a.size = FFMIN(a.size, atom.size - total_size);
7046 for (i = 0; mov_default_parse_table[i].type; i++)
7047 if (mov_default_parse_table[i].type == a.type) {
7048 parse = mov_default_parse_table[i].parse;
7052 // container is user data
7053 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
7054 atom.type == MKTAG('i','l','s','t')))
7055 parse = mov_read_udta_string;
7057 // Supports parsing the QuickTime Metadata Keys.
7058 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
7059 if (!parse && c->found_hdlr_mdta &&
7060 atom.type == MKTAG('m','e','t','a') &&
7061 a.type == MKTAG('k','e','y','s') &&
7062 c->meta_keys_count == 0) {
7063 parse = mov_read_keys;
7066 if (!parse) { /* skip leaf atoms data */
7067 avio_skip(pb, a.size);
7069 int64_t start_pos = avio_tell(pb);
7071 int err = parse(c, pb, a);
7076 if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
7077 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
7078 start_pos + a.size == avio_size(pb))) {
7079 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
7080 c->next_root_atom = start_pos + a.size;
7084 left = a.size - avio_tell(pb) + start_pos;
7085 if (left > 0) /* skip garbage at atom end */
7086 avio_skip(pb, left);
7087 else if (left < 0) {
7088 av_log(c->fc, AV_LOG_WARNING,
7089 "overread end of atom '%s' by %"PRId64" bytes\n",
7090 av_fourcc2str(a.type), -left);
7091 avio_seek(pb, left, SEEK_CUR);
7095 total_size += a.size;
7098 if (total_size < atom.size && atom.size < 0x7ffff)
7099 avio_skip(pb, atom.size - total_size);
7105 static int mov_probe(const AVProbeData *p)
7110 int moov_offset = -1;
7112 /* check file header */
7117 /* ignore invalid offset */
7118 if ((offset + 8) > (unsigned int)p->buf_size)
7120 size = AV_RB32(p->buf + offset);
7121 if (size == 1 && offset + 16 > (unsigned int)p->buf_size) {
7122 size = AV_RB64(p->buf+offset + 8);
7124 } else if (size == 0) {
7125 size = p->buf_size - offset;
7127 if (size < minsize) {
7131 tag = AV_RL32(p->buf + offset + 4);
7133 /* check for obvious tags */
7134 case MKTAG('m','o','o','v'):
7135 moov_offset = offset + 4;
7136 case MKTAG('m','d','a','t'):
7137 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
7138 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
7139 case MKTAG('f','t','y','p'):
7140 if (tag == MKTAG('f','t','y','p') &&
7141 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
7142 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
7144 score = FFMAX(score, 5);
7146 score = AVPROBE_SCORE_MAX;
7149 /* those are more common words, so rate then a bit less */
7150 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
7151 case MKTAG('w','i','d','e'):
7152 case MKTAG('f','r','e','e'):
7153 case MKTAG('j','u','n','k'):
7154 case MKTAG('p','i','c','t'):
7155 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
7157 case MKTAG(0x82,0x82,0x7f,0x7d):
7158 case MKTAG('s','k','i','p'):
7159 case MKTAG('u','u','i','d'):
7160 case MKTAG('p','r','f','l'):
7161 /* if we only find those cause probedata is too small at least rate them */
7162 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7167 if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
7168 /* moov atom in the header - we should make sure that this is not a
7169 * MOV-packed MPEG-PS */
7170 offset = moov_offset;
7172 while (offset < (p->buf_size - 16)) { /* Sufficient space */
7173 /* We found an actual hdlr atom */
7174 if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7175 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7176 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
7177 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7178 /* We found a media handler reference atom describing an
7179 * MPEG-PS-in-MOV, return a
7180 * low score to force expanding the probe window until
7181 * mpegps_probe finds what it needs */
7193 // must be done after parsing all trak because there's no order requirement
7194 static void mov_read_chapters(AVFormatContext *s)
7196 MOVContext *mov = s->priv_data;
7198 MOVStreamContext *sc;
7203 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7204 chapter_track = mov->chapter_tracks[j];
7206 for (i = 0; i < s->nb_streams; i++)
7207 if (s->streams[i]->id == chapter_track) {
7212 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7217 cur_pos = avio_tell(sc->pb);
7219 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7220 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7221 if (st->internal->nb_index_entries) {
7222 // Retrieve the first frame, if possible
7223 AVIndexEntry *sample = &st->internal->index_entries[0];
7224 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7225 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7229 if (av_get_packet(sc->pb, &st->attached_pic, sample->size) < 0)
7232 st->attached_pic.stream_index = st->index;
7233 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
7236 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7237 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7238 st->discard = AVDISCARD_ALL;
7239 for (i = 0; i < st->internal->nb_index_entries; i++) {
7240 AVIndexEntry *sample = &st->internal->index_entries[i];
7241 int64_t end = i+1 < st->internal->nb_index_entries ? st->internal->index_entries[i+1].timestamp : st->duration;
7246 if (end < sample->timestamp) {
7247 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7248 end = AV_NOPTS_VALUE;
7251 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7252 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7256 // the first two bytes are the length of the title
7257 len = avio_rb16(sc->pb);
7258 if (len > sample->size-2)
7260 title_len = 2*len + 1;
7261 if (!(title = av_mallocz(title_len)))
7264 // The samples could theoretically be in any encoding if there's an encd
7265 // atom following, but in practice are only utf-8 or utf-16, distinguished
7266 // instead by the presence of a BOM
7270 ch = avio_rb16(sc->pb);
7272 avio_get_str16be(sc->pb, len, title, title_len);
7273 else if (ch == 0xfffe)
7274 avio_get_str16le(sc->pb, len, title, title_len);
7277 if (len == 1 || len == 2)
7280 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7284 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7289 avio_seek(sc->pb, cur_pos, SEEK_SET);
7293 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7294 uint32_t value, int flags)
7297 char buf[AV_TIMECODE_STR_SIZE];
7298 AVRational rate = st->avg_frame_rate;
7299 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7302 av_dict_set(&st->metadata, "timecode",
7303 av_timecode_make_string(&tc, buf, value), 0);
7307 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7309 MOVStreamContext *sc = st->priv_data;
7310 char buf[AV_TIMECODE_STR_SIZE];
7311 int64_t cur_pos = avio_tell(sc->pb);
7312 int hh, mm, ss, ff, drop;
7314 if (!st->internal->nb_index_entries)
7317 avio_seek(sc->pb, st->internal->index_entries->pos, SEEK_SET);
7318 avio_skip(s->pb, 13);
7319 hh = avio_r8(s->pb);
7320 mm = avio_r8(s->pb);
7321 ss = avio_r8(s->pb);
7322 drop = avio_r8(s->pb);
7323 ff = avio_r8(s->pb);
7324 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7325 hh, mm, ss, drop ? ';' : ':', ff);
7326 av_dict_set(&st->metadata, "timecode", buf, 0);
7328 avio_seek(sc->pb, cur_pos, SEEK_SET);
7332 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7334 MOVStreamContext *sc = st->priv_data;
7336 int64_t cur_pos = avio_tell(sc->pb);
7339 if (!st->internal->nb_index_entries)
7342 avio_seek(sc->pb, st->internal->index_entries->pos, SEEK_SET);
7343 value = avio_rb32(s->pb);
7345 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7346 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7347 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7349 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7350 * not the case) and thus assume "frame number format" instead of QT one.
7351 * No sample with tmcd track can be found with a QT timecode at the moment,
7352 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7354 parse_timecode_in_framenum_format(s, st, value, flags);
7356 avio_seek(sc->pb, cur_pos, SEEK_SET);
7360 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7362 if (!index || !*index) return;
7363 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7364 av_encryption_info_free((*index)->encrypted_samples[i]);
7366 av_freep(&(*index)->encrypted_samples);
7367 av_freep(&(*index)->auxiliary_info_sizes);
7368 av_freep(&(*index)->auxiliary_offsets);
7372 static int mov_read_close(AVFormatContext *s)
7374 MOVContext *mov = s->priv_data;
7377 for (i = 0; i < s->nb_streams; i++) {
7378 AVStream *st = s->streams[i];
7379 MOVStreamContext *sc = st->priv_data;
7384 av_freep(&sc->ctts_data);
7385 for (j = 0; j < sc->drefs_count; j++) {
7386 av_freep(&sc->drefs[j].path);
7387 av_freep(&sc->drefs[j].dir);
7389 av_freep(&sc->drefs);
7391 sc->drefs_count = 0;
7393 if (!sc->pb_is_copied)
7394 ff_format_io_close(s, &sc->pb);
7397 av_freep(&sc->chunk_offsets);
7398 av_freep(&sc->stsc_data);
7399 av_freep(&sc->sample_sizes);
7400 av_freep(&sc->keyframes);
7401 av_freep(&sc->stts_data);
7402 av_freep(&sc->sdtp_data);
7403 av_freep(&sc->stps_data);
7404 av_freep(&sc->elst_data);
7405 av_freep(&sc->rap_group);
7406 av_freep(&sc->display_matrix);
7407 av_freep(&sc->index_ranges);
7410 for (j = 0; j < sc->stsd_count; j++)
7411 av_free(sc->extradata[j]);
7412 av_freep(&sc->extradata);
7413 av_freep(&sc->extradata_size);
7415 mov_free_encryption_index(&sc->cenc.encryption_index);
7416 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7417 av_aes_ctr_free(sc->cenc.aes_ctr);
7419 av_freep(&sc->stereo3d);
7420 av_freep(&sc->spherical);
7421 av_freep(&sc->mastering);
7422 av_freep(&sc->coll);
7425 av_freep(&mov->dv_demux);
7426 avformat_free_context(mov->dv_fctx);
7427 mov->dv_fctx = NULL;
7429 if (mov->meta_keys) {
7430 for (i = 1; i < mov->meta_keys_count; i++) {
7431 av_freep(&mov->meta_keys[i]);
7433 av_freep(&mov->meta_keys);
7436 av_freep(&mov->trex_data);
7437 av_freep(&mov->bitrates);
7439 for (i = 0; i < mov->frag_index.nb_items; i++) {
7440 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7441 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7442 mov_free_encryption_index(&frag[j].encryption_index);
7444 av_freep(&mov->frag_index.item[i].stream_info);
7446 av_freep(&mov->frag_index.item);
7448 av_freep(&mov->aes_decrypt);
7449 av_freep(&mov->chapter_tracks);
7454 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7458 for (i = 0; i < s->nb_streams; i++) {
7459 AVStream *st = s->streams[i];
7460 MOVStreamContext *sc = st->priv_data;
7462 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7463 sc->timecode_track == tmcd_id)
7469 /* look for a tmcd track not referenced by any video track, and export it globally */
7470 static void export_orphan_timecode(AVFormatContext *s)
7474 for (i = 0; i < s->nb_streams; i++) {
7475 AVStream *st = s->streams[i];
7477 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7478 !tmcd_is_referenced(s, i + 1)) {
7479 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7481 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7488 static int read_tfra(MOVContext *mov, AVIOContext *f)
7490 int version, fieldlength, i, j;
7491 int64_t pos = avio_tell(f);
7492 uint32_t size = avio_rb32(f);
7493 unsigned track_id, item_count;
7495 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7498 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7500 version = avio_r8(f);
7502 track_id = avio_rb32(f);
7503 fieldlength = avio_rb32(f);
7504 item_count = avio_rb32(f);
7505 for (i = 0; i < item_count; i++) {
7506 int64_t time, offset;
7508 MOVFragmentStreamInfo * frag_stream_info;
7511 return AVERROR_INVALIDDATA;
7515 time = avio_rb64(f);
7516 offset = avio_rb64(f);
7518 time = avio_rb32(f);
7519 offset = avio_rb32(f);
7522 // The first sample of each stream in a fragment is always a random
7523 // access sample. So it's entry in the tfra can be used as the
7524 // initial PTS of the fragment.
7525 index = update_frag_index(mov, offset);
7526 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7527 if (frag_stream_info &&
7528 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7529 frag_stream_info->first_tfra_pts = time;
7531 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7533 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7535 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7539 avio_seek(f, pos + size, SEEK_SET);
7543 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7545 int64_t stream_size = avio_size(f);
7546 int64_t original_pos = avio_tell(f);
7549 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7553 c->mfra_size = avio_rb32(f);
7554 c->have_read_mfra_size = 1;
7555 if (!c->mfra_size || c->mfra_size > stream_size) {
7556 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7559 if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
7563 if (avio_rb32(f) != c->mfra_size) {
7564 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7567 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7568 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7571 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7573 ret = read_tfra(c, f);
7578 c->frag_index.complete = 1;
7580 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7582 av_log(c->fc, AV_LOG_ERROR,
7583 "failed to seek back after looking for mfra\n");
7589 static int mov_read_header(AVFormatContext *s)
7591 MOVContext *mov = s->priv_data;
7592 AVIOContext *pb = s->pb;
7594 MOVAtom atom = { AV_RL32("root") };
7597 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7598 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7599 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7600 return AVERROR(EINVAL);
7604 mov->trak_index = -1;
7605 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7606 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7607 atom.size = avio_size(pb);
7609 atom.size = INT64_MAX;
7611 /* check MOV header */
7613 if (mov->moov_retry)
7614 avio_seek(pb, 0, SEEK_SET);
7615 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7616 av_log(s, AV_LOG_ERROR, "error reading header\n");
7619 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7620 if (!mov->found_moov) {
7621 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7622 err = AVERROR_INVALIDDATA;
7625 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7627 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7628 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7629 mov_read_chapters(s);
7630 for (i = 0; i < s->nb_streams; i++)
7631 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7632 mov_read_timecode_track(s, s->streams[i]);
7633 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7634 mov_read_rtmd_track(s, s->streams[i]);
7638 /* copy timecode metadata from tmcd tracks to the related video streams */
7639 for (i = 0; i < s->nb_streams; i++) {
7640 AVStream *st = s->streams[i];
7641 MOVStreamContext *sc = st->priv_data;
7642 if (sc->timecode_track > 0) {
7643 AVDictionaryEntry *tcr;
7644 int tmcd_st_id = -1;
7646 for (j = 0; j < s->nb_streams; j++)
7647 if (s->streams[j]->id == sc->timecode_track)
7650 if (tmcd_st_id < 0 || tmcd_st_id == i)
7652 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7654 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7657 export_orphan_timecode(s);
7659 for (i = 0; i < s->nb_streams; i++) {
7660 AVStream *st = s->streams[i];
7661 MOVStreamContext *sc = st->priv_data;
7662 fix_timescale(mov, sc);
7663 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
7664 st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7665 st->internal->skip_samples = sc->start_pad;
7667 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7668 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7669 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7670 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7671 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7672 st->codecpar->width = sc->width;
7673 st->codecpar->height = sc->height;
7675 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7676 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7680 if (mov->handbrake_version &&
7681 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7682 st->codecpar->codec_id == AV_CODEC_ID_MP3) {
7683 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7684 st->need_parsing = AVSTREAM_PARSE_FULL;
7688 if (mov->trex_data) {
7689 for (i = 0; i < s->nb_streams; i++) {
7690 AVStream *st = s->streams[i];
7691 MOVStreamContext *sc = st->priv_data;
7692 if (st->duration > 0) {
7693 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7694 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7695 sc->data_size, sc->time_scale);
7696 err = AVERROR_INVALIDDATA;
7699 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7704 if (mov->use_mfra_for > 0) {
7705 for (i = 0; i < s->nb_streams; i++) {
7706 AVStream *st = s->streams[i];
7707 MOVStreamContext *sc = st->priv_data;
7708 if (sc->duration_for_fps > 0) {
7709 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7710 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7711 sc->data_size, sc->time_scale);
7712 err = AVERROR_INVALIDDATA;
7715 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7716 sc->duration_for_fps;
7721 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7722 if (mov->bitrates[i]) {
7723 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7727 ff_rfps_calculate(s);
7729 for (i = 0; i < s->nb_streams; i++) {
7730 AVStream *st = s->streams[i];
7731 MOVStreamContext *sc = st->priv_data;
7733 switch (st->codecpar->codec_type) {
7734 case AVMEDIA_TYPE_AUDIO:
7735 err = ff_replaygain_export(st, s->metadata);
7739 case AVMEDIA_TYPE_VIDEO:
7740 if (sc->display_matrix) {
7741 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7742 sizeof(int32_t) * 9);
7746 sc->display_matrix = NULL;
7749 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7750 (uint8_t *)sc->stereo3d,
7751 sizeof(*sc->stereo3d));
7755 sc->stereo3d = NULL;
7757 if (sc->spherical) {
7758 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7759 (uint8_t *)sc->spherical,
7760 sc->spherical_size);
7764 sc->spherical = NULL;
7766 if (sc->mastering) {
7767 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7768 (uint8_t *)sc->mastering,
7769 sizeof(*sc->mastering));
7773 sc->mastering = NULL;
7776 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7777 (uint8_t *)sc->coll,
7787 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7789 for (i = 0; i < mov->frag_index.nb_items; i++)
7790 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7791 mov->frag_index.item[i].headers_read = 1;
7799 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7801 AVIndexEntry *sample = NULL;
7802 int64_t best_dts = INT64_MAX;
7804 for (i = 0; i < s->nb_streams; i++) {
7805 AVStream *avst = s->streams[i];
7806 MOVStreamContext *msc = avst->priv_data;
7807 if (msc->pb && msc->current_sample < avst->internal->nb_index_entries) {
7808 AVIndexEntry *current_sample = &avst->internal->index_entries[msc->current_sample];
7809 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7810 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7811 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7812 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7813 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
7814 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7815 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7816 sample = current_sample;
7825 static int should_retry(AVIOContext *pb, int error_code) {
7826 if (error_code == AVERROR_EOF || avio_feof(pb))
7832 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7835 MOVContext *mov = s->priv_data;
7837 if (index >= 0 && index < mov->frag_index.nb_items)
7838 target = mov->frag_index.item[index].moof_offset;
7839 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7840 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7841 return AVERROR_INVALIDDATA;
7844 mov->next_root_atom = 0;
7845 if (index < 0 || index >= mov->frag_index.nb_items)
7846 index = search_frag_moof_offset(&mov->frag_index, target);
7847 if (index < mov->frag_index.nb_items &&
7848 mov->frag_index.item[index].moof_offset == target) {
7849 if (index + 1 < mov->frag_index.nb_items)
7850 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7851 if (mov->frag_index.item[index].headers_read)
7853 mov->frag_index.item[index].headers_read = 1;
7856 mov->found_mdat = 0;
7858 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7861 if (avio_feof(s->pb))
7863 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7868 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7870 uint8_t *side, *extradata;
7873 /* Save the current index. */
7874 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7876 /* Notify the decoder that extradata changed. */
7877 extradata_size = sc->extradata_size[sc->last_stsd_index];
7878 extradata = sc->extradata[sc->last_stsd_index];
7879 if (extradata_size > 0 && extradata) {
7880 side = av_packet_new_side_data(pkt,
7881 AV_PKT_DATA_NEW_EXTRADATA,
7884 return AVERROR(ENOMEM);
7885 memcpy(side, extradata, extradata_size);
7891 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int size)
7896 return AVERROR_INVALIDDATA;
7897 new_size = ((size - 8) / 2) * 3;
7898 ret = av_new_packet(pkt, new_size);
7903 for (int j = 0; j < new_size; j += 3) {
7904 pkt->data[j] = 0xFC;
7905 pkt->data[j+1] = avio_r8(pb);
7906 pkt->data[j+2] = avio_r8(pb);
7912 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7914 MOVContext *mov = s->priv_data;
7915 MOVStreamContext *sc;
7916 AVIndexEntry *sample;
7917 AVStream *st = NULL;
7918 int64_t current_index;
7922 sample = mov_find_next_sample(s, &st);
7923 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7924 if (!mov->next_root_atom)
7926 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7931 /* must be done just before reading, to avoid infinite loop on sample */
7932 current_index = sc->current_index;
7933 mov_current_sample_inc(sc);
7935 if (mov->next_root_atom) {
7936 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7937 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7940 if (st->discard != AVDISCARD_ALL) {
7941 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7942 if (ret64 != sample->pos) {
7943 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7944 sc->ffindex, sample->pos);
7945 if (should_retry(sc->pb, ret64)) {
7946 mov_current_sample_dec(sc);
7948 return AVERROR_INVALIDDATA;
7951 if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
7952 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7956 if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
7957 ret = get_eia608_packet(sc->pb, pkt, sample->size);
7959 ret = av_get_packet(sc->pb, pkt, sample->size);
7961 if (should_retry(sc->pb, ret)) {
7962 mov_current_sample_dec(sc);
7966 #if CONFIG_DV_DEMUXER
7967 if (mov->dv_demux && sc->dv_audio_container) {
7968 AVBufferRef *buf = pkt->buf;
7969 ret = avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7971 av_packet_unref(pkt);
7974 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7979 if (sc->has_palette) {
7982 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7984 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7986 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7987 sc->has_palette = 0;
7990 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7991 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7992 st->need_parsing = AVSTREAM_PARSE_FULL;
7996 pkt->stream_index = sc->ffindex;
7997 pkt->dts = sample->timestamp;
7998 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7999 pkt->flags |= AV_PKT_FLAG_DISCARD;
8001 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
8002 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
8003 /* update ctts context */
8005 if (sc->ctts_index < sc->ctts_count &&
8006 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
8008 sc->ctts_sample = 0;
8011 int64_t next_dts = (sc->current_sample < st->internal->nb_index_entries) ?
8012 st->internal->index_entries[sc->current_sample].timestamp : st->duration;
8014 if (next_dts >= pkt->dts)
8015 pkt->duration = next_dts - pkt->dts;
8016 pkt->pts = pkt->dts;
8018 if (st->discard == AVDISCARD_ALL)
8020 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
8021 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
8022 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
8023 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
8025 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
8026 pkt->pos = sample->pos;
8028 /* Multiple stsd handling. */
8029 if (sc->stsc_data) {
8030 /* Keep track of the stsc index for the given sample, then check
8031 * if the stsd index is different from the last used one. */
8033 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
8034 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
8036 sc->stsc_sample = 0;
8037 /* Do not check indexes after a switch. */
8038 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
8039 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
8040 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
8041 ret = mov_change_extradata(sc, pkt);
8048 aax_filter(pkt->data, pkt->size, mov);
8050 ret = cenc_filter(mov, st, sc, pkt, current_index);
8058 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
8060 MOVContext *mov = s->priv_data;
8063 if (!mov->frag_index.complete)
8066 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
8069 if (!mov->frag_index.item[index].headers_read)
8070 return mov_switch_root(s, -1, index);
8071 if (index + 1 < mov->frag_index.nb_items)
8072 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
8077 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
8079 MOVStreamContext *sc = st->priv_data;
8080 int sample, time_sample, ret;
8083 // Here we consider timestamp to be PTS, hence try to offset it so that we
8084 // can search over the DTS timeline.
8085 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
8087 ret = mov_seek_fragment(s, st, timestamp);
8091 sample = av_index_search_timestamp(st, timestamp, flags);
8092 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
8093 if (sample < 0 && st->internal->nb_index_entries && timestamp < st->internal->index_entries[0].timestamp)
8095 if (sample < 0) /* not sure what to do */
8096 return AVERROR_INVALIDDATA;
8097 mov_current_sample_set(sc, sample);
8098 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
8099 /* adjust ctts index */
8100 if (sc->ctts_data) {
8102 for (i = 0; i < sc->ctts_count; i++) {
8103 int next = time_sample + sc->ctts_data[i].count;
8104 if (next > sc->current_sample) {
8106 sc->ctts_sample = sc->current_sample - time_sample;
8113 /* adjust stsd index */
8114 if (sc->chunk_count) {
8116 for (i = 0; i < sc->stsc_count; i++) {
8117 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
8118 if (next > sc->current_sample) {
8120 sc->stsc_sample = sc->current_sample - time_sample;
8123 av_assert0(next == (int)next);
8131 static int64_t mov_get_skip_samples(AVStream *st, int sample)
8133 MOVStreamContext *sc = st->priv_data;
8134 int64_t first_ts = st->internal->index_entries[0].timestamp;
8135 int64_t ts = st->internal->index_entries[sample].timestamp;
8138 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO)
8141 /* compute skip samples according to stream start_pad, seek ts and first ts */
8142 off = av_rescale_q(ts - first_ts, st->time_base,
8143 (AVRational){1, st->codecpar->sample_rate});
8144 return FFMAX(sc->start_pad - off, 0);
8147 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
8149 MOVContext *mc = s->priv_data;
8154 if (stream_index >= s->nb_streams)
8155 return AVERROR_INVALIDDATA;
8157 st = s->streams[stream_index];
8158 sample = mov_seek_stream(s, st, sample_time, flags);
8162 if (mc->seek_individually) {
8163 /* adjust seek timestamp to found sample timestamp */
8164 int64_t seek_timestamp = st->internal->index_entries[sample].timestamp;
8165 st->internal->skip_samples = mov_get_skip_samples(st, sample);
8167 for (i = 0; i < s->nb_streams; i++) {
8171 if (stream_index == i)
8174 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
8175 sample = mov_seek_stream(s, st, timestamp, flags);
8177 st->internal->skip_samples = mov_get_skip_samples(st, sample);
8180 for (i = 0; i < s->nb_streams; i++) {
8181 MOVStreamContext *sc;
8184 mov_current_sample_set(sc, 0);
8187 MOVStreamContext *sc;
8188 AVIndexEntry *entry = mov_find_next_sample(s, &st);
8190 return AVERROR_INVALIDDATA;
8192 if (sc->ffindex == stream_index && sc->current_sample == sample)
8194 mov_current_sample_inc(sc);
8200 #define OFFSET(x) offsetof(MOVContext, x)
8201 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
8202 static const AVOption mov_options[] = {
8203 {"use_absolute_path",
8204 "allow using absolute path when opening alias, this is a possible security issue",
8205 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
8207 {"seek_streams_individually",
8208 "Seek each stream individually to the closest point",
8209 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
8211 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
8213 {"advanced_editlist",
8214 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
8215 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
8217 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8220 "use mfra for fragment timestamps",
8221 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8222 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8224 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8225 FLAGS, "use_mfra_for" },
8226 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8227 FLAGS, "use_mfra_for" },
8228 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8229 FLAGS, "use_mfra_for" },
8230 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8231 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8232 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8233 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8234 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8235 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8236 { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
8237 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8238 { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
8239 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8240 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8241 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8242 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8243 .flags = AV_OPT_FLAG_DECODING_PARAM },
8244 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8245 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8246 {.i64 = 0}, 0, 1, FLAGS },
8251 static const AVClass mov_class = {
8252 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8253 .item_name = av_default_item_name,
8254 .option = mov_options,
8255 .version = LIBAVUTIL_VERSION_INT,
8258 AVInputFormat ff_mov_demuxer = {
8259 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8260 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8261 .priv_class = &mov_class,
8262 .priv_data_size = sizeof(MOVContext),
8263 .extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
8264 .read_probe = mov_probe,
8265 .read_header = mov_read_header,
8266 .read_packet = mov_read_packet,
8267 .read_close = mov_read_close,
8268 .read_seek = mov_read_seek,
8269 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,