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;
5560 avio_skip(pb, 4); /* version + flags */
5565 type = AV_STEREO3D_2D;
5568 type = AV_STEREO3D_TOPBOTTOM;
5571 type = AV_STEREO3D_SIDEBYSIDE;
5574 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5578 sc->stereo3d = av_stereo3d_alloc();
5580 return AVERROR(ENOMEM);
5582 sc->stereo3d->type = type;
5586 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5589 MOVStreamContext *sc;
5590 int size, version, layout;
5591 int32_t yaw, pitch, roll;
5592 uint32_t l = 0, t = 0, r = 0, b = 0;
5593 uint32_t tag, padding = 0;
5594 enum AVSphericalProjection projection;
5596 if (c->fc->nb_streams < 1)
5599 st = c->fc->streams[c->fc->nb_streams - 1];
5602 if (atom.size < 8) {
5603 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5604 return AVERROR_INVALIDDATA;
5607 size = avio_rb32(pb);
5608 if (size <= 12 || size > atom.size)
5609 return AVERROR_INVALIDDATA;
5611 tag = avio_rl32(pb);
5612 if (tag != MKTAG('s','v','h','d')) {
5613 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5616 version = avio_r8(pb);
5618 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5622 avio_skip(pb, 3); /* flags */
5623 avio_skip(pb, size - 12); /* metadata_source */
5625 size = avio_rb32(pb);
5626 if (size > atom.size)
5627 return AVERROR_INVALIDDATA;
5629 tag = avio_rl32(pb);
5630 if (tag != MKTAG('p','r','o','j')) {
5631 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5635 size = avio_rb32(pb);
5636 if (size > atom.size)
5637 return AVERROR_INVALIDDATA;
5639 tag = avio_rl32(pb);
5640 if (tag != MKTAG('p','r','h','d')) {
5641 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5644 version = avio_r8(pb);
5646 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5650 avio_skip(pb, 3); /* flags */
5652 /* 16.16 fixed point */
5653 yaw = avio_rb32(pb);
5654 pitch = avio_rb32(pb);
5655 roll = avio_rb32(pb);
5657 size = avio_rb32(pb);
5658 if (size > atom.size)
5659 return AVERROR_INVALIDDATA;
5661 tag = avio_rl32(pb);
5662 version = avio_r8(pb);
5664 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5668 avio_skip(pb, 3); /* flags */
5670 case MKTAG('c','b','m','p'):
5671 layout = avio_rb32(pb);
5673 av_log(c->fc, AV_LOG_WARNING,
5674 "Unsupported cubemap layout %d\n", layout);
5677 projection = AV_SPHERICAL_CUBEMAP;
5678 padding = avio_rb32(pb);
5680 case MKTAG('e','q','u','i'):
5686 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5687 av_log(c->fc, AV_LOG_ERROR,
5688 "Invalid bounding rectangle coordinates "
5689 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5690 return AVERROR_INVALIDDATA;
5693 if (l || t || r || b)
5694 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5696 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5699 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5703 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5705 return AVERROR(ENOMEM);
5707 sc->spherical->projection = projection;
5709 sc->spherical->yaw = yaw;
5710 sc->spherical->pitch = pitch;
5711 sc->spherical->roll = roll;
5713 sc->spherical->padding = padding;
5715 sc->spherical->bound_left = l;
5716 sc->spherical->bound_top = t;
5717 sc->spherical->bound_right = r;
5718 sc->spherical->bound_bottom = b;
5723 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5726 uint8_t *buffer = av_malloc(len + 1);
5730 return AVERROR(ENOMEM);
5733 ret = ffio_read_size(pb, buffer, len);
5737 /* Check for mandatory keys and values, try to support XML as best-effort */
5738 if (!sc->spherical &&
5739 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5740 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5741 av_stristr(val, "true") &&
5742 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5743 av_stristr(val, "true") &&
5744 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5745 av_stristr(val, "equirectangular")) {
5746 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5750 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5752 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5753 enum AVStereo3DType mode;
5755 if (av_stristr(buffer, "left-right"))
5756 mode = AV_STEREO3D_SIDEBYSIDE;
5757 else if (av_stristr(buffer, "top-bottom"))
5758 mode = AV_STEREO3D_TOPBOTTOM;
5760 mode = AV_STEREO3D_2D;
5762 sc->stereo3d = av_stereo3d_alloc();
5766 sc->stereo3d->type = mode;
5770 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5772 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5773 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5775 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5776 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5778 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5786 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5789 MOVStreamContext *sc;
5792 static const uint8_t uuid_isml_manifest[] = {
5793 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5794 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5796 static const uint8_t uuid_xmp[] = {
5797 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5798 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5800 static const uint8_t uuid_spherical[] = {
5801 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5802 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5805 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5806 return AVERROR_INVALIDDATA;
5808 if (c->fc->nb_streams < 1)
5810 st = c->fc->streams[c->fc->nb_streams - 1];
5813 ret = ffio_read_size(pb, uuid, sizeof(uuid));
5816 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5817 uint8_t *buffer, *ptr;
5819 size_t len = atom.size - sizeof(uuid);
5822 return AVERROR_INVALIDDATA;
5824 ret = avio_skip(pb, 4); // zeroes
5827 buffer = av_mallocz(len + 1);
5829 return AVERROR(ENOMEM);
5831 ret = ffio_read_size(pb, buffer, len);
5838 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5839 ptr += sizeof("systemBitrate=\"") - 1;
5840 c->bitrates_count++;
5841 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5843 c->bitrates_count = 0;
5845 return AVERROR(ENOMEM);
5848 ret = strtol(ptr, &endptr, 10);
5849 if (ret < 0 || errno || *endptr != '"') {
5850 c->bitrates[c->bitrates_count - 1] = 0;
5852 c->bitrates[c->bitrates_count - 1] = ret;
5857 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5859 size_t len = atom.size - sizeof(uuid);
5860 if (c->export_xmp) {
5861 buffer = av_mallocz(len + 1);
5863 return AVERROR(ENOMEM);
5865 ret = ffio_read_size(pb, buffer, len);
5871 av_dict_set(&c->fc->metadata, "xmp",
5872 buffer, AV_DICT_DONT_STRDUP_VAL);
5874 // skip all uuid atom, which makes it fast for long uuid-xmp file
5875 ret = avio_skip(pb, len);
5879 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5880 size_t len = atom.size - sizeof(uuid);
5881 ret = mov_parse_uuid_spherical(sc, pb, len);
5885 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5891 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5894 uint8_t content[16];
5899 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5905 && !memcmp(content, "Anevia\x1A\x1A", 8)
5906 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5907 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5913 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5915 uint32_t format = avio_rl32(pb);
5916 MOVStreamContext *sc;
5920 if (c->fc->nb_streams < 1)
5922 st = c->fc->streams[c->fc->nb_streams - 1];
5927 case MKTAG('e','n','c','v'): // encrypted video
5928 case MKTAG('e','n','c','a'): // encrypted audio
5929 id = mov_codec_id(st, format);
5930 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5931 st->codecpar->codec_id != id) {
5932 av_log(c->fc, AV_LOG_WARNING,
5933 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5934 (char*)&format, st->codecpar->codec_id);
5938 st->codecpar->codec_id = id;
5939 sc->format = format;
5943 if (format != sc->format) {
5944 av_log(c->fc, AV_LOG_WARNING,
5945 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5946 (char*)&format, (char*)&sc->format);
5955 * Gets the current encryption info and associated current stream context. If
5956 * we are parsing a track fragment, this will return the specific encryption
5957 * info for this fragment; otherwise this will return the global encryption
5958 * info for the current stream.
5960 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5962 MOVFragmentStreamInfo *frag_stream_info;
5966 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5967 if (frag_stream_info) {
5968 for (i = 0; i < c->fc->nb_streams; i++) {
5969 if (c->fc->streams[i]->id == frag_stream_info->id) {
5970 st = c->fc->streams[i];
5974 if (i == c->fc->nb_streams)
5976 *sc = st->priv_data;
5978 if (!frag_stream_info->encryption_index) {
5979 // If this stream isn't encrypted, don't create the index.
5980 if (!(*sc)->cenc.default_encrypted_sample)
5982 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5983 if (!frag_stream_info->encryption_index)
5984 return AVERROR(ENOMEM);
5986 *encryption_index = frag_stream_info->encryption_index;
5989 // No current track fragment, using stream level encryption info.
5991 if (c->fc->nb_streams < 1)
5993 st = c->fc->streams[c->fc->nb_streams - 1];
5994 *sc = st->priv_data;
5996 if (!(*sc)->cenc.encryption_index) {
5997 // If this stream isn't encrypted, don't create the index.
5998 if (!(*sc)->cenc.default_encrypted_sample)
6000 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
6001 if (!(*sc)->cenc.encryption_index)
6002 return AVERROR(ENOMEM);
6005 *encryption_index = (*sc)->cenc.encryption_index;
6010 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
6013 unsigned int subsample_count;
6014 AVSubsampleEncryptionInfo *subsamples;
6016 if (!sc->cenc.default_encrypted_sample) {
6017 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
6018 return AVERROR_INVALIDDATA;
6021 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
6023 return AVERROR(ENOMEM);
6025 if (sc->cenc.per_sample_iv_size != 0) {
6026 if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
6027 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
6028 av_encryption_info_free(*sample);
6034 if (use_subsamples) {
6035 subsample_count = avio_rb16(pb);
6036 av_free((*sample)->subsamples);
6037 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
6038 if (!(*sample)->subsamples) {
6039 av_encryption_info_free(*sample);
6041 return AVERROR(ENOMEM);
6044 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
6045 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
6046 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
6049 if (pb->eof_reached) {
6050 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
6051 av_encryption_info_free(*sample);
6053 return AVERROR_INVALIDDATA;
6055 (*sample)->subsample_count = subsample_count;
6061 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6063 AVEncryptionInfo **encrypted_samples;
6064 MOVEncryptionIndex *encryption_index;
6065 MOVStreamContext *sc;
6066 int use_subsamples, ret;
6067 unsigned int sample_count, i, alloc_size = 0;
6069 ret = get_current_encryption_info(c, &encryption_index, &sc);
6073 if (encryption_index->nb_encrypted_samples) {
6074 // This can happen if we have both saio/saiz and senc atoms.
6075 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6079 avio_r8(pb); /* version */
6080 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6082 sample_count = avio_rb32(pb);
6083 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6084 return AVERROR(ENOMEM);
6086 for (i = 0; i < sample_count; i++) {
6087 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6088 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6089 min_samples * sizeof(*encrypted_samples));
6090 if (encrypted_samples) {
6091 encryption_index->encrypted_samples = encrypted_samples;
6093 ret = mov_read_sample_encryption_info(
6094 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6096 ret = AVERROR(ENOMEM);
6098 if (pb->eof_reached) {
6099 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6100 ret = AVERROR_INVALIDDATA;
6105 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6106 av_freep(&encryption_index->encrypted_samples);
6110 encryption_index->nb_encrypted_samples = sample_count;
6115 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6117 AVEncryptionInfo **sample, **encrypted_samples;
6119 size_t sample_count, sample_info_size, i;
6121 unsigned int alloc_size = 0;
6123 if (encryption_index->nb_encrypted_samples)
6125 sample_count = encryption_index->auxiliary_info_sample_count;
6126 if (encryption_index->auxiliary_offsets_count != 1) {
6127 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6128 return AVERROR_PATCHWELCOME;
6130 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6131 return AVERROR(ENOMEM);
6133 prev_pos = avio_tell(pb);
6134 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6135 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6136 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6140 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6141 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6142 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6143 min_samples * sizeof(*encrypted_samples));
6144 if (!encrypted_samples) {
6145 ret = AVERROR(ENOMEM);
6148 encryption_index->encrypted_samples = encrypted_samples;
6150 sample = &encryption_index->encrypted_samples[i];
6151 sample_info_size = encryption_index->auxiliary_info_default_size
6152 ? encryption_index->auxiliary_info_default_size
6153 : encryption_index->auxiliary_info_sizes[i];
6155 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6159 if (pb->eof_reached) {
6160 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6161 ret = AVERROR_INVALIDDATA;
6163 encryption_index->nb_encrypted_samples = sample_count;
6167 avio_seek(pb, prev_pos, SEEK_SET);
6169 for (; i > 0; i--) {
6170 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6172 av_freep(&encryption_index->encrypted_samples);
6178 * Tries to read the given number of bytes from the stream and puts it in a
6179 * newly allocated buffer. This reads in small chunks to avoid allocating large
6180 * memory if the file contains an invalid/malicious size value.
6182 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6184 const unsigned int block_size = 1024 * 1024;
6185 uint8_t *buffer = NULL;
6186 unsigned int alloc_size = 0, offset = 0;
6187 while (offset < size) {
6188 unsigned int new_size =
6189 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6190 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6191 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6194 return AVERROR(ENOMEM);
6196 buffer = new_buffer;
6198 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6200 return AVERROR_INVALIDDATA;
6209 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6211 MOVEncryptionIndex *encryption_index;
6212 MOVStreamContext *sc;
6214 unsigned int sample_count, aux_info_type, aux_info_param;
6216 ret = get_current_encryption_info(c, &encryption_index, &sc);
6220 if (encryption_index->nb_encrypted_samples) {
6221 // This can happen if we have both saio/saiz and senc atoms.
6222 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6226 if (encryption_index->auxiliary_info_sample_count) {
6227 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6228 return AVERROR_INVALIDDATA;
6231 avio_r8(pb); /* version */
6232 if (avio_rb24(pb) & 0x01) { /* flags */
6233 aux_info_type = avio_rb32(pb);
6234 aux_info_param = avio_rb32(pb);
6235 if (sc->cenc.default_encrypted_sample) {
6236 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6237 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6240 if (aux_info_param != 0) {
6241 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6245 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6246 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6247 aux_info_type == MKBETAG('c','e','n','s') ||
6248 aux_info_type == MKBETAG('c','b','c','1') ||
6249 aux_info_type == MKBETAG('c','b','c','s')) &&
6250 aux_info_param == 0) {
6251 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6252 return AVERROR_INVALIDDATA;
6257 } else if (!sc->cenc.default_encrypted_sample) {
6258 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6262 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6263 sample_count = avio_rb32(pb);
6264 encryption_index->auxiliary_info_sample_count = sample_count;
6266 if (encryption_index->auxiliary_info_default_size == 0) {
6267 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6269 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6274 if (encryption_index->auxiliary_offsets_count) {
6275 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6281 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6283 uint64_t *auxiliary_offsets;
6284 MOVEncryptionIndex *encryption_index;
6285 MOVStreamContext *sc;
6287 unsigned int version, entry_count, aux_info_type, aux_info_param;
6288 unsigned int alloc_size = 0;
6290 ret = get_current_encryption_info(c, &encryption_index, &sc);
6294 if (encryption_index->nb_encrypted_samples) {
6295 // This can happen if we have both saio/saiz and senc atoms.
6296 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6300 if (encryption_index->auxiliary_offsets_count) {
6301 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6302 return AVERROR_INVALIDDATA;
6305 version = avio_r8(pb); /* version */
6306 if (avio_rb24(pb) & 0x01) { /* flags */
6307 aux_info_type = avio_rb32(pb);
6308 aux_info_param = avio_rb32(pb);
6309 if (sc->cenc.default_encrypted_sample) {
6310 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6311 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6314 if (aux_info_param != 0) {
6315 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6319 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6320 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6321 aux_info_type == MKBETAG('c','e','n','s') ||
6322 aux_info_type == MKBETAG('c','b','c','1') ||
6323 aux_info_type == MKBETAG('c','b','c','s')) &&
6324 aux_info_param == 0) {
6325 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6326 return AVERROR_INVALIDDATA;
6331 } else if (!sc->cenc.default_encrypted_sample) {
6332 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6336 entry_count = avio_rb32(pb);
6337 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6338 return AVERROR(ENOMEM);
6340 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6341 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6342 auxiliary_offsets = av_fast_realloc(
6343 encryption_index->auxiliary_offsets, &alloc_size,
6344 min_offsets * sizeof(*auxiliary_offsets));
6345 if (!auxiliary_offsets) {
6346 av_freep(&encryption_index->auxiliary_offsets);
6347 return AVERROR(ENOMEM);
6349 encryption_index->auxiliary_offsets = auxiliary_offsets;
6352 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6354 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6356 if (c->frag_index.current >= 0) {
6357 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6361 if (pb->eof_reached) {
6362 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6363 av_freep(&encryption_index->auxiliary_offsets);
6364 return AVERROR_INVALIDDATA;
6367 encryption_index->auxiliary_offsets_count = entry_count;
6369 if (encryption_index->auxiliary_info_sample_count) {
6370 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6376 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6378 AVEncryptionInitInfo *info, *old_init_info;
6381 uint8_t *side_data, *extra_data, *old_side_data;
6382 size_t side_data_size;
6383 int ret = 0, old_side_data_size;
6384 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6386 if (c->fc->nb_streams < 1)
6388 st = c->fc->streams[c->fc->nb_streams-1];
6390 version = avio_r8(pb); /* version */
6391 avio_rb24(pb); /* flags */
6393 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6394 /* key_id_size */ 16, /* data_size */ 0);
6396 return AVERROR(ENOMEM);
6398 if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
6399 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6404 kid_count = avio_rb32(pb);
6405 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
6406 ret = AVERROR(ENOMEM);
6410 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6411 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6412 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6413 min_kid_count * sizeof(*key_ids));
6415 ret = AVERROR(ENOMEM);
6418 info->key_ids = key_ids;
6420 info->key_ids[i] = av_mallocz(16);
6421 if (!info->key_ids[i]) {
6422 ret = AVERROR(ENOMEM);
6425 info->num_key_ids = i + 1;
6427 if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
6428 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6433 if (pb->eof_reached) {
6434 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6435 ret = AVERROR_INVALIDDATA;
6440 extra_data_size = avio_rb32(pb);
6441 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6445 av_freep(&info->data); // malloc(0) may still allocate something.
6446 info->data = extra_data;
6447 info->data_size = extra_data_size;
6449 // If there is existing initialization data, append to the list.
6450 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6451 if (old_side_data) {
6452 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6453 if (old_init_info) {
6454 // Append to the end of the list.
6455 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6461 info = old_init_info;
6463 // Assume existing side-data will be valid, so the only error we could get is OOM.
6464 ret = AVERROR(ENOMEM);
6469 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6471 ret = AVERROR(ENOMEM);
6474 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6475 side_data, side_data_size);
6480 av_encryption_init_info_free(info);
6484 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6487 MOVStreamContext *sc;
6489 if (c->fc->nb_streams < 1)
6491 st = c->fc->streams[c->fc->nb_streams-1];
6494 if (sc->pseudo_stream_id != 0) {
6495 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6496 return AVERROR_PATCHWELCOME;
6500 return AVERROR_INVALIDDATA;
6502 avio_rb32(pb); /* version and flags */
6504 if (!sc->cenc.default_encrypted_sample) {
6505 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6506 if (!sc->cenc.default_encrypted_sample) {
6507 return AVERROR(ENOMEM);
6511 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6515 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6518 MOVStreamContext *sc;
6519 unsigned int version, pattern, is_protected, iv_size;
6521 if (c->fc->nb_streams < 1)
6523 st = c->fc->streams[c->fc->nb_streams-1];
6526 if (sc->pseudo_stream_id != 0) {
6527 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6528 return AVERROR_PATCHWELCOME;
6531 if (!sc->cenc.default_encrypted_sample) {
6532 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6533 if (!sc->cenc.default_encrypted_sample) {
6534 return AVERROR(ENOMEM);
6539 return AVERROR_INVALIDDATA;
6541 version = avio_r8(pb); /* version */
6542 avio_rb24(pb); /* flags */
6544 avio_r8(pb); /* reserved */
6545 pattern = avio_r8(pb);
6548 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6549 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6552 is_protected = avio_r8(pb);
6553 if (is_protected && !sc->cenc.encryption_index) {
6554 // The whole stream should be by-default encrypted.
6555 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6556 if (!sc->cenc.encryption_index)
6557 return AVERROR(ENOMEM);
6559 sc->cenc.per_sample_iv_size = avio_r8(pb);
6560 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6561 sc->cenc.per_sample_iv_size != 16) {
6562 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6563 return AVERROR_INVALIDDATA;
6565 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6566 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6567 return AVERROR_INVALIDDATA;
6570 if (is_protected && !sc->cenc.per_sample_iv_size) {
6571 iv_size = avio_r8(pb);
6572 if (iv_size != 8 && iv_size != 16) {
6573 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6574 return AVERROR_INVALIDDATA;
6577 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6578 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6579 return AVERROR_INVALIDDATA;
6586 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6589 int last, type, size, ret;
6592 if (c->fc->nb_streams < 1)
6594 st = c->fc->streams[c->fc->nb_streams-1];
6596 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6597 return AVERROR_INVALIDDATA;
6599 /* Check FlacSpecificBox version. */
6600 if (avio_r8(pb) != 0)
6601 return AVERROR_INVALIDDATA;
6603 avio_rb24(pb); /* Flags */
6605 avio_read(pb, buf, sizeof(buf));
6606 flac_parse_block_header(buf, &last, &type, &size);
6608 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6609 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6610 return AVERROR_INVALIDDATA;
6613 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6618 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6623 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6627 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6628 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6629 return AVERROR_PATCHWELCOME;
6632 if (!sc->cenc.aes_ctr) {
6633 /* initialize the cipher */
6634 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6635 if (!sc->cenc.aes_ctr) {
6636 return AVERROR(ENOMEM);
6639 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6645 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6647 if (!sample->subsample_count) {
6648 /* decrypt the whole packet */
6649 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6653 for (i = 0; i < sample->subsample_count; i++) {
6654 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6655 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6656 return AVERROR_INVALIDDATA;
6659 /* skip the clear bytes */
6660 input += sample->subsamples[i].bytes_of_clear_data;
6661 size -= sample->subsamples[i].bytes_of_clear_data;
6663 /* decrypt the encrypted bytes */
6664 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6665 input += sample->subsamples[i].bytes_of_protected_data;
6666 size -= sample->subsamples[i].bytes_of_protected_data;
6670 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6671 return AVERROR_INVALIDDATA;
6677 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6679 MOVFragmentStreamInfo *frag_stream_info;
6680 MOVEncryptionIndex *encryption_index;
6681 AVEncryptionInfo *encrypted_sample;
6682 int encrypted_index, ret;
6684 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6685 encrypted_index = current_index;
6686 encryption_index = NULL;
6687 if (frag_stream_info) {
6688 // Note this only supports encryption info in the first sample descriptor.
6689 if (mov->fragment.stsd_id == 1) {
6690 if (frag_stream_info->encryption_index) {
6691 encrypted_index = current_index - frag_stream_info->index_entry;
6692 encryption_index = frag_stream_info->encryption_index;
6694 encryption_index = sc->cenc.encryption_index;
6698 encryption_index = sc->cenc.encryption_index;
6701 if (encryption_index) {
6702 if (encryption_index->auxiliary_info_sample_count &&
6703 !encryption_index->nb_encrypted_samples) {
6704 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6705 return AVERROR_INVALIDDATA;
6707 if (encryption_index->auxiliary_offsets_count &&
6708 !encryption_index->nb_encrypted_samples) {
6709 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6710 return AVERROR_INVALIDDATA;
6713 if (!encryption_index->nb_encrypted_samples) {
6714 // Full-sample encryption with default settings.
6715 encrypted_sample = sc->cenc.default_encrypted_sample;
6716 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6717 // Per-sample setting override.
6718 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6720 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6721 return AVERROR_INVALIDDATA;
6724 if (mov->decryption_key) {
6725 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6728 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6730 return AVERROR(ENOMEM);
6731 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6741 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6743 const int OPUS_SEEK_PREROLL_MS = 80;
6749 if (c->fc->nb_streams < 1)
6751 st = c->fc->streams[c->fc->nb_streams-1];
6753 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6754 return AVERROR_INVALIDDATA;
6756 /* Check OpusSpecificBox version. */
6757 if (avio_r8(pb) != 0) {
6758 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6759 return AVERROR_INVALIDDATA;
6762 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6763 size = atom.size + 8;
6765 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
6768 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6769 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6770 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6771 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6773 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6774 little-endian; aside from the preceeding magic and version they're
6775 otherwise currently identical. Data after output gain at offset 16
6776 doesn't need to be bytewapped. */
6777 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6778 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6779 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6780 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6782 st->codecpar->initial_padding = pre_skip;
6783 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6784 (AVRational){1, 1000},
6785 (AVRational){1, 48000});
6790 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6793 unsigned format_info;
6794 int channel_assignment, channel_assignment1, channel_assignment2;
6797 if (c->fc->nb_streams < 1)
6799 st = c->fc->streams[c->fc->nb_streams-1];
6802 return AVERROR_INVALIDDATA;
6804 format_info = avio_rb32(pb);
6806 ratebits = (format_info >> 28) & 0xF;
6807 channel_assignment1 = (format_info >> 15) & 0x1F;
6808 channel_assignment2 = format_info & 0x1FFF;
6809 if (channel_assignment2)
6810 channel_assignment = channel_assignment2;
6812 channel_assignment = channel_assignment1;
6814 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6815 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6816 st->codecpar->channels = truehd_channels(channel_assignment);
6817 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6822 static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6826 AVDOVIDecoderConfigurationRecord *dovi;
6830 if (c->fc->nb_streams < 1)
6832 st = c->fc->streams[c->fc->nb_streams-1];
6834 if ((uint64_t)atom.size > (1<<30) || atom.size < 4)
6835 return AVERROR_INVALIDDATA;
6837 dovi = av_dovi_alloc(&dovi_size);
6839 return AVERROR(ENOMEM);
6841 dovi->dv_version_major = avio_r8(pb);
6842 dovi->dv_version_minor = avio_r8(pb);
6844 buf = avio_rb16(pb);
6845 dovi->dv_profile = (buf >> 9) & 0x7f; // 7 bits
6846 dovi->dv_level = (buf >> 3) & 0x3f; // 6 bits
6847 dovi->rpu_present_flag = (buf >> 2) & 0x01; // 1 bit
6848 dovi->el_present_flag = (buf >> 1) & 0x01; // 1 bit
6849 dovi->bl_present_flag = buf & 0x01; // 1 bit
6850 if (atom.size >= 24) { // 4 + 4 + 4 * 4
6852 dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits
6854 // 0 stands for None
6855 // Dolby Vision V1.2.93 profiles and levels
6856 dovi->dv_bl_signal_compatibility_id = 0;
6859 ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF,
6860 (uint8_t *)dovi, dovi_size);
6866 av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC box, version: %d.%d, profile: %d, level: %d, "
6867 "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n",
6868 dovi->dv_version_major, dovi->dv_version_minor,
6869 dovi->dv_profile, dovi->dv_level,
6870 dovi->rpu_present_flag,
6871 dovi->el_present_flag,
6872 dovi->bl_present_flag,
6873 dovi->dv_bl_signal_compatibility_id
6879 static const MOVParseTableEntry mov_default_parse_table[] = {
6880 { MKTAG('A','C','L','R'), mov_read_aclr },
6881 { MKTAG('A','P','R','G'), mov_read_avid },
6882 { MKTAG('A','A','L','P'), mov_read_avid },
6883 { MKTAG('A','R','E','S'), mov_read_ares },
6884 { MKTAG('a','v','s','s'), mov_read_avss },
6885 { MKTAG('a','v','1','C'), mov_read_av1c },
6886 { MKTAG('c','h','p','l'), mov_read_chpl },
6887 { MKTAG('c','o','6','4'), mov_read_stco },
6888 { MKTAG('c','o','l','r'), mov_read_colr },
6889 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6890 { MKTAG('d','i','n','f'), mov_read_default },
6891 { MKTAG('D','p','x','E'), mov_read_dpxe },
6892 { MKTAG('d','r','e','f'), mov_read_dref },
6893 { MKTAG('e','d','t','s'), mov_read_default },
6894 { MKTAG('e','l','s','t'), mov_read_elst },
6895 { MKTAG('e','n','d','a'), mov_read_enda },
6896 { MKTAG('f','i','e','l'), mov_read_fiel },
6897 { MKTAG('a','d','r','m'), mov_read_adrm },
6898 { MKTAG('f','t','y','p'), mov_read_ftyp },
6899 { MKTAG('g','l','b','l'), mov_read_glbl },
6900 { MKTAG('h','d','l','r'), mov_read_hdlr },
6901 { MKTAG('i','l','s','t'), mov_read_ilst },
6902 { MKTAG('j','p','2','h'), mov_read_jp2h },
6903 { MKTAG('m','d','a','t'), mov_read_mdat },
6904 { MKTAG('m','d','h','d'), mov_read_mdhd },
6905 { MKTAG('m','d','i','a'), mov_read_default },
6906 { MKTAG('m','e','t','a'), mov_read_meta },
6907 { MKTAG('m','i','n','f'), mov_read_default },
6908 { MKTAG('m','o','o','f'), mov_read_moof },
6909 { MKTAG('m','o','o','v'), mov_read_moov },
6910 { MKTAG('m','v','e','x'), mov_read_default },
6911 { MKTAG('m','v','h','d'), mov_read_mvhd },
6912 { MKTAG('S','M','I',' '), mov_read_svq3 },
6913 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6914 { MKTAG('a','v','c','C'), mov_read_glbl },
6915 { MKTAG('p','a','s','p'), mov_read_pasp },
6916 { MKTAG('s','i','d','x'), mov_read_sidx },
6917 { MKTAG('s','t','b','l'), mov_read_default },
6918 { MKTAG('s','t','c','o'), mov_read_stco },
6919 { MKTAG('s','t','p','s'), mov_read_stps },
6920 { MKTAG('s','t','r','f'), mov_read_strf },
6921 { MKTAG('s','t','s','c'), mov_read_stsc },
6922 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6923 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6924 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6925 { MKTAG('s','t','t','s'), mov_read_stts },
6926 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6927 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
6928 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6929 { MKTAG('t','f','d','t'), mov_read_tfdt },
6930 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6931 { MKTAG('t','r','a','k'), mov_read_trak },
6932 { MKTAG('t','r','a','f'), mov_read_default },
6933 { MKTAG('t','r','e','f'), mov_read_default },
6934 { MKTAG('t','m','c','d'), mov_read_tmcd },
6935 { MKTAG('c','h','a','p'), mov_read_chap },
6936 { MKTAG('t','r','e','x'), mov_read_trex },
6937 { MKTAG('t','r','u','n'), mov_read_trun },
6938 { MKTAG('u','d','t','a'), mov_read_default },
6939 { MKTAG('w','a','v','e'), mov_read_wave },
6940 { MKTAG('e','s','d','s'), mov_read_esds },
6941 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6942 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6943 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6944 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6945 { MKTAG('w','f','e','x'), mov_read_wfex },
6946 { MKTAG('c','m','o','v'), mov_read_cmov },
6947 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6948 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6949 { MKTAG('s','b','g','p'), mov_read_sbgp },
6950 { MKTAG('h','v','c','C'), mov_read_glbl },
6951 { MKTAG('u','u','i','d'), mov_read_uuid },
6952 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6953 { MKTAG('f','r','e','e'), mov_read_free },
6954 { MKTAG('-','-','-','-'), mov_read_custom },
6955 { MKTAG('s','i','n','f'), mov_read_default },
6956 { MKTAG('f','r','m','a'), mov_read_frma },
6957 { MKTAG('s','e','n','c'), mov_read_senc },
6958 { MKTAG('s','a','i','z'), mov_read_saiz },
6959 { MKTAG('s','a','i','o'), mov_read_saio },
6960 { MKTAG('p','s','s','h'), mov_read_pssh },
6961 { MKTAG('s','c','h','m'), mov_read_schm },
6962 { MKTAG('s','c','h','i'), mov_read_default },
6963 { MKTAG('t','e','n','c'), mov_read_tenc },
6964 { MKTAG('d','f','L','a'), mov_read_dfla },
6965 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6966 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6967 { MKTAG('d','O','p','s'), mov_read_dops },
6968 { MKTAG('d','m','l','p'), mov_read_dmlp },
6969 { MKTAG('S','m','D','m'), mov_read_smdm },
6970 { MKTAG('C','o','L','L'), mov_read_coll },
6971 { MKTAG('v','p','c','C'), mov_read_vpcc },
6972 { MKTAG('m','d','c','v'), mov_read_mdcv },
6973 { MKTAG('c','l','l','i'), mov_read_clli },
6974 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
6975 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
6979 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6981 int64_t total_size = 0;
6985 if (c->atom_depth > 10) {
6986 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6987 return AVERROR_INVALIDDATA;
6992 atom.size = INT64_MAX;
6993 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6994 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
6997 if (atom.size >= 8) {
6998 a.size = avio_rb32(pb);
6999 a.type = avio_rl32(pb);
7000 if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
7001 a.type == MKTAG('h','o','o','v')) &&
7003 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
7006 type = avio_rl32(pb);
7009 avio_seek(pb, -8, SEEK_CUR);
7010 if (type == MKTAG('m','v','h','d') ||
7011 type == MKTAG('c','m','o','v')) {
7012 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
7013 a.type = MKTAG('m','o','o','v');
7016 if (atom.type != MKTAG('r','o','o','t') &&
7017 atom.type != MKTAG('m','o','o','v')) {
7018 if (a.type == MKTAG('t','r','a','k') ||
7019 a.type == MKTAG('m','d','a','t')) {
7020 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
7027 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
7028 a.size = avio_rb64(pb) - 8;
7032 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
7033 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
7035 a.size = atom.size - total_size + 8;
7040 a.size = FFMIN(a.size, atom.size - total_size);
7042 for (i = 0; mov_default_parse_table[i].type; i++)
7043 if (mov_default_parse_table[i].type == a.type) {
7044 parse = mov_default_parse_table[i].parse;
7048 // container is user data
7049 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
7050 atom.type == MKTAG('i','l','s','t')))
7051 parse = mov_read_udta_string;
7053 // Supports parsing the QuickTime Metadata Keys.
7054 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
7055 if (!parse && c->found_hdlr_mdta &&
7056 atom.type == MKTAG('m','e','t','a') &&
7057 a.type == MKTAG('k','e','y','s') &&
7058 c->meta_keys_count == 0) {
7059 parse = mov_read_keys;
7062 if (!parse) { /* skip leaf atoms data */
7063 avio_skip(pb, a.size);
7065 int64_t start_pos = avio_tell(pb);
7067 int err = parse(c, pb, a);
7072 if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
7073 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
7074 start_pos + a.size == avio_size(pb))) {
7075 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
7076 c->next_root_atom = start_pos + a.size;
7080 left = a.size - avio_tell(pb) + start_pos;
7081 if (left > 0) /* skip garbage at atom end */
7082 avio_skip(pb, left);
7083 else if (left < 0) {
7084 av_log(c->fc, AV_LOG_WARNING,
7085 "overread end of atom '%s' by %"PRId64" bytes\n",
7086 av_fourcc2str(a.type), -left);
7087 avio_seek(pb, left, SEEK_CUR);
7091 total_size += a.size;
7094 if (total_size < atom.size && atom.size < 0x7ffff)
7095 avio_skip(pb, atom.size - total_size);
7101 static int mov_probe(const AVProbeData *p)
7106 int moov_offset = -1;
7108 /* check file header */
7112 /* ignore invalid offset */
7113 if ((offset + 8) > (unsigned int)p->buf_size)
7115 size = AV_RB32(p->buf + offset);
7116 tag = AV_RL32(p->buf + offset + 4);
7118 /* check for obvious tags */
7119 case MKTAG('m','o','o','v'):
7120 moov_offset = offset + 4;
7121 case MKTAG('m','d','a','t'):
7122 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
7123 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
7124 case MKTAG('f','t','y','p'):
7127 offset + 12 > (unsigned int)p->buf_size ||
7128 AV_RB64(p->buf+offset + 8) == 0)) {
7129 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7130 } else if (tag == MKTAG('f','t','y','p') &&
7131 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
7132 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
7134 score = FFMAX(score, 5);
7136 score = AVPROBE_SCORE_MAX;
7138 offset = FFMAX(4, size) + offset;
7140 /* those are more common words, so rate then a bit less */
7141 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
7142 case MKTAG('w','i','d','e'):
7143 case MKTAG('f','r','e','e'):
7144 case MKTAG('j','u','n','k'):
7145 case MKTAG('p','i','c','t'):
7146 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
7147 offset = FFMAX(4, size) + offset;
7149 case MKTAG(0x82,0x82,0x7f,0x7d):
7150 case MKTAG('s','k','i','p'):
7151 case MKTAG('u','u','i','d'):
7152 case MKTAG('p','r','f','l'):
7153 /* if we only find those cause probedata is too small at least rate them */
7154 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7155 offset = FFMAX(4, size) + offset;
7158 offset = FFMAX(4, size) + offset;
7161 if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
7162 /* moov atom in the header - we should make sure that this is not a
7163 * MOV-packed MPEG-PS */
7164 offset = moov_offset;
7166 while (offset < (p->buf_size - 16)) { /* Sufficient space */
7167 /* We found an actual hdlr atom */
7168 if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7169 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7170 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
7171 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7172 /* We found a media handler reference atom describing an
7173 * MPEG-PS-in-MOV, return a
7174 * low score to force expanding the probe window until
7175 * mpegps_probe finds what it needs */
7187 // must be done after parsing all trak because there's no order requirement
7188 static void mov_read_chapters(AVFormatContext *s)
7190 MOVContext *mov = s->priv_data;
7192 MOVStreamContext *sc;
7197 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7198 chapter_track = mov->chapter_tracks[j];
7200 for (i = 0; i < s->nb_streams; i++)
7201 if (s->streams[i]->id == chapter_track) {
7206 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7211 cur_pos = avio_tell(sc->pb);
7213 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7214 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7215 if (st->internal->nb_index_entries) {
7216 // Retrieve the first frame, if possible
7217 AVIndexEntry *sample = &st->internal->index_entries[0];
7218 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7219 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7223 if (av_get_packet(sc->pb, &st->attached_pic, sample->size) < 0)
7226 st->attached_pic.stream_index = st->index;
7227 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
7230 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7231 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7232 st->discard = AVDISCARD_ALL;
7233 for (i = 0; i < st->internal->nb_index_entries; i++) {
7234 AVIndexEntry *sample = &st->internal->index_entries[i];
7235 int64_t end = i+1 < st->internal->nb_index_entries ? st->internal->index_entries[i+1].timestamp : st->duration;
7240 if (end < sample->timestamp) {
7241 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7242 end = AV_NOPTS_VALUE;
7245 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7246 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7250 // the first two bytes are the length of the title
7251 len = avio_rb16(sc->pb);
7252 if (len > sample->size-2)
7254 title_len = 2*len + 1;
7255 if (!(title = av_mallocz(title_len)))
7258 // The samples could theoretically be in any encoding if there's an encd
7259 // atom following, but in practice are only utf-8 or utf-16, distinguished
7260 // instead by the presence of a BOM
7264 ch = avio_rb16(sc->pb);
7266 avio_get_str16be(sc->pb, len, title, title_len);
7267 else if (ch == 0xfffe)
7268 avio_get_str16le(sc->pb, len, title, title_len);
7271 if (len == 1 || len == 2)
7274 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7278 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7283 avio_seek(sc->pb, cur_pos, SEEK_SET);
7287 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7288 uint32_t value, int flags)
7291 char buf[AV_TIMECODE_STR_SIZE];
7292 AVRational rate = st->avg_frame_rate;
7293 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7296 av_dict_set(&st->metadata, "timecode",
7297 av_timecode_make_string(&tc, buf, value), 0);
7301 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7303 MOVStreamContext *sc = st->priv_data;
7304 char buf[AV_TIMECODE_STR_SIZE];
7305 int64_t cur_pos = avio_tell(sc->pb);
7306 int hh, mm, ss, ff, drop;
7308 if (!st->internal->nb_index_entries)
7311 avio_seek(sc->pb, st->internal->index_entries->pos, SEEK_SET);
7312 avio_skip(s->pb, 13);
7313 hh = avio_r8(s->pb);
7314 mm = avio_r8(s->pb);
7315 ss = avio_r8(s->pb);
7316 drop = avio_r8(s->pb);
7317 ff = avio_r8(s->pb);
7318 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7319 hh, mm, ss, drop ? ';' : ':', ff);
7320 av_dict_set(&st->metadata, "timecode", buf, 0);
7322 avio_seek(sc->pb, cur_pos, SEEK_SET);
7326 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7328 MOVStreamContext *sc = st->priv_data;
7330 int64_t cur_pos = avio_tell(sc->pb);
7333 if (!st->internal->nb_index_entries)
7336 avio_seek(sc->pb, st->internal->index_entries->pos, SEEK_SET);
7337 value = avio_rb32(s->pb);
7339 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7340 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7341 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7343 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7344 * not the case) and thus assume "frame number format" instead of QT one.
7345 * No sample with tmcd track can be found with a QT timecode at the moment,
7346 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7348 parse_timecode_in_framenum_format(s, st, value, flags);
7350 avio_seek(sc->pb, cur_pos, SEEK_SET);
7354 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7356 if (!index || !*index) return;
7357 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7358 av_encryption_info_free((*index)->encrypted_samples[i]);
7360 av_freep(&(*index)->encrypted_samples);
7361 av_freep(&(*index)->auxiliary_info_sizes);
7362 av_freep(&(*index)->auxiliary_offsets);
7366 static int mov_read_close(AVFormatContext *s)
7368 MOVContext *mov = s->priv_data;
7371 for (i = 0; i < s->nb_streams; i++) {
7372 AVStream *st = s->streams[i];
7373 MOVStreamContext *sc = st->priv_data;
7378 av_freep(&sc->ctts_data);
7379 for (j = 0; j < sc->drefs_count; j++) {
7380 av_freep(&sc->drefs[j].path);
7381 av_freep(&sc->drefs[j].dir);
7383 av_freep(&sc->drefs);
7385 sc->drefs_count = 0;
7387 if (!sc->pb_is_copied)
7388 ff_format_io_close(s, &sc->pb);
7391 av_freep(&sc->chunk_offsets);
7392 av_freep(&sc->stsc_data);
7393 av_freep(&sc->sample_sizes);
7394 av_freep(&sc->keyframes);
7395 av_freep(&sc->stts_data);
7396 av_freep(&sc->sdtp_data);
7397 av_freep(&sc->stps_data);
7398 av_freep(&sc->elst_data);
7399 av_freep(&sc->rap_group);
7400 av_freep(&sc->display_matrix);
7401 av_freep(&sc->index_ranges);
7404 for (j = 0; j < sc->stsd_count; j++)
7405 av_free(sc->extradata[j]);
7406 av_freep(&sc->extradata);
7407 av_freep(&sc->extradata_size);
7409 mov_free_encryption_index(&sc->cenc.encryption_index);
7410 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7411 av_aes_ctr_free(sc->cenc.aes_ctr);
7413 av_freep(&sc->stereo3d);
7414 av_freep(&sc->spherical);
7415 av_freep(&sc->mastering);
7416 av_freep(&sc->coll);
7419 av_freep(&mov->dv_demux);
7420 avformat_free_context(mov->dv_fctx);
7421 mov->dv_fctx = NULL;
7423 if (mov->meta_keys) {
7424 for (i = 1; i < mov->meta_keys_count; i++) {
7425 av_freep(&mov->meta_keys[i]);
7427 av_freep(&mov->meta_keys);
7430 av_freep(&mov->trex_data);
7431 av_freep(&mov->bitrates);
7433 for (i = 0; i < mov->frag_index.nb_items; i++) {
7434 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7435 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7436 mov_free_encryption_index(&frag[j].encryption_index);
7438 av_freep(&mov->frag_index.item[i].stream_info);
7440 av_freep(&mov->frag_index.item);
7442 av_freep(&mov->aes_decrypt);
7443 av_freep(&mov->chapter_tracks);
7448 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7452 for (i = 0; i < s->nb_streams; i++) {
7453 AVStream *st = s->streams[i];
7454 MOVStreamContext *sc = st->priv_data;
7456 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7457 sc->timecode_track == tmcd_id)
7463 /* look for a tmcd track not referenced by any video track, and export it globally */
7464 static void export_orphan_timecode(AVFormatContext *s)
7468 for (i = 0; i < s->nb_streams; i++) {
7469 AVStream *st = s->streams[i];
7471 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7472 !tmcd_is_referenced(s, i + 1)) {
7473 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7475 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7482 static int read_tfra(MOVContext *mov, AVIOContext *f)
7484 int version, fieldlength, i, j;
7485 int64_t pos = avio_tell(f);
7486 uint32_t size = avio_rb32(f);
7487 unsigned track_id, item_count;
7489 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7492 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7494 version = avio_r8(f);
7496 track_id = avio_rb32(f);
7497 fieldlength = avio_rb32(f);
7498 item_count = avio_rb32(f);
7499 for (i = 0; i < item_count; i++) {
7500 int64_t time, offset;
7502 MOVFragmentStreamInfo * frag_stream_info;
7505 return AVERROR_INVALIDDATA;
7509 time = avio_rb64(f);
7510 offset = avio_rb64(f);
7512 time = avio_rb32(f);
7513 offset = avio_rb32(f);
7516 // The first sample of each stream in a fragment is always a random
7517 // access sample. So it's entry in the tfra can be used as the
7518 // initial PTS of the fragment.
7519 index = update_frag_index(mov, offset);
7520 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7521 if (frag_stream_info &&
7522 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7523 frag_stream_info->first_tfra_pts = time;
7525 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7527 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7529 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7533 avio_seek(f, pos + size, SEEK_SET);
7537 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7539 int64_t stream_size = avio_size(f);
7540 int64_t original_pos = avio_tell(f);
7543 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7547 c->mfra_size = avio_rb32(f);
7548 c->have_read_mfra_size = 1;
7549 if (!c->mfra_size || c->mfra_size > stream_size) {
7550 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7553 if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
7557 if (avio_rb32(f) != c->mfra_size) {
7558 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7561 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7562 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7565 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7567 ret = read_tfra(c, f);
7572 c->frag_index.complete = 1;
7574 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7576 av_log(c->fc, AV_LOG_ERROR,
7577 "failed to seek back after looking for mfra\n");
7583 static int mov_read_header(AVFormatContext *s)
7585 MOVContext *mov = s->priv_data;
7586 AVIOContext *pb = s->pb;
7588 MOVAtom atom = { AV_RL32("root") };
7591 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7592 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7593 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7594 return AVERROR(EINVAL);
7598 mov->trak_index = -1;
7599 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7600 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7601 atom.size = avio_size(pb);
7603 atom.size = INT64_MAX;
7605 /* check MOV header */
7607 if (mov->moov_retry)
7608 avio_seek(pb, 0, SEEK_SET);
7609 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7610 av_log(s, AV_LOG_ERROR, "error reading header\n");
7613 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7614 if (!mov->found_moov) {
7615 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7616 err = AVERROR_INVALIDDATA;
7619 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7621 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7622 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7623 mov_read_chapters(s);
7624 for (i = 0; i < s->nb_streams; i++)
7625 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7626 mov_read_timecode_track(s, s->streams[i]);
7627 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7628 mov_read_rtmd_track(s, s->streams[i]);
7632 /* copy timecode metadata from tmcd tracks to the related video streams */
7633 for (i = 0; i < s->nb_streams; i++) {
7634 AVStream *st = s->streams[i];
7635 MOVStreamContext *sc = st->priv_data;
7636 if (sc->timecode_track > 0) {
7637 AVDictionaryEntry *tcr;
7638 int tmcd_st_id = -1;
7640 for (j = 0; j < s->nb_streams; j++)
7641 if (s->streams[j]->id == sc->timecode_track)
7644 if (tmcd_st_id < 0 || tmcd_st_id == i)
7646 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7648 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7651 export_orphan_timecode(s);
7653 for (i = 0; i < s->nb_streams; i++) {
7654 AVStream *st = s->streams[i];
7655 MOVStreamContext *sc = st->priv_data;
7656 fix_timescale(mov, sc);
7657 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
7658 st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7659 st->internal->skip_samples = sc->start_pad;
7661 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7662 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7663 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7664 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7665 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7666 st->codecpar->width = sc->width;
7667 st->codecpar->height = sc->height;
7669 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7670 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7674 if (mov->handbrake_version &&
7675 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7676 st->codecpar->codec_id == AV_CODEC_ID_MP3) {
7677 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7678 st->need_parsing = AVSTREAM_PARSE_FULL;
7682 if (mov->trex_data) {
7683 for (i = 0; i < s->nb_streams; i++) {
7684 AVStream *st = s->streams[i];
7685 MOVStreamContext *sc = st->priv_data;
7686 if (st->duration > 0) {
7687 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7688 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7689 sc->data_size, sc->time_scale);
7690 err = AVERROR_INVALIDDATA;
7693 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7698 if (mov->use_mfra_for > 0) {
7699 for (i = 0; i < s->nb_streams; i++) {
7700 AVStream *st = s->streams[i];
7701 MOVStreamContext *sc = st->priv_data;
7702 if (sc->duration_for_fps > 0) {
7703 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7704 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7705 sc->data_size, sc->time_scale);
7706 err = AVERROR_INVALIDDATA;
7709 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7710 sc->duration_for_fps;
7715 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7716 if (mov->bitrates[i]) {
7717 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7721 ff_rfps_calculate(s);
7723 for (i = 0; i < s->nb_streams; i++) {
7724 AVStream *st = s->streams[i];
7725 MOVStreamContext *sc = st->priv_data;
7727 switch (st->codecpar->codec_type) {
7728 case AVMEDIA_TYPE_AUDIO:
7729 err = ff_replaygain_export(st, s->metadata);
7733 case AVMEDIA_TYPE_VIDEO:
7734 if (sc->display_matrix) {
7735 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7736 sizeof(int32_t) * 9);
7740 sc->display_matrix = NULL;
7743 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7744 (uint8_t *)sc->stereo3d,
7745 sizeof(*sc->stereo3d));
7749 sc->stereo3d = NULL;
7751 if (sc->spherical) {
7752 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7753 (uint8_t *)sc->spherical,
7754 sc->spherical_size);
7758 sc->spherical = NULL;
7760 if (sc->mastering) {
7761 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7762 (uint8_t *)sc->mastering,
7763 sizeof(*sc->mastering));
7767 sc->mastering = NULL;
7770 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7771 (uint8_t *)sc->coll,
7781 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7783 for (i = 0; i < mov->frag_index.nb_items; i++)
7784 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7785 mov->frag_index.item[i].headers_read = 1;
7793 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7795 AVIndexEntry *sample = NULL;
7796 int64_t best_dts = INT64_MAX;
7798 for (i = 0; i < s->nb_streams; i++) {
7799 AVStream *avst = s->streams[i];
7800 MOVStreamContext *msc = avst->priv_data;
7801 if (msc->pb && msc->current_sample < avst->internal->nb_index_entries) {
7802 AVIndexEntry *current_sample = &avst->internal->index_entries[msc->current_sample];
7803 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7804 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7805 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7806 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7807 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
7808 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7809 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7810 sample = current_sample;
7819 static int should_retry(AVIOContext *pb, int error_code) {
7820 if (error_code == AVERROR_EOF || avio_feof(pb))
7826 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7829 MOVContext *mov = s->priv_data;
7831 if (index >= 0 && index < mov->frag_index.nb_items)
7832 target = mov->frag_index.item[index].moof_offset;
7833 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7834 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7835 return AVERROR_INVALIDDATA;
7838 mov->next_root_atom = 0;
7839 if (index < 0 || index >= mov->frag_index.nb_items)
7840 index = search_frag_moof_offset(&mov->frag_index, target);
7841 if (index < mov->frag_index.nb_items &&
7842 mov->frag_index.item[index].moof_offset == target) {
7843 if (index + 1 < mov->frag_index.nb_items)
7844 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7845 if (mov->frag_index.item[index].headers_read)
7847 mov->frag_index.item[index].headers_read = 1;
7850 mov->found_mdat = 0;
7852 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7855 if (avio_feof(s->pb))
7857 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7862 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7864 uint8_t *side, *extradata;
7867 /* Save the current index. */
7868 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7870 /* Notify the decoder that extradata changed. */
7871 extradata_size = sc->extradata_size[sc->last_stsd_index];
7872 extradata = sc->extradata[sc->last_stsd_index];
7873 if (extradata_size > 0 && extradata) {
7874 side = av_packet_new_side_data(pkt,
7875 AV_PKT_DATA_NEW_EXTRADATA,
7878 return AVERROR(ENOMEM);
7879 memcpy(side, extradata, extradata_size);
7885 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int size)
7890 return AVERROR_INVALIDDATA;
7891 new_size = ((size - 8) / 2) * 3;
7892 ret = av_new_packet(pkt, new_size);
7897 for (int j = 0; j < new_size; j += 3) {
7898 pkt->data[j] = 0xFC;
7899 pkt->data[j+1] = avio_r8(pb);
7900 pkt->data[j+2] = avio_r8(pb);
7906 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7908 MOVContext *mov = s->priv_data;
7909 MOVStreamContext *sc;
7910 AVIndexEntry *sample;
7911 AVStream *st = NULL;
7912 int64_t current_index;
7916 sample = mov_find_next_sample(s, &st);
7917 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7918 if (!mov->next_root_atom)
7920 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7925 /* must be done just before reading, to avoid infinite loop on sample */
7926 current_index = sc->current_index;
7927 mov_current_sample_inc(sc);
7929 if (mov->next_root_atom) {
7930 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7931 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7934 if (st->discard != AVDISCARD_ALL) {
7935 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7936 if (ret64 != sample->pos) {
7937 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7938 sc->ffindex, sample->pos);
7939 if (should_retry(sc->pb, ret64)) {
7940 mov_current_sample_dec(sc);
7942 return AVERROR_INVALIDDATA;
7945 if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
7946 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7950 if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
7951 ret = get_eia608_packet(sc->pb, pkt, sample->size);
7953 ret = av_get_packet(sc->pb, pkt, sample->size);
7955 if (should_retry(sc->pb, ret)) {
7956 mov_current_sample_dec(sc);
7960 #if CONFIG_DV_DEMUXER
7961 if (mov->dv_demux && sc->dv_audio_container) {
7962 AVBufferRef *buf = pkt->buf;
7963 ret = avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7965 av_packet_unref(pkt);
7968 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7973 if (sc->has_palette) {
7976 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7978 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7980 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7981 sc->has_palette = 0;
7984 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7985 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7986 st->need_parsing = AVSTREAM_PARSE_FULL;
7990 pkt->stream_index = sc->ffindex;
7991 pkt->dts = sample->timestamp;
7992 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7993 pkt->flags |= AV_PKT_FLAG_DISCARD;
7995 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7996 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
7997 /* update ctts context */
7999 if (sc->ctts_index < sc->ctts_count &&
8000 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
8002 sc->ctts_sample = 0;
8005 int64_t next_dts = (sc->current_sample < st->internal->nb_index_entries) ?
8006 st->internal->index_entries[sc->current_sample].timestamp : st->duration;
8008 if (next_dts >= pkt->dts)
8009 pkt->duration = next_dts - pkt->dts;
8010 pkt->pts = pkt->dts;
8012 if (st->discard == AVDISCARD_ALL)
8014 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
8015 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
8016 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
8017 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
8019 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
8020 pkt->pos = sample->pos;
8022 /* Multiple stsd handling. */
8023 if (sc->stsc_data) {
8024 /* Keep track of the stsc index for the given sample, then check
8025 * if the stsd index is different from the last used one. */
8027 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
8028 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
8030 sc->stsc_sample = 0;
8031 /* Do not check indexes after a switch. */
8032 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
8033 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
8034 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
8035 ret = mov_change_extradata(sc, pkt);
8042 aax_filter(pkt->data, pkt->size, mov);
8044 ret = cenc_filter(mov, st, sc, pkt, current_index);
8052 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
8054 MOVContext *mov = s->priv_data;
8057 if (!mov->frag_index.complete)
8060 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
8063 if (!mov->frag_index.item[index].headers_read)
8064 return mov_switch_root(s, -1, index);
8065 if (index + 1 < mov->frag_index.nb_items)
8066 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
8071 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
8073 MOVStreamContext *sc = st->priv_data;
8074 int sample, time_sample, ret;
8077 // Here we consider timestamp to be PTS, hence try to offset it so that we
8078 // can search over the DTS timeline.
8079 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
8081 ret = mov_seek_fragment(s, st, timestamp);
8085 sample = av_index_search_timestamp(st, timestamp, flags);
8086 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
8087 if (sample < 0 && st->internal->nb_index_entries && timestamp < st->internal->index_entries[0].timestamp)
8089 if (sample < 0) /* not sure what to do */
8090 return AVERROR_INVALIDDATA;
8091 mov_current_sample_set(sc, sample);
8092 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
8093 /* adjust ctts index */
8094 if (sc->ctts_data) {
8096 for (i = 0; i < sc->ctts_count; i++) {
8097 int next = time_sample + sc->ctts_data[i].count;
8098 if (next > sc->current_sample) {
8100 sc->ctts_sample = sc->current_sample - time_sample;
8107 /* adjust stsd index */
8108 if (sc->chunk_count) {
8110 for (i = 0; i < sc->stsc_count; i++) {
8111 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
8112 if (next > sc->current_sample) {
8114 sc->stsc_sample = sc->current_sample - time_sample;
8117 av_assert0(next == (int)next);
8125 static int64_t mov_get_skip_samples(AVStream *st, int sample)
8127 MOVStreamContext *sc = st->priv_data;
8128 int64_t first_ts = st->internal->index_entries[0].timestamp;
8129 int64_t ts = st->internal->index_entries[sample].timestamp;
8132 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO)
8135 /* compute skip samples according to stream start_pad, seek ts and first ts */
8136 off = av_rescale_q(ts - first_ts, st->time_base,
8137 (AVRational){1, st->codecpar->sample_rate});
8138 return FFMAX(sc->start_pad - off, 0);
8141 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
8143 MOVContext *mc = s->priv_data;
8148 if (stream_index >= s->nb_streams)
8149 return AVERROR_INVALIDDATA;
8151 st = s->streams[stream_index];
8152 sample = mov_seek_stream(s, st, sample_time, flags);
8156 if (mc->seek_individually) {
8157 /* adjust seek timestamp to found sample timestamp */
8158 int64_t seek_timestamp = st->internal->index_entries[sample].timestamp;
8159 st->internal->skip_samples = mov_get_skip_samples(st, sample);
8161 for (i = 0; i < s->nb_streams; i++) {
8165 if (stream_index == i)
8168 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
8169 sample = mov_seek_stream(s, st, timestamp, flags);
8171 st->internal->skip_samples = mov_get_skip_samples(st, sample);
8174 for (i = 0; i < s->nb_streams; i++) {
8175 MOVStreamContext *sc;
8178 mov_current_sample_set(sc, 0);
8181 MOVStreamContext *sc;
8182 AVIndexEntry *entry = mov_find_next_sample(s, &st);
8184 return AVERROR_INVALIDDATA;
8186 if (sc->ffindex == stream_index && sc->current_sample == sample)
8188 mov_current_sample_inc(sc);
8194 #define OFFSET(x) offsetof(MOVContext, x)
8195 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
8196 static const AVOption mov_options[] = {
8197 {"use_absolute_path",
8198 "allow using absolute path when opening alias, this is a possible security issue",
8199 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
8201 {"seek_streams_individually",
8202 "Seek each stream individually to the closest point",
8203 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
8205 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
8207 {"advanced_editlist",
8208 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
8209 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
8211 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8214 "use mfra for fragment timestamps",
8215 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8216 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8218 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8219 FLAGS, "use_mfra_for" },
8220 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8221 FLAGS, "use_mfra_for" },
8222 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8223 FLAGS, "use_mfra_for" },
8224 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8225 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8226 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8227 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8228 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8229 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8230 { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
8231 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8232 { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
8233 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8234 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8235 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8236 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8237 .flags = AV_OPT_FLAG_DECODING_PARAM },
8238 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8239 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8240 {.i64 = 0}, 0, 1, FLAGS },
8245 static const AVClass mov_class = {
8246 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8247 .item_name = av_default_item_name,
8248 .option = mov_options,
8249 .version = LIBAVUTIL_VERSION_INT,
8252 AVInputFormat ff_mov_demuxer = {
8253 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8254 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8255 .priv_class = &mov_class,
8256 .priv_data_size = sizeof(MOVContext),
8257 .extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
8258 .read_probe = mov_probe,
8259 .read_header = mov_read_header,
8260 .read_packet = mov_read_packet,
8261 .read_close = mov_read_close,
8262 .read_seek = mov_read_seek,
8263 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,