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;
593 sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
595 return AVERROR(ENOMEM);
596 sc->drefs_count = entries;
598 for (i = 0; i < entries; i++) {
599 MOVDref *dref = &sc->drefs[i];
600 uint32_t size = avio_rb32(pb);
601 int64_t next = avio_tell(pb) + size - 4;
604 return AVERROR_INVALIDDATA;
606 dref->type = avio_rl32(pb);
607 avio_rb32(pb); // version + flags
609 if (dref->type == MKTAG('a','l','i','s') && size > 150) {
610 /* macintosh alias record */
611 uint16_t volume_len, len;
617 volume_len = avio_r8(pb);
618 volume_len = FFMIN(volume_len, 27);
619 ret = ffio_read_size(pb, dref->volume, 27);
622 dref->volume[volume_len] = 0;
623 av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
628 len = FFMIN(len, 63);
629 ret = ffio_read_size(pb, dref->filename, 63);
632 dref->filename[len] = 0;
633 av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
637 /* read next level up_from_alias/down_to_target */
638 dref->nlvl_from = avio_rb16(pb);
639 dref->nlvl_to = avio_rb16(pb);
640 av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
641 dref->nlvl_from, dref->nlvl_to);
645 for (type = 0; type != -1 && avio_tell(pb) < next; ) {
648 type = avio_rb16(pb);
650 av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
653 if (type == 2) { // absolute path
655 dref->path = av_mallocz(len+1);
657 return AVERROR(ENOMEM);
659 ret = ffio_read_size(pb, dref->path, len);
661 av_freep(&dref->path);
664 if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
666 memmove(dref->path, dref->path+volume_len, len);
669 // trim string of any ending zeros
670 for (j = len - 1; j >= 0; j--) {
671 if (dref->path[j] == 0)
676 for (j = 0; j < len; j++)
677 if (dref->path[j] == ':' || dref->path[j] == 0)
679 av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
680 } else if (type == 0) { // directory name
682 dref->dir = av_malloc(len+1);
684 return AVERROR(ENOMEM);
686 ret = ffio_read_size(pb, dref->dir, len);
688 av_freep(&dref->dir);
692 for (j = 0; j < len; j++)
693 if (dref->dir[j] == ':')
695 av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
700 av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
705 avio_seek(pb, next, SEEK_SET);
710 static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
719 avio_r8(pb); /* version */
720 avio_rb24(pb); /* flags */
723 ctype = avio_rl32(pb);
724 type = avio_rl32(pb); /* component subtype */
726 av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
727 av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
729 if (c->trak_index < 0) { // meta not inside a trak
730 if (type == MKTAG('m','d','t','a')) {
731 c->found_hdlr_mdta = 1;
736 st = c->fc->streams[c->fc->nb_streams-1];
738 if (type == MKTAG('v','i','d','e'))
739 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
740 else if (type == MKTAG('s','o','u','n'))
741 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
742 else if (type == MKTAG('m','1','a',' '))
743 st->codecpar->codec_id = AV_CODEC_ID_MP2;
744 else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
745 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
747 avio_rb32(pb); /* component manufacture */
748 avio_rb32(pb); /* component flags */
749 avio_rb32(pb); /* component flags mask */
751 title_size = atom.size - 24;
752 if (title_size > 0) {
753 if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
754 return AVERROR_INVALIDDATA;
755 title_str = av_malloc(title_size + 1); /* Add null terminator */
757 return AVERROR(ENOMEM);
759 ret = ffio_read_size(pb, title_str, title_size);
761 av_freep(&title_str);
764 title_str[title_size] = 0;
766 int off = (!c->isom && title_str[0] == title_size - 1);
767 // flag added so as to not set stream handler name if already set from mdia->hdlr
768 av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
770 av_freep(&title_str);
776 static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
778 return ff_mov_read_esds(c->fc, pb);
781 static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
784 enum AVAudioServiceType *ast;
785 int ac3info, acmod, lfeon, bsmod;
787 if (c->fc->nb_streams < 1)
789 st = c->fc->streams[c->fc->nb_streams-1];
791 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
794 return AVERROR(ENOMEM);
796 ac3info = avio_rb24(pb);
797 bsmod = (ac3info >> 14) & 0x7;
798 acmod = (ac3info >> 11) & 0x7;
799 lfeon = (ac3info >> 10) & 0x1;
800 st->codecpar->channels = ((int[]){2,1,2,3,3,4,4,5})[acmod] + lfeon;
801 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
803 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
805 if (st->codecpar->channels > 1 && bsmod == 0x7)
806 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
808 #if FF_API_LAVF_AVCTX
809 FF_DISABLE_DEPRECATION_WARNINGS
810 st->codec->audio_service_type = *ast;
811 FF_ENABLE_DEPRECATION_WARNINGS
817 static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
820 enum AVAudioServiceType *ast;
821 int eac3info, acmod, lfeon, bsmod;
823 if (c->fc->nb_streams < 1)
825 st = c->fc->streams[c->fc->nb_streams-1];
827 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
830 return AVERROR(ENOMEM);
832 /* No need to parse fields for additional independent substreams and its
833 * associated dependent substreams since libavcodec's E-AC-3 decoder
834 * does not support them yet. */
835 avio_rb16(pb); /* data_rate and num_ind_sub */
836 eac3info = avio_rb24(pb);
837 bsmod = (eac3info >> 12) & 0x1f;
838 acmod = (eac3info >> 9) & 0x7;
839 lfeon = (eac3info >> 8) & 0x1;
840 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
842 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
843 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
845 if (st->codecpar->channels > 1 && bsmod == 0x7)
846 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
848 #if FF_API_LAVF_AVCTX
849 FF_DISABLE_DEPRECATION_WARNINGS
850 st->codec->audio_service_type = *ast;
851 FF_ENABLE_DEPRECATION_WARNINGS
857 static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
860 uint8_t buf[DDTS_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
862 uint32_t frame_duration_code = 0;
863 uint32_t channel_layout_code = 0;
867 if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
870 init_get_bits(&gb, buf, 8 * DDTS_SIZE);
872 if (c->fc->nb_streams < 1) {
875 st = c->fc->streams[c->fc->nb_streams-1];
877 st->codecpar->sample_rate = get_bits_long(&gb, 32);
878 if (st->codecpar->sample_rate <= 0) {
879 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
880 return AVERROR_INVALIDDATA;
882 skip_bits_long(&gb, 32); /* max bitrate */
883 st->codecpar->bit_rate = get_bits_long(&gb, 32);
884 st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
885 frame_duration_code = get_bits(&gb, 2);
886 skip_bits(&gb, 30); /* various fields */
887 channel_layout_code = get_bits(&gb, 16);
889 st->codecpar->frame_size =
890 (frame_duration_code == 0) ? 512 :
891 (frame_duration_code == 1) ? 1024 :
892 (frame_duration_code == 2) ? 2048 :
893 (frame_duration_code == 3) ? 4096 : 0;
895 if (channel_layout_code > 0xff) {
896 av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout\n");
898 st->codecpar->channel_layout =
899 ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
900 ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
901 ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
902 ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
903 ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
904 ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0);
906 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
911 static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
915 if (c->fc->nb_streams < 1)
917 st = c->fc->streams[c->fc->nb_streams-1];
922 /* skip version and flags */
925 ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
930 static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
935 if (c->fc->nb_streams < 1)
937 st = c->fc->streams[c->fc->nb_streams-1];
939 if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
940 av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
945 static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
947 const int num = avio_rb32(pb);
948 const int den = avio_rb32(pb);
951 if (c->fc->nb_streams < 1)
953 st = c->fc->streams[c->fc->nb_streams-1];
955 if ((st->sample_aspect_ratio.den != 1 || st->sample_aspect_ratio.num) && // default
956 (den != st->sample_aspect_ratio.den || num != st->sample_aspect_ratio.num)) {
957 av_log(c->fc, AV_LOG_WARNING,
958 "sample aspect ratio already set to %d:%d, ignoring 'pasp' atom (%d:%d)\n",
959 st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
961 } else if (den != 0) {
962 av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den,
968 /* this atom contains actual media data */
969 static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
971 if (atom.size == 0) /* wrong one (MP4) */
974 return 0; /* now go for moov */
977 #define DRM_BLOB_SIZE 56
979 static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
981 uint8_t intermediate_key[20];
982 uint8_t intermediate_iv[20];
985 uint8_t file_checksum[20];
986 uint8_t calculated_checksum[20];
990 uint8_t *activation_bytes = c->activation_bytes;
991 uint8_t *fixed_key = c->audible_fixed_key;
995 sha = av_sha_alloc();
997 return AVERROR(ENOMEM);
998 av_free(c->aes_decrypt);
999 c->aes_decrypt = av_aes_alloc();
1000 if (!c->aes_decrypt) {
1001 ret = AVERROR(ENOMEM);
1005 /* drm blob processing */
1006 avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1007 avio_read(pb, input, DRM_BLOB_SIZE);
1008 avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1009 avio_read(pb, file_checksum, 20);
1011 av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == "); // required by external tools
1012 for (i = 0; i < 20; i++)
1013 av_log(c->fc, AV_LOG_INFO, "%02x", file_checksum[i]);
1014 av_log(c->fc, AV_LOG_INFO, "\n");
1016 /* verify activation data */
1017 if (!activation_bytes) {
1018 av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1019 ret = 0; /* allow ffprobe to continue working on .aax files */
1022 if (c->activation_bytes_size != 4) {
1023 av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1024 ret = AVERROR(EINVAL);
1028 /* verify fixed key */
1029 if (c->audible_fixed_key_size != 16) {
1030 av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1031 ret = AVERROR(EINVAL);
1035 /* AAX (and AAX+) key derivation */
1036 av_sha_init(sha, 160);
1037 av_sha_update(sha, fixed_key, 16);
1038 av_sha_update(sha, activation_bytes, 4);
1039 av_sha_final(sha, intermediate_key);
1040 av_sha_init(sha, 160);
1041 av_sha_update(sha, fixed_key, 16);
1042 av_sha_update(sha, intermediate_key, 20);
1043 av_sha_update(sha, activation_bytes, 4);
1044 av_sha_final(sha, intermediate_iv);
1045 av_sha_init(sha, 160);
1046 av_sha_update(sha, intermediate_key, 16);
1047 av_sha_update(sha, intermediate_iv, 16);
1048 av_sha_final(sha, calculated_checksum);
1049 if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1050 av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1051 ret = AVERROR_INVALIDDATA;
1054 av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1055 av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1056 for (i = 0; i < 4; i++) {
1057 // file data (in output) is stored in big-endian mode
1058 if (activation_bytes[i] != output[3 - i]) { // critical error
1059 av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1060 ret = AVERROR_INVALIDDATA;
1064 memcpy(c->file_key, output + 8, 16);
1065 memcpy(input, output + 26, 16);
1066 av_sha_init(sha, 160);
1067 av_sha_update(sha, input, 16);
1068 av_sha_update(sha, c->file_key, 16);
1069 av_sha_update(sha, fixed_key, 16);
1070 av_sha_final(sha, c->file_iv);
1078 static int mov_aaxc_crypto(MOVContext *c)
1080 if (c->audible_key_size != 16) {
1081 av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
1082 return AVERROR(EINVAL);
1085 if (c->audible_iv_size != 16) {
1086 av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
1087 return AVERROR(EINVAL);
1090 c->aes_decrypt = av_aes_alloc();
1091 if (!c->aes_decrypt) {
1092 return AVERROR(ENOMEM);
1095 memcpy(c->file_key, c->audible_key, 16);
1096 memcpy(c->file_iv, c->audible_iv, 16);
1102 // Audible AAX (and AAX+) bytestream decryption
1103 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1106 unsigned char iv[16];
1108 memcpy(iv, c->file_iv, 16); // iv is overwritten
1109 blocks = size >> 4; // trailing bytes are not encrypted!
1110 av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1111 av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1116 /* read major brand, minor version and compatible brands and store them as metadata */
1117 static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1120 int comp_brand_size;
1121 char* comp_brands_str;
1122 uint8_t type[5] = {0};
1123 int ret = ffio_read_size(pb, type, 4);
1127 if (strcmp(type, "qt "))
1129 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1130 av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1131 minor_ver = avio_rb32(pb); /* minor version */
1132 av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1134 comp_brand_size = atom.size - 8;
1135 if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1136 return AVERROR_INVALIDDATA;
1137 comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1138 if (!comp_brands_str)
1139 return AVERROR(ENOMEM);
1141 ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1143 av_freep(&comp_brands_str);
1146 comp_brands_str[comp_brand_size] = 0;
1147 av_dict_set(&c->fc->metadata, "compatible_brands",
1148 comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1150 // Logic for handling Audible's .aaxc files
1151 if (!strcmp(type, "aaxc")) {
1158 /* this atom should contain all header atoms */
1159 static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1163 if (c->found_moov) {
1164 av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1165 avio_skip(pb, atom.size);
1169 if ((ret = mov_read_default(c, pb, atom)) < 0)
1171 /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1172 /* so we don't parse the whole file if over a network */
1174 return 0; /* now go for mdat */
1177 static MOVFragmentStreamInfo * get_frag_stream_info(
1178 MOVFragmentIndex *frag_index,
1183 MOVFragmentIndexItem * item;
1185 if (index < 0 || index >= frag_index->nb_items)
1187 item = &frag_index->item[index];
1188 for (i = 0; i < item->nb_stream_info; i++)
1189 if (item->stream_info[i].id == id)
1190 return &item->stream_info[i];
1192 // This shouldn't happen
1196 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1199 MOVFragmentIndexItem * item;
1201 if (frag_index->current < 0 ||
1202 frag_index->current >= frag_index->nb_items)
1205 item = &frag_index->item[frag_index->current];
1206 for (i = 0; i < item->nb_stream_info; i++)
1207 if (item->stream_info[i].id == id) {
1212 // id not found. This shouldn't happen.
1216 static MOVFragmentStreamInfo * get_current_frag_stream_info(
1217 MOVFragmentIndex *frag_index)
1219 MOVFragmentIndexItem *item;
1220 if (frag_index->current < 0 ||
1221 frag_index->current >= frag_index->nb_items)
1224 item = &frag_index->item[frag_index->current];
1225 if (item->current >= 0 && item->current < item->nb_stream_info)
1226 return &item->stream_info[item->current];
1228 // This shouldn't happen
1232 static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
1235 int64_t moof_offset;
1237 // Optimize for appending new entries
1238 if (!frag_index->nb_items ||
1239 frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1240 return frag_index->nb_items;
1243 b = frag_index->nb_items;
1247 moof_offset = frag_index->item[m].moof_offset;
1248 if (moof_offset >= offset)
1250 if (moof_offset <= offset)
1256 static int64_t get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
1258 av_assert0(frag_stream_info);
1259 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1260 return frag_stream_info->sidx_pts;
1261 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1262 return frag_stream_info->first_tfra_pts;
1263 return frag_stream_info->tfdt_dts;
1266 static int64_t get_frag_time(MOVFragmentIndex *frag_index,
1267 int index, int track_id)
1269 MOVFragmentStreamInfo * frag_stream_info;
1273 if (track_id >= 0) {
1274 frag_stream_info = get_frag_stream_info(frag_index, index, track_id);
1275 return frag_stream_info->sidx_pts;
1278 for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1279 frag_stream_info = &frag_index->item[index].stream_info[i];
1280 timestamp = get_stream_info_time(frag_stream_info);
1281 if (timestamp != AV_NOPTS_VALUE)
1284 return AV_NOPTS_VALUE;
1287 static int search_frag_timestamp(MOVFragmentIndex *frag_index,
1288 AVStream *st, int64_t timestamp)
1295 // If the stream is referenced by any sidx, limit the search
1296 // to fragments that referenced this stream in the sidx
1297 MOVStreamContext *sc = st->priv_data;
1303 b = frag_index->nb_items;
1306 m0 = m = (a + b) >> 1;
1309 (frag_time = get_frag_time(frag_index, m, id)) == AV_NOPTS_VALUE)
1312 if (m < b && frag_time <= timestamp)
1321 static int update_frag_index(MOVContext *c, int64_t offset)
1324 MOVFragmentIndexItem * item;
1325 MOVFragmentStreamInfo * frag_stream_info;
1327 // If moof_offset already exists in frag_index, return index to it
1328 index = search_frag_moof_offset(&c->frag_index, offset);
1329 if (index < c->frag_index.nb_items &&
1330 c->frag_index.item[index].moof_offset == offset)
1333 // offset is not yet in frag index.
1334 // Insert new item at index (sorted by moof offset)
1335 item = av_fast_realloc(c->frag_index.item,
1336 &c->frag_index.allocated_size,
1337 (c->frag_index.nb_items + 1) *
1338 sizeof(*c->frag_index.item));
1341 c->frag_index.item = item;
1343 frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1344 sizeof(*item->stream_info));
1345 if (!frag_stream_info)
1348 for (i = 0; i < c->fc->nb_streams; i++) {
1349 // Avoid building frag index if streams lack track id.
1350 if (c->fc->streams[i]->id < 0) {
1351 av_free(frag_stream_info);
1352 return AVERROR_INVALIDDATA;
1355 frag_stream_info[i].id = c->fc->streams[i]->id;
1356 frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1357 frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1358 frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1359 frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1360 frag_stream_info[i].index_entry = -1;
1361 frag_stream_info[i].encryption_index = NULL;
1364 if (index < c->frag_index.nb_items)
1365 memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1366 (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1368 item = &c->frag_index.item[index];
1369 item->headers_read = 0;
1371 item->nb_stream_info = c->fc->nb_streams;
1372 item->moof_offset = offset;
1373 item->stream_info = frag_stream_info;
1374 c->frag_index.nb_items++;
1379 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1380 int id, int entries)
1383 MOVFragmentStreamInfo * frag_stream_info;
1387 for (i = index; i < frag_index->nb_items; i++) {
1388 frag_stream_info = get_frag_stream_info(frag_index, i, id);
1389 if (frag_stream_info && frag_stream_info->index_entry >= 0)
1390 frag_stream_info->index_entry += entries;
1394 static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1396 // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1397 c->fragment.found_tfhd = 0;
1399 if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1400 c->has_looked_for_mfra = 1;
1401 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1403 av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1405 if ((ret = mov_read_mfra(c, pb)) < 0) {
1406 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1407 "read the mfra (may be a live ismv)\n");
1410 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1411 "seekable, can not look for mfra\n");
1414 c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1415 av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1416 c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1417 return mov_read_default(c, pb, atom);
1420 static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time, void *logctx)
1423 if (time >= 2082844800)
1424 time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1426 if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1427 av_log(logctx, AV_LOG_DEBUG, "creation_time is not representable\n");
1431 avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1435 static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1438 MOVStreamContext *sc;
1440 char language[4] = {0};
1442 int64_t creation_time;
1444 if (c->fc->nb_streams < 1)
1446 st = c->fc->streams[c->fc->nb_streams-1];
1449 if (sc->time_scale) {
1450 av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1451 return AVERROR_INVALIDDATA;
1454 version = avio_r8(pb);
1456 avpriv_request_sample(c->fc, "Version %d", version);
1457 return AVERROR_PATCHWELCOME;
1459 avio_rb24(pb); /* flags */
1461 creation_time = avio_rb64(pb);
1464 creation_time = avio_rb32(pb);
1465 avio_rb32(pb); /* modification time */
1467 mov_metadata_creation_time(&st->metadata, creation_time, c->fc);
1469 sc->time_scale = avio_rb32(pb);
1470 if (sc->time_scale <= 0) {
1471 av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1474 st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1476 lang = avio_rb16(pb); /* language */
1477 if (ff_mov_lang_to_iso639(lang, language))
1478 av_dict_set(&st->metadata, "language", language, 0);
1479 avio_rb16(pb); /* quality */
1484 static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1487 int64_t creation_time;
1488 int version = avio_r8(pb); /* version */
1489 avio_rb24(pb); /* flags */
1492 creation_time = avio_rb64(pb);
1495 creation_time = avio_rb32(pb);
1496 avio_rb32(pb); /* modification time */
1498 mov_metadata_creation_time(&c->fc->metadata, creation_time, c->fc);
1499 c->time_scale = avio_rb32(pb); /* time scale */
1500 if (c->time_scale <= 0) {
1501 av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1504 av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1506 c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1507 // set the AVFormatContext duration because the duration of individual tracks
1508 // may be inaccurate
1509 if (c->time_scale > 0 && !c->trex_data)
1510 c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale);
1511 avio_rb32(pb); /* preferred scale */
1513 avio_rb16(pb); /* preferred volume */
1515 avio_skip(pb, 10); /* reserved */
1517 /* movie display matrix, store it in main context and use it later on */
1518 for (i = 0; i < 3; i++) {
1519 c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1520 c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1521 c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1524 avio_rb32(pb); /* preview time */
1525 avio_rb32(pb); /* preview duration */
1526 avio_rb32(pb); /* poster time */
1527 avio_rb32(pb); /* selection time */
1528 avio_rb32(pb); /* selection duration */
1529 avio_rb32(pb); /* current time */
1530 avio_rb32(pb); /* next track ID */
1535 static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1540 if (c->fc->nb_streams < 1)
1542 st = c->fc->streams[c->fc->nb_streams-1];
1544 little_endian = avio_rb16(pb) & 0xFF;
1545 av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1546 if (little_endian == 1) {
1547 switch (st->codecpar->codec_id) {
1548 case AV_CODEC_ID_PCM_S24BE:
1549 st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE;
1551 case AV_CODEC_ID_PCM_S32BE:
1552 st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE;
1554 case AV_CODEC_ID_PCM_F32BE:
1555 st->codecpar->codec_id = AV_CODEC_ID_PCM_F32LE;
1557 case AV_CODEC_ID_PCM_F64BE:
1558 st->codecpar->codec_id = AV_CODEC_ID_PCM_F64LE;
1567 static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1570 uint8_t *icc_profile;
1571 char color_parameter_type[5] = { 0 };
1572 uint16_t color_primaries, color_trc, color_matrix;
1575 if (c->fc->nb_streams < 1)
1577 st = c->fc->streams[c->fc->nb_streams - 1];
1579 ret = ffio_read_size(pb, color_parameter_type, 4);
1582 if (strncmp(color_parameter_type, "nclx", 4) &&
1583 strncmp(color_parameter_type, "nclc", 4) &&
1584 strncmp(color_parameter_type, "prof", 4)) {
1585 av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
1586 color_parameter_type);
1590 if (!strncmp(color_parameter_type, "prof", 4)) {
1591 icc_profile = av_stream_new_side_data(st, AV_PKT_DATA_ICC_PROFILE, atom.size - 4);
1593 return AVERROR(ENOMEM);
1594 ret = ffio_read_size(pb, icc_profile, atom.size - 4);
1598 color_primaries = avio_rb16(pb);
1599 color_trc = avio_rb16(pb);
1600 color_matrix = avio_rb16(pb);
1602 av_log(c->fc, AV_LOG_TRACE,
1603 "%s: pri %d trc %d matrix %d",
1604 color_parameter_type, color_primaries, color_trc, color_matrix);
1606 if (!strncmp(color_parameter_type, "nclx", 4)) {
1607 uint8_t color_range = avio_r8(pb) >> 7;
1608 av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
1610 st->codecpar->color_range = AVCOL_RANGE_JPEG;
1612 st->codecpar->color_range = AVCOL_RANGE_MPEG;
1615 if (!av_color_primaries_name(color_primaries))
1616 color_primaries = AVCOL_PRI_UNSPECIFIED;
1617 if (!av_color_transfer_name(color_trc))
1618 color_trc = AVCOL_TRC_UNSPECIFIED;
1619 if (!av_color_space_name(color_matrix))
1620 color_matrix = AVCOL_SPC_UNSPECIFIED;
1622 st->codecpar->color_primaries = color_primaries;
1623 st->codecpar->color_trc = color_trc;
1624 st->codecpar->color_space = color_matrix;
1625 av_log(c->fc, AV_LOG_TRACE, "\n");
1630 static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1633 unsigned mov_field_order;
1634 enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
1636 if (c->fc->nb_streams < 1) // will happen with jp2 files
1638 st = c->fc->streams[c->fc->nb_streams-1];
1640 return AVERROR_INVALIDDATA;
1641 mov_field_order = avio_rb16(pb);
1642 if ((mov_field_order & 0xFF00) == 0x0100)
1643 decoded_field_order = AV_FIELD_PROGRESSIVE;
1644 else if ((mov_field_order & 0xFF00) == 0x0200) {
1645 switch (mov_field_order & 0xFF) {
1646 case 0x01: decoded_field_order = AV_FIELD_TT;
1648 case 0x06: decoded_field_order = AV_FIELD_BB;
1650 case 0x09: decoded_field_order = AV_FIELD_TB;
1652 case 0x0E: decoded_field_order = AV_FIELD_BT;
1656 if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
1657 av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
1659 st->codecpar->field_order = decoded_field_order;
1664 static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
1667 uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
1668 if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
1669 return AVERROR_INVALIDDATA;
1670 if ((err = av_reallocp(&par->extradata, size)) < 0) {
1671 par->extradata_size = 0;
1674 par->extradata_size = size - AV_INPUT_BUFFER_PADDING_SIZE;
1678 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
1679 static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1680 AVCodecParameters *par, uint8_t *buf)
1682 int64_t result = atom.size;
1685 AV_WB32(buf , atom.size + 8);
1686 AV_WL32(buf + 4, atom.type);
1687 err = ffio_read_size(pb, buf + 8, atom.size);
1689 par->extradata_size -= atom.size;
1691 } else if (err < atom.size) {
1692 av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
1693 par->extradata_size -= atom.size - err;
1696 memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1700 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
1701 static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1702 enum AVCodecID codec_id)
1705 uint64_t original_size;
1708 if (c->fc->nb_streams < 1) // will happen with jp2 files
1710 st = c->fc->streams[c->fc->nb_streams-1];
1712 if (st->codecpar->codec_id != codec_id)
1713 return 0; /* unexpected codec_id - don't mess with extradata */
1715 original_size = st->codecpar->extradata_size;
1716 err = mov_realloc_extradata(st->codecpar, atom);
1720 err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
1723 return 0; // Note: this is the original behavior to ignore truncation.
1726 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
1727 static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1729 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
1732 static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1734 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS);
1737 static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1739 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
1742 static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1744 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
1747 static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1749 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
1751 ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
1755 static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1757 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
1759 if (!ret && c->fc->nb_streams >= 1) {
1760 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1761 if (par->extradata_size >= 40) {
1762 par->height = AV_RB16(&par->extradata[36]);
1763 par->width = AV_RB16(&par->extradata[38]);
1769 static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1771 if (c->fc->nb_streams >= 1) {
1772 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1773 if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
1774 par->codec_id == AV_CODEC_ID_H264 &&
1778 cid = avio_rb16(pb);
1779 /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
1780 if (cid == 0xd4d || cid == 0xd4e)
1783 } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
1784 par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
1785 par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
1789 num = avio_rb32(pb);
1790 den = avio_rb32(pb);
1791 if (num <= 0 || den <= 0)
1793 switch (avio_rb32(pb)) {
1795 if (den >= INT_MAX / 2)
1799 c->fc->streams[c->fc->nb_streams-1]->internal->display_aspect_ratio.num = num;
1800 c->fc->streams[c->fc->nb_streams-1]->internal->display_aspect_ratio.den = den;
1807 return mov_read_avid(c, pb, atom);
1810 static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1814 uint64_t original_size;
1815 if (c->fc->nb_streams >= 1) {
1816 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1817 if (par->codec_id == AV_CODEC_ID_H264)
1819 if (atom.size == 16) {
1820 original_size = par->extradata_size;
1821 ret = mov_realloc_extradata(par, atom);
1823 length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
1824 if (length == atom.size) {
1825 const uint8_t range_value = par->extradata[original_size + 19];
1826 switch (range_value) {
1828 par->color_range = AVCOL_RANGE_MPEG;
1831 par->color_range = AVCOL_RANGE_JPEG;
1834 av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
1837 ff_dlog(c->fc, "color_range: %d\n", par->color_range);
1839 /* For some reason the whole atom was not added to the extradata */
1840 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
1843 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
1846 av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
1853 static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1855 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
1858 static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1863 if (c->fc->nb_streams < 1)
1865 st = c->fc->streams[c->fc->nb_streams-1];
1867 if ((uint64_t)atom.size > (1<<30))
1868 return AVERROR_INVALIDDATA;
1870 if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
1871 st->codecpar->codec_id == AV_CODEC_ID_QDMC ||
1872 st->codecpar->codec_id == AV_CODEC_ID_SPEEX) {
1873 // pass all frma atom to codec, needed at least for QDMC and QDM2
1874 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1877 } else if (atom.size > 8) { /* to read frma, esds atoms */
1878 if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
1880 ret = ffio_ensure_seekback(pb, 8);
1883 buffer = avio_rb64(pb);
1885 if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
1886 && buffer >> 32 <= atom.size
1887 && buffer >> 32 >= 8) {
1890 } else if (!st->codecpar->extradata_size) {
1891 #define ALAC_EXTRADATA_SIZE 36
1892 st->codecpar->extradata = av_mallocz(ALAC_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
1893 if (!st->codecpar->extradata)
1894 return AVERROR(ENOMEM);
1895 st->codecpar->extradata_size = ALAC_EXTRADATA_SIZE;
1896 AV_WB32(st->codecpar->extradata , ALAC_EXTRADATA_SIZE);
1897 AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
1898 AV_WB64(st->codecpar->extradata + 12, buffer);
1899 avio_read(pb, st->codecpar->extradata + 20, 16);
1900 avio_skip(pb, atom.size - 24);
1904 if ((ret = mov_read_default(c, pb, atom)) < 0)
1907 avio_skip(pb, atom.size);
1912 * This function reads atom content and puts data in extradata without tag
1913 * nor size unlike mov_read_extradata.
1915 static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1920 if (c->fc->nb_streams < 1)
1922 st = c->fc->streams[c->fc->nb_streams-1];
1924 if ((uint64_t)atom.size > (1<<30))
1925 return AVERROR_INVALIDDATA;
1927 if (atom.size >= 10) {
1928 // Broken files created by legacy versions of libavformat will
1929 // wrap a whole fiel atom inside of a glbl atom.
1930 unsigned size = avio_rb32(pb);
1931 unsigned type = avio_rl32(pb);
1932 avio_seek(pb, -8, SEEK_CUR);
1933 if (type == MKTAG('f','i','e','l') && size == atom.size)
1934 return mov_read_default(c, pb, atom);
1936 if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
1937 av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
1940 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1943 if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
1944 /* HEVC-based Dolby Vision derived from hvc1.
1945 Happens to match with an identifier
1946 previously utilized for DV. Thus, if we have
1947 the hvcC extradata box available as specified,
1948 set codec to HEVC */
1949 st->codecpar->codec_id = AV_CODEC_ID_HEVC;
1954 static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1957 uint8_t profile_level;
1960 if (c->fc->nb_streams < 1)
1962 st = c->fc->streams[c->fc->nb_streams-1];
1964 if (atom.size >= (1<<28) || atom.size < 7)
1965 return AVERROR_INVALIDDATA;
1967 profile_level = avio_r8(pb);
1968 if ((profile_level & 0xf0) != 0xc0)
1971 avio_seek(pb, 6, SEEK_CUR);
1972 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
1980 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
1981 * but can have extradata appended at the end after the 40 bytes belonging
1984 static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1989 if (c->fc->nb_streams < 1)
1991 if (atom.size <= 40)
1993 st = c->fc->streams[c->fc->nb_streams-1];
1995 if ((uint64_t)atom.size > (1<<30))
1996 return AVERROR_INVALIDDATA;
1999 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2006 static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2009 MOVStreamContext *sc;
2010 unsigned int i, entries;
2012 if (c->trak_index < 0) {
2013 av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2016 if (c->fc->nb_streams < 1)
2018 st = c->fc->streams[c->fc->nb_streams-1];
2021 avio_r8(pb); /* version */
2022 avio_rb24(pb); /* flags */
2024 entries = avio_rb32(pb);
2029 if (sc->chunk_offsets)
2030 av_log(c->fc, AV_LOG_WARNING, "Duplicated STCO atom\n");
2031 av_free(sc->chunk_offsets);
2032 sc->chunk_count = 0;
2033 sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2034 if (!sc->chunk_offsets)
2035 return AVERROR(ENOMEM);
2036 sc->chunk_count = entries;
2038 if (atom.type == MKTAG('s','t','c','o'))
2039 for (i = 0; i < entries && !pb->eof_reached; i++)
2040 sc->chunk_offsets[i] = avio_rb32(pb);
2041 else if (atom.type == MKTAG('c','o','6','4'))
2042 for (i = 0; i < entries && !pb->eof_reached; i++)
2043 sc->chunk_offsets[i] = avio_rb64(pb);
2045 return AVERROR_INVALIDDATA;
2047 sc->chunk_count = i;
2049 if (pb->eof_reached) {
2050 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2057 static int mov_codec_id(AVStream *st, uint32_t format)
2059 int id = ff_codec_get_id(ff_codec_movaudio_tags, format);
2062 ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2063 (format & 0xFFFF) == 'T' + ('S' << 8)))
2064 id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format) & 0xFFFF);
2066 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2067 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2068 } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2069 /* skip old ASF MPEG-4 tag */
2070 format && format != MKTAG('m','p','4','s')) {
2071 id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2073 id = ff_codec_get_id(ff_codec_bmp_tags, format);
2075 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
2076 else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2077 (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE &&
2078 st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2079 id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
2081 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
2083 id = ff_codec_get_id(ff_codec_movdata_tags, format);
2087 st->codecpar->codec_tag = format;
2092 static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
2093 AVStream *st, MOVStreamContext *sc)
2095 uint8_t codec_name[32] = { 0 };
2099 /* The first 16 bytes of the video sample description are already
2100 * read in ff_mov_read_stsd_entries() */
2101 stsd_start = avio_tell(pb) - 16;
2103 avio_rb16(pb); /* version */
2104 avio_rb16(pb); /* revision level */
2105 avio_rb32(pb); /* vendor */
2106 avio_rb32(pb); /* temporal quality */
2107 avio_rb32(pb); /* spatial quality */
2109 st->codecpar->width = avio_rb16(pb); /* width */
2110 st->codecpar->height = avio_rb16(pb); /* height */
2112 avio_rb32(pb); /* horiz resolution */
2113 avio_rb32(pb); /* vert resolution */
2114 avio_rb32(pb); /* data size, always 0 */
2115 avio_rb16(pb); /* frames per samples */
2117 len = avio_r8(pb); /* codec name, pascal string */
2120 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2122 avio_skip(pb, 31 - len);
2125 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2127 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2128 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2129 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2130 st->codecpar->width &= ~1;
2131 st->codecpar->height &= ~1;
2133 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2134 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2135 !strncmp(codec_name, "Sorenson H263", 13))
2136 st->codecpar->codec_id = AV_CODEC_ID_FLV1;
2138 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2140 avio_seek(pb, stsd_start, SEEK_SET);
2142 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2143 st->codecpar->bits_per_coded_sample &= 0x1F;
2144 sc->has_palette = 1;
2148 static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
2149 AVStream *st, MOVStreamContext *sc)
2151 int bits_per_sample, flags;
2152 uint16_t version = avio_rb16(pb);
2153 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2155 avio_rb16(pb); /* revision level */
2156 avio_rb32(pb); /* vendor */
2158 st->codecpar->channels = avio_rb16(pb); /* channel count */
2159 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2160 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", st->codecpar->channels);
2162 sc->audio_cid = avio_rb16(pb);
2163 avio_rb16(pb); /* packet size = 0 */
2165 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2167 // Read QT version 1 fields. In version 0 these do not exist.
2168 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2170 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2171 (sc->stsd_version == 0 && version > 0)) {
2173 sc->samples_per_frame = avio_rb32(pb);
2174 avio_rb32(pb); /* bytes per packet */
2175 sc->bytes_per_frame = avio_rb32(pb);
2176 avio_rb32(pb); /* bytes per sample */
2177 } else if (version == 2) {
2178 avio_rb32(pb); /* sizeof struct only */
2179 st->codecpar->sample_rate = av_int2double(avio_rb64(pb));
2180 st->codecpar->channels = avio_rb32(pb);
2181 avio_rb32(pb); /* always 0x7F000000 */
2182 st->codecpar->bits_per_coded_sample = avio_rb32(pb);
2184 flags = avio_rb32(pb); /* lpcm format specific flag */
2185 sc->bytes_per_frame = avio_rb32(pb);
2186 sc->samples_per_frame = avio_rb32(pb);
2187 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2188 st->codecpar->codec_id =
2189 ff_mov_get_lpcm_codec_id(st->codecpar->bits_per_coded_sample,
2192 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2193 /* can't correctly handle variable sized packet as audio unit */
2194 switch (st->codecpar->codec_id) {
2195 case AV_CODEC_ID_MP2:
2196 case AV_CODEC_ID_MP3:
2197 st->need_parsing = AVSTREAM_PARSE_FULL;
2203 if (sc->format == 0) {
2204 if (st->codecpar->bits_per_coded_sample == 8)
2205 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2206 else if (st->codecpar->bits_per_coded_sample == 16)
2207 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2210 switch (st->codecpar->codec_id) {
2211 case AV_CODEC_ID_PCM_S8:
2212 case AV_CODEC_ID_PCM_U8:
2213 if (st->codecpar->bits_per_coded_sample == 16)
2214 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16BE;
2216 case AV_CODEC_ID_PCM_S16LE:
2217 case AV_CODEC_ID_PCM_S16BE:
2218 if (st->codecpar->bits_per_coded_sample == 8)
2219 st->codecpar->codec_id = AV_CODEC_ID_PCM_S8;
2220 else if (st->codecpar->bits_per_coded_sample == 24)
2221 st->codecpar->codec_id =
2222 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2223 AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
2224 else if (st->codecpar->bits_per_coded_sample == 32)
2225 st->codecpar->codec_id =
2226 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2227 AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
2229 /* set values for old format before stsd version 1 appeared */
2230 case AV_CODEC_ID_MACE3:
2231 sc->samples_per_frame = 6;
2232 sc->bytes_per_frame = 2 * st->codecpar->channels;
2234 case AV_CODEC_ID_MACE6:
2235 sc->samples_per_frame = 6;
2236 sc->bytes_per_frame = 1 * st->codecpar->channels;
2238 case AV_CODEC_ID_ADPCM_IMA_QT:
2239 sc->samples_per_frame = 64;
2240 sc->bytes_per_frame = 34 * st->codecpar->channels;
2242 case AV_CODEC_ID_GSM:
2243 sc->samples_per_frame = 160;
2244 sc->bytes_per_frame = 33;
2250 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2251 if (bits_per_sample) {
2252 st->codecpar->bits_per_coded_sample = bits_per_sample;
2253 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->channels;
2257 static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
2258 AVStream *st, MOVStreamContext *sc,
2261 // ttxt stsd contains display flags, justification, background
2262 // color, fonts, and default styles, so fake an atom to read it
2263 MOVAtom fake_atom = { .size = size };
2264 // mp4s contains a regular esds atom
2265 if (st->codecpar->codec_tag != AV_RL32("mp4s"))
2266 mov_read_glbl(c, pb, fake_atom);
2267 st->codecpar->width = sc->width;
2268 st->codecpar->height = sc->height;
2271 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2276 y = (ycbcr >> 16) & 0xFF;
2277 cr = (ycbcr >> 8) & 0xFF;
2280 b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
2281 g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
2282 r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
2284 return (r << 16) | (g << 8) | b;
2287 static int mov_rewrite_dvd_sub_extradata(AVStream *st)
2289 char buf[256] = {0};
2290 uint8_t *src = st->codecpar->extradata;
2293 if (st->codecpar->extradata_size != 64)
2296 if (st->codecpar->width > 0 && st->codecpar->height > 0)
2297 snprintf(buf, sizeof(buf), "size: %dx%d\n",
2298 st->codecpar->width, st->codecpar->height);
2299 av_strlcat(buf, "palette: ", sizeof(buf));
2301 for (i = 0; i < 16; i++) {
2302 uint32_t yuv = AV_RB32(src + i * 4);
2303 uint32_t rgba = yuv_to_rgba(yuv);
2305 av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2308 if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2311 ret = ff_alloc_extradata(st->codecpar, strlen(buf));
2314 memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2319 static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
2320 AVStream *st, MOVStreamContext *sc,
2325 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2326 if ((int)size != size)
2327 return AVERROR(ENOMEM);
2329 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2333 MOVStreamContext *tmcd_ctx = st->priv_data;
2335 val = AV_RB32(st->codecpar->extradata + 4);
2336 tmcd_ctx->tmcd_flags = val;
2337 st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2338 st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2339 #if FF_API_LAVF_AVCTX
2340 FF_DISABLE_DEPRECATION_WARNINGS
2341 st->codec->time_base = av_inv_q(st->avg_frame_rate);
2342 FF_ENABLE_DEPRECATION_WARNINGS
2344 /* adjust for per frame dur in counter mode */
2345 if (tmcd_ctx->tmcd_flags & 0x0008) {
2346 int timescale = AV_RB32(st->codecpar->extradata + 8);
2347 int framedur = AV_RB32(st->codecpar->extradata + 12);
2348 st->avg_frame_rate.num *= timescale;
2349 st->avg_frame_rate.den *= framedur;
2350 #if FF_API_LAVF_AVCTX
2351 FF_DISABLE_DEPRECATION_WARNINGS
2352 st->codec->time_base.den *= timescale;
2353 st->codec->time_base.num *= framedur;
2354 FF_ENABLE_DEPRECATION_WARNINGS
2358 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2359 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2360 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2361 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2362 if (str_size > 0 && size >= (int)str_size + 30 &&
2363 st->codecpar->extradata[30] /* Don't add empty string */) {
2364 char *reel_name = av_malloc(str_size + 1);
2366 return AVERROR(ENOMEM);
2367 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2368 reel_name[str_size] = 0; /* Add null terminator */
2369 av_dict_set(&st->metadata, "reel_name", reel_name,
2370 AV_DICT_DONT_STRDUP_VAL);
2376 /* other codec type, just skip (rtp, mp4s ...) */
2377 avio_skip(pb, size);
2382 static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
2383 AVStream *st, MOVStreamContext *sc)
2385 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2386 !st->codecpar->sample_rate && sc->time_scale > 1)
2387 st->codecpar->sample_rate = sc->time_scale;
2389 /* special codec parameters handling */
2390 switch (st->codecpar->codec_id) {
2391 #if CONFIG_DV_DEMUXER
2392 case AV_CODEC_ID_DVAUDIO:
2393 c->dv_fctx = avformat_alloc_context();
2395 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2396 return AVERROR(ENOMEM);
2398 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2400 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2401 return AVERROR(ENOMEM);
2403 sc->dv_audio_container = 1;
2404 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
2407 /* no ifdef since parameters are always those */
2408 case AV_CODEC_ID_QCELP:
2409 st->codecpar->channels = 1;
2410 // force sample rate for qcelp when not stored in mov
2411 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2412 st->codecpar->sample_rate = 8000;
2413 // FIXME: Why is the following needed for some files?
2414 sc->samples_per_frame = 160;
2415 if (!sc->bytes_per_frame)
2416 sc->bytes_per_frame = 35;
2418 case AV_CODEC_ID_AMR_NB:
2419 st->codecpar->channels = 1;
2420 /* force sample rate for amr, stsd in 3gp does not store sample rate */
2421 st->codecpar->sample_rate = 8000;
2423 case AV_CODEC_ID_AMR_WB:
2424 st->codecpar->channels = 1;
2425 st->codecpar->sample_rate = 16000;
2427 case AV_CODEC_ID_MP2:
2428 case AV_CODEC_ID_MP3:
2429 /* force type after stsd for m1a hdlr */
2430 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2432 case AV_CODEC_ID_GSM:
2433 case AV_CODEC_ID_ADPCM_MS:
2434 case AV_CODEC_ID_ADPCM_IMA_WAV:
2435 case AV_CODEC_ID_ILBC:
2436 case AV_CODEC_ID_MACE3:
2437 case AV_CODEC_ID_MACE6:
2438 case AV_CODEC_ID_QDM2:
2439 st->codecpar->block_align = sc->bytes_per_frame;
2441 case AV_CODEC_ID_ALAC:
2442 if (st->codecpar->extradata_size == 36) {
2443 st->codecpar->channels = AV_RB8 (st->codecpar->extradata + 21);
2444 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2447 case AV_CODEC_ID_AC3:
2448 case AV_CODEC_ID_EAC3:
2449 case AV_CODEC_ID_MPEG1VIDEO:
2450 case AV_CODEC_ID_VC1:
2451 case AV_CODEC_ID_VP8:
2452 case AV_CODEC_ID_VP9:
2453 st->need_parsing = AVSTREAM_PARSE_FULL;
2455 case AV_CODEC_ID_AV1:
2456 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2464 static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
2465 int codec_tag, int format,
2468 int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2471 (codec_tag != format &&
2472 // AVID 1:1 samples with differing data format and codec tag exist
2473 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
2474 // prores is allowed to have differing data format and codec tag
2475 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
2477 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
2478 (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id
2479 : codec_tag != MKTAG('j','p','e','g')))) {
2480 /* Multiple fourcc, we skip JPEG. This is not correct, we should
2481 * export it as a separate AVStream but this needs a few changes
2482 * in the MOV demuxer, patch welcome. */
2484 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
2485 avio_skip(pb, size);
2492 int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
2495 MOVStreamContext *sc;
2496 int pseudo_stream_id;
2498 av_assert0 (c->fc->nb_streams >= 1);
2499 st = c->fc->streams[c->fc->nb_streams-1];
2502 for (pseudo_stream_id = 0;
2503 pseudo_stream_id < entries && !pb->eof_reached;
2504 pseudo_stream_id++) {
2505 //Parsing Sample description table
2507 int ret, dref_id = 1;
2508 MOVAtom a = { AV_RL32("stsd") };
2509 int64_t start_pos = avio_tell(pb);
2510 int64_t size = avio_rb32(pb); /* size */
2511 uint32_t format = avio_rl32(pb); /* data format */
2514 avio_rb32(pb); /* reserved */
2515 avio_rb16(pb); /* reserved */
2516 dref_id = avio_rb16(pb);
2517 } else if (size <= 7) {
2518 av_log(c->fc, AV_LOG_ERROR,
2519 "invalid size %"PRId64" in stsd\n", size);
2520 return AVERROR_INVALIDDATA;
2523 if (mov_skip_multiple_stsd(c, pb, st->codecpar->codec_tag, format,
2524 size - (avio_tell(pb) - start_pos))) {
2529 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
2530 sc->dref_id= dref_id;
2531 sc->format = format;
2533 id = mov_codec_id(st, format);
2535 av_log(c->fc, AV_LOG_TRACE,
2536 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
2537 av_fourcc2str(format), st->codecpar->codec_type);
2539 st->codecpar->codec_id = id;
2540 if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) {
2541 mov_parse_stsd_video(c, pb, st, sc);
2542 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
2543 mov_parse_stsd_audio(c, pb, st, sc);
2544 if (st->codecpar->sample_rate < 0) {
2545 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
2546 return AVERROR_INVALIDDATA;
2548 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
2549 mov_parse_stsd_subtitle(c, pb, st, sc,
2550 size - (avio_tell(pb) - start_pos));
2552 ret = mov_parse_stsd_data(c, pb, st, sc,
2553 size - (avio_tell(pb) - start_pos));
2557 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
2558 a.size = size - (avio_tell(pb) - start_pos);
2560 if ((ret = mov_read_default(c, pb, a)) < 0)
2562 } else if (a.size > 0)
2563 avio_skip(pb, a.size);
2565 if (sc->extradata && st->codecpar->extradata) {
2566 int extra_size = st->codecpar->extradata_size;
2568 /* Move the current stream extradata to the stream context one. */
2569 sc->extradata_size[pseudo_stream_id] = extra_size;
2570 sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
2571 st->codecpar->extradata = NULL;
2572 st->codecpar->extradata_size = 0;
2577 if (pb->eof_reached) {
2578 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
2585 static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2588 MOVStreamContext *sc;
2591 if (c->fc->nb_streams < 1)
2593 st = c->fc->streams[c->fc->nb_streams - 1];
2596 sc->stsd_version = avio_r8(pb);
2597 avio_rb24(pb); /* flags */
2598 entries = avio_rb32(pb);
2600 /* Each entry contains a size (4 bytes) and format (4 bytes). */
2601 if (entries <= 0 || entries > atom.size / 8) {
2602 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
2603 return AVERROR_INVALIDDATA;
2606 if (sc->extradata) {
2607 av_log(c->fc, AV_LOG_ERROR,
2608 "Duplicate stsd found in this track.\n");
2609 return AVERROR_INVALIDDATA;
2612 /* Prepare space for hosting multiple extradata. */
2613 sc->extradata = av_mallocz_array(entries, sizeof(*sc->extradata));
2615 return AVERROR(ENOMEM);
2617 sc->extradata_size = av_mallocz_array(entries, sizeof(*sc->extradata_size));
2618 if (!sc->extradata_size) {
2619 ret = AVERROR(ENOMEM);
2623 ret = ff_mov_read_stsd_entries(c, pb, entries);
2627 /* Restore back the primary extradata. */
2628 av_freep(&st->codecpar->extradata);
2629 st->codecpar->extradata_size = sc->extradata_size[0];
2630 if (sc->extradata_size[0]) {
2631 st->codecpar->extradata = av_mallocz(sc->extradata_size[0] + AV_INPUT_BUFFER_PADDING_SIZE);
2632 if (!st->codecpar->extradata)
2633 return AVERROR(ENOMEM);
2634 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
2637 return mov_finalize_stsd_codec(c, pb, st, sc);
2639 if (sc->extradata) {
2641 for (j = 0; j < sc->stsd_count; j++)
2642 av_freep(&sc->extradata[j]);
2645 av_freep(&sc->extradata);
2646 av_freep(&sc->extradata_size);
2650 static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2653 MOVStreamContext *sc;
2654 unsigned int i, entries;
2656 if (c->fc->nb_streams < 1)
2658 st = c->fc->streams[c->fc->nb_streams-1];
2661 avio_r8(pb); /* version */
2662 avio_rb24(pb); /* flags */
2664 entries = avio_rb32(pb);
2665 if ((uint64_t)entries * 12 + 4 > atom.size)
2666 return AVERROR_INVALIDDATA;
2668 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
2673 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSC atom\n");
2674 av_free(sc->stsc_data);
2676 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
2678 return AVERROR(ENOMEM);
2680 for (i = 0; i < entries && !pb->eof_reached; i++) {
2681 sc->stsc_data[i].first = avio_rb32(pb);
2682 sc->stsc_data[i].count = avio_rb32(pb);
2683 sc->stsc_data[i].id = avio_rb32(pb);
2687 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
2688 int64_t first_min = i + 1;
2689 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
2690 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
2691 sc->stsc_data[i].first < first_min ||
2692 sc->stsc_data[i].count < 1 ||
2693 sc->stsc_data[i].id < 1) {
2694 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);
2695 if (i+1 >= sc->stsc_count) {
2696 if (sc->stsc_data[i].count == 0 && i > 0) {
2700 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
2701 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
2702 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
2703 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
2704 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
2707 av_assert0(sc->stsc_data[i+1].first >= 2);
2708 // We replace this entry by the next valid
2709 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
2710 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
2711 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
2715 if (pb->eof_reached) {
2716 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
2723 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
2725 return index < count - 1;
2728 /* Compute the samples value for the stsc entry at the given index. */
2729 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
2733 if (mov_stsc_index_valid(index, sc->stsc_count))
2734 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
2736 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
2737 av_assert0(sc->stsc_data[index].first <= sc->chunk_count);
2738 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
2741 return sc->stsc_data[index].count * (int64_t)chunk_count;
2744 static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2747 MOVStreamContext *sc;
2748 unsigned i, entries;
2750 if (c->fc->nb_streams < 1)
2752 st = c->fc->streams[c->fc->nb_streams-1];
2755 avio_rb32(pb); // version + flags
2757 entries = avio_rb32(pb);
2759 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
2760 av_free(sc->stps_data);
2762 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
2764 return AVERROR(ENOMEM);
2766 for (i = 0; i < entries && !pb->eof_reached; i++) {
2767 sc->stps_data[i] = avio_rb32(pb);
2772 if (pb->eof_reached) {
2773 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
2780 static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2783 MOVStreamContext *sc;
2784 unsigned int i, entries;
2786 if (c->fc->nb_streams < 1)
2788 st = c->fc->streams[c->fc->nb_streams-1];
2791 avio_r8(pb); /* version */
2792 avio_rb24(pb); /* flags */
2794 entries = avio_rb32(pb);
2796 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
2799 sc->keyframe_absent = 1;
2800 if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
2801 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2805 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
2806 if (entries >= UINT_MAX / sizeof(int))
2807 return AVERROR_INVALIDDATA;
2808 av_freep(&sc->keyframes);
2809 sc->keyframe_count = 0;
2810 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
2812 return AVERROR(ENOMEM);
2814 for (i = 0; i < entries && !pb->eof_reached; i++) {
2815 sc->keyframes[i] = avio_rb32(pb);
2818 sc->keyframe_count = i;
2820 if (pb->eof_reached) {
2821 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
2828 static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2831 MOVStreamContext *sc;
2832 unsigned int i, entries, sample_size, field_size, num_bytes;
2837 if (c->fc->nb_streams < 1)
2839 st = c->fc->streams[c->fc->nb_streams-1];
2842 avio_r8(pb); /* version */
2843 avio_rb24(pb); /* flags */
2845 if (atom.type == MKTAG('s','t','s','z')) {
2846 sample_size = avio_rb32(pb);
2847 if (!sc->sample_size) /* do not overwrite value computed in stsd */
2848 sc->sample_size = sample_size;
2849 sc->stsz_sample_size = sample_size;
2853 avio_rb24(pb); /* reserved */
2854 field_size = avio_r8(pb);
2856 entries = avio_rb32(pb);
2858 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
2860 sc->sample_count = entries;
2864 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
2865 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
2866 return AVERROR_INVALIDDATA;
2871 if (entries >= (UINT_MAX - 4) / field_size)
2872 return AVERROR_INVALIDDATA;
2873 if (sc->sample_sizes)
2874 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
2875 av_free(sc->sample_sizes);
2876 sc->sample_count = 0;
2877 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
2878 if (!sc->sample_sizes)
2879 return AVERROR(ENOMEM);
2881 num_bytes = (entries*field_size+4)>>3;
2883 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
2885 av_freep(&sc->sample_sizes);
2886 return AVERROR(ENOMEM);
2889 ret = ffio_read_size(pb, buf, num_bytes);
2891 av_freep(&sc->sample_sizes);
2893 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
2897 init_get_bits(&gb, buf, 8*num_bytes);
2899 for (i = 0; i < entries && !pb->eof_reached; i++) {
2900 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
2901 if (sc->sample_sizes[i] < 0) {
2903 av_log(c->fc, AV_LOG_ERROR, "Invalid sample size %d\n", sc->sample_sizes[i]);
2904 return AVERROR_INVALIDDATA;
2906 sc->data_size += sc->sample_sizes[i];
2909 sc->sample_count = i;
2913 if (pb->eof_reached) {
2914 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSZ atom\n");
2921 static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2924 MOVStreamContext *sc;
2925 unsigned int i, entries, alloc_size = 0;
2926 int64_t duration = 0;
2927 int64_t total_sample_count = 0;
2929 if (c->fc->nb_streams < 1)
2931 st = c->fc->streams[c->fc->nb_streams-1];
2934 avio_r8(pb); /* version */
2935 avio_rb24(pb); /* flags */
2936 entries = avio_rb32(pb);
2938 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
2939 c->fc->nb_streams-1, entries);
2942 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
2943 av_freep(&sc->stts_data);
2945 if (entries >= INT_MAX / sizeof(*sc->stts_data))
2946 return AVERROR(ENOMEM);
2948 for (i = 0; i < entries && !pb->eof_reached; i++) {
2949 int sample_duration;
2950 unsigned int sample_count;
2951 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
2952 MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
2953 min_entries * sizeof(*sc->stts_data));
2955 av_freep(&sc->stts_data);
2957 return AVERROR(ENOMEM);
2959 sc->stts_count = min_entries;
2960 sc->stts_data = stts_data;
2962 sample_count = avio_rb32(pb);
2963 sample_duration = avio_rb32(pb);
2965 sc->stts_data[i].count= sample_count;
2966 sc->stts_data[i].duration= sample_duration;
2968 av_log(c->fc, AV_LOG_TRACE, "sample_count=%d, sample_duration=%d\n",
2969 sample_count, sample_duration);
2971 duration+=(int64_t)sample_duration*(uint64_t)sample_count;
2972 total_sample_count+=sample_count;
2978 duration <= INT64_MAX - sc->duration_for_fps &&
2979 total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
2980 sc->duration_for_fps += duration;
2981 sc->nb_frames_for_fps += total_sample_count;
2984 if (pb->eof_reached) {
2985 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
2989 st->nb_frames= total_sample_count;
2991 st->duration= FFMIN(st->duration, duration);
2992 sc->track_end = duration;
2996 static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2999 MOVStreamContext *sc;
3002 if (c->fc->nb_streams < 1)
3004 st = c->fc->streams[c->fc->nb_streams - 1];
3007 avio_r8(pb); /* version */
3008 avio_rb24(pb); /* flags */
3009 entries = atom.size - 4;
3011 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3012 c->fc->nb_streams - 1, entries);
3015 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3016 av_freep(&sc->sdtp_data);
3019 sc->sdtp_data = av_mallocz(entries);
3021 return AVERROR(ENOMEM);
3023 for (i = 0; i < entries && !pb->eof_reached; i++)
3024 sc->sdtp_data[i] = avio_r8(pb);
3030 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3033 if (duration == INT_MIN) {
3034 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3037 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3041 static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3044 MOVStreamContext *sc;
3045 unsigned int i, entries, ctts_count = 0;
3047 if (c->fc->nb_streams < 1)
3049 st = c->fc->streams[c->fc->nb_streams-1];
3052 avio_r8(pb); /* version */
3053 avio_rb24(pb); /* flags */
3054 entries = avio_rb32(pb);
3056 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3060 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3061 return AVERROR_INVALIDDATA;
3062 av_freep(&sc->ctts_data);
3063 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3065 return AVERROR(ENOMEM);
3067 for (i = 0; i < entries && !pb->eof_reached; i++) {
3068 int count = avio_rb32(pb);
3069 int duration = avio_rb32(pb);
3072 av_log(c->fc, AV_LOG_TRACE,
3073 "ignoring CTTS entry with count=%d duration=%d\n",
3078 add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3081 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3084 if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3085 av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3086 av_freep(&sc->ctts_data);
3092 mov_update_dts_shift(sc, duration, c->fc);
3095 sc->ctts_count = ctts_count;
3097 if (pb->eof_reached) {
3098 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3102 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3107 static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3110 MOVStreamContext *sc;
3111 unsigned int i, entries;
3113 uint32_t grouping_type;
3115 if (c->fc->nb_streams < 1)
3117 st = c->fc->streams[c->fc->nb_streams-1];
3120 version = avio_r8(pb); /* version */
3121 avio_rb24(pb); /* flags */
3122 grouping_type = avio_rl32(pb);
3123 if (grouping_type != MKTAG( 'r','a','p',' '))
3124 return 0; /* only support 'rap ' grouping */
3126 avio_rb32(pb); /* grouping_type_parameter */
3128 entries = avio_rb32(pb);
3132 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP atom\n");
3133 av_free(sc->rap_group);
3134 sc->rap_group_count = 0;
3135 sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group));
3137 return AVERROR(ENOMEM);
3139 for (i = 0; i < entries && !pb->eof_reached; i++) {
3140 sc->rap_group[i].count = avio_rb32(pb); /* sample_count */
3141 sc->rap_group[i].index = avio_rb32(pb); /* group_description_index */
3144 sc->rap_group_count = i;
3146 if (pb->eof_reached) {
3147 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3155 * Get ith edit list entry (media time, duration).
3157 static int get_edit_list_entry(MOVContext *mov,
3158 const MOVStreamContext *msc,
3159 unsigned int edit_list_index,
3160 int64_t *edit_list_media_time,
3161 int64_t *edit_list_duration,
3162 int64_t global_timescale)
3164 if (edit_list_index == msc->elst_count) {
3167 *edit_list_media_time = msc->elst_data[edit_list_index].time;
3168 *edit_list_duration = msc->elst_data[edit_list_index].duration;
3170 /* duration is in global timescale units;convert to msc timescale */
3171 if (global_timescale == 0) {
3172 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3175 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3181 * Find the closest previous frame to the timestamp_pts, in e_old index
3182 * entries. Searching for just any frame / just key frames can be controlled by
3183 * last argument 'flag'.
3184 * Note that if ctts_data is not NULL, we will always search for a key frame
3185 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3186 * return the first frame of the video.
3188 * Here the timestamp_pts is considered to be a presentation timestamp and
3189 * the timestamp of index entries are considered to be decoding timestamps.
3191 * Returns 0 if successful in finding a frame, else returns -1.
3192 * Places the found index corresponding output arg.
3194 * If ctts_old is not NULL, then refines the searched entry by searching
3195 * backwards from the found timestamp, to find the frame with correct PTS.
3197 * Places the found ctts_index and ctts_sample in corresponding output args.
3199 static int find_prev_closest_index(AVStream *st,
3200 AVIndexEntry *e_old,
3204 int64_t timestamp_pts,
3207 int64_t* ctts_index,
3208 int64_t* ctts_sample)
3210 MOVStreamContext *msc = st->priv_data;
3211 AVIndexEntry *e_keep = st->internal->index_entries;
3212 int nb_keep = st->internal->nb_index_entries;
3214 int64_t index_ctts_count;
3218 // If dts_shift > 0, then all the index timestamps will have to be offset by
3219 // at least dts_shift amount to obtain PTS.
3220 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3221 if (msc->dts_shift > 0) {
3222 timestamp_pts -= msc->dts_shift;
3225 st->internal->index_entries = e_old;
3226 st->internal->nb_index_entries = nb_old;
3227 *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3229 // Keep going backwards in the index entries until the timestamp is the same.
3231 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3233 if ((flag & AVSEEK_FLAG_ANY) ||
3234 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3240 // If we have CTTS then refine the search, by searching backwards over PTS
3241 // computed by adding corresponding CTTS durations to index timestamps.
3242 if (ctts_data && *index >= 0) {
3243 av_assert0(ctts_index);
3244 av_assert0(ctts_sample);
3245 // Find out the ctts_index for the found frame.
3248 for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3249 if (*ctts_index < ctts_count) {
3251 if (ctts_data[*ctts_index].count == *ctts_sample) {
3258 while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3259 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3260 // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3261 // compensated by dts_shift above.
3262 if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3263 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3268 if (*ctts_sample == 0) {
3270 if (*ctts_index >= 0)
3271 *ctts_sample = ctts_data[*ctts_index].count - 1;
3278 /* restore AVStream state*/
3279 st->internal->index_entries = e_keep;
3280 st->internal->nb_index_entries = nb_keep;
3281 return *index >= 0 ? 0 : -1;
3285 * Add index entry with the given values, to the end of st->internal->index_entries.
3286 * Returns the new size st->internal->index_entries if successful, else returns -1.
3288 * This function is similar to ff_add_index_entry in libavformat/utils.c
3289 * except that here we are always unconditionally adding an index entry to
3290 * the end, instead of searching the entries list and skipping the add if
3291 * there is an existing entry with the same timestamp.
3292 * This is needed because the mov_fix_index calls this func with the same
3293 * unincremented timestamp for successive discarded frames.
3295 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3296 int size, int distance, int flags)
3298 AVIndexEntry *entries, *ie;
3300 const size_t min_size_needed = (st->internal->nb_index_entries + 1) * sizeof(AVIndexEntry);
3302 // Double the allocation each time, to lower memory fragmentation.
3303 // Another difference from ff_add_index_entry function.
3304 const size_t requested_size =
3305 min_size_needed > st->internal->index_entries_allocated_size ?
3306 FFMAX(min_size_needed, 2 * st->internal->index_entries_allocated_size) :
3309 if (st->internal->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
3312 entries = av_fast_realloc(st->internal->index_entries,
3313 &st->internal->index_entries_allocated_size,
3318 st->internal->index_entries= entries;
3320 index= st->internal->nb_index_entries++;
3321 ie= &entries[index];
3324 ie->timestamp = timestamp;
3325 ie->min_distance= distance;
3332 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3333 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3335 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3336 int64_t* frame_duration_buffer,
3337 int frame_duration_buffer_size) {
3339 av_assert0(end_index >= 0 && end_index <= st->internal->nb_index_entries);
3340 for (i = 0; i < frame_duration_buffer_size; i++) {
3341 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3342 st->internal->index_entries[end_index - 1 - i].timestamp = end_ts;
3347 * Append a new ctts entry to ctts_data.
3348 * Returns the new ctts_count if successful, else returns -1.
3350 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3351 int count, int duration)
3353 MOVStts *ctts_buf_new;
3354 const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVStts);
3355 const size_t requested_size =
3356 min_size_needed > *allocated_size ?
3357 FFMAX(min_size_needed, 2 * (*allocated_size)) :
3360 if ((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
3363 ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3368 *ctts_data = ctts_buf_new;
3370 ctts_buf_new[*ctts_count].count = count;
3371 ctts_buf_new[*ctts_count].duration = duration;
3373 *ctts_count = (*ctts_count) + 1;
3377 #define MAX_REORDER_DELAY 16
3378 static void mov_estimate_video_delay(MOVContext *c, AVStream* st)
3380 MOVStreamContext *msc = st->priv_data;
3383 int ctts_sample = 0;
3384 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3386 int j, r, num_swaps;
3388 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3389 pts_buf[j] = INT64_MIN;
3391 if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3392 st->codecpar->codec_id == AV_CODEC_ID_H264) {
3393 st->codecpar->video_delay = 0;
3394 for (ind = 0; ind < st->internal->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3395 // Point j to the last elem of the buffer and insert the current pts there.
3397 buf_start = (buf_start + 1);
3398 if (buf_start == MAX_REORDER_DELAY + 1)
3401 pts_buf[j] = st->internal->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3403 // The timestamps that are already in the sorted buffer, and are greater than the
3404 // current pts, are exactly the timestamps that need to be buffered to output PTS
3405 // in correct sorted order.
3406 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3407 // can be computed as the maximum no. of swaps any particular timestamp needs to
3408 // go through, to keep this buffer in sorted order.
3410 while (j != buf_start) {
3412 if (r < 0) r = MAX_REORDER_DELAY;
3413 if (pts_buf[j] < pts_buf[r]) {
3414 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3421 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3424 if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3429 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3430 st->codecpar->video_delay, st->index);
3434 static void mov_current_sample_inc(MOVStreamContext *sc)
3436 sc->current_sample++;
3437 sc->current_index++;
3438 if (sc->index_ranges &&
3439 sc->current_index >= sc->current_index_range->end &&
3440 sc->current_index_range->end) {
3441 sc->current_index_range++;
3442 sc->current_index = sc->current_index_range->start;
3446 static void mov_current_sample_dec(MOVStreamContext *sc)
3448 sc->current_sample--;
3449 sc->current_index--;
3450 if (sc->index_ranges &&
3451 sc->current_index < sc->current_index_range->start &&
3452 sc->current_index_range > sc->index_ranges) {
3453 sc->current_index_range--;
3454 sc->current_index = sc->current_index_range->end - 1;
3458 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3462 sc->current_sample = current_sample;
3463 sc->current_index = current_sample;
3464 if (!sc->index_ranges) {
3468 for (sc->current_index_range = sc->index_ranges;
3469 sc->current_index_range->end;
3470 sc->current_index_range++) {
3471 range_size = sc->current_index_range->end - sc->current_index_range->start;
3472 if (range_size > current_sample) {
3473 sc->current_index = sc->current_index_range->start + current_sample;
3476 current_sample -= range_size;
3481 * Fix st->internal->index_entries, so that it contains only the entries (and the entries
3482 * which are needed to decode them) that fall in the edit list time ranges.
3483 * Also fixes the timestamps of the index entries to match the timeline
3484 * specified the edit lists.
3486 static void mov_fix_index(MOVContext *mov, AVStream *st)
3488 MOVStreamContext *msc = st->priv_data;
3489 AVIndexEntry *e_old = st->internal->index_entries;
3490 int nb_old = st->internal->nb_index_entries;
3491 const AVIndexEntry *e_old_end = e_old + nb_old;
3492 const AVIndexEntry *current = NULL;
3493 MOVStts *ctts_data_old = msc->ctts_data;
3494 int64_t ctts_index_old = 0;
3495 int64_t ctts_sample_old = 0;
3496 int64_t ctts_count_old = msc->ctts_count;
3497 int64_t edit_list_media_time = 0;
3498 int64_t edit_list_duration = 0;
3499 int64_t frame_duration = 0;
3500 int64_t edit_list_dts_counter = 0;
3501 int64_t edit_list_dts_entry_end = 0;
3502 int64_t edit_list_start_ctts_sample = 0;
3504 int64_t curr_ctts = 0;
3505 int64_t empty_edits_sum_duration = 0;
3506 int64_t edit_list_index = 0;
3509 int64_t start_dts = 0;
3510 int64_t edit_list_start_encountered = 0;
3511 int64_t search_timestamp = 0;
3512 int64_t* frame_duration_buffer = NULL;
3513 int num_discarded_begin = 0;
3514 int first_non_zero_audio_edit = -1;
3515 int packet_skip_samples = 0;
3516 MOVIndexRange *current_index_range;
3518 int found_keyframe_after_edit = 0;
3519 int found_non_empty_edit = 0;
3521 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
3525 // allocate the index ranges array
3526 msc->index_ranges = av_malloc((msc->elst_count + 1) * sizeof(msc->index_ranges[0]));
3527 if (!msc->index_ranges) {
3528 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
3531 msc->current_index_range = msc->index_ranges;
3532 current_index_range = msc->index_ranges - 1;
3534 // Clean AVStream from traces of old index
3535 st->internal->index_entries = NULL;
3536 st->internal->index_entries_allocated_size = 0;
3537 st->internal->nb_index_entries = 0;
3539 // Clean ctts fields of MOVStreamContext
3540 msc->ctts_data = NULL;
3541 msc->ctts_count = 0;
3542 msc->ctts_index = 0;
3543 msc->ctts_sample = 0;
3544 msc->ctts_allocated_size = 0;
3546 // Reinitialize min_corrected_pts so that it can be computed again.
3547 msc->min_corrected_pts = -1;
3549 // If the dts_shift is positive (in case of negative ctts values in mov),
3550 // then negate the DTS by dts_shift
3551 if (msc->dts_shift > 0) {
3552 edit_list_dts_entry_end -= msc->dts_shift;
3553 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
3556 start_dts = edit_list_dts_entry_end;
3558 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
3559 &edit_list_duration, mov->time_scale)) {
3560 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
3561 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
3563 edit_list_dts_counter = edit_list_dts_entry_end;
3564 edit_list_dts_entry_end += edit_list_duration;
3565 num_discarded_begin = 0;
3566 if (!found_non_empty_edit && edit_list_media_time == -1) {
3567 empty_edits_sum_duration += edit_list_duration;
3570 found_non_empty_edit = 1;
3572 // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
3573 // according to the edit list below.
3574 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3575 if (first_non_zero_audio_edit < 0) {
3576 first_non_zero_audio_edit = 1;
3578 first_non_zero_audio_edit = 0;
3581 if (first_non_zero_audio_edit > 0)
3582 st->internal->skip_samples = msc->start_pad = 0;
3585 // While reordering frame index according to edit list we must handle properly
3586 // the scenario when edit list entry starts from none key frame.
3587 // We find closest previous key frame and preserve it and consequent frames in index.
3588 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
3589 search_timestamp = edit_list_media_time;
3590 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3591 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
3592 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
3593 // edit_list_media_time to cover the decoder delay.
3594 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
3597 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
3598 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3599 av_log(mov->fc, AV_LOG_WARNING,
3600 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
3601 st->index, edit_list_index, search_timestamp);
3602 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
3603 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3604 av_log(mov->fc, AV_LOG_WARNING,
3605 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
3606 st->index, edit_list_index, search_timestamp);
3609 ctts_sample_old = 0;
3612 current = e_old + index;
3613 edit_list_start_ctts_sample = ctts_sample_old;
3615 // Iterate over index and arrange it according to edit list
3616 edit_list_start_encountered = 0;
3617 found_keyframe_after_edit = 0;
3618 for (; current < e_old_end; current++, index++) {
3619 // check if frame outside edit list mark it for discard
3620 frame_duration = (current + 1 < e_old_end) ?
3621 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
3623 flags = current->flags;
3625 // frames (pts) before or after edit list
3626 curr_cts = current->timestamp + msc->dts_shift;
3629 if (ctts_data_old && ctts_index_old < ctts_count_old) {
3630 curr_ctts = ctts_data_old[ctts_index_old].duration;
3631 av_log(mov->fc, AV_LOG_DEBUG, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
3632 curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
3633 curr_cts += curr_ctts;
3635 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
3636 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3637 &msc->ctts_allocated_size,
3638 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3639 ctts_data_old[ctts_index_old].duration) == -1) {
3640 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3642 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3643 ctts_data_old[ctts_index_old].duration);
3647 ctts_sample_old = 0;
3648 edit_list_start_ctts_sample = 0;
3652 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
3653 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
3654 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
3655 first_non_zero_audio_edit > 0) {
3656 packet_skip_samples = edit_list_media_time - curr_cts;
3657 st->internal->skip_samples += packet_skip_samples;
3659 // Shift the index entry timestamp by packet_skip_samples to be correct.
3660 edit_list_dts_counter -= packet_skip_samples;
3661 if (edit_list_start_encountered == 0) {
3662 edit_list_start_encountered = 1;
3663 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
3664 // discarded packets.
3665 if (frame_duration_buffer) {
3666 fix_index_entry_timestamps(st, st->internal->nb_index_entries, edit_list_dts_counter,
3667 frame_duration_buffer, num_discarded_begin);
3668 av_freep(&frame_duration_buffer);
3672 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
3674 flags |= AVINDEX_DISCARD_FRAME;
3675 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
3677 if (edit_list_start_encountered == 0) {
3678 num_discarded_begin++;
3679 frame_duration_buffer = av_realloc(frame_duration_buffer,
3680 num_discarded_begin * sizeof(int64_t));
3681 if (!frame_duration_buffer) {
3682 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
3685 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
3687 // Increment skip_samples for the first non-zero audio edit list
3688 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3689 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
3690 st->internal->skip_samples += frame_duration;
3695 if (msc->min_corrected_pts < 0) {
3696 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
3698 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
3700 if (edit_list_start_encountered == 0) {
3701 edit_list_start_encountered = 1;
3702 // Make timestamps strictly monotonically increasing by rewriting timestamps for
3703 // discarded packets.
3704 if (frame_duration_buffer) {
3705 fix_index_entry_timestamps(st, st->internal->nb_index_entries, edit_list_dts_counter,
3706 frame_duration_buffer, num_discarded_begin);
3707 av_freep(&frame_duration_buffer);
3712 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
3713 current->min_distance, flags) == -1) {
3714 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
3718 // Update the index ranges array
3719 if (current_index_range < msc->index_ranges || index != current_index_range->end) {
3720 current_index_range++;
3721 current_index_range->start = index;
3723 current_index_range->end = index + 1;
3725 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
3726 if (edit_list_start_encountered > 0) {
3727 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
3730 // Break when found first key frame after edit entry completion
3731 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
3732 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
3733 if (ctts_data_old) {
3734 // If we have CTTS and this is the first keyframe after edit elist,
3735 // wait for one more, because there might be trailing B-frames after this I-frame
3736 // that do belong to the edit.
3737 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
3738 found_keyframe_after_edit = 1;
3741 if (ctts_sample_old != 0) {
3742 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3743 &msc->ctts_allocated_size,
3744 ctts_sample_old - edit_list_start_ctts_sample,
3745 ctts_data_old[ctts_index_old].duration) == -1) {
3746 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3747 ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
3748 ctts_data_old[ctts_index_old].duration);
3757 // If there are empty edits, then msc->min_corrected_pts might be positive
3758 // intentionally. So we subtract the sum duration of emtpy edits here.
3759 msc->min_corrected_pts -= empty_edits_sum_duration;
3761 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
3762 // dts by that amount to make the first pts zero.
3763 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
3764 if (msc->min_corrected_pts > 0) {
3765 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
3766 for (i = 0; i < st->internal->nb_index_entries; ++i) {
3767 st->internal->index_entries[i].timestamp -= msc->min_corrected_pts;
3771 // Start time should be equal to zero or the duration of any empty edits.
3772 st->start_time = empty_edits_sum_duration;
3774 // Update av stream length, if it ends up shorter than the track's media duration
3775 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
3776 msc->start_pad = st->internal->skip_samples;
3778 // Free the old index and the old CTTS structures
3780 av_free(ctts_data_old);
3781 av_freep(&frame_duration_buffer);
3783 // Null terminate the index ranges array
3784 current_index_range++;
3785 current_index_range->start = 0;
3786 current_index_range->end = 0;
3787 msc->current_index = msc->index_ranges[0].start;
3790 static void mov_build_index(MOVContext *mov, AVStream *st)
3792 MOVStreamContext *sc = st->priv_data;
3793 int64_t current_offset;
3794 int64_t current_dts = 0;
3795 unsigned int stts_index = 0;
3796 unsigned int stsc_index = 0;
3797 unsigned int stss_index = 0;
3798 unsigned int stps_index = 0;
3800 uint64_t stream_size = 0;
3801 MOVStts *ctts_data_old = sc->ctts_data;
3802 unsigned int ctts_count_old = sc->ctts_count;
3804 if (sc->elst_count) {
3805 int i, edit_start_index = 0, multiple_edits = 0;
3806 int64_t empty_duration = 0; // empty duration of the first edit list entry
3807 int64_t start_time = 0; // start time of the media
3809 for (i = 0; i < sc->elst_count; i++) {
3810 const MOVElst *e = &sc->elst_data[i];
3811 if (i == 0 && e->time == -1) {
3812 /* if empty, the first entry is the start time of the stream
3813 * relative to the presentation itself */
3814 empty_duration = e->duration;
3815 edit_start_index = 1;
3816 } else if (i == edit_start_index && e->time >= 0) {
3817 start_time = e->time;
3823 if (multiple_edits && !mov->advanced_editlist)
3824 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
3825 "Use -advanced_editlist to correctly decode otherwise "
3826 "a/v desync might occur\n");
3828 /* adjust first dts according to edit list */
3829 if ((empty_duration || start_time) && mov->time_scale > 0) {
3831 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
3832 sc->time_offset = start_time - empty_duration;
3833 sc->min_corrected_pts = start_time;
3834 if (!mov->advanced_editlist)
3835 current_dts = -sc->time_offset;
3838 if (!multiple_edits && !mov->advanced_editlist &&
3839 st->codecpar->codec_id == AV_CODEC_ID_AAC && start_time > 0)
3840 sc->start_pad = start_time;
3843 /* only use old uncompressed audio chunk demuxing when stts specifies it */
3844 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3845 sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
3846 unsigned int current_sample = 0;
3847 unsigned int stts_sample = 0;
3848 unsigned int sample_size;
3849 unsigned int distance = 0;
3850 unsigned int rap_group_index = 0;
3851 unsigned int rap_group_sample = 0;
3852 int64_t last_dts = 0;
3853 int64_t dts_correction = 0;
3854 int rap_group_present = sc->rap_group_count && sc->rap_group;
3855 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
3857 current_dts -= sc->dts_shift;
3858 last_dts = current_dts;
3860 if (!sc->sample_count || st->internal->nb_index_entries)
3862 if (sc->sample_count >= UINT_MAX / sizeof(*st->internal->index_entries) - st->internal->nb_index_entries)
3864 if (av_reallocp_array(&st->internal->index_entries,
3865 st->internal->nb_index_entries + sc->sample_count,
3866 sizeof(*st->internal->index_entries)) < 0) {
3867 st->internal->nb_index_entries = 0;
3870 st->internal->index_entries_allocated_size = (st->internal->nb_index_entries + sc->sample_count) * sizeof(*st->internal->index_entries);
3872 if (ctts_data_old) {
3873 // Expand ctts entries such that we have a 1-1 mapping with samples
3874 if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
3877 sc->ctts_allocated_size = 0;
3878 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size,
3879 sc->sample_count * sizeof(*sc->ctts_data));
3880 if (!sc->ctts_data) {
3881 av_free(ctts_data_old);
3885 memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
3887 for (i = 0; i < ctts_count_old &&
3888 sc->ctts_count < sc->sample_count; i++)
3889 for (j = 0; j < ctts_data_old[i].count &&
3890 sc->ctts_count < sc->sample_count; j++)
3891 add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
3892 &sc->ctts_allocated_size, 1,
3893 ctts_data_old[i].duration);
3894 av_free(ctts_data_old);
3897 for (i = 0; i < sc->chunk_count; i++) {
3898 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
3899 current_offset = sc->chunk_offsets[i];
3900 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3901 i + 1 == sc->stsc_data[stsc_index + 1].first)
3904 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
3905 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
3906 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
3907 sc->stsz_sample_size = sc->sample_size;
3909 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
3910 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
3911 sc->stsz_sample_size = sc->sample_size;
3914 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
3916 if (current_sample >= sc->sample_count) {
3917 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
3921 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
3923 if (stss_index + 1 < sc->keyframe_count)
3925 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
3927 if (stps_index + 1 < sc->stps_count)
3930 if (rap_group_present && rap_group_index < sc->rap_group_count) {
3931 if (sc->rap_group[rap_group_index].index > 0)
3933 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
3934 rap_group_sample = 0;
3938 if (sc->keyframe_absent
3940 && !rap_group_present
3941 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
3945 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
3946 if (sc->pseudo_stream_id == -1 ||
3947 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
3949 if (sample_size > 0x3FFFFFFF) {
3950 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
3953 e = &st->internal->index_entries[st->internal->nb_index_entries++];
3954 e->pos = current_offset;
3955 e->timestamp = current_dts;
3956 e->size = sample_size;
3957 e->min_distance = distance;
3958 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
3959 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
3960 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
3961 current_offset, current_dts, sample_size, distance, keyframe);
3962 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->internal->nb_index_entries < 100)
3963 ff_rfps_add_frame(mov->fc, st, current_dts);
3966 current_offset += sample_size;
3967 stream_size += sample_size;
3969 /* A negative sample duration is invalid based on the spec,
3970 * but some samples need it to correct the DTS. */
3971 if (sc->stts_data[stts_index].duration < 0) {
3972 av_log(mov->fc, AV_LOG_WARNING,
3973 "Invalid SampleDelta %d in STTS, at %d st:%d\n",
3974 sc->stts_data[stts_index].duration, stts_index,
3976 dts_correction += sc->stts_data[stts_index].duration - 1;
3977 sc->stts_data[stts_index].duration = 1;
3979 current_dts += sc->stts_data[stts_index].duration;
3980 if (!dts_correction || current_dts + dts_correction > last_dts) {
3981 current_dts += dts_correction;
3984 /* Avoid creating non-monotonous DTS */
3985 dts_correction += current_dts - last_dts - 1;
3986 current_dts = last_dts + 1;
3988 last_dts = current_dts;
3992 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
3998 if (st->duration > 0)
3999 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
4001 unsigned chunk_samples, total = 0;
4003 if (!sc->chunk_count)
4006 // compute total chunk count
4007 for (i = 0; i < sc->stsc_count; i++) {
4008 unsigned count, chunk_count;
4010 chunk_samples = sc->stsc_data[i].count;
4011 if (i != sc->stsc_count - 1 &&
4012 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
4013 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
4017 if (sc->samples_per_frame >= 160) { // gsm
4018 count = chunk_samples / sc->samples_per_frame;
4019 } else if (sc->samples_per_frame > 1) {
4020 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4021 count = (chunk_samples+samples-1) / samples;
4023 count = (chunk_samples+1023) / 1024;
4026 if (mov_stsc_index_valid(i, sc->stsc_count))
4027 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4029 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4030 total += chunk_count * count;
4033 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4034 if (total >= UINT_MAX / sizeof(*st->internal->index_entries) - st->internal->nb_index_entries)
4036 if (av_reallocp_array(&st->internal->index_entries,
4037 st->internal->nb_index_entries + total,
4038 sizeof(*st->internal->index_entries)) < 0) {
4039 st->internal->nb_index_entries = 0;
4042 st->internal->index_entries_allocated_size = (st->internal->nb_index_entries + total) * sizeof(*st->internal->index_entries);
4045 for (i = 0; i < sc->chunk_count; i++) {
4046 current_offset = sc->chunk_offsets[i];
4047 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4048 i + 1 == sc->stsc_data[stsc_index + 1].first)
4050 chunk_samples = sc->stsc_data[stsc_index].count;
4052 while (chunk_samples > 0) {
4054 unsigned size, samples;
4056 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4057 avpriv_request_sample(mov->fc,
4058 "Zero bytes per frame, but %d samples per frame",
4059 sc->samples_per_frame);
4063 if (sc->samples_per_frame >= 160) { // gsm
4064 samples = sc->samples_per_frame;
4065 size = sc->bytes_per_frame;
4067 if (sc->samples_per_frame > 1) {
4068 samples = FFMIN((1024 / sc->samples_per_frame)*
4069 sc->samples_per_frame, chunk_samples);
4070 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
4072 samples = FFMIN(1024, chunk_samples);
4073 size = samples * sc->sample_size;
4077 if (st->internal->nb_index_entries >= total) {
4078 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4081 if (size > 0x3FFFFFFF) {
4082 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4085 e = &st->internal->index_entries[st->internal->nb_index_entries++];
4086 e->pos = current_offset;
4087 e->timestamp = current_dts;
4089 e->min_distance = 0;
4090 e->flags = AVINDEX_KEYFRAME;
4091 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4092 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4095 current_offset += size;
4096 current_dts += samples;
4097 chunk_samples -= samples;
4102 if (!mov->ignore_editlist && mov->advanced_editlist) {
4103 // Fix index according to edit lists.
4104 mov_fix_index(mov, st);
4107 // Update start time of the stream.
4108 if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->internal->nb_index_entries > 0) {
4109 st->start_time = st->internal->index_entries[0].timestamp + sc->dts_shift;
4110 if (sc->ctts_data) {
4111 st->start_time += sc->ctts_data[0].duration;
4115 mov_estimate_video_delay(mov, st);
4118 static int test_same_origin(const char *src, const char *ref) {
4128 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4129 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4131 if (strlen(src) == 0) {
4133 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4134 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4135 strlen(src_host) + 1 >= sizeof(src_host) ||
4136 strlen(ref_host) + 1 >= sizeof(ref_host)) {
4138 } else if (strcmp(src_proto, ref_proto) ||
4139 strcmp(src_auth, ref_auth) ||
4140 strcmp(src_host, ref_host) ||
4141 src_port != ref_port) {
4147 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4149 /* try relative path, we do not try the absolute because it can leak information about our
4150 system to an attacker */
4151 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4152 char filename[1025];
4153 const char *src_path;
4156 /* find a source dir */
4157 src_path = strrchr(src, '/');
4163 /* find a next level down to target */
4164 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4165 if (ref->path[l] == '/') {
4166 if (i == ref->nlvl_to - 1)
4172 /* compose filename if next level down to target was found */
4173 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4174 memcpy(filename, src, src_path - src);
4175 filename[src_path - src] = 0;
4177 for (i = 1; i < ref->nlvl_from; i++)
4178 av_strlcat(filename, "../", sizeof(filename));
4180 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4181 if (!c->use_absolute_path) {
4182 int same_origin = test_same_origin(src, filename);
4185 av_log(c->fc, AV_LOG_ERROR,
4186 "Reference with mismatching origin, %s not tried for security reasons, "
4187 "set demuxer option use_absolute_path to allow it anyway\n",
4189 return AVERROR(ENOENT);
4192 if (strstr(ref->path + l + 1, "..") ||
4193 strstr(ref->path + l + 1, ":") ||
4194 (ref->nlvl_from > 1 && same_origin < 0) ||
4195 (filename[0] == '/' && src_path == src))
4196 return AVERROR(ENOENT);
4199 if (strlen(filename) + 1 == sizeof(filename))
4200 return AVERROR(ENOENT);
4201 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4204 } else if (c->use_absolute_path) {
4205 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4206 "this is a possible security issue\n");
4207 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4210 av_log(c->fc, AV_LOG_ERROR,
4211 "Absolute path %s not tried for security reasons, "
4212 "set demuxer option use_absolute_path to allow absolute paths\n",
4216 return AVERROR(ENOENT);
4219 static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
4221 if (sc->time_scale <= 0) {
4222 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4223 sc->time_scale = c->time_scale;
4224 if (sc->time_scale <= 0)
4229 static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4232 MOVStreamContext *sc;
4235 st = avformat_new_stream(c->fc, NULL);
4236 if (!st) return AVERROR(ENOMEM);
4238 sc = av_mallocz(sizeof(MOVStreamContext));
4239 if (!sc) return AVERROR(ENOMEM);
4242 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
4243 sc->ffindex = st->index;
4244 c->trak_index = st->index;
4246 if ((ret = mov_read_default(c, pb, atom)) < 0)
4251 // Here stsc refers to a chunk not described in stco. This is technically invalid,
4252 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4253 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4255 av_freep(&sc->stsc_data);
4259 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4260 (!sc->sample_size && !sc->sample_count))) ||
4261 (!sc->chunk_count && sc->sample_count)) {
4262 av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4266 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4267 av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4269 return AVERROR_INVALIDDATA;
4272 fix_timescale(c, sc);
4274 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4276 mov_build_index(c, st);
4278 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4279 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4280 if (c->enable_drefs) {
4281 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4282 av_log(c->fc, AV_LOG_ERROR,
4283 "stream %d, error opening alias: path='%s', dir='%s', "
4284 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4285 st->index, dref->path, dref->dir, dref->filename,
4286 dref->volume, dref->nlvl_from, dref->nlvl_to);
4288 av_log(c->fc, AV_LOG_WARNING,
4289 "Skipped opening external track: "
4290 "stream %d, alias: path='%s', dir='%s', "
4291 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4292 "Set enable_drefs to allow this.\n",
4293 st->index, dref->path, dref->dir, dref->filename,
4294 dref->volume, dref->nlvl_from, dref->nlvl_to);
4298 sc->pb_is_copied = 1;
4301 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4302 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4303 sc->height && sc->width &&
4304 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4305 st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4306 ((double)st->codecpar->width * sc->height), INT_MAX);
4309 #if FF_API_R_FRAME_RATE
4310 if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4311 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
4312 sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4316 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4317 if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4318 TAG_IS_AVCI(st->codecpar->codec_tag)) {
4319 ret = ff_generate_avci_extradata(st);
4324 switch (st->codecpar->codec_id) {
4325 #if CONFIG_H261_DECODER
4326 case AV_CODEC_ID_H261:
4328 #if CONFIG_H263_DECODER
4329 case AV_CODEC_ID_H263:
4331 #if CONFIG_MPEG4_DECODER
4332 case AV_CODEC_ID_MPEG4:
4334 st->codecpar->width = 0; /* let decoder init width/height */
4335 st->codecpar->height= 0;
4339 // If the duration of the mp3 packets is not constant, then they could need a parser
4340 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4341 && sc->stts_count > 3
4342 && sc->stts_count*10 > st->nb_frames
4343 && sc->time_scale == st->codecpar->sample_rate) {
4344 st->need_parsing = AVSTREAM_PARSE_FULL;
4346 /* Do not need those anymore. */
4347 av_freep(&sc->chunk_offsets);
4348 av_freep(&sc->sample_sizes);
4349 av_freep(&sc->keyframes);
4350 av_freep(&sc->stts_data);
4351 av_freep(&sc->stps_data);
4352 av_freep(&sc->elst_data);
4353 av_freep(&sc->rap_group);
4358 static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4361 c->itunes_metadata = 1;
4362 ret = mov_read_default(c, pb, atom);
4363 c->itunes_metadata = 0;
4367 static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4376 count = avio_rb32(pb);
4377 if (count > UINT_MAX / sizeof(*c->meta_keys) - 1) {
4378 av_log(c->fc, AV_LOG_ERROR,
4379 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
4380 return AVERROR_INVALIDDATA;
4383 c->meta_keys_count = count + 1;
4384 c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
4386 return AVERROR(ENOMEM);
4388 for (i = 1; i <= count; ++i) {
4389 uint32_t key_size = avio_rb32(pb);
4390 uint32_t type = avio_rl32(pb);
4392 av_log(c->fc, AV_LOG_ERROR,
4393 "The key# %"PRIu32" in meta has invalid size:"
4394 "%"PRIu32"\n", i, key_size);
4395 return AVERROR_INVALIDDATA;
4398 if (type != MKTAG('m','d','t','a')) {
4399 avio_skip(pb, key_size);
4401 c->meta_keys[i] = av_mallocz(key_size + 1);
4402 if (!c->meta_keys[i])
4403 return AVERROR(ENOMEM);
4404 avio_read(pb, c->meta_keys[i], key_size);
4410 static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4412 int64_t end = avio_tell(pb) + atom.size;
4413 uint8_t *key = NULL, *val = NULL, *mean = NULL;
4417 MOVStreamContext *sc;
4419 if (c->fc->nb_streams < 1)
4421 st = c->fc->streams[c->fc->nb_streams-1];
4424 for (i = 0; i < 3; i++) {
4428 if (end - avio_tell(pb) <= 12)
4431 len = avio_rb32(pb);
4432 tag = avio_rl32(pb);
4433 avio_skip(pb, 4); // flags
4435 if (len < 12 || len - 12 > end - avio_tell(pb))
4439 if (tag == MKTAG('m', 'e', 'a', 'n'))
4441 else if (tag == MKTAG('n', 'a', 'm', 'e'))
4443 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
4453 *p = av_malloc(len + 1);
4455 ret = AVERROR(ENOMEM);
4458 ret = ffio_read_size(pb, *p, len);
4466 if (mean && key && val) {
4467 if (strcmp(key, "iTunSMPB") == 0) {
4468 int priming, remainder, samples;
4469 if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
4470 if(priming>0 && priming<16384)
4471 sc->start_pad = priming;
4474 if (strcmp(key, "cdec") != 0) {
4475 av_dict_set(&c->fc->metadata, key, val,
4476 AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
4480 av_log(c->fc, AV_LOG_VERBOSE,
4481 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
4484 avio_seek(pb, end, SEEK_SET);
4491 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4493 while (atom.size > 8) {
4497 tag = avio_rl32(pb);
4499 if (tag == MKTAG('h','d','l','r')) {
4500 avio_seek(pb, -8, SEEK_CUR);
4502 return mov_read_default(c, pb, atom);
4508 // return 1 when matrix is identity, 0 otherwise
4509 #define IS_MATRIX_IDENT(matrix) \
4510 ( (matrix)[0][0] == (1 << 16) && \
4511 (matrix)[1][1] == (1 << 16) && \
4512 (matrix)[2][2] == (1 << 30) && \
4513 !(matrix)[0][1] && !(matrix)[0][2] && \
4514 !(matrix)[1][0] && !(matrix)[1][2] && \
4515 !(matrix)[2][0] && !(matrix)[2][1])
4517 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4522 int display_matrix[3][3];
4523 int res_display_matrix[3][3] = { { 0 } };
4525 MOVStreamContext *sc;
4529 if (c->fc->nb_streams < 1)
4531 st = c->fc->streams[c->fc->nb_streams-1];
4534 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4535 // avoids corrupting AVStreams mapped to an earlier tkhd.
4537 return AVERROR_INVALIDDATA;
4539 version = avio_r8(pb);
4540 flags = avio_rb24(pb);
4541 st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
4547 avio_rb32(pb); /* creation time */
4548 avio_rb32(pb); /* modification time */
4550 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4551 avio_rb32(pb); /* reserved */
4553 /* highlevel (considering edits) duration in movie timebase */
4554 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4555 avio_rb32(pb); /* reserved */
4556 avio_rb32(pb); /* reserved */
4558 avio_rb16(pb); /* layer */
4559 avio_rb16(pb); /* alternate group */
4560 avio_rb16(pb); /* volume */
4561 avio_rb16(pb); /* reserved */
4563 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4564 // they're kept in fixed point format through all calculations
4565 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4566 // side data, but the scale factor is not needed to calculate aspect ratio
4567 for (i = 0; i < 3; i++) {
4568 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
4569 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
4570 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
4573 width = avio_rb32(pb); // 16.16 fixed point track width
4574 height = avio_rb32(pb); // 16.16 fixed point track height
4575 sc->width = width >> 16;
4576 sc->height = height >> 16;
4578 // apply the moov display matrix (after the tkhd one)
4579 for (i = 0; i < 3; i++) {
4580 const int sh[3] = { 16, 16, 30 };
4581 for (j = 0; j < 3; j++) {
4582 for (e = 0; e < 3; e++) {
4583 res_display_matrix[i][j] +=
4584 ((int64_t) display_matrix[i][e] *
4585 c->movie_display_matrix[e][j]) >> sh[e];
4590 // save the matrix when it is not the default identity
4591 if (!IS_MATRIX_IDENT(res_display_matrix)) {
4594 av_freep(&sc->display_matrix);
4595 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4596 if (!sc->display_matrix)
4597 return AVERROR(ENOMEM);
4599 for (i = 0; i < 3; i++)
4600 for (j = 0; j < 3; j++)
4601 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4603 #if FF_API_OLD_ROTATE_API
4604 rotate = av_display_rotation_get(sc->display_matrix);
4605 if (!isnan(rotate)) {
4606 char rotate_buf[64];
4608 if (rotate < 0) // for backward compatibility
4610 snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate);
4611 av_dict_set(&st->metadata, "rotate", rotate_buf, 0);
4616 // transform the display width/height according to the matrix
4617 // to keep the same scale, use [width height 1<<16]
4618 if (width && height && sc->display_matrix) {
4619 double disp_transform[2];
4621 for (i = 0; i < 2; i++)
4622 disp_transform[i] = hypot(sc->display_matrix[0 + i],
4623 sc->display_matrix[3 + i]);
4625 if (disp_transform[0] > 0 && disp_transform[1] > 0 &&
4626 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4627 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4628 st->sample_aspect_ratio = av_d2q(
4629 disp_transform[0] / disp_transform[1],
4635 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4637 MOVFragment *frag = &c->fragment;
4638 MOVTrackExt *trex = NULL;
4639 int flags, track_id, i;
4640 MOVFragmentStreamInfo * frag_stream_info;
4642 avio_r8(pb); /* version */
4643 flags = avio_rb24(pb);
4645 track_id = avio_rb32(pb);
4647 return AVERROR_INVALIDDATA;
4648 for (i = 0; i < c->trex_count; i++)
4649 if (c->trex_data[i].track_id == track_id) {
4650 trex = &c->trex_data[i];
4654 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4657 c->fragment.found_tfhd = 1;
4658 frag->track_id = track_id;
4659 set_frag_stream(&c->frag_index, track_id);
4661 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4662 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4663 frag->moof_offset : frag->implicit_offset;
4664 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4666 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4667 avio_rb32(pb) : trex->duration;
4668 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4669 avio_rb32(pb) : trex->size;
4670 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4671 avio_rb32(pb) : trex->flags;
4672 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4674 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4675 if (frag_stream_info)
4676 frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
4681 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4686 num = atom.size / 4;
4687 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4688 return AVERROR(ENOMEM);
4690 av_free(c->chapter_tracks);
4691 c->chapter_tracks = new_tracks;
4692 c->nb_chapter_tracks = num;
4694 for (i = 0; i < num && !pb->eof_reached; i++)
4695 c->chapter_tracks[i] = avio_rb32(pb);
4700 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4705 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4706 return AVERROR_INVALIDDATA;
4707 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4708 sizeof(*c->trex_data))) < 0) {
4713 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4715 trex = &c->trex_data[c->trex_count++];
4716 avio_r8(pb); /* version */
4717 avio_rb24(pb); /* flags */
4718 trex->track_id = avio_rb32(pb);
4719 trex->stsd_id = avio_rb32(pb);
4720 trex->duration = avio_rb32(pb);
4721 trex->size = avio_rb32(pb);
4722 trex->flags = avio_rb32(pb);
4726 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4728 MOVFragment *frag = &c->fragment;
4729 AVStream *st = NULL;
4730 MOVStreamContext *sc;
4732 MOVFragmentStreamInfo * frag_stream_info;
4733 int64_t base_media_decode_time;
4735 for (i = 0; i < c->fc->nb_streams; i++) {
4736 if (c->fc->streams[i]->id == frag->track_id) {
4737 st = c->fc->streams[i];
4742 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4746 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4748 version = avio_r8(pb);
4749 avio_rb24(pb); /* flags */
4751 base_media_decode_time = avio_rb64(pb);
4753 base_media_decode_time = avio_rb32(pb);
4756 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4757 if (frag_stream_info)
4758 frag_stream_info->tfdt_dts = base_media_decode_time;
4759 sc->track_end = base_media_decode_time;
4764 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4766 MOVFragment *frag = &c->fragment;
4767 AVStream *st = NULL;
4768 MOVStreamContext *sc;
4771 int64_t dts, pts = AV_NOPTS_VALUE;
4772 int data_offset = 0;
4773 unsigned entries, first_sample_flags = frag->flags;
4774 int flags, distance, i;
4775 int64_t prev_dts = AV_NOPTS_VALUE;
4776 int next_frag_index = -1, index_entry_pos;
4777 size_t requested_size;
4778 size_t old_ctts_allocated_size;
4779 AVIndexEntry *new_entries;
4780 MOVFragmentStreamInfo * frag_stream_info;
4782 if (!frag->found_tfhd) {
4783 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4784 return AVERROR_INVALIDDATA;
4787 for (i = 0; i < c->fc->nb_streams; i++) {
4788 if (c->fc->streams[i]->id == frag->track_id) {
4789 st = c->fc->streams[i];
4794 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4798 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4801 // Find the next frag_index index that has a valid index_entry for
4802 // the current track_id.
4804 // A valid index_entry means the trun for the fragment was read
4805 // and it's samples are in index_entries at the given position.
4806 // New index entries will be inserted before the index_entry found.
4807 index_entry_pos = st->internal->nb_index_entries;
4808 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4809 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4810 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4811 next_frag_index = i;
4812 index_entry_pos = frag_stream_info->index_entry;
4816 av_assert0(index_entry_pos <= st->internal->nb_index_entries);
4818 avio_r8(pb); /* version */
4819 flags = avio_rb24(pb);
4820 entries = avio_rb32(pb);
4821 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4823 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4824 return AVERROR_INVALIDDATA;
4825 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4826 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4828 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4829 if (frag_stream_info) {
4830 if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
4831 dts = frag_stream_info->next_trun_dts - sc->time_offset;
4832 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4833 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4834 pts = frag_stream_info->first_tfra_pts;
4835 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4836 ", using it for pts\n", pts);
4837 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4838 c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
4839 dts = frag_stream_info->first_tfra_pts;
4840 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4841 ", using it for dts\n", pts);
4842 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4843 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4844 // pts = frag_stream_info->sidx_pts;
4845 dts = frag_stream_info->sidx_pts - sc->time_offset;
4846 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4847 ", using it for pts\n", pts);
4848 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4849 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4850 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4851 ", using it for dts\n", dts);
4853 dts = sc->track_end - sc->time_offset;
4854 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4855 ", using it for dts\n", dts);
4858 dts = sc->track_end - sc->time_offset;
4859 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4860 ", using it for dts\n", dts);
4862 offset = frag->base_data_offset + data_offset;
4864 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4866 // realloc space for new index entries
4867 if((uint64_t)st->internal->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4868 entries = UINT_MAX / sizeof(AVIndexEntry) - st->internal->nb_index_entries;
4869 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4874 requested_size = (st->internal->nb_index_entries + entries) * sizeof(AVIndexEntry);
4875 new_entries = av_fast_realloc(st->internal->index_entries,
4876 &st->internal->index_entries_allocated_size,
4879 return AVERROR(ENOMEM);
4880 st->internal->index_entries= new_entries;
4882 requested_size = (st->internal->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4883 old_ctts_allocated_size = sc->ctts_allocated_size;
4884 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4887 return AVERROR(ENOMEM);
4888 sc->ctts_data = ctts_data;
4890 // In case there were samples without ctts entries, ensure they get
4891 // zero valued entries. This ensures clips which mix boxes with and
4892 // without ctts entries don't pickup uninitialized data.
4893 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4894 sc->ctts_allocated_size - old_ctts_allocated_size);
4896 if (index_entry_pos < st->internal->nb_index_entries) {
4897 // Make hole in index_entries and ctts_data for new samples
4898 memmove(st->internal->index_entries + index_entry_pos + entries,
4899 st->internal->index_entries + index_entry_pos,
4900 sizeof(*st->internal->index_entries) *
4901 (st->internal->nb_index_entries - index_entry_pos));
4902 memmove(sc->ctts_data + index_entry_pos + entries,
4903 sc->ctts_data + index_entry_pos,
4904 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4905 if (index_entry_pos < sc->current_sample) {
4906 sc->current_sample += entries;
4910 st->internal->nb_index_entries += entries;
4911 sc->ctts_count = st->internal->nb_index_entries;
4913 // Record the index_entry position in frag_index of this fragment
4914 if (frag_stream_info)
4915 frag_stream_info->index_entry = index_entry_pos;
4917 if (index_entry_pos > 0)
4918 prev_dts = st->internal->index_entries[index_entry_pos-1].timestamp;
4920 for (i = 0; i < entries && !pb->eof_reached; i++) {
4921 unsigned sample_size = frag->size;
4922 int sample_flags = i ? frag->flags : first_sample_flags;
4923 unsigned sample_duration = frag->duration;
4924 unsigned ctts_duration = 0;
4926 int index_entry_flags = 0;
4928 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4929 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4930 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4931 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4933 mov_update_dts_shift(sc, ctts_duration, c->fc);
4934 if (pts != AV_NOPTS_VALUE) {
4935 dts = pts - sc->dts_shift;
4936 if (flags & MOV_TRUN_SAMPLE_CTS) {
4937 dts -= ctts_duration;
4939 dts -= sc->time_offset;
4941 av_log(c->fc, AV_LOG_DEBUG,
4942 "pts %"PRId64" calculated dts %"PRId64
4943 " sc->dts_shift %d ctts.duration %d"
4944 " sc->time_offset %"PRId64
4945 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4947 sc->dts_shift, ctts_duration,
4948 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4949 pts = AV_NOPTS_VALUE;
4952 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4956 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4957 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4960 index_entry_flags |= AVINDEX_KEYFRAME;
4962 // Fragments can overlap in time. Discard overlapping frames after
4964 if (prev_dts >= dts)
4965 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4967 st->internal->index_entries[index_entry_pos].pos = offset;
4968 st->internal->index_entries[index_entry_pos].timestamp = dts;
4969 st->internal->index_entries[index_entry_pos].size= sample_size;
4970 st->internal->index_entries[index_entry_pos].min_distance= distance;
4971 st->internal->index_entries[index_entry_pos].flags = index_entry_flags;
4973 sc->ctts_data[index_entry_pos].count = 1;
4974 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4977 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4978 "size %u, distance %d, keyframe %d\n", st->index,
4979 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4981 dts += sample_duration;
4982 offset += sample_size;
4983 sc->data_size += sample_size;
4985 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4986 1 <= INT_MAX - sc->nb_frames_for_fps
4988 sc->duration_for_fps += sample_duration;
4989 sc->nb_frames_for_fps ++;
4992 if (frag_stream_info)
4993 frag_stream_info->next_trun_dts = dts + sc->time_offset;
4995 // EOF found before reading all entries. Fix the hole this would
4996 // leave in index_entries and ctts_data
4997 int gap = entries - i;
4998 memmove(st->internal->index_entries + index_entry_pos,
4999 st->internal->index_entries + index_entry_pos + gap,
5000 sizeof(*st->internal->index_entries) *
5001 (st->internal->nb_index_entries - (index_entry_pos + gap)));
5002 memmove(sc->ctts_data + index_entry_pos,
5003 sc->ctts_data + index_entry_pos + gap,
5004 sizeof(*sc->ctts_data) *
5005 (sc->ctts_count - (index_entry_pos + gap)));
5007 st->internal->nb_index_entries -= gap;
5008 sc->ctts_count -= gap;
5009 if (index_entry_pos < sc->current_sample) {
5010 sc->current_sample -= gap;
5015 // The end of this new fragment may overlap in time with the start
5016 // of the next fragment in index_entries. Mark the samples in the next
5017 // fragment that overlap with AVINDEX_DISCARD_FRAME
5018 prev_dts = AV_NOPTS_VALUE;
5019 if (index_entry_pos > 0)
5020 prev_dts = st->internal->index_entries[index_entry_pos-1].timestamp;
5021 for (i = index_entry_pos; i < st->internal->nb_index_entries; i++) {
5022 if (prev_dts < st->internal->index_entries[i].timestamp)
5024 st->internal->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
5027 // If a hole was created to insert the new index_entries into,
5028 // the index_entry recorded for all subsequent moof must
5029 // be incremented by the number of entries inserted.
5030 fix_frag_index_entries(&c->frag_index, next_frag_index,
5031 frag->track_id, entries);
5033 if (pb->eof_reached) {
5034 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
5038 frag->implicit_offset = offset;
5040 sc->track_end = dts + sc->time_offset;
5041 if (st->duration < sc->track_end)
5042 st->duration = sc->track_end;
5047 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5049 int64_t stream_size = avio_size(pb);
5050 int64_t offset = avio_tell(pb) + atom.size, pts, timestamp;
5051 uint8_t version, is_complete;
5052 unsigned i, j, track_id, item_count;
5053 AVStream *st = NULL;
5054 AVStream *ref_st = NULL;
5055 MOVStreamContext *sc, *ref_sc = NULL;
5056 AVRational timescale;
5058 version = avio_r8(pb);
5060 avpriv_request_sample(c->fc, "sidx version %u", version);
5064 avio_rb24(pb); // flags
5066 track_id = avio_rb32(pb); // Reference ID
5067 for (i = 0; i < c->fc->nb_streams; i++) {
5068 if (c->fc->streams[i]->id == track_id) {
5069 st = c->fc->streams[i];
5074 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5080 timescale = av_make_q(1, avio_rb32(pb));
5082 if (timescale.den <= 0) {
5083 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5084 return AVERROR_INVALIDDATA;
5088 pts = avio_rb32(pb);
5089 offset += avio_rb32(pb);
5091 pts = avio_rb64(pb);
5092 offset += avio_rb64(pb);
5095 avio_rb16(pb); // reserved
5097 item_count = avio_rb16(pb);
5099 for (i = 0; i < item_count; i++) {
5101 MOVFragmentStreamInfo * frag_stream_info;
5102 uint32_t size = avio_rb32(pb);
5103 uint32_t duration = avio_rb32(pb);
5104 if (size & 0x80000000) {
5105 avpriv_request_sample(c->fc, "sidx reference_type 1");
5106 return AVERROR_PATCHWELCOME;
5108 avio_rb32(pb); // sap_flags
5109 timestamp = av_rescale_q(pts, timescale, st->time_base);
5111 index = update_frag_index(c, offset);
5112 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5113 if (frag_stream_info)
5114 frag_stream_info->sidx_pts = timestamp;
5120 st->duration = sc->track_end = pts;
5124 // See if the remaining bytes are just an mfra which we can ignore.
5125 is_complete = offset == stream_size;
5126 if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL)) {
5128 int64_t original_pos = avio_tell(pb);
5129 if (!c->have_read_mfra_size) {
5130 if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
5132 c->mfra_size = avio_rb32(pb);
5133 c->have_read_mfra_size = 1;
5134 if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
5137 if (offset + c->mfra_size == stream_size)
5142 // Find first entry in fragment index that came from an sidx.
5143 // This will pretty much always be the first entry.
5144 for (i = 0; i < c->frag_index.nb_items; i++) {
5145 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5146 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5147 MOVFragmentStreamInfo * si;
5148 si = &item->stream_info[j];
5149 if (si->sidx_pts != AV_NOPTS_VALUE) {
5150 ref_st = c->fc->streams[j];
5151 ref_sc = ref_st->priv_data;
5156 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5157 st = c->fc->streams[i];
5159 if (!sc->has_sidx) {
5160 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5164 c->frag_index.complete = 1;
5170 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5171 /* like the files created with Adobe Premiere 5.0, for samples see */
5172 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5173 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5178 return 0; /* continue */
5179 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5180 avio_skip(pb, atom.size - 4);
5183 atom.type = avio_rl32(pb);
5185 if (atom.type != MKTAG('m','d','a','t')) {
5186 avio_skip(pb, atom.size);
5189 err = mov_read_mdat(c, pb, atom);
5193 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5198 uint8_t *moov_data; /* uncompressed data */
5199 long cmov_len, moov_len;
5202 avio_rb32(pb); /* dcom atom */
5203 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5204 return AVERROR_INVALIDDATA;
5205 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5206 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5207 return AVERROR_INVALIDDATA;
5209 avio_rb32(pb); /* cmvd atom */
5210 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5211 return AVERROR_INVALIDDATA;
5212 moov_len = avio_rb32(pb); /* uncompressed size */
5213 cmov_len = atom.size - 6 * 4;
5215 cmov_data = av_malloc(cmov_len);
5217 return AVERROR(ENOMEM);
5218 moov_data = av_malloc(moov_len);
5221 return AVERROR(ENOMEM);
5223 ret = ffio_read_size(pb, cmov_data, cmov_len);
5225 goto free_and_return;
5227 ret = AVERROR_INVALIDDATA;
5228 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5229 goto free_and_return;
5230 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5231 goto free_and_return;
5232 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5233 atom.type = MKTAG('m','o','o','v');
5234 atom.size = moov_len;
5235 ret = mov_read_default(c, &ctx, atom);
5241 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5242 return AVERROR(ENOSYS);
5246 /* edit list atom */
5247 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5249 MOVStreamContext *sc;
5250 int i, edit_count, version;
5251 int64_t elst_entry_size;
5253 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5255 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5257 version = avio_r8(pb); /* version */
5258 avio_rb24(pb); /* flags */
5259 edit_count = avio_rb32(pb); /* entries */
5262 elst_entry_size = version == 1 ? 20 : 12;
5263 if (atom.size != edit_count * elst_entry_size) {
5264 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5265 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5266 edit_count, atom.size + 8);
5267 return AVERROR_INVALIDDATA;
5269 edit_count = atom.size / elst_entry_size;
5270 if (edit_count * elst_entry_size != atom.size) {
5271 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
5279 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5280 av_free(sc->elst_data);
5282 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5284 return AVERROR(ENOMEM);
5286 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5287 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5288 MOVElst *e = &sc->elst_data[i];
5291 e->duration = avio_rb64(pb);
5292 e->time = avio_rb64(pb);
5295 e->duration = avio_rb32(pb); /* segment duration */
5296 e->time = (int32_t)avio_rb32(pb); /* media time */
5299 e->rate = avio_rb32(pb) / 65536.0;
5301 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5302 e->duration, e->time, e->rate);
5304 if (e->time < 0 && e->time != -1 &&
5305 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5306 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5307 c->fc->nb_streams-1, i, e->time);
5308 return AVERROR_INVALIDDATA;
5316 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5318 MOVStreamContext *sc;
5320 if (c->fc->nb_streams < 1)
5321 return AVERROR_INVALIDDATA;
5322 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5323 sc->timecode_track = avio_rb32(pb);
5327 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5332 if (c->fc->nb_streams < 1)
5334 st = c->fc->streams[c->fc->nb_streams - 1];
5336 if (atom.size < 4) {
5337 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5338 return AVERROR_INVALIDDATA;
5341 /* For now, propagate only the OBUs, if any. Once libavcodec is
5342 updated to handle isobmff style extradata this can be removed. */
5348 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5355 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5358 int version, color_range, color_primaries, color_trc, color_space;
5360 if (c->fc->nb_streams < 1)
5362 st = c->fc->streams[c->fc->nb_streams - 1];
5364 if (atom.size < 5) {
5365 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5366 return AVERROR_INVALIDDATA;
5369 version = avio_r8(pb);
5371 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5374 avio_skip(pb, 3); /* flags */
5376 avio_skip(pb, 2); /* profile + level */
5377 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5378 color_primaries = avio_r8(pb);
5379 color_trc = avio_r8(pb);
5380 color_space = avio_r8(pb);
5381 if (avio_rb16(pb)) /* codecIntializationDataSize */
5382 return AVERROR_INVALIDDATA;
5384 if (!av_color_primaries_name(color_primaries))
5385 color_primaries = AVCOL_PRI_UNSPECIFIED;
5386 if (!av_color_transfer_name(color_trc))
5387 color_trc = AVCOL_TRC_UNSPECIFIED;
5388 if (!av_color_space_name(color_space))
5389 color_space = AVCOL_SPC_UNSPECIFIED;
5391 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5392 st->codecpar->color_primaries = color_primaries;
5393 st->codecpar->color_trc = color_trc;
5394 st->codecpar->color_space = color_space;
5399 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5401 MOVStreamContext *sc;
5404 if (c->fc->nb_streams < 1)
5405 return AVERROR_INVALIDDATA;
5407 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5409 if (atom.size < 5) {
5410 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5411 return AVERROR_INVALIDDATA;
5414 version = avio_r8(pb);
5416 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5419 avio_skip(pb, 3); /* flags */
5421 sc->mastering = av_mastering_display_metadata_alloc();
5423 return AVERROR(ENOMEM);
5425 for (i = 0; i < 3; i++) {
5426 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5427 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5429 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5430 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5432 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5433 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5435 sc->mastering->has_primaries = 1;
5436 sc->mastering->has_luminance = 1;
5441 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5443 MOVStreamContext *sc;
5444 const int mapping[3] = {1, 2, 0};
5445 const int chroma_den = 50000;
5446 const int luma_den = 10000;
5449 if (c->fc->nb_streams < 1)
5450 return AVERROR_INVALIDDATA;
5452 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5454 if (atom.size < 24) {
5455 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5456 return AVERROR_INVALIDDATA;
5459 sc->mastering = av_mastering_display_metadata_alloc();
5461 return AVERROR(ENOMEM);
5463 for (i = 0; i < 3; i++) {
5464 const int j = mapping[i];
5465 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5466 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5468 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5469 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5471 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5472 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5474 sc->mastering->has_luminance = 1;
5475 sc->mastering->has_primaries = 1;
5480 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5482 MOVStreamContext *sc;
5485 if (c->fc->nb_streams < 1)
5486 return AVERROR_INVALIDDATA;
5488 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5490 if (atom.size < 5) {
5491 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5492 return AVERROR_INVALIDDATA;
5495 version = avio_r8(pb);
5497 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5500 avio_skip(pb, 3); /* flags */
5502 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5504 return AVERROR(ENOMEM);
5506 sc->coll->MaxCLL = avio_rb16(pb);
5507 sc->coll->MaxFALL = avio_rb16(pb);
5512 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5514 MOVStreamContext *sc;
5516 if (c->fc->nb_streams < 1)
5517 return AVERROR_INVALIDDATA;
5519 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5521 if (atom.size < 4) {
5522 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5523 return AVERROR_INVALIDDATA;
5526 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5528 return AVERROR(ENOMEM);
5530 sc->coll->MaxCLL = avio_rb16(pb);
5531 sc->coll->MaxFALL = avio_rb16(pb);
5536 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5539 MOVStreamContext *sc;
5540 enum AVStereo3DType type;
5543 if (c->fc->nb_streams < 1)
5546 st = c->fc->streams[c->fc->nb_streams - 1];
5549 if (atom.size < 5) {
5550 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5551 return AVERROR_INVALIDDATA;
5553 avio_skip(pb, 4); /* version + flags */
5558 type = AV_STEREO3D_2D;
5561 type = AV_STEREO3D_TOPBOTTOM;
5564 type = AV_STEREO3D_SIDEBYSIDE;
5567 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5571 sc->stereo3d = av_stereo3d_alloc();
5573 return AVERROR(ENOMEM);
5575 sc->stereo3d->type = type;
5579 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5582 MOVStreamContext *sc;
5583 int size, version, layout;
5584 int32_t yaw, pitch, roll;
5585 uint32_t l = 0, t = 0, r = 0, b = 0;
5586 uint32_t tag, padding = 0;
5587 enum AVSphericalProjection projection;
5589 if (c->fc->nb_streams < 1)
5592 st = c->fc->streams[c->fc->nb_streams - 1];
5595 if (atom.size < 8) {
5596 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5597 return AVERROR_INVALIDDATA;
5600 size = avio_rb32(pb);
5601 if (size <= 12 || size > atom.size)
5602 return AVERROR_INVALIDDATA;
5604 tag = avio_rl32(pb);
5605 if (tag != MKTAG('s','v','h','d')) {
5606 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5609 version = avio_r8(pb);
5611 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5615 avio_skip(pb, 3); /* flags */
5616 avio_skip(pb, size - 12); /* metadata_source */
5618 size = avio_rb32(pb);
5619 if (size > atom.size)
5620 return AVERROR_INVALIDDATA;
5622 tag = avio_rl32(pb);
5623 if (tag != MKTAG('p','r','o','j')) {
5624 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5628 size = avio_rb32(pb);
5629 if (size > atom.size)
5630 return AVERROR_INVALIDDATA;
5632 tag = avio_rl32(pb);
5633 if (tag != MKTAG('p','r','h','d')) {
5634 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5637 version = avio_r8(pb);
5639 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5643 avio_skip(pb, 3); /* flags */
5645 /* 16.16 fixed point */
5646 yaw = avio_rb32(pb);
5647 pitch = avio_rb32(pb);
5648 roll = avio_rb32(pb);
5650 size = avio_rb32(pb);
5651 if (size > atom.size)
5652 return AVERROR_INVALIDDATA;
5654 tag = avio_rl32(pb);
5655 version = avio_r8(pb);
5657 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5661 avio_skip(pb, 3); /* flags */
5663 case MKTAG('c','b','m','p'):
5664 layout = avio_rb32(pb);
5666 av_log(c->fc, AV_LOG_WARNING,
5667 "Unsupported cubemap layout %d\n", layout);
5670 projection = AV_SPHERICAL_CUBEMAP;
5671 padding = avio_rb32(pb);
5673 case MKTAG('e','q','u','i'):
5679 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5680 av_log(c->fc, AV_LOG_ERROR,
5681 "Invalid bounding rectangle coordinates "
5682 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5683 return AVERROR_INVALIDDATA;
5686 if (l || t || r || b)
5687 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5689 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5692 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5696 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5698 return AVERROR(ENOMEM);
5700 sc->spherical->projection = projection;
5702 sc->spherical->yaw = yaw;
5703 sc->spherical->pitch = pitch;
5704 sc->spherical->roll = roll;
5706 sc->spherical->padding = padding;
5708 sc->spherical->bound_left = l;
5709 sc->spherical->bound_top = t;
5710 sc->spherical->bound_right = r;
5711 sc->spherical->bound_bottom = b;
5716 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5719 uint8_t *buffer = av_malloc(len + 1);
5723 return AVERROR(ENOMEM);
5726 ret = ffio_read_size(pb, buffer, len);
5730 /* Check for mandatory keys and values, try to support XML as best-effort */
5731 if (!sc->spherical &&
5732 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5733 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5734 av_stristr(val, "true") &&
5735 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5736 av_stristr(val, "true") &&
5737 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5738 av_stristr(val, "equirectangular")) {
5739 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5743 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5745 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5746 enum AVStereo3DType mode;
5748 if (av_stristr(buffer, "left-right"))
5749 mode = AV_STEREO3D_SIDEBYSIDE;
5750 else if (av_stristr(buffer, "top-bottom"))
5751 mode = AV_STEREO3D_TOPBOTTOM;
5753 mode = AV_STEREO3D_2D;
5755 sc->stereo3d = av_stereo3d_alloc();
5759 sc->stereo3d->type = mode;
5763 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5765 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5766 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5768 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5769 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5771 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5779 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5782 MOVStreamContext *sc;
5785 static const uint8_t uuid_isml_manifest[] = {
5786 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5787 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5789 static const uint8_t uuid_xmp[] = {
5790 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5791 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5793 static const uint8_t uuid_spherical[] = {
5794 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5795 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5798 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5799 return AVERROR_INVALIDDATA;
5801 if (c->fc->nb_streams < 1)
5803 st = c->fc->streams[c->fc->nb_streams - 1];
5806 ret = ffio_read_size(pb, uuid, sizeof(uuid));
5809 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5810 uint8_t *buffer, *ptr;
5812 size_t len = atom.size - sizeof(uuid);
5815 return AVERROR_INVALIDDATA;
5817 ret = avio_skip(pb, 4); // zeroes
5820 buffer = av_mallocz(len + 1);
5822 return AVERROR(ENOMEM);
5824 ret = ffio_read_size(pb, buffer, len);
5831 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5832 ptr += sizeof("systemBitrate=\"") - 1;
5833 c->bitrates_count++;
5834 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5836 c->bitrates_count = 0;
5838 return AVERROR(ENOMEM);
5841 ret = strtol(ptr, &endptr, 10);
5842 if (ret < 0 || errno || *endptr != '"') {
5843 c->bitrates[c->bitrates_count - 1] = 0;
5845 c->bitrates[c->bitrates_count - 1] = ret;
5850 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5852 size_t len = atom.size - sizeof(uuid);
5853 if (c->export_xmp) {
5854 buffer = av_mallocz(len + 1);
5856 return AVERROR(ENOMEM);
5858 ret = ffio_read_size(pb, buffer, len);
5864 av_dict_set(&c->fc->metadata, "xmp",
5865 buffer, AV_DICT_DONT_STRDUP_VAL);
5867 // skip all uuid atom, which makes it fast for long uuid-xmp file
5868 ret = avio_skip(pb, len);
5872 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5873 size_t len = atom.size - sizeof(uuid);
5874 ret = mov_parse_uuid_spherical(sc, pb, len);
5878 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5884 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5887 uint8_t content[16];
5892 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5898 && !memcmp(content, "Anevia\x1A\x1A", 8)
5899 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5900 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5906 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5908 uint32_t format = avio_rl32(pb);
5909 MOVStreamContext *sc;
5913 if (c->fc->nb_streams < 1)
5915 st = c->fc->streams[c->fc->nb_streams - 1];
5920 case MKTAG('e','n','c','v'): // encrypted video
5921 case MKTAG('e','n','c','a'): // encrypted audio
5922 id = mov_codec_id(st, format);
5923 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5924 st->codecpar->codec_id != id) {
5925 av_log(c->fc, AV_LOG_WARNING,
5926 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5927 (char*)&format, st->codecpar->codec_id);
5931 st->codecpar->codec_id = id;
5932 sc->format = format;
5936 if (format != sc->format) {
5937 av_log(c->fc, AV_LOG_WARNING,
5938 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5939 (char*)&format, (char*)&sc->format);
5948 * Gets the current encryption info and associated current stream context. If
5949 * we are parsing a track fragment, this will return the specific encryption
5950 * info for this fragment; otherwise this will return the global encryption
5951 * info for the current stream.
5953 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5955 MOVFragmentStreamInfo *frag_stream_info;
5959 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5960 if (frag_stream_info) {
5961 for (i = 0; i < c->fc->nb_streams; i++) {
5962 if (c->fc->streams[i]->id == frag_stream_info->id) {
5963 st = c->fc->streams[i];
5967 if (i == c->fc->nb_streams)
5969 *sc = st->priv_data;
5971 if (!frag_stream_info->encryption_index) {
5972 // If this stream isn't encrypted, don't create the index.
5973 if (!(*sc)->cenc.default_encrypted_sample)
5975 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5976 if (!frag_stream_info->encryption_index)
5977 return AVERROR(ENOMEM);
5979 *encryption_index = frag_stream_info->encryption_index;
5982 // No current track fragment, using stream level encryption info.
5984 if (c->fc->nb_streams < 1)
5986 st = c->fc->streams[c->fc->nb_streams - 1];
5987 *sc = st->priv_data;
5989 if (!(*sc)->cenc.encryption_index) {
5990 // If this stream isn't encrypted, don't create the index.
5991 if (!(*sc)->cenc.default_encrypted_sample)
5993 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5994 if (!(*sc)->cenc.encryption_index)
5995 return AVERROR(ENOMEM);
5998 *encryption_index = (*sc)->cenc.encryption_index;
6003 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
6006 unsigned int subsample_count;
6007 AVSubsampleEncryptionInfo *subsamples;
6009 if (!sc->cenc.default_encrypted_sample) {
6010 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
6011 return AVERROR_INVALIDDATA;
6014 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
6016 return AVERROR(ENOMEM);
6018 if (sc->cenc.per_sample_iv_size != 0) {
6019 if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
6020 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
6021 av_encryption_info_free(*sample);
6027 if (use_subsamples) {
6028 subsample_count = avio_rb16(pb);
6029 av_free((*sample)->subsamples);
6030 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
6031 if (!(*sample)->subsamples) {
6032 av_encryption_info_free(*sample);
6034 return AVERROR(ENOMEM);
6037 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
6038 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
6039 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
6042 if (pb->eof_reached) {
6043 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
6044 av_encryption_info_free(*sample);
6046 return AVERROR_INVALIDDATA;
6048 (*sample)->subsample_count = subsample_count;
6054 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6056 AVEncryptionInfo **encrypted_samples;
6057 MOVEncryptionIndex *encryption_index;
6058 MOVStreamContext *sc;
6059 int use_subsamples, ret;
6060 unsigned int sample_count, i, alloc_size = 0;
6062 ret = get_current_encryption_info(c, &encryption_index, &sc);
6066 if (encryption_index->nb_encrypted_samples) {
6067 // This can happen if we have both saio/saiz and senc atoms.
6068 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6072 avio_r8(pb); /* version */
6073 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6075 sample_count = avio_rb32(pb);
6076 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6077 return AVERROR(ENOMEM);
6079 for (i = 0; i < sample_count; i++) {
6080 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6081 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6082 min_samples * sizeof(*encrypted_samples));
6083 if (encrypted_samples) {
6084 encryption_index->encrypted_samples = encrypted_samples;
6086 ret = mov_read_sample_encryption_info(
6087 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6089 ret = AVERROR(ENOMEM);
6091 if (pb->eof_reached) {
6092 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6093 ret = AVERROR_INVALIDDATA;
6098 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6099 av_freep(&encryption_index->encrypted_samples);
6103 encryption_index->nb_encrypted_samples = sample_count;
6108 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6110 AVEncryptionInfo **sample, **encrypted_samples;
6112 size_t sample_count, sample_info_size, i;
6114 unsigned int alloc_size = 0;
6116 if (encryption_index->nb_encrypted_samples)
6118 sample_count = encryption_index->auxiliary_info_sample_count;
6119 if (encryption_index->auxiliary_offsets_count != 1) {
6120 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6121 return AVERROR_PATCHWELCOME;
6123 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6124 return AVERROR(ENOMEM);
6126 prev_pos = avio_tell(pb);
6127 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6128 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6129 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6133 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6134 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6135 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6136 min_samples * sizeof(*encrypted_samples));
6137 if (!encrypted_samples) {
6138 ret = AVERROR(ENOMEM);
6141 encryption_index->encrypted_samples = encrypted_samples;
6143 sample = &encryption_index->encrypted_samples[i];
6144 sample_info_size = encryption_index->auxiliary_info_default_size
6145 ? encryption_index->auxiliary_info_default_size
6146 : encryption_index->auxiliary_info_sizes[i];
6148 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6152 if (pb->eof_reached) {
6153 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6154 ret = AVERROR_INVALIDDATA;
6156 encryption_index->nb_encrypted_samples = sample_count;
6160 avio_seek(pb, prev_pos, SEEK_SET);
6162 for (; i > 0; i--) {
6163 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6165 av_freep(&encryption_index->encrypted_samples);
6171 * Tries to read the given number of bytes from the stream and puts it in a
6172 * newly allocated buffer. This reads in small chunks to avoid allocating large
6173 * memory if the file contains an invalid/malicious size value.
6175 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6177 const unsigned int block_size = 1024 * 1024;
6178 uint8_t *buffer = NULL;
6179 unsigned int alloc_size = 0, offset = 0;
6180 while (offset < size) {
6181 unsigned int new_size =
6182 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6183 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6184 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6187 return AVERROR(ENOMEM);
6189 buffer = new_buffer;
6191 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6193 return AVERROR_INVALIDDATA;
6202 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6204 MOVEncryptionIndex *encryption_index;
6205 MOVStreamContext *sc;
6207 unsigned int sample_count, aux_info_type, aux_info_param;
6209 ret = get_current_encryption_info(c, &encryption_index, &sc);
6213 if (encryption_index->nb_encrypted_samples) {
6214 // This can happen if we have both saio/saiz and senc atoms.
6215 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6219 if (encryption_index->auxiliary_info_sample_count) {
6220 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6221 return AVERROR_INVALIDDATA;
6224 avio_r8(pb); /* version */
6225 if (avio_rb24(pb) & 0x01) { /* flags */
6226 aux_info_type = avio_rb32(pb);
6227 aux_info_param = avio_rb32(pb);
6228 if (sc->cenc.default_encrypted_sample) {
6229 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6230 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6233 if (aux_info_param != 0) {
6234 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6238 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6239 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6240 aux_info_type == MKBETAG('c','e','n','s') ||
6241 aux_info_type == MKBETAG('c','b','c','1') ||
6242 aux_info_type == MKBETAG('c','b','c','s')) &&
6243 aux_info_param == 0) {
6244 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6245 return AVERROR_INVALIDDATA;
6250 } else if (!sc->cenc.default_encrypted_sample) {
6251 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6255 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6256 sample_count = avio_rb32(pb);
6257 encryption_index->auxiliary_info_sample_count = sample_count;
6259 if (encryption_index->auxiliary_info_default_size == 0) {
6260 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6262 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6267 if (encryption_index->auxiliary_offsets_count) {
6268 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6274 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6276 uint64_t *auxiliary_offsets;
6277 MOVEncryptionIndex *encryption_index;
6278 MOVStreamContext *sc;
6280 unsigned int version, entry_count, aux_info_type, aux_info_param;
6281 unsigned int alloc_size = 0;
6283 ret = get_current_encryption_info(c, &encryption_index, &sc);
6287 if (encryption_index->nb_encrypted_samples) {
6288 // This can happen if we have both saio/saiz and senc atoms.
6289 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6293 if (encryption_index->auxiliary_offsets_count) {
6294 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6295 return AVERROR_INVALIDDATA;
6298 version = avio_r8(pb); /* version */
6299 if (avio_rb24(pb) & 0x01) { /* flags */
6300 aux_info_type = avio_rb32(pb);
6301 aux_info_param = avio_rb32(pb);
6302 if (sc->cenc.default_encrypted_sample) {
6303 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6304 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6307 if (aux_info_param != 0) {
6308 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6312 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6313 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6314 aux_info_type == MKBETAG('c','e','n','s') ||
6315 aux_info_type == MKBETAG('c','b','c','1') ||
6316 aux_info_type == MKBETAG('c','b','c','s')) &&
6317 aux_info_param == 0) {
6318 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6319 return AVERROR_INVALIDDATA;
6324 } else if (!sc->cenc.default_encrypted_sample) {
6325 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6329 entry_count = avio_rb32(pb);
6330 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6331 return AVERROR(ENOMEM);
6333 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6334 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6335 auxiliary_offsets = av_fast_realloc(
6336 encryption_index->auxiliary_offsets, &alloc_size,
6337 min_offsets * sizeof(*auxiliary_offsets));
6338 if (!auxiliary_offsets) {
6339 av_freep(&encryption_index->auxiliary_offsets);
6340 return AVERROR(ENOMEM);
6342 encryption_index->auxiliary_offsets = auxiliary_offsets;
6345 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6347 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6349 if (c->frag_index.current >= 0) {
6350 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6354 if (pb->eof_reached) {
6355 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6356 av_freep(&encryption_index->auxiliary_offsets);
6357 return AVERROR_INVALIDDATA;
6360 encryption_index->auxiliary_offsets_count = entry_count;
6362 if (encryption_index->auxiliary_info_sample_count) {
6363 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6369 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6371 AVEncryptionInitInfo *info, *old_init_info;
6374 uint8_t *side_data, *extra_data, *old_side_data;
6375 size_t side_data_size;
6376 int ret = 0, old_side_data_size;
6377 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6379 if (c->fc->nb_streams < 1)
6381 st = c->fc->streams[c->fc->nb_streams-1];
6383 version = avio_r8(pb); /* version */
6384 avio_rb24(pb); /* flags */
6386 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6387 /* key_id_size */ 16, /* data_size */ 0);
6389 return AVERROR(ENOMEM);
6391 if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
6392 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6397 kid_count = avio_rb32(pb);
6398 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
6399 ret = AVERROR(ENOMEM);
6403 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6404 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6405 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6406 min_kid_count * sizeof(*key_ids));
6408 ret = AVERROR(ENOMEM);
6411 info->key_ids = key_ids;
6413 info->key_ids[i] = av_mallocz(16);
6414 if (!info->key_ids[i]) {
6415 ret = AVERROR(ENOMEM);
6418 info->num_key_ids = i + 1;
6420 if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
6421 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6426 if (pb->eof_reached) {
6427 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6428 ret = AVERROR_INVALIDDATA;
6433 extra_data_size = avio_rb32(pb);
6434 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6438 av_freep(&info->data); // malloc(0) may still allocate something.
6439 info->data = extra_data;
6440 info->data_size = extra_data_size;
6442 // If there is existing initialization data, append to the list.
6443 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6444 if (old_side_data) {
6445 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6446 if (old_init_info) {
6447 // Append to the end of the list.
6448 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6454 info = old_init_info;
6456 // Assume existing side-data will be valid, so the only error we could get is OOM.
6457 ret = AVERROR(ENOMEM);
6462 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6464 ret = AVERROR(ENOMEM);
6467 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6468 side_data, side_data_size);
6473 av_encryption_init_info_free(info);
6477 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6480 MOVStreamContext *sc;
6482 if (c->fc->nb_streams < 1)
6484 st = c->fc->streams[c->fc->nb_streams-1];
6487 if (sc->pseudo_stream_id != 0) {
6488 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6489 return AVERROR_PATCHWELCOME;
6493 return AVERROR_INVALIDDATA;
6495 avio_rb32(pb); /* version and flags */
6497 if (!sc->cenc.default_encrypted_sample) {
6498 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6499 if (!sc->cenc.default_encrypted_sample) {
6500 return AVERROR(ENOMEM);
6504 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6508 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6511 MOVStreamContext *sc;
6512 unsigned int version, pattern, is_protected, iv_size;
6514 if (c->fc->nb_streams < 1)
6516 st = c->fc->streams[c->fc->nb_streams-1];
6519 if (sc->pseudo_stream_id != 0) {
6520 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6521 return AVERROR_PATCHWELCOME;
6524 if (!sc->cenc.default_encrypted_sample) {
6525 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6526 if (!sc->cenc.default_encrypted_sample) {
6527 return AVERROR(ENOMEM);
6532 return AVERROR_INVALIDDATA;
6534 version = avio_r8(pb); /* version */
6535 avio_rb24(pb); /* flags */
6537 avio_r8(pb); /* reserved */
6538 pattern = avio_r8(pb);
6541 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6542 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6545 is_protected = avio_r8(pb);
6546 if (is_protected && !sc->cenc.encryption_index) {
6547 // The whole stream should be by-default encrypted.
6548 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6549 if (!sc->cenc.encryption_index)
6550 return AVERROR(ENOMEM);
6552 sc->cenc.per_sample_iv_size = avio_r8(pb);
6553 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6554 sc->cenc.per_sample_iv_size != 16) {
6555 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6556 return AVERROR_INVALIDDATA;
6558 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6559 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6560 return AVERROR_INVALIDDATA;
6563 if (is_protected && !sc->cenc.per_sample_iv_size) {
6564 iv_size = avio_r8(pb);
6565 if (iv_size != 8 && iv_size != 16) {
6566 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6567 return AVERROR_INVALIDDATA;
6570 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6571 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6572 return AVERROR_INVALIDDATA;
6579 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6582 int last, type, size, ret;
6585 if (c->fc->nb_streams < 1)
6587 st = c->fc->streams[c->fc->nb_streams-1];
6589 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6590 return AVERROR_INVALIDDATA;
6592 /* Check FlacSpecificBox version. */
6593 if (avio_r8(pb) != 0)
6594 return AVERROR_INVALIDDATA;
6596 avio_rb24(pb); /* Flags */
6598 avio_read(pb, buf, sizeof(buf));
6599 flac_parse_block_header(buf, &last, &type, &size);
6601 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6602 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6603 return AVERROR_INVALIDDATA;
6606 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6611 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6616 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6620 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6621 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6622 return AVERROR_PATCHWELCOME;
6625 if (!sc->cenc.aes_ctr) {
6626 /* initialize the cipher */
6627 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6628 if (!sc->cenc.aes_ctr) {
6629 return AVERROR(ENOMEM);
6632 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6638 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6640 if (!sample->subsample_count) {
6641 /* decrypt the whole packet */
6642 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6646 for (i = 0; i < sample->subsample_count; i++) {
6647 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6648 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6649 return AVERROR_INVALIDDATA;
6652 /* skip the clear bytes */
6653 input += sample->subsamples[i].bytes_of_clear_data;
6654 size -= sample->subsamples[i].bytes_of_clear_data;
6656 /* decrypt the encrypted bytes */
6657 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6658 input += sample->subsamples[i].bytes_of_protected_data;
6659 size -= sample->subsamples[i].bytes_of_protected_data;
6663 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6664 return AVERROR_INVALIDDATA;
6670 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6672 MOVFragmentStreamInfo *frag_stream_info;
6673 MOVEncryptionIndex *encryption_index;
6674 AVEncryptionInfo *encrypted_sample;
6675 int encrypted_index, ret;
6677 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6678 encrypted_index = current_index;
6679 encryption_index = NULL;
6680 if (frag_stream_info) {
6681 // Note this only supports encryption info in the first sample descriptor.
6682 if (mov->fragment.stsd_id == 1) {
6683 if (frag_stream_info->encryption_index) {
6684 encrypted_index = current_index - frag_stream_info->index_entry;
6685 encryption_index = frag_stream_info->encryption_index;
6687 encryption_index = sc->cenc.encryption_index;
6691 encryption_index = sc->cenc.encryption_index;
6694 if (encryption_index) {
6695 if (encryption_index->auxiliary_info_sample_count &&
6696 !encryption_index->nb_encrypted_samples) {
6697 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6698 return AVERROR_INVALIDDATA;
6700 if (encryption_index->auxiliary_offsets_count &&
6701 !encryption_index->nb_encrypted_samples) {
6702 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6703 return AVERROR_INVALIDDATA;
6706 if (!encryption_index->nb_encrypted_samples) {
6707 // Full-sample encryption with default settings.
6708 encrypted_sample = sc->cenc.default_encrypted_sample;
6709 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6710 // Per-sample setting override.
6711 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6713 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6714 return AVERROR_INVALIDDATA;
6717 if (mov->decryption_key) {
6718 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6721 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6723 return AVERROR(ENOMEM);
6724 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6734 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6736 const int OPUS_SEEK_PREROLL_MS = 80;
6742 if (c->fc->nb_streams < 1)
6744 st = c->fc->streams[c->fc->nb_streams-1];
6746 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6747 return AVERROR_INVALIDDATA;
6749 /* Check OpusSpecificBox version. */
6750 if (avio_r8(pb) != 0) {
6751 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6752 return AVERROR_INVALIDDATA;
6755 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6756 size = atom.size + 8;
6758 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
6761 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6762 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6763 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6764 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6766 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6767 little-endian; aside from the preceeding magic and version they're
6768 otherwise currently identical. Data after output gain at offset 16
6769 doesn't need to be bytewapped. */
6770 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6771 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6772 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6773 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6775 st->codecpar->initial_padding = pre_skip;
6776 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6777 (AVRational){1, 1000},
6778 (AVRational){1, 48000});
6783 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6786 unsigned format_info;
6787 int channel_assignment, channel_assignment1, channel_assignment2;
6790 if (c->fc->nb_streams < 1)
6792 st = c->fc->streams[c->fc->nb_streams-1];
6795 return AVERROR_INVALIDDATA;
6797 format_info = avio_rb32(pb);
6799 ratebits = (format_info >> 28) & 0xF;
6800 channel_assignment1 = (format_info >> 15) & 0x1F;
6801 channel_assignment2 = format_info & 0x1FFF;
6802 if (channel_assignment2)
6803 channel_assignment = channel_assignment2;
6805 channel_assignment = channel_assignment1;
6807 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6808 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6809 st->codecpar->channels = truehd_channels(channel_assignment);
6810 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6815 static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6819 AVDOVIDecoderConfigurationRecord *dovi;
6823 if (c->fc->nb_streams < 1)
6825 st = c->fc->streams[c->fc->nb_streams-1];
6827 if ((uint64_t)atom.size > (1<<30) || atom.size < 4)
6828 return AVERROR_INVALIDDATA;
6830 dovi = av_dovi_alloc(&dovi_size);
6832 return AVERROR(ENOMEM);
6834 dovi->dv_version_major = avio_r8(pb);
6835 dovi->dv_version_minor = avio_r8(pb);
6837 buf = avio_rb16(pb);
6838 dovi->dv_profile = (buf >> 9) & 0x7f; // 7 bits
6839 dovi->dv_level = (buf >> 3) & 0x3f; // 6 bits
6840 dovi->rpu_present_flag = (buf >> 2) & 0x01; // 1 bit
6841 dovi->el_present_flag = (buf >> 1) & 0x01; // 1 bit
6842 dovi->bl_present_flag = buf & 0x01; // 1 bit
6843 if (atom.size >= 24) { // 4 + 4 + 4 * 4
6845 dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits
6847 // 0 stands for None
6848 // Dolby Vision V1.2.93 profiles and levels
6849 dovi->dv_bl_signal_compatibility_id = 0;
6852 ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF,
6853 (uint8_t *)dovi, dovi_size);
6859 av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC box, version: %d.%d, profile: %d, level: %d, "
6860 "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n",
6861 dovi->dv_version_major, dovi->dv_version_minor,
6862 dovi->dv_profile, dovi->dv_level,
6863 dovi->rpu_present_flag,
6864 dovi->el_present_flag,
6865 dovi->bl_present_flag,
6866 dovi->dv_bl_signal_compatibility_id
6872 static const MOVParseTableEntry mov_default_parse_table[] = {
6873 { MKTAG('A','C','L','R'), mov_read_aclr },
6874 { MKTAG('A','P','R','G'), mov_read_avid },
6875 { MKTAG('A','A','L','P'), mov_read_avid },
6876 { MKTAG('A','R','E','S'), mov_read_ares },
6877 { MKTAG('a','v','s','s'), mov_read_avss },
6878 { MKTAG('a','v','1','C'), mov_read_av1c },
6879 { MKTAG('c','h','p','l'), mov_read_chpl },
6880 { MKTAG('c','o','6','4'), mov_read_stco },
6881 { MKTAG('c','o','l','r'), mov_read_colr },
6882 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6883 { MKTAG('d','i','n','f'), mov_read_default },
6884 { MKTAG('D','p','x','E'), mov_read_dpxe },
6885 { MKTAG('d','r','e','f'), mov_read_dref },
6886 { MKTAG('e','d','t','s'), mov_read_default },
6887 { MKTAG('e','l','s','t'), mov_read_elst },
6888 { MKTAG('e','n','d','a'), mov_read_enda },
6889 { MKTAG('f','i','e','l'), mov_read_fiel },
6890 { MKTAG('a','d','r','m'), mov_read_adrm },
6891 { MKTAG('f','t','y','p'), mov_read_ftyp },
6892 { MKTAG('g','l','b','l'), mov_read_glbl },
6893 { MKTAG('h','d','l','r'), mov_read_hdlr },
6894 { MKTAG('i','l','s','t'), mov_read_ilst },
6895 { MKTAG('j','p','2','h'), mov_read_jp2h },
6896 { MKTAG('m','d','a','t'), mov_read_mdat },
6897 { MKTAG('m','d','h','d'), mov_read_mdhd },
6898 { MKTAG('m','d','i','a'), mov_read_default },
6899 { MKTAG('m','e','t','a'), mov_read_meta },
6900 { MKTAG('m','i','n','f'), mov_read_default },
6901 { MKTAG('m','o','o','f'), mov_read_moof },
6902 { MKTAG('m','o','o','v'), mov_read_moov },
6903 { MKTAG('m','v','e','x'), mov_read_default },
6904 { MKTAG('m','v','h','d'), mov_read_mvhd },
6905 { MKTAG('S','M','I',' '), mov_read_svq3 },
6906 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6907 { MKTAG('a','v','c','C'), mov_read_glbl },
6908 { MKTAG('p','a','s','p'), mov_read_pasp },
6909 { MKTAG('s','i','d','x'), mov_read_sidx },
6910 { MKTAG('s','t','b','l'), mov_read_default },
6911 { MKTAG('s','t','c','o'), mov_read_stco },
6912 { MKTAG('s','t','p','s'), mov_read_stps },
6913 { MKTAG('s','t','r','f'), mov_read_strf },
6914 { MKTAG('s','t','s','c'), mov_read_stsc },
6915 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6916 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6917 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6918 { MKTAG('s','t','t','s'), mov_read_stts },
6919 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6920 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
6921 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6922 { MKTAG('t','f','d','t'), mov_read_tfdt },
6923 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6924 { MKTAG('t','r','a','k'), mov_read_trak },
6925 { MKTAG('t','r','a','f'), mov_read_default },
6926 { MKTAG('t','r','e','f'), mov_read_default },
6927 { MKTAG('t','m','c','d'), mov_read_tmcd },
6928 { MKTAG('c','h','a','p'), mov_read_chap },
6929 { MKTAG('t','r','e','x'), mov_read_trex },
6930 { MKTAG('t','r','u','n'), mov_read_trun },
6931 { MKTAG('u','d','t','a'), mov_read_default },
6932 { MKTAG('w','a','v','e'), mov_read_wave },
6933 { MKTAG('e','s','d','s'), mov_read_esds },
6934 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6935 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6936 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6937 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6938 { MKTAG('w','f','e','x'), mov_read_wfex },
6939 { MKTAG('c','m','o','v'), mov_read_cmov },
6940 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6941 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6942 { MKTAG('s','b','g','p'), mov_read_sbgp },
6943 { MKTAG('h','v','c','C'), mov_read_glbl },
6944 { MKTAG('u','u','i','d'), mov_read_uuid },
6945 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6946 { MKTAG('f','r','e','e'), mov_read_free },
6947 { MKTAG('-','-','-','-'), mov_read_custom },
6948 { MKTAG('s','i','n','f'), mov_read_default },
6949 { MKTAG('f','r','m','a'), mov_read_frma },
6950 { MKTAG('s','e','n','c'), mov_read_senc },
6951 { MKTAG('s','a','i','z'), mov_read_saiz },
6952 { MKTAG('s','a','i','o'), mov_read_saio },
6953 { MKTAG('p','s','s','h'), mov_read_pssh },
6954 { MKTAG('s','c','h','m'), mov_read_schm },
6955 { MKTAG('s','c','h','i'), mov_read_default },
6956 { MKTAG('t','e','n','c'), mov_read_tenc },
6957 { MKTAG('d','f','L','a'), mov_read_dfla },
6958 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6959 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6960 { MKTAG('d','O','p','s'), mov_read_dops },
6961 { MKTAG('d','m','l','p'), mov_read_dmlp },
6962 { MKTAG('S','m','D','m'), mov_read_smdm },
6963 { MKTAG('C','o','L','L'), mov_read_coll },
6964 { MKTAG('v','p','c','C'), mov_read_vpcc },
6965 { MKTAG('m','d','c','v'), mov_read_mdcv },
6966 { MKTAG('c','l','l','i'), mov_read_clli },
6967 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
6968 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
6972 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6974 int64_t total_size = 0;
6978 if (c->atom_depth > 10) {
6979 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6980 return AVERROR_INVALIDDATA;
6985 atom.size = INT64_MAX;
6986 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6987 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
6990 if (atom.size >= 8) {
6991 a.size = avio_rb32(pb);
6992 a.type = avio_rl32(pb);
6993 if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
6994 a.type == MKTAG('h','o','o','v')) &&
6996 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
6999 type = avio_rl32(pb);
7000 avio_seek(pb, -8, SEEK_CUR);
7001 if (type == MKTAG('m','v','h','d') ||
7002 type == MKTAG('c','m','o','v')) {
7003 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
7004 a.type = MKTAG('m','o','o','v');
7007 if (atom.type != MKTAG('r','o','o','t') &&
7008 atom.type != MKTAG('m','o','o','v')) {
7009 if (a.type == MKTAG('t','r','a','k') ||
7010 a.type == MKTAG('m','d','a','t')) {
7011 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
7018 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
7019 a.size = avio_rb64(pb) - 8;
7023 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
7024 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
7026 a.size = atom.size - total_size + 8;
7031 a.size = FFMIN(a.size, atom.size - total_size);
7033 for (i = 0; mov_default_parse_table[i].type; i++)
7034 if (mov_default_parse_table[i].type == a.type) {
7035 parse = mov_default_parse_table[i].parse;
7039 // container is user data
7040 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
7041 atom.type == MKTAG('i','l','s','t')))
7042 parse = mov_read_udta_string;
7044 // Supports parsing the QuickTime Metadata Keys.
7045 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
7046 if (!parse && c->found_hdlr_mdta &&
7047 atom.type == MKTAG('m','e','t','a') &&
7048 a.type == MKTAG('k','e','y','s') &&
7049 c->meta_keys_count == 0) {
7050 parse = mov_read_keys;
7053 if (!parse) { /* skip leaf atoms data */
7054 avio_skip(pb, a.size);
7056 int64_t start_pos = avio_tell(pb);
7058 int err = parse(c, pb, a);
7063 if (c->found_moov && c->found_mdat &&
7064 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
7065 start_pos + a.size == avio_size(pb))) {
7066 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
7067 c->next_root_atom = start_pos + a.size;
7071 left = a.size - avio_tell(pb) + start_pos;
7072 if (left > 0) /* skip garbage at atom end */
7073 avio_skip(pb, left);
7074 else if (left < 0) {
7075 av_log(c->fc, AV_LOG_WARNING,
7076 "overread end of atom '%s' by %"PRId64" bytes\n",
7077 av_fourcc2str(a.type), -left);
7078 avio_seek(pb, left, SEEK_CUR);
7082 total_size += a.size;
7085 if (total_size < atom.size && atom.size < 0x7ffff)
7086 avio_skip(pb, atom.size - total_size);
7092 static int mov_probe(const AVProbeData *p)
7097 int moov_offset = -1;
7099 /* check file header */
7102 /* ignore invalid offset */
7103 if ((offset + 8) > (unsigned int)p->buf_size)
7105 tag = AV_RL32(p->buf + offset + 4);
7107 /* check for obvious tags */
7108 case MKTAG('m','o','o','v'):
7109 moov_offset = offset + 4;
7110 case MKTAG('m','d','a','t'):
7111 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
7112 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
7113 case MKTAG('f','t','y','p'):
7114 if (AV_RB32(p->buf+offset) < 8 &&
7115 (AV_RB32(p->buf+offset) != 1 ||
7116 offset + 12 > (unsigned int)p->buf_size ||
7117 AV_RB64(p->buf+offset + 8) == 0)) {
7118 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7119 } else if (tag == MKTAG('f','t','y','p') &&
7120 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
7121 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
7123 score = FFMAX(score, 5);
7125 score = AVPROBE_SCORE_MAX;
7127 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7129 /* those are more common words, so rate then a bit less */
7130 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
7131 case MKTAG('w','i','d','e'):
7132 case MKTAG('f','r','e','e'):
7133 case MKTAG('j','u','n','k'):
7134 case MKTAG('p','i','c','t'):
7135 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
7136 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7138 case MKTAG(0x82,0x82,0x7f,0x7d):
7139 case MKTAG('s','k','i','p'):
7140 case MKTAG('u','u','i','d'):
7141 case MKTAG('p','r','f','l'):
7142 /* if we only find those cause probedata is too small at least rate them */
7143 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7144 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7147 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7150 if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
7151 /* moov atom in the header - we should make sure that this is not a
7152 * MOV-packed MPEG-PS */
7153 offset = moov_offset;
7155 while (offset < (p->buf_size - 16)) { /* Sufficient space */
7156 /* We found an actual hdlr atom */
7157 if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7158 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7159 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
7160 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7161 /* We found a media handler reference atom describing an
7162 * MPEG-PS-in-MOV, return a
7163 * low score to force expanding the probe window until
7164 * mpegps_probe finds what it needs */
7176 // must be done after parsing all trak because there's no order requirement
7177 static void mov_read_chapters(AVFormatContext *s)
7179 MOVContext *mov = s->priv_data;
7181 MOVStreamContext *sc;
7186 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7187 chapter_track = mov->chapter_tracks[j];
7189 for (i = 0; i < s->nb_streams; i++)
7190 if (s->streams[i]->id == chapter_track) {
7195 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7200 cur_pos = avio_tell(sc->pb);
7202 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7203 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7204 if (st->internal->nb_index_entries) {
7205 // Retrieve the first frame, if possible
7206 AVIndexEntry *sample = &st->internal->index_entries[0];
7207 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7208 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7212 if (av_get_packet(sc->pb, &st->attached_pic, sample->size) < 0)
7215 st->attached_pic.stream_index = st->index;
7216 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
7219 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7220 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7221 st->discard = AVDISCARD_ALL;
7222 for (i = 0; i < st->internal->nb_index_entries; i++) {
7223 AVIndexEntry *sample = &st->internal->index_entries[i];
7224 int64_t end = i+1 < st->internal->nb_index_entries ? st->internal->index_entries[i+1].timestamp : st->duration;
7229 if (end < sample->timestamp) {
7230 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7231 end = AV_NOPTS_VALUE;
7234 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7235 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7239 // the first two bytes are the length of the title
7240 len = avio_rb16(sc->pb);
7241 if (len > sample->size-2)
7243 title_len = 2*len + 1;
7244 if (!(title = av_mallocz(title_len)))
7247 // The samples could theoretically be in any encoding if there's an encd
7248 // atom following, but in practice are only utf-8 or utf-16, distinguished
7249 // instead by the presence of a BOM
7253 ch = avio_rb16(sc->pb);
7255 avio_get_str16be(sc->pb, len, title, title_len);
7256 else if (ch == 0xfffe)
7257 avio_get_str16le(sc->pb, len, title, title_len);
7260 if (len == 1 || len == 2)
7263 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7267 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7272 avio_seek(sc->pb, cur_pos, SEEK_SET);
7276 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7277 uint32_t value, int flags)
7280 char buf[AV_TIMECODE_STR_SIZE];
7281 AVRational rate = st->avg_frame_rate;
7282 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7285 av_dict_set(&st->metadata, "timecode",
7286 av_timecode_make_string(&tc, buf, value), 0);
7290 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7292 MOVStreamContext *sc = st->priv_data;
7293 char buf[AV_TIMECODE_STR_SIZE];
7294 int64_t cur_pos = avio_tell(sc->pb);
7295 int hh, mm, ss, ff, drop;
7297 if (!st->internal->nb_index_entries)
7300 avio_seek(sc->pb, st->internal->index_entries->pos, SEEK_SET);
7301 avio_skip(s->pb, 13);
7302 hh = avio_r8(s->pb);
7303 mm = avio_r8(s->pb);
7304 ss = avio_r8(s->pb);
7305 drop = avio_r8(s->pb);
7306 ff = avio_r8(s->pb);
7307 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7308 hh, mm, ss, drop ? ';' : ':', ff);
7309 av_dict_set(&st->metadata, "timecode", buf, 0);
7311 avio_seek(sc->pb, cur_pos, SEEK_SET);
7315 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7317 MOVStreamContext *sc = st->priv_data;
7319 int64_t cur_pos = avio_tell(sc->pb);
7322 if (!st->internal->nb_index_entries)
7325 avio_seek(sc->pb, st->internal->index_entries->pos, SEEK_SET);
7326 value = avio_rb32(s->pb);
7328 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7329 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7330 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7332 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7333 * not the case) and thus assume "frame number format" instead of QT one.
7334 * No sample with tmcd track can be found with a QT timecode at the moment,
7335 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7337 parse_timecode_in_framenum_format(s, st, value, flags);
7339 avio_seek(sc->pb, cur_pos, SEEK_SET);
7343 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7345 if (!index || !*index) return;
7346 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7347 av_encryption_info_free((*index)->encrypted_samples[i]);
7349 av_freep(&(*index)->encrypted_samples);
7350 av_freep(&(*index)->auxiliary_info_sizes);
7351 av_freep(&(*index)->auxiliary_offsets);
7355 static int mov_read_close(AVFormatContext *s)
7357 MOVContext *mov = s->priv_data;
7360 for (i = 0; i < s->nb_streams; i++) {
7361 AVStream *st = s->streams[i];
7362 MOVStreamContext *sc = st->priv_data;
7367 av_freep(&sc->ctts_data);
7368 for (j = 0; j < sc->drefs_count; j++) {
7369 av_freep(&sc->drefs[j].path);
7370 av_freep(&sc->drefs[j].dir);
7372 av_freep(&sc->drefs);
7374 sc->drefs_count = 0;
7376 if (!sc->pb_is_copied)
7377 ff_format_io_close(s, &sc->pb);
7380 av_freep(&sc->chunk_offsets);
7381 av_freep(&sc->stsc_data);
7382 av_freep(&sc->sample_sizes);
7383 av_freep(&sc->keyframes);
7384 av_freep(&sc->stts_data);
7385 av_freep(&sc->sdtp_data);
7386 av_freep(&sc->stps_data);
7387 av_freep(&sc->elst_data);
7388 av_freep(&sc->rap_group);
7389 av_freep(&sc->display_matrix);
7390 av_freep(&sc->index_ranges);
7393 for (j = 0; j < sc->stsd_count; j++)
7394 av_free(sc->extradata[j]);
7395 av_freep(&sc->extradata);
7396 av_freep(&sc->extradata_size);
7398 mov_free_encryption_index(&sc->cenc.encryption_index);
7399 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7400 av_aes_ctr_free(sc->cenc.aes_ctr);
7402 av_freep(&sc->stereo3d);
7403 av_freep(&sc->spherical);
7404 av_freep(&sc->mastering);
7405 av_freep(&sc->coll);
7408 av_freep(&mov->dv_demux);
7409 avformat_free_context(mov->dv_fctx);
7410 mov->dv_fctx = NULL;
7412 if (mov->meta_keys) {
7413 for (i = 1; i < mov->meta_keys_count; i++) {
7414 av_freep(&mov->meta_keys[i]);
7416 av_freep(&mov->meta_keys);
7419 av_freep(&mov->trex_data);
7420 av_freep(&mov->bitrates);
7422 for (i = 0; i < mov->frag_index.nb_items; i++) {
7423 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7424 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7425 mov_free_encryption_index(&frag[j].encryption_index);
7427 av_freep(&mov->frag_index.item[i].stream_info);
7429 av_freep(&mov->frag_index.item);
7431 av_freep(&mov->aes_decrypt);
7432 av_freep(&mov->chapter_tracks);
7437 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7441 for (i = 0; i < s->nb_streams; i++) {
7442 AVStream *st = s->streams[i];
7443 MOVStreamContext *sc = st->priv_data;
7445 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7446 sc->timecode_track == tmcd_id)
7452 /* look for a tmcd track not referenced by any video track, and export it globally */
7453 static void export_orphan_timecode(AVFormatContext *s)
7457 for (i = 0; i < s->nb_streams; i++) {
7458 AVStream *st = s->streams[i];
7460 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7461 !tmcd_is_referenced(s, i + 1)) {
7462 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7464 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7471 static int read_tfra(MOVContext *mov, AVIOContext *f)
7473 int version, fieldlength, i, j;
7474 int64_t pos = avio_tell(f);
7475 uint32_t size = avio_rb32(f);
7476 unsigned track_id, item_count;
7478 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7481 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7483 version = avio_r8(f);
7485 track_id = avio_rb32(f);
7486 fieldlength = avio_rb32(f);
7487 item_count = avio_rb32(f);
7488 for (i = 0; i < item_count; i++) {
7489 int64_t time, offset;
7491 MOVFragmentStreamInfo * frag_stream_info;
7494 return AVERROR_INVALIDDATA;
7498 time = avio_rb64(f);
7499 offset = avio_rb64(f);
7501 time = avio_rb32(f);
7502 offset = avio_rb32(f);
7505 // The first sample of each stream in a fragment is always a random
7506 // access sample. So it's entry in the tfra can be used as the
7507 // initial PTS of the fragment.
7508 index = update_frag_index(mov, offset);
7509 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7510 if (frag_stream_info &&
7511 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7512 frag_stream_info->first_tfra_pts = time;
7514 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7516 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7518 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7522 avio_seek(f, pos + size, SEEK_SET);
7526 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7528 int64_t stream_size = avio_size(f);
7529 int64_t original_pos = avio_tell(f);
7532 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7536 c->mfra_size = avio_rb32(f);
7537 c->have_read_mfra_size = 1;
7538 if (!c->mfra_size || c->mfra_size > stream_size) {
7539 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7542 if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
7546 if (avio_rb32(f) != c->mfra_size) {
7547 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7550 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7551 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7554 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7556 ret = read_tfra(c, f);
7561 c->frag_index.complete = 1;
7563 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7565 av_log(c->fc, AV_LOG_ERROR,
7566 "failed to seek back after looking for mfra\n");
7572 static int mov_read_header(AVFormatContext *s)
7574 MOVContext *mov = s->priv_data;
7575 AVIOContext *pb = s->pb;
7577 MOVAtom atom = { AV_RL32("root") };
7580 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7581 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7582 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7583 return AVERROR(EINVAL);
7587 mov->trak_index = -1;
7588 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7589 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7590 atom.size = avio_size(pb);
7592 atom.size = INT64_MAX;
7594 /* check MOV header */
7596 if (mov->moov_retry)
7597 avio_seek(pb, 0, SEEK_SET);
7598 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7599 av_log(s, AV_LOG_ERROR, "error reading header\n");
7602 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7603 if (!mov->found_moov) {
7604 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7605 err = AVERROR_INVALIDDATA;
7608 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7610 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7611 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7612 mov_read_chapters(s);
7613 for (i = 0; i < s->nb_streams; i++)
7614 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7615 mov_read_timecode_track(s, s->streams[i]);
7616 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7617 mov_read_rtmd_track(s, s->streams[i]);
7621 /* copy timecode metadata from tmcd tracks to the related video streams */
7622 for (i = 0; i < s->nb_streams; i++) {
7623 AVStream *st = s->streams[i];
7624 MOVStreamContext *sc = st->priv_data;
7625 if (sc->timecode_track > 0) {
7626 AVDictionaryEntry *tcr;
7627 int tmcd_st_id = -1;
7629 for (j = 0; j < s->nb_streams; j++)
7630 if (s->streams[j]->id == sc->timecode_track)
7633 if (tmcd_st_id < 0 || tmcd_st_id == i)
7635 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7637 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7640 export_orphan_timecode(s);
7642 for (i = 0; i < s->nb_streams; i++) {
7643 AVStream *st = s->streams[i];
7644 MOVStreamContext *sc = st->priv_data;
7645 fix_timescale(mov, sc);
7646 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
7647 st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7648 st->internal->skip_samples = sc->start_pad;
7650 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7651 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7652 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7653 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7654 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7655 st->codecpar->width = sc->width;
7656 st->codecpar->height = sc->height;
7658 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7659 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7663 if (mov->handbrake_version &&
7664 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7665 st->codecpar->codec_id == AV_CODEC_ID_MP3) {
7666 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7667 st->need_parsing = AVSTREAM_PARSE_FULL;
7671 if (mov->trex_data) {
7672 for (i = 0; i < s->nb_streams; i++) {
7673 AVStream *st = s->streams[i];
7674 MOVStreamContext *sc = st->priv_data;
7675 if (st->duration > 0) {
7676 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7677 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7678 sc->data_size, sc->time_scale);
7679 err = AVERROR_INVALIDDATA;
7682 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7687 if (mov->use_mfra_for > 0) {
7688 for (i = 0; i < s->nb_streams; i++) {
7689 AVStream *st = s->streams[i];
7690 MOVStreamContext *sc = st->priv_data;
7691 if (sc->duration_for_fps > 0) {
7692 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7693 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7694 sc->data_size, sc->time_scale);
7695 err = AVERROR_INVALIDDATA;
7698 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7699 sc->duration_for_fps;
7704 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7705 if (mov->bitrates[i]) {
7706 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7710 ff_rfps_calculate(s);
7712 for (i = 0; i < s->nb_streams; i++) {
7713 AVStream *st = s->streams[i];
7714 MOVStreamContext *sc = st->priv_data;
7716 switch (st->codecpar->codec_type) {
7717 case AVMEDIA_TYPE_AUDIO:
7718 err = ff_replaygain_export(st, s->metadata);
7722 case AVMEDIA_TYPE_VIDEO:
7723 if (sc->display_matrix) {
7724 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7725 sizeof(int32_t) * 9);
7729 sc->display_matrix = NULL;
7732 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7733 (uint8_t *)sc->stereo3d,
7734 sizeof(*sc->stereo3d));
7738 sc->stereo3d = NULL;
7740 if (sc->spherical) {
7741 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7742 (uint8_t *)sc->spherical,
7743 sc->spherical_size);
7747 sc->spherical = NULL;
7749 if (sc->mastering) {
7750 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7751 (uint8_t *)sc->mastering,
7752 sizeof(*sc->mastering));
7756 sc->mastering = NULL;
7759 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7760 (uint8_t *)sc->coll,
7770 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7772 for (i = 0; i < mov->frag_index.nb_items; i++)
7773 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7774 mov->frag_index.item[i].headers_read = 1;
7782 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7784 AVIndexEntry *sample = NULL;
7785 int64_t best_dts = INT64_MAX;
7787 for (i = 0; i < s->nb_streams; i++) {
7788 AVStream *avst = s->streams[i];
7789 MOVStreamContext *msc = avst->priv_data;
7790 if (msc->pb && msc->current_sample < avst->internal->nb_index_entries) {
7791 AVIndexEntry *current_sample = &avst->internal->index_entries[msc->current_sample];
7792 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7793 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7794 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7795 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7796 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
7797 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7798 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7799 sample = current_sample;
7808 static int should_retry(AVIOContext *pb, int error_code) {
7809 if (error_code == AVERROR_EOF || avio_feof(pb))
7815 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7818 MOVContext *mov = s->priv_data;
7820 if (index >= 0 && index < mov->frag_index.nb_items)
7821 target = mov->frag_index.item[index].moof_offset;
7822 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7823 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7824 return AVERROR_INVALIDDATA;
7827 mov->next_root_atom = 0;
7828 if (index < 0 || index >= mov->frag_index.nb_items)
7829 index = search_frag_moof_offset(&mov->frag_index, target);
7830 if (index < mov->frag_index.nb_items &&
7831 mov->frag_index.item[index].moof_offset == target) {
7832 if (index + 1 < mov->frag_index.nb_items)
7833 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7834 if (mov->frag_index.item[index].headers_read)
7836 mov->frag_index.item[index].headers_read = 1;
7839 mov->found_mdat = 0;
7841 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7844 if (avio_feof(s->pb))
7846 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7851 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7853 uint8_t *side, *extradata;
7856 /* Save the current index. */
7857 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7859 /* Notify the decoder that extradata changed. */
7860 extradata_size = sc->extradata_size[sc->last_stsd_index];
7861 extradata = sc->extradata[sc->last_stsd_index];
7862 if (extradata_size > 0 && extradata) {
7863 side = av_packet_new_side_data(pkt,
7864 AV_PKT_DATA_NEW_EXTRADATA,
7867 return AVERROR(ENOMEM);
7868 memcpy(side, extradata, extradata_size);
7874 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int size)
7879 return AVERROR_INVALIDDATA;
7880 new_size = ((size - 8) / 2) * 3;
7881 ret = av_new_packet(pkt, new_size);
7886 for (int j = 0; j < new_size; j += 3) {
7887 pkt->data[j] = 0xFC;
7888 pkt->data[j+1] = avio_r8(pb);
7889 pkt->data[j+2] = avio_r8(pb);
7895 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7897 MOVContext *mov = s->priv_data;
7898 MOVStreamContext *sc;
7899 AVIndexEntry *sample;
7900 AVStream *st = NULL;
7901 int64_t current_index;
7905 sample = mov_find_next_sample(s, &st);
7906 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7907 if (!mov->next_root_atom)
7909 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7914 /* must be done just before reading, to avoid infinite loop on sample */
7915 current_index = sc->current_index;
7916 mov_current_sample_inc(sc);
7918 if (mov->next_root_atom) {
7919 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7920 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7923 if (st->discard != AVDISCARD_ALL) {
7924 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7925 if (ret64 != sample->pos) {
7926 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7927 sc->ffindex, sample->pos);
7928 if (should_retry(sc->pb, ret64)) {
7929 mov_current_sample_dec(sc);
7931 return AVERROR_INVALIDDATA;
7934 if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
7935 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7939 if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
7940 ret = get_eia608_packet(sc->pb, pkt, sample->size);
7942 ret = av_get_packet(sc->pb, pkt, sample->size);
7944 if (should_retry(sc->pb, ret)) {
7945 mov_current_sample_dec(sc);
7949 #if CONFIG_DV_DEMUXER
7950 if (mov->dv_demux && sc->dv_audio_container) {
7951 AVBufferRef *buf = pkt->buf;
7952 ret = avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7954 av_packet_unref(pkt);
7957 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7962 if (sc->has_palette) {
7965 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7967 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7969 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7970 sc->has_palette = 0;
7973 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7974 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7975 st->need_parsing = AVSTREAM_PARSE_FULL;
7979 pkt->stream_index = sc->ffindex;
7980 pkt->dts = sample->timestamp;
7981 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7982 pkt->flags |= AV_PKT_FLAG_DISCARD;
7984 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7985 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
7986 /* update ctts context */
7988 if (sc->ctts_index < sc->ctts_count &&
7989 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
7991 sc->ctts_sample = 0;
7994 int64_t next_dts = (sc->current_sample < st->internal->nb_index_entries) ?
7995 st->internal->index_entries[sc->current_sample].timestamp : st->duration;
7997 if (next_dts >= pkt->dts)
7998 pkt->duration = next_dts - pkt->dts;
7999 pkt->pts = pkt->dts;
8001 if (st->discard == AVDISCARD_ALL)
8003 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
8004 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
8005 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
8006 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
8008 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
8009 pkt->pos = sample->pos;
8011 /* Multiple stsd handling. */
8012 if (sc->stsc_data) {
8013 /* Keep track of the stsc index for the given sample, then check
8014 * if the stsd index is different from the last used one. */
8016 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
8017 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
8019 sc->stsc_sample = 0;
8020 /* Do not check indexes after a switch. */
8021 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
8022 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
8023 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
8024 ret = mov_change_extradata(sc, pkt);
8031 aax_filter(pkt->data, pkt->size, mov);
8033 ret = cenc_filter(mov, st, sc, pkt, current_index);
8041 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
8043 MOVContext *mov = s->priv_data;
8046 if (!mov->frag_index.complete)
8049 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
8052 if (!mov->frag_index.item[index].headers_read)
8053 return mov_switch_root(s, -1, index);
8054 if (index + 1 < mov->frag_index.nb_items)
8055 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
8060 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
8062 MOVStreamContext *sc = st->priv_data;
8063 int sample, time_sample, ret;
8066 // Here we consider timestamp to be PTS, hence try to offset it so that we
8067 // can search over the DTS timeline.
8068 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
8070 ret = mov_seek_fragment(s, st, timestamp);
8074 sample = av_index_search_timestamp(st, timestamp, flags);
8075 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
8076 if (sample < 0 && st->internal->nb_index_entries && timestamp < st->internal->index_entries[0].timestamp)
8078 if (sample < 0) /* not sure what to do */
8079 return AVERROR_INVALIDDATA;
8080 mov_current_sample_set(sc, sample);
8081 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
8082 /* adjust ctts index */
8083 if (sc->ctts_data) {
8085 for (i = 0; i < sc->ctts_count; i++) {
8086 int next = time_sample + sc->ctts_data[i].count;
8087 if (next > sc->current_sample) {
8089 sc->ctts_sample = sc->current_sample - time_sample;
8096 /* adjust stsd index */
8097 if (sc->chunk_count) {
8099 for (i = 0; i < sc->stsc_count; i++) {
8100 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
8101 if (next > sc->current_sample) {
8103 sc->stsc_sample = sc->current_sample - time_sample;
8106 av_assert0(next == (int)next);
8114 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
8116 MOVContext *mc = s->priv_data;
8121 if (stream_index >= s->nb_streams)
8122 return AVERROR_INVALIDDATA;
8124 st = s->streams[stream_index];
8125 sample = mov_seek_stream(s, st, sample_time, flags);
8129 if (mc->seek_individually) {
8130 /* adjust seek timestamp to found sample timestamp */
8131 int64_t seek_timestamp = st->internal->index_entries[sample].timestamp;
8133 for (i = 0; i < s->nb_streams; i++) {
8135 MOVStreamContext *sc = s->streams[i]->priv_data;
8137 st->internal->skip_samples = (sample_time <= 0) ? sc->start_pad : 0;
8139 if (stream_index == i)
8142 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
8143 mov_seek_stream(s, st, timestamp, flags);
8146 for (i = 0; i < s->nb_streams; i++) {
8147 MOVStreamContext *sc;
8150 mov_current_sample_set(sc, 0);
8153 MOVStreamContext *sc;
8154 AVIndexEntry *entry = mov_find_next_sample(s, &st);
8156 return AVERROR_INVALIDDATA;
8158 if (sc->ffindex == stream_index && sc->current_sample == sample)
8160 mov_current_sample_inc(sc);
8166 #define OFFSET(x) offsetof(MOVContext, x)
8167 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
8168 static const AVOption mov_options[] = {
8169 {"use_absolute_path",
8170 "allow using absolute path when opening alias, this is a possible security issue",
8171 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
8173 {"seek_streams_individually",
8174 "Seek each stream individually to the closest point",
8175 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
8177 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
8179 {"advanced_editlist",
8180 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
8181 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
8183 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8186 "use mfra for fragment timestamps",
8187 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8188 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8190 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8191 FLAGS, "use_mfra_for" },
8192 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8193 FLAGS, "use_mfra_for" },
8194 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8195 FLAGS, "use_mfra_for" },
8196 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8197 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8198 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8199 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8200 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8201 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8202 { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
8203 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8204 { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
8205 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8206 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8207 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8208 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8209 .flags = AV_OPT_FLAG_DECODING_PARAM },
8210 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8211 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8212 {.i64 = 0}, 0, 1, FLAGS },
8217 static const AVClass mov_class = {
8218 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8219 .item_name = av_default_item_name,
8220 .option = mov_options,
8221 .version = LIBAVUTIL_VERSION_INT,
8224 AVInputFormat ff_mov_demuxer = {
8225 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8226 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8227 .priv_class = &mov_class,
8228 .priv_data_size = sizeof(MOVContext),
8229 .extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
8230 .read_probe = mov_probe,
8231 .read_header = mov_read_header,
8232 .read_packet = mov_read_packet,
8233 .read_close = mov_read_close,
8234 .read_seek = mov_read_seek,
8235 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,