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 if (n_hmmt > len / 4)
292 return AVERROR_INVALIDDATA;
293 for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
294 int moment_time = avio_rb32(pb);
295 avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
300 static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
302 char tmp_key[AV_FOURCC_MAX_STRING_SIZE] = {0};
303 char key2[32], language[4] = {0};
305 const char *key = NULL;
306 uint16_t langcode = 0;
307 uint32_t data_type = 0, str_size, str_size_alloc;
308 int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
313 case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
314 case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
315 case MKTAG( 'X','M','P','_'):
316 if (c->export_xmp) { key = "xmp"; raw = 1; } break;
317 case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
318 case MKTAG( 'a','k','I','D'): key = "account_type";
319 parse = mov_metadata_int8_no_padding; break;
320 case MKTAG( 'a','p','I','D'): key = "account_id"; break;
321 case MKTAG( 'c','a','t','g'): key = "category"; break;
322 case MKTAG( 'c','p','i','l'): key = "compilation";
323 parse = mov_metadata_int8_no_padding; break;
324 case MKTAG( 'c','p','r','t'): key = "copyright"; break;
325 case MKTAG( 'd','e','s','c'): key = "description"; break;
326 case MKTAG( 'd','i','s','k'): key = "disc";
327 parse = mov_metadata_track_or_disc_number; break;
328 case MKTAG( 'e','g','i','d'): key = "episode_uid";
329 parse = mov_metadata_int8_no_padding; break;
330 case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
331 case MKTAG( 'g','n','r','e'): key = "genre";
332 parse = mov_metadata_gnre; break;
333 case MKTAG( 'h','d','v','d'): key = "hd_video";
334 parse = mov_metadata_int8_no_padding; break;
335 case MKTAG( 'H','M','M','T'):
336 return mov_metadata_hmmt(c, pb, atom.size);
337 case MKTAG( 'k','e','y','w'): key = "keywords"; break;
338 case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
339 case MKTAG( 'l','o','c','i'):
340 return mov_metadata_loci(c, pb, atom.size);
341 case MKTAG( 'm','a','n','u'): key = "make"; break;
342 case MKTAG( 'm','o','d','l'): key = "model"; break;
343 case MKTAG( 'p','c','s','t'): key = "podcast";
344 parse = mov_metadata_int8_no_padding; break;
345 case MKTAG( 'p','g','a','p'): key = "gapless_playback";
346 parse = mov_metadata_int8_no_padding; break;
347 case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
348 case MKTAG( 'r','t','n','g'): key = "rating";
349 parse = mov_metadata_int8_no_padding; break;
350 case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
351 case MKTAG( 's','o','a','l'): key = "sort_album"; break;
352 case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
353 case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
354 case MKTAG( 's','o','n','m'): key = "sort_name"; break;
355 case MKTAG( 's','o','s','n'): key = "sort_show"; break;
356 case MKTAG( 's','t','i','k'): key = "media_type";
357 parse = mov_metadata_int8_no_padding; break;
358 case MKTAG( 't','r','k','n'): key = "track";
359 parse = mov_metadata_track_or_disc_number; break;
360 case MKTAG( 't','v','e','n'): key = "episode_id"; break;
361 case MKTAG( 't','v','e','s'): key = "episode_sort";
362 parse = mov_metadata_int8_bypass_padding; break;
363 case MKTAG( 't','v','n','n'): key = "network"; break;
364 case MKTAG( 't','v','s','h'): key = "show"; break;
365 case MKTAG( 't','v','s','n'): key = "season_number";
366 parse = mov_metadata_int8_bypass_padding; break;
367 case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
368 case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
369 case MKTAG(0xa9,'a','l','b'): key = "album"; break;
370 case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
371 case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
372 case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
373 case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
374 case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
375 case MKTAG(0xa9,'d','a','y'): key = "date"; break;
376 case MKTAG(0xa9,'d','i','r'): key = "director"; break;
377 case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
378 case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
379 case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
380 case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
381 case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
382 case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
383 case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
384 case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
385 case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
386 case MKTAG(0xa9,'m','a','k'): key = "make"; break;
387 case MKTAG(0xa9,'m','o','d'): key = "model"; break;
388 case MKTAG(0xa9,'n','a','m'): key = "title"; break;
389 case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
390 case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
391 case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
392 case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
393 case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
394 case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
395 case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
396 case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
397 case MKTAG(0xa9,'t','r','k'): key = "track"; break;
398 case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
399 case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
400 case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
401 case MKTAG(0xa9,'x','y','z'): key = "location"; break;
404 if (c->itunes_metadata && atom.size > 8) {
405 int data_size = avio_rb32(pb);
406 int tag = avio_rl32(pb);
407 if (tag == MKTAG('d','a','t','a') && data_size <= atom.size) {
408 data_type = avio_rb32(pb); // type
409 avio_rb32(pb); // unknown
410 str_size = data_size - 16;
413 if (atom.type == MKTAG('c', 'o', 'v', 'r')) {
414 int ret = mov_read_covr(c, pb, data_type, str_size);
416 av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
419 atom.size -= str_size;
423 } else if (!key && c->found_hdlr_mdta && c->meta_keys) {
424 uint32_t index = AV_RB32(&atom.type);
425 if (index < c->meta_keys_count && index > 0) {
426 key = c->meta_keys[index];
428 av_log(c->fc, AV_LOG_WARNING,
429 "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
430 index, c->meta_keys_count);
434 } else if (atom.size > 4 && key && !c->itunes_metadata && !raw) {
435 str_size = avio_rb16(pb); // string length
436 if (str_size > atom.size) {
438 avio_seek(pb, -2, SEEK_CUR);
439 av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
442 langcode = avio_rb16(pb);
443 ff_mov_lang_to_iso639(langcode, language);
446 str_size = atom.size;
448 if (c->export_all && !key) {
449 key = av_fourcc_make_string(tmp_key, atom.type);
454 if (atom.size < 0 || str_size >= INT_MAX/2)
455 return AVERROR_INVALIDDATA;
457 // Allocates enough space if data_type is a int32 or float32 number, otherwise
458 // worst-case requirement for output string in case of utf8 coded input
459 num = (data_type >= 21 && data_type <= 23);
460 str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
461 str = av_mallocz(str_size_alloc);
463 return AVERROR(ENOMEM);
466 parse(c, pb, str_size, key);
468 if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
469 mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
470 } else if (data_type == 21) { // BE signed integer, variable size
473 val = (int8_t)avio_r8(pb);
474 else if (str_size == 2)
475 val = (int16_t)avio_rb16(pb);
476 else if (str_size == 3)
477 val = ((int32_t)(avio_rb24(pb)<<8))>>8;
478 else if (str_size == 4)
479 val = (int32_t)avio_rb32(pb);
480 if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
481 av_log(c->fc, AV_LOG_ERROR,
482 "Failed to store the number (%d) in string.\n", val);
484 return AVERROR_INVALIDDATA;
486 } else if (data_type == 22) { // BE unsigned integer, variable size
487 unsigned int val = 0;
490 else if (str_size == 2)
492 else if (str_size == 3)
494 else if (str_size == 4)
496 if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
497 av_log(c->fc, AV_LOG_ERROR,
498 "Failed to store the number (%u) in string.\n", val);
500 return AVERROR_INVALIDDATA;
502 } else if (data_type == 23 && str_size >= 4) { // BE float32
503 float val = av_int2float(avio_rb32(pb));
504 if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
505 av_log(c->fc, AV_LOG_ERROR,
506 "Failed to store the float32 number (%f) in string.\n", val);
508 return AVERROR_INVALIDDATA;
511 int ret = ffio_read_size(pb, str, str_size);
518 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
519 av_dict_set(&c->fc->metadata, key, str, 0);
520 if (*language && strcmp(language, "und")) {
521 snprintf(key2, sizeof(key2), "%s-%s", key, language);
522 av_dict_set(&c->fc->metadata, key2, str, 0);
524 if (!strcmp(key, "encoder")) {
525 int major, minor, micro;
526 if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, µ) == 3) {
527 c->handbrake_version = 1000000*major + 1000*minor + micro;
536 static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
539 int i, nb_chapters, str_len, version;
543 if (c->ignore_chapters)
546 if ((atom.size -= 5) < 0)
549 version = avio_r8(pb);
552 avio_rb32(pb); // ???
553 nb_chapters = avio_r8(pb);
555 for (i = 0; i < nb_chapters; i++) {
559 start = avio_rb64(pb);
560 str_len = avio_r8(pb);
562 if ((atom.size -= 9+str_len) < 0)
565 ret = ffio_read_size(pb, str, str_len);
569 avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
574 #define MIN_DATA_ENTRY_BOX_SIZE 12
575 static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
578 MOVStreamContext *sc;
581 if (c->fc->nb_streams < 1)
583 st = c->fc->streams[c->fc->nb_streams-1];
586 avio_rb32(pb); // version + flags
587 entries = avio_rb32(pb);
589 entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
590 entries >= UINT_MAX / sizeof(*sc->drefs))
591 return AVERROR_INVALIDDATA;
593 for (i = 0; i < sc->drefs_count; i++) {
594 MOVDref *dref = &sc->drefs[i];
595 av_freep(&dref->path);
596 av_freep(&dref->dir);
600 sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
602 return AVERROR(ENOMEM);
603 sc->drefs_count = entries;
605 for (i = 0; i < entries; i++) {
606 MOVDref *dref = &sc->drefs[i];
607 uint32_t size = avio_rb32(pb);
608 int64_t next = avio_tell(pb) + size - 4;
611 return AVERROR_INVALIDDATA;
613 dref->type = avio_rl32(pb);
614 avio_rb32(pb); // version + flags
616 if (dref->type == MKTAG('a','l','i','s') && size > 150) {
617 /* macintosh alias record */
618 uint16_t volume_len, len;
624 volume_len = avio_r8(pb);
625 volume_len = FFMIN(volume_len, 27);
626 ret = ffio_read_size(pb, dref->volume, 27);
629 dref->volume[volume_len] = 0;
630 av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
635 len = FFMIN(len, 63);
636 ret = ffio_read_size(pb, dref->filename, 63);
639 dref->filename[len] = 0;
640 av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
644 /* read next level up_from_alias/down_to_target */
645 dref->nlvl_from = avio_rb16(pb);
646 dref->nlvl_to = avio_rb16(pb);
647 av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
648 dref->nlvl_from, dref->nlvl_to);
652 for (type = 0; type != -1 && avio_tell(pb) < next; ) {
655 type = avio_rb16(pb);
657 av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
660 if (type == 2) { // absolute path
662 dref->path = av_mallocz(len+1);
664 return AVERROR(ENOMEM);
666 ret = ffio_read_size(pb, dref->path, len);
668 av_freep(&dref->path);
671 if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
673 memmove(dref->path, dref->path+volume_len, len);
676 // trim string of any ending zeros
677 for (j = len - 1; j >= 0; j--) {
678 if (dref->path[j] == 0)
683 for (j = 0; j < len; j++)
684 if (dref->path[j] == ':' || dref->path[j] == 0)
686 av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
687 } else if (type == 0) { // directory name
689 dref->dir = av_malloc(len+1);
691 return AVERROR(ENOMEM);
693 ret = ffio_read_size(pb, dref->dir, len);
695 av_freep(&dref->dir);
699 for (j = 0; j < len; j++)
700 if (dref->dir[j] == ':')
702 av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
707 av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
712 avio_seek(pb, next, SEEK_SET);
717 static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
726 avio_r8(pb); /* version */
727 avio_rb24(pb); /* flags */
730 ctype = avio_rl32(pb);
731 type = avio_rl32(pb); /* component subtype */
733 av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
734 av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
736 if (c->trak_index < 0) { // meta not inside a trak
737 if (type == MKTAG('m','d','t','a')) {
738 c->found_hdlr_mdta = 1;
743 st = c->fc->streams[c->fc->nb_streams-1];
745 if (type == MKTAG('v','i','d','e'))
746 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
747 else if (type == MKTAG('s','o','u','n'))
748 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
749 else if (type == MKTAG('m','1','a',' '))
750 st->codecpar->codec_id = AV_CODEC_ID_MP2;
751 else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
752 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
754 avio_rb32(pb); /* component manufacture */
755 avio_rb32(pb); /* component flags */
756 avio_rb32(pb); /* component flags mask */
758 title_size = atom.size - 24;
759 if (title_size > 0) {
760 if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
761 return AVERROR_INVALIDDATA;
762 title_str = av_malloc(title_size + 1); /* Add null terminator */
764 return AVERROR(ENOMEM);
766 ret = ffio_read_size(pb, title_str, title_size);
768 av_freep(&title_str);
771 title_str[title_size] = 0;
773 int off = (!c->isom && title_str[0] == title_size - 1);
774 // flag added so as to not set stream handler name if already set from mdia->hdlr
775 av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
777 av_freep(&title_str);
783 static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
785 return ff_mov_read_esds(c->fc, pb);
788 static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
791 enum AVAudioServiceType *ast;
792 int ac3info, acmod, lfeon, bsmod;
794 if (c->fc->nb_streams < 1)
796 st = c->fc->streams[c->fc->nb_streams-1];
798 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
801 return AVERROR(ENOMEM);
803 ac3info = avio_rb24(pb);
804 bsmod = (ac3info >> 14) & 0x7;
805 acmod = (ac3info >> 11) & 0x7;
806 lfeon = (ac3info >> 10) & 0x1;
807 st->codecpar->channels = ((int[]){2,1,2,3,3,4,4,5})[acmod] + lfeon;
808 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
810 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
812 if (st->codecpar->channels > 1 && bsmod == 0x7)
813 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
815 #if FF_API_LAVF_AVCTX
816 FF_DISABLE_DEPRECATION_WARNINGS
817 st->codec->audio_service_type = *ast;
818 FF_ENABLE_DEPRECATION_WARNINGS
824 static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
827 enum AVAudioServiceType *ast;
828 int eac3info, acmod, lfeon, bsmod;
830 if (c->fc->nb_streams < 1)
832 st = c->fc->streams[c->fc->nb_streams-1];
834 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
837 return AVERROR(ENOMEM);
839 /* No need to parse fields for additional independent substreams and its
840 * associated dependent substreams since libavcodec's E-AC-3 decoder
841 * does not support them yet. */
842 avio_rb16(pb); /* data_rate and num_ind_sub */
843 eac3info = avio_rb24(pb);
844 bsmod = (eac3info >> 12) & 0x1f;
845 acmod = (eac3info >> 9) & 0x7;
846 lfeon = (eac3info >> 8) & 0x1;
847 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
849 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
850 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
852 if (st->codecpar->channels > 1 && bsmod == 0x7)
853 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
855 #if FF_API_LAVF_AVCTX
856 FF_DISABLE_DEPRECATION_WARNINGS
857 st->codec->audio_service_type = *ast;
858 FF_ENABLE_DEPRECATION_WARNINGS
864 static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
867 uint8_t buf[DDTS_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
869 uint32_t frame_duration_code = 0;
870 uint32_t channel_layout_code = 0;
874 if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
877 init_get_bits(&gb, buf, 8 * DDTS_SIZE);
879 if (c->fc->nb_streams < 1) {
882 st = c->fc->streams[c->fc->nb_streams-1];
884 st->codecpar->sample_rate = get_bits_long(&gb, 32);
885 if (st->codecpar->sample_rate <= 0) {
886 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
887 return AVERROR_INVALIDDATA;
889 skip_bits_long(&gb, 32); /* max bitrate */
890 st->codecpar->bit_rate = get_bits_long(&gb, 32);
891 st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
892 frame_duration_code = get_bits(&gb, 2);
893 skip_bits(&gb, 30); /* various fields */
894 channel_layout_code = get_bits(&gb, 16);
896 st->codecpar->frame_size =
897 (frame_duration_code == 0) ? 512 :
898 (frame_duration_code == 1) ? 1024 :
899 (frame_duration_code == 2) ? 2048 :
900 (frame_duration_code == 3) ? 4096 : 0;
902 if (channel_layout_code > 0xff) {
903 av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout\n");
905 st->codecpar->channel_layout =
906 ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
907 ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
908 ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
909 ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
910 ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
911 ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0);
913 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
918 static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
922 if (c->fc->nb_streams < 1)
924 st = c->fc->streams[c->fc->nb_streams-1];
929 /* skip version and flags */
932 ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
937 static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
942 if (c->fc->nb_streams < 1)
944 st = c->fc->streams[c->fc->nb_streams-1];
946 if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
947 av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
952 static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
954 const int num = avio_rb32(pb);
955 const int den = avio_rb32(pb);
958 if (c->fc->nb_streams < 1)
960 st = c->fc->streams[c->fc->nb_streams-1];
962 if ((st->sample_aspect_ratio.den != 1 || st->sample_aspect_ratio.num) && // default
963 (den != st->sample_aspect_ratio.den || num != st->sample_aspect_ratio.num)) {
964 av_log(c->fc, AV_LOG_WARNING,
965 "sample aspect ratio already set to %d:%d, ignoring 'pasp' atom (%d:%d)\n",
966 st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
968 } else if (den != 0) {
969 av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den,
975 /* this atom contains actual media data */
976 static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
978 if (atom.size == 0) /* wrong one (MP4) */
981 return 0; /* now go for moov */
984 #define DRM_BLOB_SIZE 56
986 static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
988 uint8_t intermediate_key[20];
989 uint8_t intermediate_iv[20];
992 uint8_t file_checksum[20];
993 uint8_t calculated_checksum[20];
997 uint8_t *activation_bytes = c->activation_bytes;
998 uint8_t *fixed_key = c->audible_fixed_key;
1002 sha = av_sha_alloc();
1004 return AVERROR(ENOMEM);
1005 av_free(c->aes_decrypt);
1006 c->aes_decrypt = av_aes_alloc();
1007 if (!c->aes_decrypt) {
1008 ret = AVERROR(ENOMEM);
1012 /* drm blob processing */
1013 avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1014 avio_read(pb, input, DRM_BLOB_SIZE);
1015 avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1016 avio_read(pb, file_checksum, 20);
1018 av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == "); // required by external tools
1019 for (i = 0; i < 20; i++)
1020 av_log(c->fc, AV_LOG_INFO, "%02x", file_checksum[i]);
1021 av_log(c->fc, AV_LOG_INFO, "\n");
1023 /* verify activation data */
1024 if (!activation_bytes) {
1025 av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1026 ret = 0; /* allow ffprobe to continue working on .aax files */
1029 if (c->activation_bytes_size != 4) {
1030 av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1031 ret = AVERROR(EINVAL);
1035 /* verify fixed key */
1036 if (c->audible_fixed_key_size != 16) {
1037 av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1038 ret = AVERROR(EINVAL);
1042 /* AAX (and AAX+) key derivation */
1043 av_sha_init(sha, 160);
1044 av_sha_update(sha, fixed_key, 16);
1045 av_sha_update(sha, activation_bytes, 4);
1046 av_sha_final(sha, intermediate_key);
1047 av_sha_init(sha, 160);
1048 av_sha_update(sha, fixed_key, 16);
1049 av_sha_update(sha, intermediate_key, 20);
1050 av_sha_update(sha, activation_bytes, 4);
1051 av_sha_final(sha, intermediate_iv);
1052 av_sha_init(sha, 160);
1053 av_sha_update(sha, intermediate_key, 16);
1054 av_sha_update(sha, intermediate_iv, 16);
1055 av_sha_final(sha, calculated_checksum);
1056 if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1057 av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1058 ret = AVERROR_INVALIDDATA;
1061 av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1062 av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1063 for (i = 0; i < 4; i++) {
1064 // file data (in output) is stored in big-endian mode
1065 if (activation_bytes[i] != output[3 - i]) { // critical error
1066 av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1067 ret = AVERROR_INVALIDDATA;
1071 memcpy(c->file_key, output + 8, 16);
1072 memcpy(input, output + 26, 16);
1073 av_sha_init(sha, 160);
1074 av_sha_update(sha, input, 16);
1075 av_sha_update(sha, c->file_key, 16);
1076 av_sha_update(sha, fixed_key, 16);
1077 av_sha_final(sha, c->file_iv);
1085 static int mov_aaxc_crypto(MOVContext *c)
1087 if (c->audible_key_size != 16) {
1088 av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
1089 return AVERROR(EINVAL);
1092 if (c->audible_iv_size != 16) {
1093 av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
1094 return AVERROR(EINVAL);
1097 c->aes_decrypt = av_aes_alloc();
1098 if (!c->aes_decrypt) {
1099 return AVERROR(ENOMEM);
1102 memcpy(c->file_key, c->audible_key, 16);
1103 memcpy(c->file_iv, c->audible_iv, 16);
1109 // Audible AAX (and AAX+) bytestream decryption
1110 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1113 unsigned char iv[16];
1115 memcpy(iv, c->file_iv, 16); // iv is overwritten
1116 blocks = size >> 4; // trailing bytes are not encrypted!
1117 av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1118 av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1123 /* read major brand, minor version and compatible brands and store them as metadata */
1124 static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1127 int comp_brand_size;
1128 char* comp_brands_str;
1129 uint8_t type[5] = {0};
1130 int ret = ffio_read_size(pb, type, 4);
1134 if (strcmp(type, "qt "))
1136 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1137 av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1138 minor_ver = avio_rb32(pb); /* minor version */
1139 av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1141 comp_brand_size = atom.size - 8;
1142 if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1143 return AVERROR_INVALIDDATA;
1144 comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1145 if (!comp_brands_str)
1146 return AVERROR(ENOMEM);
1148 ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1150 av_freep(&comp_brands_str);
1153 comp_brands_str[comp_brand_size] = 0;
1154 av_dict_set(&c->fc->metadata, "compatible_brands",
1155 comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1157 // Logic for handling Audible's .aaxc files
1158 if (!strcmp(type, "aaxc")) {
1165 /* this atom should contain all header atoms */
1166 static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1170 if (c->found_moov) {
1171 av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1172 avio_skip(pb, atom.size);
1176 if ((ret = mov_read_default(c, pb, atom)) < 0)
1178 /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1179 /* so we don't parse the whole file if over a network */
1181 return 0; /* now go for mdat */
1184 static MOVFragmentStreamInfo * get_frag_stream_info(
1185 MOVFragmentIndex *frag_index,
1190 MOVFragmentIndexItem * item;
1192 if (index < 0 || index >= frag_index->nb_items)
1194 item = &frag_index->item[index];
1195 for (i = 0; i < item->nb_stream_info; i++)
1196 if (item->stream_info[i].id == id)
1197 return &item->stream_info[i];
1199 // This shouldn't happen
1203 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1206 MOVFragmentIndexItem * item;
1208 if (frag_index->current < 0 ||
1209 frag_index->current >= frag_index->nb_items)
1212 item = &frag_index->item[frag_index->current];
1213 for (i = 0; i < item->nb_stream_info; i++)
1214 if (item->stream_info[i].id == id) {
1219 // id not found. This shouldn't happen.
1223 static MOVFragmentStreamInfo * get_current_frag_stream_info(
1224 MOVFragmentIndex *frag_index)
1226 MOVFragmentIndexItem *item;
1227 if (frag_index->current < 0 ||
1228 frag_index->current >= frag_index->nb_items)
1231 item = &frag_index->item[frag_index->current];
1232 if (item->current >= 0 && item->current < item->nb_stream_info)
1233 return &item->stream_info[item->current];
1235 // This shouldn't happen
1239 static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
1242 int64_t moof_offset;
1244 // Optimize for appending new entries
1245 if (!frag_index->nb_items ||
1246 frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1247 return frag_index->nb_items;
1250 b = frag_index->nb_items;
1254 moof_offset = frag_index->item[m].moof_offset;
1255 if (moof_offset >= offset)
1257 if (moof_offset <= offset)
1263 static int64_t get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
1265 av_assert0(frag_stream_info);
1266 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1267 return frag_stream_info->sidx_pts;
1268 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1269 return frag_stream_info->first_tfra_pts;
1270 return frag_stream_info->tfdt_dts;
1273 static int64_t get_frag_time(MOVFragmentIndex *frag_index,
1274 int index, int track_id)
1276 MOVFragmentStreamInfo * frag_stream_info;
1280 if (track_id >= 0) {
1281 frag_stream_info = get_frag_stream_info(frag_index, index, track_id);
1282 return frag_stream_info->sidx_pts;
1285 for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1286 frag_stream_info = &frag_index->item[index].stream_info[i];
1287 timestamp = get_stream_info_time(frag_stream_info);
1288 if (timestamp != AV_NOPTS_VALUE)
1291 return AV_NOPTS_VALUE;
1294 static int search_frag_timestamp(MOVFragmentIndex *frag_index,
1295 AVStream *st, int64_t timestamp)
1302 // If the stream is referenced by any sidx, limit the search
1303 // to fragments that referenced this stream in the sidx
1304 MOVStreamContext *sc = st->priv_data;
1310 b = frag_index->nb_items;
1313 m0 = m = (a + b) >> 1;
1316 (frag_time = get_frag_time(frag_index, m, id)) == AV_NOPTS_VALUE)
1319 if (m < b && frag_time <= timestamp)
1328 static int update_frag_index(MOVContext *c, int64_t offset)
1331 MOVFragmentIndexItem * item;
1332 MOVFragmentStreamInfo * frag_stream_info;
1334 // If moof_offset already exists in frag_index, return index to it
1335 index = search_frag_moof_offset(&c->frag_index, offset);
1336 if (index < c->frag_index.nb_items &&
1337 c->frag_index.item[index].moof_offset == offset)
1340 // offset is not yet in frag index.
1341 // Insert new item at index (sorted by moof offset)
1342 item = av_fast_realloc(c->frag_index.item,
1343 &c->frag_index.allocated_size,
1344 (c->frag_index.nb_items + 1) *
1345 sizeof(*c->frag_index.item));
1348 c->frag_index.item = item;
1350 frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1351 sizeof(*item->stream_info));
1352 if (!frag_stream_info)
1355 for (i = 0; i < c->fc->nb_streams; i++) {
1356 // Avoid building frag index if streams lack track id.
1357 if (c->fc->streams[i]->id < 0) {
1358 av_free(frag_stream_info);
1359 return AVERROR_INVALIDDATA;
1362 frag_stream_info[i].id = c->fc->streams[i]->id;
1363 frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1364 frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1365 frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1366 frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1367 frag_stream_info[i].index_entry = -1;
1368 frag_stream_info[i].encryption_index = NULL;
1371 if (index < c->frag_index.nb_items)
1372 memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1373 (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1375 item = &c->frag_index.item[index];
1376 item->headers_read = 0;
1378 item->nb_stream_info = c->fc->nb_streams;
1379 item->moof_offset = offset;
1380 item->stream_info = frag_stream_info;
1381 c->frag_index.nb_items++;
1386 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1387 int id, int entries)
1390 MOVFragmentStreamInfo * frag_stream_info;
1394 for (i = index; i < frag_index->nb_items; i++) {
1395 frag_stream_info = get_frag_stream_info(frag_index, i, id);
1396 if (frag_stream_info && frag_stream_info->index_entry >= 0)
1397 frag_stream_info->index_entry += entries;
1401 static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1403 // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1404 c->fragment.found_tfhd = 0;
1406 if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1407 c->has_looked_for_mfra = 1;
1408 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1410 av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1412 if ((ret = mov_read_mfra(c, pb)) < 0) {
1413 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1414 "read the mfra (may be a live ismv)\n");
1417 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1418 "seekable, can not look for mfra\n");
1421 c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1422 av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1423 c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1424 return mov_read_default(c, pb, atom);
1427 static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time, void *logctx)
1430 if (time >= 2082844800)
1431 time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1433 if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1434 av_log(logctx, AV_LOG_DEBUG, "creation_time is not representable\n");
1438 avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1442 static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1445 MOVStreamContext *sc;
1447 char language[4] = {0};
1449 int64_t creation_time;
1451 if (c->fc->nb_streams < 1)
1453 st = c->fc->streams[c->fc->nb_streams-1];
1456 if (sc->time_scale) {
1457 av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1458 return AVERROR_INVALIDDATA;
1461 version = avio_r8(pb);
1463 avpriv_request_sample(c->fc, "Version %d", version);
1464 return AVERROR_PATCHWELCOME;
1466 avio_rb24(pb); /* flags */
1468 creation_time = avio_rb64(pb);
1471 creation_time = avio_rb32(pb);
1472 avio_rb32(pb); /* modification time */
1474 mov_metadata_creation_time(&st->metadata, creation_time, c->fc);
1476 sc->time_scale = avio_rb32(pb);
1477 if (sc->time_scale <= 0) {
1478 av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1481 st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1483 lang = avio_rb16(pb); /* language */
1484 if (ff_mov_lang_to_iso639(lang, language))
1485 av_dict_set(&st->metadata, "language", language, 0);
1486 avio_rb16(pb); /* quality */
1491 static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1494 int64_t creation_time;
1495 int version = avio_r8(pb); /* version */
1496 avio_rb24(pb); /* flags */
1499 creation_time = avio_rb64(pb);
1502 creation_time = avio_rb32(pb);
1503 avio_rb32(pb); /* modification time */
1505 mov_metadata_creation_time(&c->fc->metadata, creation_time, c->fc);
1506 c->time_scale = avio_rb32(pb); /* time scale */
1507 if (c->time_scale <= 0) {
1508 av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1511 av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1513 c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1514 // set the AVFormatContext duration because the duration of individual tracks
1515 // may be inaccurate
1517 c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale);
1518 avio_rb32(pb); /* preferred scale */
1520 avio_rb16(pb); /* preferred volume */
1522 avio_skip(pb, 10); /* reserved */
1524 /* movie display matrix, store it in main context and use it later on */
1525 for (i = 0; i < 3; i++) {
1526 c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1527 c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1528 c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1531 avio_rb32(pb); /* preview time */
1532 avio_rb32(pb); /* preview duration */
1533 avio_rb32(pb); /* poster time */
1534 avio_rb32(pb); /* selection time */
1535 avio_rb32(pb); /* selection duration */
1536 avio_rb32(pb); /* current time */
1537 avio_rb32(pb); /* next track ID */
1542 static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1547 if (c->fc->nb_streams < 1)
1549 st = c->fc->streams[c->fc->nb_streams-1];
1551 little_endian = avio_rb16(pb) & 0xFF;
1552 av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1553 if (little_endian == 1) {
1554 switch (st->codecpar->codec_id) {
1555 case AV_CODEC_ID_PCM_S24BE:
1556 st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE;
1558 case AV_CODEC_ID_PCM_S32BE:
1559 st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE;
1561 case AV_CODEC_ID_PCM_F32BE:
1562 st->codecpar->codec_id = AV_CODEC_ID_PCM_F32LE;
1564 case AV_CODEC_ID_PCM_F64BE:
1565 st->codecpar->codec_id = AV_CODEC_ID_PCM_F64LE;
1574 static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1577 uint8_t *icc_profile;
1578 char color_parameter_type[5] = { 0 };
1579 uint16_t color_primaries, color_trc, color_matrix;
1582 if (c->fc->nb_streams < 1)
1584 st = c->fc->streams[c->fc->nb_streams - 1];
1586 ret = ffio_read_size(pb, color_parameter_type, 4);
1589 if (strncmp(color_parameter_type, "nclx", 4) &&
1590 strncmp(color_parameter_type, "nclc", 4) &&
1591 strncmp(color_parameter_type, "prof", 4)) {
1592 av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
1593 color_parameter_type);
1597 if (!strncmp(color_parameter_type, "prof", 4)) {
1598 icc_profile = av_stream_new_side_data(st, AV_PKT_DATA_ICC_PROFILE, atom.size - 4);
1600 return AVERROR(ENOMEM);
1601 ret = ffio_read_size(pb, icc_profile, atom.size - 4);
1605 color_primaries = avio_rb16(pb);
1606 color_trc = avio_rb16(pb);
1607 color_matrix = avio_rb16(pb);
1609 av_log(c->fc, AV_LOG_TRACE,
1610 "%s: pri %d trc %d matrix %d",
1611 color_parameter_type, color_primaries, color_trc, color_matrix);
1613 if (!strncmp(color_parameter_type, "nclx", 4)) {
1614 uint8_t color_range = avio_r8(pb) >> 7;
1615 av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
1617 st->codecpar->color_range = AVCOL_RANGE_JPEG;
1619 st->codecpar->color_range = AVCOL_RANGE_MPEG;
1622 if (!av_color_primaries_name(color_primaries))
1623 color_primaries = AVCOL_PRI_UNSPECIFIED;
1624 if (!av_color_transfer_name(color_trc))
1625 color_trc = AVCOL_TRC_UNSPECIFIED;
1626 if (!av_color_space_name(color_matrix))
1627 color_matrix = AVCOL_SPC_UNSPECIFIED;
1629 st->codecpar->color_primaries = color_primaries;
1630 st->codecpar->color_trc = color_trc;
1631 st->codecpar->color_space = color_matrix;
1632 av_log(c->fc, AV_LOG_TRACE, "\n");
1637 static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1640 unsigned mov_field_order;
1641 enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
1643 if (c->fc->nb_streams < 1) // will happen with jp2 files
1645 st = c->fc->streams[c->fc->nb_streams-1];
1647 return AVERROR_INVALIDDATA;
1648 mov_field_order = avio_rb16(pb);
1649 if ((mov_field_order & 0xFF00) == 0x0100)
1650 decoded_field_order = AV_FIELD_PROGRESSIVE;
1651 else if ((mov_field_order & 0xFF00) == 0x0200) {
1652 switch (mov_field_order & 0xFF) {
1653 case 0x01: decoded_field_order = AV_FIELD_TT;
1655 case 0x06: decoded_field_order = AV_FIELD_BB;
1657 case 0x09: decoded_field_order = AV_FIELD_TB;
1659 case 0x0E: decoded_field_order = AV_FIELD_BT;
1663 if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
1664 av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
1666 st->codecpar->field_order = decoded_field_order;
1671 static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
1674 uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
1675 if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
1676 return AVERROR_INVALIDDATA;
1677 if ((err = av_reallocp(&par->extradata, size)) < 0) {
1678 par->extradata_size = 0;
1681 par->extradata_size = size - AV_INPUT_BUFFER_PADDING_SIZE;
1685 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
1686 static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1687 AVCodecParameters *par, uint8_t *buf)
1689 int64_t result = atom.size;
1692 AV_WB32(buf , atom.size + 8);
1693 AV_WL32(buf + 4, atom.type);
1694 err = ffio_read_size(pb, buf + 8, atom.size);
1696 par->extradata_size -= atom.size;
1698 } else if (err < atom.size) {
1699 av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
1700 par->extradata_size -= atom.size - err;
1703 memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1707 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
1708 static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1709 enum AVCodecID codec_id)
1712 uint64_t original_size;
1715 if (c->fc->nb_streams < 1) // will happen with jp2 files
1717 st = c->fc->streams[c->fc->nb_streams-1];
1719 if (st->codecpar->codec_id != codec_id)
1720 return 0; /* unexpected codec_id - don't mess with extradata */
1722 original_size = st->codecpar->extradata_size;
1723 err = mov_realloc_extradata(st->codecpar, atom);
1727 err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
1730 return 0; // Note: this is the original behavior to ignore truncation.
1733 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
1734 static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1736 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
1739 static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1741 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS);
1744 static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1746 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
1749 static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1751 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
1754 static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1756 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
1758 ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
1762 static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1764 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
1766 if (!ret && c->fc->nb_streams >= 1) {
1767 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1768 if (par->extradata_size >= 40) {
1769 par->height = AV_RB16(&par->extradata[36]);
1770 par->width = AV_RB16(&par->extradata[38]);
1776 static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1778 if (c->fc->nb_streams >= 1) {
1779 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1780 if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
1781 par->codec_id == AV_CODEC_ID_H264 &&
1785 cid = avio_rb16(pb);
1786 /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
1787 if (cid == 0xd4d || cid == 0xd4e)
1790 } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
1791 par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
1792 par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
1796 num = avio_rb32(pb);
1797 den = avio_rb32(pb);
1798 if (num <= 0 || den <= 0)
1800 switch (avio_rb32(pb)) {
1802 if (den >= INT_MAX / 2)
1806 c->fc->streams[c->fc->nb_streams-1]->internal->display_aspect_ratio.num = num;
1807 c->fc->streams[c->fc->nb_streams-1]->internal->display_aspect_ratio.den = den;
1814 return mov_read_avid(c, pb, atom);
1817 static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1821 uint64_t original_size;
1822 if (c->fc->nb_streams >= 1) {
1823 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1824 if (par->codec_id == AV_CODEC_ID_H264)
1826 if (atom.size == 16) {
1827 original_size = par->extradata_size;
1828 ret = mov_realloc_extradata(par, atom);
1830 length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
1831 if (length == atom.size) {
1832 const uint8_t range_value = par->extradata[original_size + 19];
1833 switch (range_value) {
1835 par->color_range = AVCOL_RANGE_MPEG;
1838 par->color_range = AVCOL_RANGE_JPEG;
1841 av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
1844 ff_dlog(c->fc, "color_range: %d\n", par->color_range);
1846 /* For some reason the whole atom was not added to the extradata */
1847 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
1850 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
1853 av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
1860 static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1862 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
1865 static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1870 if (c->fc->nb_streams < 1)
1872 st = c->fc->streams[c->fc->nb_streams-1];
1874 if ((uint64_t)atom.size > (1<<30))
1875 return AVERROR_INVALIDDATA;
1877 if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
1878 st->codecpar->codec_id == AV_CODEC_ID_QDMC ||
1879 st->codecpar->codec_id == AV_CODEC_ID_SPEEX) {
1880 // pass all frma atom to codec, needed at least for QDMC and QDM2
1881 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1884 } else if (atom.size > 8) { /* to read frma, esds atoms */
1885 if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
1887 ret = ffio_ensure_seekback(pb, 8);
1890 buffer = avio_rb64(pb);
1892 if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
1893 && buffer >> 32 <= atom.size
1894 && buffer >> 32 >= 8) {
1897 } else if (!st->codecpar->extradata_size) {
1898 #define ALAC_EXTRADATA_SIZE 36
1899 st->codecpar->extradata = av_mallocz(ALAC_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
1900 if (!st->codecpar->extradata)
1901 return AVERROR(ENOMEM);
1902 st->codecpar->extradata_size = ALAC_EXTRADATA_SIZE;
1903 AV_WB32(st->codecpar->extradata , ALAC_EXTRADATA_SIZE);
1904 AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
1905 AV_WB64(st->codecpar->extradata + 12, buffer);
1906 avio_read(pb, st->codecpar->extradata + 20, 16);
1907 avio_skip(pb, atom.size - 24);
1911 if ((ret = mov_read_default(c, pb, atom)) < 0)
1914 avio_skip(pb, atom.size);
1919 * This function reads atom content and puts data in extradata without tag
1920 * nor size unlike mov_read_extradata.
1922 static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1927 if (c->fc->nb_streams < 1)
1929 st = c->fc->streams[c->fc->nb_streams-1];
1931 if ((uint64_t)atom.size > (1<<30))
1932 return AVERROR_INVALIDDATA;
1934 if (atom.size >= 10) {
1935 // Broken files created by legacy versions of libavformat will
1936 // wrap a whole fiel atom inside of a glbl atom.
1937 unsigned size = avio_rb32(pb);
1938 unsigned type = avio_rl32(pb);
1939 avio_seek(pb, -8, SEEK_CUR);
1940 if (type == MKTAG('f','i','e','l') && size == atom.size)
1941 return mov_read_default(c, pb, atom);
1943 if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
1944 av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
1947 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1950 if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
1951 /* HEVC-based Dolby Vision derived from hvc1.
1952 Happens to match with an identifier
1953 previously utilized for DV. Thus, if we have
1954 the hvcC extradata box available as specified,
1955 set codec to HEVC */
1956 st->codecpar->codec_id = AV_CODEC_ID_HEVC;
1961 static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1964 uint8_t profile_level;
1967 if (c->fc->nb_streams < 1)
1969 st = c->fc->streams[c->fc->nb_streams-1];
1971 if (atom.size >= (1<<28) || atom.size < 7)
1972 return AVERROR_INVALIDDATA;
1974 profile_level = avio_r8(pb);
1975 if ((profile_level & 0xf0) != 0xc0)
1978 avio_seek(pb, 6, SEEK_CUR);
1979 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
1987 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
1988 * but can have extradata appended at the end after the 40 bytes belonging
1991 static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1996 if (c->fc->nb_streams < 1)
1998 if (atom.size <= 40)
2000 st = c->fc->streams[c->fc->nb_streams-1];
2002 if ((uint64_t)atom.size > (1<<30))
2003 return AVERROR_INVALIDDATA;
2006 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2013 static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2016 MOVStreamContext *sc;
2017 unsigned int i, entries;
2019 if (c->trak_index < 0) {
2020 av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2023 if (c->fc->nb_streams < 1)
2025 st = c->fc->streams[c->fc->nb_streams-1];
2028 avio_r8(pb); /* version */
2029 avio_rb24(pb); /* flags */
2031 entries = avio_rb32(pb);
2036 if (sc->chunk_offsets)
2037 av_log(c->fc, AV_LOG_WARNING, "Duplicated STCO atom\n");
2038 av_free(sc->chunk_offsets);
2039 sc->chunk_count = 0;
2040 sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2041 if (!sc->chunk_offsets)
2042 return AVERROR(ENOMEM);
2043 sc->chunk_count = entries;
2045 if (atom.type == MKTAG('s','t','c','o'))
2046 for (i = 0; i < entries && !pb->eof_reached; i++)
2047 sc->chunk_offsets[i] = avio_rb32(pb);
2048 else if (atom.type == MKTAG('c','o','6','4'))
2049 for (i = 0; i < entries && !pb->eof_reached; i++)
2050 sc->chunk_offsets[i] = avio_rb64(pb);
2052 return AVERROR_INVALIDDATA;
2054 sc->chunk_count = i;
2056 if (pb->eof_reached) {
2057 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2064 static int mov_codec_id(AVStream *st, uint32_t format)
2066 int id = ff_codec_get_id(ff_codec_movaudio_tags, format);
2069 ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2070 (format & 0xFFFF) == 'T' + ('S' << 8)))
2071 id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format) & 0xFFFF);
2073 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2074 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2075 } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2076 /* skip old ASF MPEG-4 tag */
2077 format && format != MKTAG('m','p','4','s')) {
2078 id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2080 id = ff_codec_get_id(ff_codec_bmp_tags, format);
2082 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
2083 else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2084 (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE &&
2085 st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2086 id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
2088 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
2090 id = ff_codec_get_id(ff_codec_movdata_tags, format);
2094 st->codecpar->codec_tag = format;
2099 static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
2100 AVStream *st, MOVStreamContext *sc)
2102 uint8_t codec_name[32] = { 0 };
2107 /* The first 16 bytes of the video sample description are already
2108 * read in ff_mov_read_stsd_entries() */
2109 stsd_start = avio_tell(pb) - 16;
2111 avio_rb16(pb); /* version */
2112 avio_rb16(pb); /* revision level */
2113 id = avio_rl32(pb); /* vendor */
2114 av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2115 avio_rb32(pb); /* temporal quality */
2116 avio_rb32(pb); /* spatial quality */
2118 st->codecpar->width = avio_rb16(pb); /* width */
2119 st->codecpar->height = avio_rb16(pb); /* height */
2121 avio_rb32(pb); /* horiz resolution */
2122 avio_rb32(pb); /* vert resolution */
2123 avio_rb32(pb); /* data size, always 0 */
2124 avio_rb16(pb); /* frames per samples */
2126 len = avio_r8(pb); /* codec name, pascal string */
2129 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2131 avio_skip(pb, 31 - len);
2134 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2136 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2137 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2138 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2139 st->codecpar->width &= ~1;
2140 st->codecpar->height &= ~1;
2142 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2143 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2144 !strncmp(codec_name, "Sorenson H263", 13))
2145 st->codecpar->codec_id = AV_CODEC_ID_FLV1;
2147 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2149 avio_seek(pb, stsd_start, SEEK_SET);
2151 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2152 st->codecpar->bits_per_coded_sample &= 0x1F;
2153 sc->has_palette = 1;
2157 static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
2158 AVStream *st, MOVStreamContext *sc)
2160 int bits_per_sample, flags;
2161 uint16_t version = avio_rb16(pb);
2163 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2165 avio_rb16(pb); /* revision level */
2166 id = avio_rl32(pb); /* vendor */
2167 av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2169 st->codecpar->channels = avio_rb16(pb); /* channel count */
2170 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2171 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", st->codecpar->channels);
2173 sc->audio_cid = avio_rb16(pb);
2174 avio_rb16(pb); /* packet size = 0 */
2176 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2178 // Read QT version 1 fields. In version 0 these do not exist.
2179 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2181 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2182 (sc->stsd_version == 0 && version > 0)) {
2184 sc->samples_per_frame = avio_rb32(pb);
2185 avio_rb32(pb); /* bytes per packet */
2186 sc->bytes_per_frame = avio_rb32(pb);
2187 avio_rb32(pb); /* bytes per sample */
2188 } else if (version == 2) {
2189 avio_rb32(pb); /* sizeof struct only */
2190 st->codecpar->sample_rate = av_int2double(avio_rb64(pb));
2191 st->codecpar->channels = avio_rb32(pb);
2192 avio_rb32(pb); /* always 0x7F000000 */
2193 st->codecpar->bits_per_coded_sample = avio_rb32(pb);
2195 flags = avio_rb32(pb); /* lpcm format specific flag */
2196 sc->bytes_per_frame = avio_rb32(pb);
2197 sc->samples_per_frame = avio_rb32(pb);
2198 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2199 st->codecpar->codec_id =
2200 ff_mov_get_lpcm_codec_id(st->codecpar->bits_per_coded_sample,
2203 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2204 /* can't correctly handle variable sized packet as audio unit */
2205 switch (st->codecpar->codec_id) {
2206 case AV_CODEC_ID_MP2:
2207 case AV_CODEC_ID_MP3:
2208 st->need_parsing = AVSTREAM_PARSE_FULL;
2214 if (sc->format == 0) {
2215 if (st->codecpar->bits_per_coded_sample == 8)
2216 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2217 else if (st->codecpar->bits_per_coded_sample == 16)
2218 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2221 switch (st->codecpar->codec_id) {
2222 case AV_CODEC_ID_PCM_S8:
2223 case AV_CODEC_ID_PCM_U8:
2224 if (st->codecpar->bits_per_coded_sample == 16)
2225 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16BE;
2227 case AV_CODEC_ID_PCM_S16LE:
2228 case AV_CODEC_ID_PCM_S16BE:
2229 if (st->codecpar->bits_per_coded_sample == 8)
2230 st->codecpar->codec_id = AV_CODEC_ID_PCM_S8;
2231 else if (st->codecpar->bits_per_coded_sample == 24)
2232 st->codecpar->codec_id =
2233 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2234 AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
2235 else if (st->codecpar->bits_per_coded_sample == 32)
2236 st->codecpar->codec_id =
2237 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2238 AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
2240 /* set values for old format before stsd version 1 appeared */
2241 case AV_CODEC_ID_MACE3:
2242 sc->samples_per_frame = 6;
2243 sc->bytes_per_frame = 2 * st->codecpar->channels;
2245 case AV_CODEC_ID_MACE6:
2246 sc->samples_per_frame = 6;
2247 sc->bytes_per_frame = 1 * st->codecpar->channels;
2249 case AV_CODEC_ID_ADPCM_IMA_QT:
2250 sc->samples_per_frame = 64;
2251 sc->bytes_per_frame = 34 * st->codecpar->channels;
2253 case AV_CODEC_ID_GSM:
2254 sc->samples_per_frame = 160;
2255 sc->bytes_per_frame = 33;
2261 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2262 if (bits_per_sample) {
2263 st->codecpar->bits_per_coded_sample = bits_per_sample;
2264 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->channels;
2268 static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
2269 AVStream *st, MOVStreamContext *sc,
2272 // ttxt stsd contains display flags, justification, background
2273 // color, fonts, and default styles, so fake an atom to read it
2274 MOVAtom fake_atom = { .size = size };
2275 // mp4s contains a regular esds atom
2276 if (st->codecpar->codec_tag != AV_RL32("mp4s"))
2277 mov_read_glbl(c, pb, fake_atom);
2278 st->codecpar->width = sc->width;
2279 st->codecpar->height = sc->height;
2282 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2287 y = (ycbcr >> 16) & 0xFF;
2288 cr = (ycbcr >> 8) & 0xFF;
2291 b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
2292 g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
2293 r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
2295 return (r << 16) | (g << 8) | b;
2298 static int mov_rewrite_dvd_sub_extradata(AVStream *st)
2300 char buf[256] = {0};
2301 uint8_t *src = st->codecpar->extradata;
2304 if (st->codecpar->extradata_size != 64)
2307 if (st->codecpar->width > 0 && st->codecpar->height > 0)
2308 snprintf(buf, sizeof(buf), "size: %dx%d\n",
2309 st->codecpar->width, st->codecpar->height);
2310 av_strlcat(buf, "palette: ", sizeof(buf));
2312 for (i = 0; i < 16; i++) {
2313 uint32_t yuv = AV_RB32(src + i * 4);
2314 uint32_t rgba = yuv_to_rgba(yuv);
2316 av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2319 if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2322 ret = ff_alloc_extradata(st->codecpar, strlen(buf));
2325 memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2330 static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
2331 AVStream *st, MOVStreamContext *sc,
2336 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2337 if ((int)size != size)
2338 return AVERROR(ENOMEM);
2340 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2344 MOVStreamContext *tmcd_ctx = st->priv_data;
2346 val = AV_RB32(st->codecpar->extradata + 4);
2347 tmcd_ctx->tmcd_flags = val;
2348 st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2349 st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2350 #if FF_API_LAVF_AVCTX
2351 FF_DISABLE_DEPRECATION_WARNINGS
2352 st->codec->time_base = av_inv_q(st->avg_frame_rate);
2353 FF_ENABLE_DEPRECATION_WARNINGS
2356 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2357 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2358 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2359 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2360 if (str_size > 0 && size >= (int)str_size + 30 &&
2361 st->codecpar->extradata[30] /* Don't add empty string */) {
2362 char *reel_name = av_malloc(str_size + 1);
2364 return AVERROR(ENOMEM);
2365 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2366 reel_name[str_size] = 0; /* Add null terminator */
2367 av_dict_set(&st->metadata, "reel_name", reel_name,
2368 AV_DICT_DONT_STRDUP_VAL);
2374 /* other codec type, just skip (rtp, mp4s ...) */
2375 avio_skip(pb, size);
2380 static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
2381 AVStream *st, MOVStreamContext *sc)
2383 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2384 !st->codecpar->sample_rate && sc->time_scale > 1)
2385 st->codecpar->sample_rate = sc->time_scale;
2387 /* special codec parameters handling */
2388 switch (st->codecpar->codec_id) {
2389 #if CONFIG_DV_DEMUXER
2390 case AV_CODEC_ID_DVAUDIO:
2391 c->dv_fctx = avformat_alloc_context();
2393 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2394 return AVERROR(ENOMEM);
2396 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2398 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2399 return AVERROR(ENOMEM);
2401 sc->dv_audio_container = 1;
2402 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
2405 /* no ifdef since parameters are always those */
2406 case AV_CODEC_ID_QCELP:
2407 st->codecpar->channels = 1;
2408 // force sample rate for qcelp when not stored in mov
2409 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2410 st->codecpar->sample_rate = 8000;
2411 // FIXME: Why is the following needed for some files?
2412 sc->samples_per_frame = 160;
2413 if (!sc->bytes_per_frame)
2414 sc->bytes_per_frame = 35;
2416 case AV_CODEC_ID_AMR_NB:
2417 st->codecpar->channels = 1;
2418 /* force sample rate for amr, stsd in 3gp does not store sample rate */
2419 st->codecpar->sample_rate = 8000;
2421 case AV_CODEC_ID_AMR_WB:
2422 st->codecpar->channels = 1;
2423 st->codecpar->sample_rate = 16000;
2425 case AV_CODEC_ID_MP2:
2426 case AV_CODEC_ID_MP3:
2427 /* force type after stsd for m1a hdlr */
2428 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2430 case AV_CODEC_ID_GSM:
2431 case AV_CODEC_ID_ADPCM_MS:
2432 case AV_CODEC_ID_ADPCM_IMA_WAV:
2433 case AV_CODEC_ID_ILBC:
2434 case AV_CODEC_ID_MACE3:
2435 case AV_CODEC_ID_MACE6:
2436 case AV_CODEC_ID_QDM2:
2437 st->codecpar->block_align = sc->bytes_per_frame;
2439 case AV_CODEC_ID_ALAC:
2440 if (st->codecpar->extradata_size == 36) {
2441 st->codecpar->channels = AV_RB8 (st->codecpar->extradata + 21);
2442 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2445 case AV_CODEC_ID_AC3:
2446 case AV_CODEC_ID_EAC3:
2447 case AV_CODEC_ID_MPEG1VIDEO:
2448 case AV_CODEC_ID_VC1:
2449 case AV_CODEC_ID_VP8:
2450 case AV_CODEC_ID_VP9:
2451 st->need_parsing = AVSTREAM_PARSE_FULL;
2453 case AV_CODEC_ID_AV1:
2454 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2462 static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
2463 int codec_tag, int format,
2466 int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2469 (codec_tag != format &&
2470 // AVID 1:1 samples with differing data format and codec tag exist
2471 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
2472 // prores is allowed to have differing data format and codec tag
2473 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
2475 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
2476 (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id
2477 : codec_tag != MKTAG('j','p','e','g')))) {
2478 /* Multiple fourcc, we skip JPEG. This is not correct, we should
2479 * export it as a separate AVStream but this needs a few changes
2480 * in the MOV demuxer, patch welcome. */
2482 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
2483 avio_skip(pb, size);
2490 int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
2493 MOVStreamContext *sc;
2494 int pseudo_stream_id;
2496 av_assert0 (c->fc->nb_streams >= 1);
2497 st = c->fc->streams[c->fc->nb_streams-1];
2500 for (pseudo_stream_id = 0;
2501 pseudo_stream_id < entries && !pb->eof_reached;
2502 pseudo_stream_id++) {
2503 //Parsing Sample description table
2505 int ret, dref_id = 1;
2506 MOVAtom a = { AV_RL32("stsd") };
2507 int64_t start_pos = avio_tell(pb);
2508 int64_t size = avio_rb32(pb); /* size */
2509 uint32_t format = avio_rl32(pb); /* data format */
2512 avio_rb32(pb); /* reserved */
2513 avio_rb16(pb); /* reserved */
2514 dref_id = avio_rb16(pb);
2515 } else if (size <= 7) {
2516 av_log(c->fc, AV_LOG_ERROR,
2517 "invalid size %"PRId64" in stsd\n", size);
2518 return AVERROR_INVALIDDATA;
2521 if (mov_skip_multiple_stsd(c, pb, st->codecpar->codec_tag, format,
2522 size - (avio_tell(pb) - start_pos))) {
2527 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
2528 sc->dref_id= dref_id;
2529 sc->format = format;
2531 id = mov_codec_id(st, format);
2533 av_log(c->fc, AV_LOG_TRACE,
2534 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
2535 av_fourcc2str(format), st->codecpar->codec_type);
2537 st->codecpar->codec_id = id;
2538 if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) {
2539 mov_parse_stsd_video(c, pb, st, sc);
2540 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
2541 mov_parse_stsd_audio(c, pb, st, sc);
2542 if (st->codecpar->sample_rate < 0) {
2543 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
2544 return AVERROR_INVALIDDATA;
2546 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
2547 mov_parse_stsd_subtitle(c, pb, st, sc,
2548 size - (avio_tell(pb) - start_pos));
2550 ret = mov_parse_stsd_data(c, pb, st, sc,
2551 size - (avio_tell(pb) - start_pos));
2555 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
2556 a.size = size - (avio_tell(pb) - start_pos);
2558 if ((ret = mov_read_default(c, pb, a)) < 0)
2560 } else if (a.size > 0)
2561 avio_skip(pb, a.size);
2563 if (sc->extradata && st->codecpar->extradata) {
2564 int extra_size = st->codecpar->extradata_size;
2566 /* Move the current stream extradata to the stream context one. */
2567 sc->extradata_size[pseudo_stream_id] = extra_size;
2568 sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
2569 st->codecpar->extradata = NULL;
2570 st->codecpar->extradata_size = 0;
2575 if (pb->eof_reached) {
2576 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
2583 static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2586 MOVStreamContext *sc;
2589 if (c->fc->nb_streams < 1)
2591 st = c->fc->streams[c->fc->nb_streams - 1];
2594 sc->stsd_version = avio_r8(pb);
2595 avio_rb24(pb); /* flags */
2596 entries = avio_rb32(pb);
2598 /* Each entry contains a size (4 bytes) and format (4 bytes). */
2599 if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
2600 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
2601 return AVERROR_INVALIDDATA;
2604 if (sc->extradata) {
2605 av_log(c->fc, AV_LOG_ERROR,
2606 "Duplicate stsd found in this track.\n");
2607 return AVERROR_INVALIDDATA;
2610 /* Prepare space for hosting multiple extradata. */
2611 sc->extradata = av_mallocz_array(entries, sizeof(*sc->extradata));
2613 return AVERROR(ENOMEM);
2615 sc->extradata_size = av_mallocz_array(entries, sizeof(*sc->extradata_size));
2616 if (!sc->extradata_size) {
2617 ret = AVERROR(ENOMEM);
2621 ret = ff_mov_read_stsd_entries(c, pb, entries);
2625 /* Restore back the primary extradata. */
2626 av_freep(&st->codecpar->extradata);
2627 st->codecpar->extradata_size = sc->extradata_size[0];
2628 if (sc->extradata_size[0]) {
2629 st->codecpar->extradata = av_mallocz(sc->extradata_size[0] + AV_INPUT_BUFFER_PADDING_SIZE);
2630 if (!st->codecpar->extradata)
2631 return AVERROR(ENOMEM);
2632 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
2635 return mov_finalize_stsd_codec(c, pb, st, sc);
2637 if (sc->extradata) {
2639 for (j = 0; j < sc->stsd_count; j++)
2640 av_freep(&sc->extradata[j]);
2643 av_freep(&sc->extradata);
2644 av_freep(&sc->extradata_size);
2648 static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2651 MOVStreamContext *sc;
2652 unsigned int i, entries;
2654 if (c->fc->nb_streams < 1)
2656 st = c->fc->streams[c->fc->nb_streams-1];
2659 avio_r8(pb); /* version */
2660 avio_rb24(pb); /* flags */
2662 entries = avio_rb32(pb);
2663 if ((uint64_t)entries * 12 + 4 > atom.size)
2664 return AVERROR_INVALIDDATA;
2666 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
2671 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSC atom\n");
2672 av_free(sc->stsc_data);
2674 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
2676 return AVERROR(ENOMEM);
2678 for (i = 0; i < entries && !pb->eof_reached; i++) {
2679 sc->stsc_data[i].first = avio_rb32(pb);
2680 sc->stsc_data[i].count = avio_rb32(pb);
2681 sc->stsc_data[i].id = avio_rb32(pb);
2685 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
2686 int64_t first_min = i + 1;
2687 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
2688 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
2689 sc->stsc_data[i].first < first_min ||
2690 sc->stsc_data[i].count < 1 ||
2691 sc->stsc_data[i].id < 1) {
2692 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);
2693 if (i+1 >= sc->stsc_count) {
2694 if (sc->stsc_data[i].count == 0 && i > 0) {
2698 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
2699 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
2700 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
2701 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
2702 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
2705 av_assert0(sc->stsc_data[i+1].first >= 2);
2706 // We replace this entry by the next valid
2707 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
2708 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
2709 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
2713 if (pb->eof_reached) {
2714 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
2721 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
2723 return index < count - 1;
2726 /* Compute the samples value for the stsc entry at the given index. */
2727 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
2731 if (mov_stsc_index_valid(index, sc->stsc_count))
2732 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
2734 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
2735 av_assert0(sc->stsc_data[index].first <= sc->chunk_count);
2736 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
2739 return sc->stsc_data[index].count * (int64_t)chunk_count;
2742 static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2745 MOVStreamContext *sc;
2746 unsigned i, entries;
2748 if (c->fc->nb_streams < 1)
2750 st = c->fc->streams[c->fc->nb_streams-1];
2753 avio_rb32(pb); // version + flags
2755 entries = avio_rb32(pb);
2757 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
2758 av_free(sc->stps_data);
2760 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
2762 return AVERROR(ENOMEM);
2764 for (i = 0; i < entries && !pb->eof_reached; i++) {
2765 sc->stps_data[i] = avio_rb32(pb);
2770 if (pb->eof_reached) {
2771 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
2778 static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2781 MOVStreamContext *sc;
2782 unsigned int i, entries;
2784 if (c->fc->nb_streams < 1)
2786 st = c->fc->streams[c->fc->nb_streams-1];
2789 avio_r8(pb); /* version */
2790 avio_rb24(pb); /* flags */
2792 entries = avio_rb32(pb);
2794 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
2797 sc->keyframe_absent = 1;
2798 if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
2799 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2803 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
2804 if (entries >= UINT_MAX / sizeof(int))
2805 return AVERROR_INVALIDDATA;
2806 av_freep(&sc->keyframes);
2807 sc->keyframe_count = 0;
2808 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
2810 return AVERROR(ENOMEM);
2812 for (i = 0; i < entries && !pb->eof_reached; i++) {
2813 sc->keyframes[i] = avio_rb32(pb);
2816 sc->keyframe_count = i;
2818 if (pb->eof_reached) {
2819 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
2826 static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2829 MOVStreamContext *sc;
2830 unsigned int i, entries, sample_size, field_size, num_bytes;
2835 if (c->fc->nb_streams < 1)
2837 st = c->fc->streams[c->fc->nb_streams-1];
2840 avio_r8(pb); /* version */
2841 avio_rb24(pb); /* flags */
2843 if (atom.type == MKTAG('s','t','s','z')) {
2844 sample_size = avio_rb32(pb);
2845 if (!sc->sample_size) /* do not overwrite value computed in stsd */
2846 sc->sample_size = sample_size;
2847 sc->stsz_sample_size = sample_size;
2851 avio_rb24(pb); /* reserved */
2852 field_size = avio_r8(pb);
2854 entries = avio_rb32(pb);
2856 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
2858 sc->sample_count = entries;
2862 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
2863 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
2864 return AVERROR_INVALIDDATA;
2869 if (entries >= (UINT_MAX - 4) / field_size)
2870 return AVERROR_INVALIDDATA;
2871 if (sc->sample_sizes)
2872 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
2873 av_free(sc->sample_sizes);
2874 sc->sample_count = 0;
2875 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
2876 if (!sc->sample_sizes)
2877 return AVERROR(ENOMEM);
2879 num_bytes = (entries*field_size+4)>>3;
2881 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
2883 av_freep(&sc->sample_sizes);
2884 return AVERROR(ENOMEM);
2887 ret = ffio_read_size(pb, buf, num_bytes);
2889 av_freep(&sc->sample_sizes);
2891 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
2895 init_get_bits(&gb, buf, 8*num_bytes);
2897 for (i = 0; i < entries && !pb->eof_reached; i++) {
2898 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
2899 if (sc->sample_sizes[i] < 0) {
2901 av_log(c->fc, AV_LOG_ERROR, "Invalid sample size %d\n", sc->sample_sizes[i]);
2902 return AVERROR_INVALIDDATA;
2904 sc->data_size += sc->sample_sizes[i];
2907 sc->sample_count = i;
2911 if (pb->eof_reached) {
2912 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSZ atom\n");
2919 static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2922 MOVStreamContext *sc;
2923 unsigned int i, entries, alloc_size = 0;
2924 int64_t duration = 0;
2925 int64_t total_sample_count = 0;
2927 if (c->fc->nb_streams < 1)
2929 st = c->fc->streams[c->fc->nb_streams-1];
2932 avio_r8(pb); /* version */
2933 avio_rb24(pb); /* flags */
2934 entries = avio_rb32(pb);
2936 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
2937 c->fc->nb_streams-1, entries);
2940 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
2941 av_freep(&sc->stts_data);
2943 if (entries >= INT_MAX / sizeof(*sc->stts_data))
2944 return AVERROR(ENOMEM);
2946 for (i = 0; i < entries && !pb->eof_reached; i++) {
2947 int sample_duration;
2948 unsigned int sample_count;
2949 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
2950 MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
2951 min_entries * sizeof(*sc->stts_data));
2953 av_freep(&sc->stts_data);
2955 return AVERROR(ENOMEM);
2957 sc->stts_count = min_entries;
2958 sc->stts_data = stts_data;
2960 sample_count = avio_rb32(pb);
2961 sample_duration = avio_rb32(pb);
2963 sc->stts_data[i].count= sample_count;
2964 sc->stts_data[i].duration= sample_duration;
2966 av_log(c->fc, AV_LOG_TRACE, "sample_count=%d, sample_duration=%d\n",
2967 sample_count, sample_duration);
2969 duration+=(int64_t)sample_duration*(uint64_t)sample_count;
2970 total_sample_count+=sample_count;
2976 duration <= INT64_MAX - sc->duration_for_fps &&
2977 total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
2978 sc->duration_for_fps += duration;
2979 sc->nb_frames_for_fps += total_sample_count;
2982 if (pb->eof_reached) {
2983 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
2987 st->nb_frames= total_sample_count;
2989 st->duration= FFMIN(st->duration, duration);
2990 sc->track_end = duration;
2994 static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2997 MOVStreamContext *sc;
3000 if (c->fc->nb_streams < 1)
3002 st = c->fc->streams[c->fc->nb_streams - 1];
3005 avio_r8(pb); /* version */
3006 avio_rb24(pb); /* flags */
3007 entries = atom.size - 4;
3009 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3010 c->fc->nb_streams - 1, entries);
3013 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3014 av_freep(&sc->sdtp_data);
3017 sc->sdtp_data = av_mallocz(entries);
3019 return AVERROR(ENOMEM);
3021 for (i = 0; i < entries && !pb->eof_reached; i++)
3022 sc->sdtp_data[i] = avio_r8(pb);
3028 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3031 if (duration == INT_MIN) {
3032 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3035 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3039 static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3042 MOVStreamContext *sc;
3043 unsigned int i, entries, ctts_count = 0;
3045 if (c->fc->nb_streams < 1)
3047 st = c->fc->streams[c->fc->nb_streams-1];
3050 avio_r8(pb); /* version */
3051 avio_rb24(pb); /* flags */
3052 entries = avio_rb32(pb);
3054 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3058 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3059 return AVERROR_INVALIDDATA;
3060 av_freep(&sc->ctts_data);
3061 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3063 return AVERROR(ENOMEM);
3065 for (i = 0; i < entries && !pb->eof_reached; i++) {
3066 int count = avio_rb32(pb);
3067 int duration = avio_rb32(pb);
3070 av_log(c->fc, AV_LOG_TRACE,
3071 "ignoring CTTS entry with count=%d duration=%d\n",
3076 add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3079 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3082 if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3083 av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3084 av_freep(&sc->ctts_data);
3090 mov_update_dts_shift(sc, duration, c->fc);
3093 sc->ctts_count = ctts_count;
3095 if (pb->eof_reached) {
3096 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3100 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3105 static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3108 MOVStreamContext *sc;
3109 unsigned int i, entries;
3111 uint32_t grouping_type;
3113 if (c->fc->nb_streams < 1)
3115 st = c->fc->streams[c->fc->nb_streams-1];
3118 version = avio_r8(pb); /* version */
3119 avio_rb24(pb); /* flags */
3120 grouping_type = avio_rl32(pb);
3121 if (grouping_type != MKTAG( 'r','a','p',' '))
3122 return 0; /* only support 'rap ' grouping */
3124 avio_rb32(pb); /* grouping_type_parameter */
3126 entries = avio_rb32(pb);
3130 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP atom\n");
3131 av_free(sc->rap_group);
3132 sc->rap_group_count = 0;
3133 sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group));
3135 return AVERROR(ENOMEM);
3137 for (i = 0; i < entries && !pb->eof_reached; i++) {
3138 sc->rap_group[i].count = avio_rb32(pb); /* sample_count */
3139 sc->rap_group[i].index = avio_rb32(pb); /* group_description_index */
3142 sc->rap_group_count = i;
3144 if (pb->eof_reached) {
3145 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3153 * Get ith edit list entry (media time, duration).
3155 static int get_edit_list_entry(MOVContext *mov,
3156 const MOVStreamContext *msc,
3157 unsigned int edit_list_index,
3158 int64_t *edit_list_media_time,
3159 int64_t *edit_list_duration,
3160 int64_t global_timescale)
3162 if (edit_list_index == msc->elst_count) {
3165 *edit_list_media_time = msc->elst_data[edit_list_index].time;
3166 *edit_list_duration = msc->elst_data[edit_list_index].duration;
3168 /* duration is in global timescale units;convert to msc timescale */
3169 if (global_timescale == 0) {
3170 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3173 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3179 * Find the closest previous frame to the timestamp_pts, in e_old index
3180 * entries. Searching for just any frame / just key frames can be controlled by
3181 * last argument 'flag'.
3182 * Note that if ctts_data is not NULL, we will always search for a key frame
3183 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3184 * return the first frame of the video.
3186 * Here the timestamp_pts is considered to be a presentation timestamp and
3187 * the timestamp of index entries are considered to be decoding timestamps.
3189 * Returns 0 if successful in finding a frame, else returns -1.
3190 * Places the found index corresponding output arg.
3192 * If ctts_old is not NULL, then refines the searched entry by searching
3193 * backwards from the found timestamp, to find the frame with correct PTS.
3195 * Places the found ctts_index and ctts_sample in corresponding output args.
3197 static int find_prev_closest_index(AVStream *st,
3198 AVIndexEntry *e_old,
3202 int64_t timestamp_pts,
3205 int64_t* ctts_index,
3206 int64_t* ctts_sample)
3208 MOVStreamContext *msc = st->priv_data;
3209 AVIndexEntry *e_keep = st->internal->index_entries;
3210 int nb_keep = st->internal->nb_index_entries;
3212 int64_t index_ctts_count;
3216 // If dts_shift > 0, then all the index timestamps will have to be offset by
3217 // at least dts_shift amount to obtain PTS.
3218 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3219 if (msc->dts_shift > 0) {
3220 timestamp_pts -= msc->dts_shift;
3223 st->internal->index_entries = e_old;
3224 st->internal->nb_index_entries = nb_old;
3225 *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3227 // Keep going backwards in the index entries until the timestamp is the same.
3229 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3231 if ((flag & AVSEEK_FLAG_ANY) ||
3232 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3238 // If we have CTTS then refine the search, by searching backwards over PTS
3239 // computed by adding corresponding CTTS durations to index timestamps.
3240 if (ctts_data && *index >= 0) {
3241 av_assert0(ctts_index);
3242 av_assert0(ctts_sample);
3243 // Find out the ctts_index for the found frame.
3246 for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3247 if (*ctts_index < ctts_count) {
3249 if (ctts_data[*ctts_index].count == *ctts_sample) {
3256 while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3257 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3258 // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3259 // compensated by dts_shift above.
3260 if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3261 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3266 if (*ctts_sample == 0) {
3268 if (*ctts_index >= 0)
3269 *ctts_sample = ctts_data[*ctts_index].count - 1;
3276 /* restore AVStream state*/
3277 st->internal->index_entries = e_keep;
3278 st->internal->nb_index_entries = nb_keep;
3279 return *index >= 0 ? 0 : -1;
3283 * Add index entry with the given values, to the end of st->internal->index_entries.
3284 * Returns the new size st->internal->index_entries if successful, else returns -1.
3286 * This function is similar to ff_add_index_entry in libavformat/utils.c
3287 * except that here we are always unconditionally adding an index entry to
3288 * the end, instead of searching the entries list and skipping the add if
3289 * there is an existing entry with the same timestamp.
3290 * This is needed because the mov_fix_index calls this func with the same
3291 * unincremented timestamp for successive discarded frames.
3293 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3294 int size, int distance, int flags)
3296 AVIndexEntry *entries, *ie;
3298 const size_t min_size_needed = (st->internal->nb_index_entries + 1) * sizeof(AVIndexEntry);
3300 // Double the allocation each time, to lower memory fragmentation.
3301 // Another difference from ff_add_index_entry function.
3302 const size_t requested_size =
3303 min_size_needed > st->internal->index_entries_allocated_size ?
3304 FFMAX(min_size_needed, 2 * st->internal->index_entries_allocated_size) :
3307 if (st->internal->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
3310 entries = av_fast_realloc(st->internal->index_entries,
3311 &st->internal->index_entries_allocated_size,
3316 st->internal->index_entries= entries;
3318 index= st->internal->nb_index_entries++;
3319 ie= &entries[index];
3322 ie->timestamp = timestamp;
3323 ie->min_distance= distance;
3330 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3331 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3333 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3334 int64_t* frame_duration_buffer,
3335 int frame_duration_buffer_size) {
3337 av_assert0(end_index >= 0 && end_index <= st->internal->nb_index_entries);
3338 for (i = 0; i < frame_duration_buffer_size; i++) {
3339 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3340 st->internal->index_entries[end_index - 1 - i].timestamp = end_ts;
3345 * Append a new ctts entry to ctts_data.
3346 * Returns the new ctts_count if successful, else returns -1.
3348 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3349 int count, int duration)
3351 MOVStts *ctts_buf_new;
3352 const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVStts);
3353 const size_t requested_size =
3354 min_size_needed > *allocated_size ?
3355 FFMAX(min_size_needed, 2 * (*allocated_size)) :
3358 if ((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
3361 ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3366 *ctts_data = ctts_buf_new;
3368 ctts_buf_new[*ctts_count].count = count;
3369 ctts_buf_new[*ctts_count].duration = duration;
3371 *ctts_count = (*ctts_count) + 1;
3375 #define MAX_REORDER_DELAY 16
3376 static void mov_estimate_video_delay(MOVContext *c, AVStream* st)
3378 MOVStreamContext *msc = st->priv_data;
3381 int ctts_sample = 0;
3382 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3384 int j, r, num_swaps;
3386 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3387 pts_buf[j] = INT64_MIN;
3389 if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3390 st->codecpar->codec_id == AV_CODEC_ID_H264) {
3391 st->codecpar->video_delay = 0;
3392 for (ind = 0; ind < st->internal->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3393 // Point j to the last elem of the buffer and insert the current pts there.
3395 buf_start = (buf_start + 1);
3396 if (buf_start == MAX_REORDER_DELAY + 1)
3399 pts_buf[j] = st->internal->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3401 // The timestamps that are already in the sorted buffer, and are greater than the
3402 // current pts, are exactly the timestamps that need to be buffered to output PTS
3403 // in correct sorted order.
3404 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3405 // can be computed as the maximum no. of swaps any particular timestamp needs to
3406 // go through, to keep this buffer in sorted order.
3408 while (j != buf_start) {
3410 if (r < 0) r = MAX_REORDER_DELAY;
3411 if (pts_buf[j] < pts_buf[r]) {
3412 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3419 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3422 if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3427 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3428 st->codecpar->video_delay, st->index);
3432 static void mov_current_sample_inc(MOVStreamContext *sc)
3434 sc->current_sample++;
3435 sc->current_index++;
3436 if (sc->index_ranges &&
3437 sc->current_index >= sc->current_index_range->end &&
3438 sc->current_index_range->end) {
3439 sc->current_index_range++;
3440 sc->current_index = sc->current_index_range->start;
3444 static void mov_current_sample_dec(MOVStreamContext *sc)
3446 sc->current_sample--;
3447 sc->current_index--;
3448 if (sc->index_ranges &&
3449 sc->current_index < sc->current_index_range->start &&
3450 sc->current_index_range > sc->index_ranges) {
3451 sc->current_index_range--;
3452 sc->current_index = sc->current_index_range->end - 1;
3456 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3460 sc->current_sample = current_sample;
3461 sc->current_index = current_sample;
3462 if (!sc->index_ranges) {
3466 for (sc->current_index_range = sc->index_ranges;
3467 sc->current_index_range->end;
3468 sc->current_index_range++) {
3469 range_size = sc->current_index_range->end - sc->current_index_range->start;
3470 if (range_size > current_sample) {
3471 sc->current_index = sc->current_index_range->start + current_sample;
3474 current_sample -= range_size;
3479 * Fix st->internal->index_entries, so that it contains only the entries (and the entries
3480 * which are needed to decode them) that fall in the edit list time ranges.
3481 * Also fixes the timestamps of the index entries to match the timeline
3482 * specified the edit lists.
3484 static void mov_fix_index(MOVContext *mov, AVStream *st)
3486 MOVStreamContext *msc = st->priv_data;
3487 AVIndexEntry *e_old = st->internal->index_entries;
3488 int nb_old = st->internal->nb_index_entries;
3489 const AVIndexEntry *e_old_end = e_old + nb_old;
3490 const AVIndexEntry *current = NULL;
3491 MOVStts *ctts_data_old = msc->ctts_data;
3492 int64_t ctts_index_old = 0;
3493 int64_t ctts_sample_old = 0;
3494 int64_t ctts_count_old = msc->ctts_count;
3495 int64_t edit_list_media_time = 0;
3496 int64_t edit_list_duration = 0;
3497 int64_t frame_duration = 0;
3498 int64_t edit_list_dts_counter = 0;
3499 int64_t edit_list_dts_entry_end = 0;
3500 int64_t edit_list_start_ctts_sample = 0;
3502 int64_t curr_ctts = 0;
3503 int64_t empty_edits_sum_duration = 0;
3504 int64_t edit_list_index = 0;
3507 int64_t start_dts = 0;
3508 int64_t edit_list_start_encountered = 0;
3509 int64_t search_timestamp = 0;
3510 int64_t* frame_duration_buffer = NULL;
3511 int num_discarded_begin = 0;
3512 int first_non_zero_audio_edit = -1;
3513 int packet_skip_samples = 0;
3514 MOVIndexRange *current_index_range;
3516 int found_keyframe_after_edit = 0;
3517 int found_non_empty_edit = 0;
3519 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
3523 // allocate the index ranges array
3524 msc->index_ranges = av_malloc((msc->elst_count + 1) * sizeof(msc->index_ranges[0]));
3525 if (!msc->index_ranges) {
3526 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
3529 msc->current_index_range = msc->index_ranges;
3530 current_index_range = msc->index_ranges - 1;
3532 // Clean AVStream from traces of old index
3533 st->internal->index_entries = NULL;
3534 st->internal->index_entries_allocated_size = 0;
3535 st->internal->nb_index_entries = 0;
3537 // Clean ctts fields of MOVStreamContext
3538 msc->ctts_data = NULL;
3539 msc->ctts_count = 0;
3540 msc->ctts_index = 0;
3541 msc->ctts_sample = 0;
3542 msc->ctts_allocated_size = 0;
3544 // Reinitialize min_corrected_pts so that it can be computed again.
3545 msc->min_corrected_pts = -1;
3547 // If the dts_shift is positive (in case of negative ctts values in mov),
3548 // then negate the DTS by dts_shift
3549 if (msc->dts_shift > 0) {
3550 edit_list_dts_entry_end -= msc->dts_shift;
3551 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
3554 start_dts = edit_list_dts_entry_end;
3556 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
3557 &edit_list_duration, mov->time_scale)) {
3558 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
3559 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
3561 edit_list_dts_counter = edit_list_dts_entry_end;
3562 edit_list_dts_entry_end += edit_list_duration;
3563 num_discarded_begin = 0;
3564 if (!found_non_empty_edit && edit_list_media_time == -1) {
3565 empty_edits_sum_duration += edit_list_duration;
3568 found_non_empty_edit = 1;
3570 // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
3571 // according to the edit list below.
3572 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3573 if (first_non_zero_audio_edit < 0) {
3574 first_non_zero_audio_edit = 1;
3576 first_non_zero_audio_edit = 0;
3579 if (first_non_zero_audio_edit > 0)
3580 st->internal->skip_samples = msc->start_pad = 0;
3583 // While reordering frame index according to edit list we must handle properly
3584 // the scenario when edit list entry starts from none key frame.
3585 // We find closest previous key frame and preserve it and consequent frames in index.
3586 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
3587 search_timestamp = edit_list_media_time;
3588 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3589 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
3590 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
3591 // edit_list_media_time to cover the decoder delay.
3592 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
3595 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
3596 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3597 av_log(mov->fc, AV_LOG_WARNING,
3598 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
3599 st->index, edit_list_index, search_timestamp);
3600 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
3601 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3602 av_log(mov->fc, AV_LOG_WARNING,
3603 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
3604 st->index, edit_list_index, search_timestamp);
3607 ctts_sample_old = 0;
3610 current = e_old + index;
3611 edit_list_start_ctts_sample = ctts_sample_old;
3613 // Iterate over index and arrange it according to edit list
3614 edit_list_start_encountered = 0;
3615 found_keyframe_after_edit = 0;
3616 for (; current < e_old_end; current++, index++) {
3617 // check if frame outside edit list mark it for discard
3618 frame_duration = (current + 1 < e_old_end) ?
3619 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
3621 flags = current->flags;
3623 // frames (pts) before or after edit list
3624 curr_cts = current->timestamp + msc->dts_shift;
3627 if (ctts_data_old && ctts_index_old < ctts_count_old) {
3628 curr_ctts = ctts_data_old[ctts_index_old].duration;
3629 av_log(mov->fc, AV_LOG_DEBUG, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
3630 curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
3631 curr_cts += curr_ctts;
3633 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
3634 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3635 &msc->ctts_allocated_size,
3636 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3637 ctts_data_old[ctts_index_old].duration) == -1) {
3638 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3640 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3641 ctts_data_old[ctts_index_old].duration);
3645 ctts_sample_old = 0;
3646 edit_list_start_ctts_sample = 0;
3650 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
3651 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
3652 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
3653 first_non_zero_audio_edit > 0) {
3654 packet_skip_samples = edit_list_media_time - curr_cts;
3655 st->internal->skip_samples += packet_skip_samples;
3657 // Shift the index entry timestamp by packet_skip_samples to be correct.
3658 edit_list_dts_counter -= packet_skip_samples;
3659 if (edit_list_start_encountered == 0) {
3660 edit_list_start_encountered = 1;
3661 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
3662 // discarded packets.
3663 if (frame_duration_buffer) {
3664 fix_index_entry_timestamps(st, st->internal->nb_index_entries, edit_list_dts_counter,
3665 frame_duration_buffer, num_discarded_begin);
3666 av_freep(&frame_duration_buffer);
3670 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
3672 flags |= AVINDEX_DISCARD_FRAME;
3673 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
3675 if (edit_list_start_encountered == 0) {
3676 num_discarded_begin++;
3677 frame_duration_buffer = av_realloc(frame_duration_buffer,
3678 num_discarded_begin * sizeof(int64_t));
3679 if (!frame_duration_buffer) {
3680 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
3683 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
3685 // Increment skip_samples for the first non-zero audio edit list
3686 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3687 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
3688 st->internal->skip_samples += frame_duration;
3693 if (msc->min_corrected_pts < 0) {
3694 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
3696 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
3698 if (edit_list_start_encountered == 0) {
3699 edit_list_start_encountered = 1;
3700 // Make timestamps strictly monotonically increasing by rewriting timestamps for
3701 // discarded packets.
3702 if (frame_duration_buffer) {
3703 fix_index_entry_timestamps(st, st->internal->nb_index_entries, edit_list_dts_counter,
3704 frame_duration_buffer, num_discarded_begin);
3705 av_freep(&frame_duration_buffer);
3710 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
3711 current->min_distance, flags) == -1) {
3712 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
3716 // Update the index ranges array
3717 if (current_index_range < msc->index_ranges || index != current_index_range->end) {
3718 current_index_range++;
3719 current_index_range->start = index;
3721 current_index_range->end = index + 1;
3723 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
3724 if (edit_list_start_encountered > 0) {
3725 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
3728 // Break when found first key frame after edit entry completion
3729 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
3730 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
3731 if (ctts_data_old) {
3732 // If we have CTTS and this is the first keyframe after edit elist,
3733 // wait for one more, because there might be trailing B-frames after this I-frame
3734 // that do belong to the edit.
3735 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
3736 found_keyframe_after_edit = 1;
3739 if (ctts_sample_old != 0) {
3740 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3741 &msc->ctts_allocated_size,
3742 ctts_sample_old - edit_list_start_ctts_sample,
3743 ctts_data_old[ctts_index_old].duration) == -1) {
3744 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3745 ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
3746 ctts_data_old[ctts_index_old].duration);
3755 // If there are empty edits, then msc->min_corrected_pts might be positive
3756 // intentionally. So we subtract the sum duration of emtpy edits here.
3757 msc->min_corrected_pts -= empty_edits_sum_duration;
3759 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
3760 // dts by that amount to make the first pts zero.
3761 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
3762 if (msc->min_corrected_pts > 0) {
3763 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
3764 for (i = 0; i < st->internal->nb_index_entries; ++i) {
3765 st->internal->index_entries[i].timestamp -= msc->min_corrected_pts;
3769 // Start time should be equal to zero or the duration of any empty edits.
3770 st->start_time = empty_edits_sum_duration;
3772 // Update av stream length, if it ends up shorter than the track's media duration
3773 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
3774 msc->start_pad = st->internal->skip_samples;
3776 // Free the old index and the old CTTS structures
3778 av_free(ctts_data_old);
3779 av_freep(&frame_duration_buffer);
3781 // Null terminate the index ranges array
3782 current_index_range++;
3783 current_index_range->start = 0;
3784 current_index_range->end = 0;
3785 msc->current_index = msc->index_ranges[0].start;
3788 static void mov_build_index(MOVContext *mov, AVStream *st)
3790 MOVStreamContext *sc = st->priv_data;
3791 int64_t current_offset;
3792 int64_t current_dts = 0;
3793 unsigned int stts_index = 0;
3794 unsigned int stsc_index = 0;
3795 unsigned int stss_index = 0;
3796 unsigned int stps_index = 0;
3798 uint64_t stream_size = 0;
3799 MOVStts *ctts_data_old = sc->ctts_data;
3800 unsigned int ctts_count_old = sc->ctts_count;
3802 if (sc->elst_count) {
3803 int i, edit_start_index = 0, multiple_edits = 0;
3804 int64_t empty_duration = 0; // empty duration of the first edit list entry
3805 int64_t start_time = 0; // start time of the media
3807 for (i = 0; i < sc->elst_count; i++) {
3808 const MOVElst *e = &sc->elst_data[i];
3809 if (i == 0 && e->time == -1) {
3810 /* if empty, the first entry is the start time of the stream
3811 * relative to the presentation itself */
3812 empty_duration = e->duration;
3813 edit_start_index = 1;
3814 } else if (i == edit_start_index && e->time >= 0) {
3815 start_time = e->time;
3821 if (multiple_edits && !mov->advanced_editlist)
3822 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
3823 "Use -advanced_editlist to correctly decode otherwise "
3824 "a/v desync might occur\n");
3826 /* adjust first dts according to edit list */
3827 if ((empty_duration || start_time) && mov->time_scale > 0) {
3829 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
3830 sc->time_offset = start_time - empty_duration;
3831 sc->min_corrected_pts = start_time;
3832 if (!mov->advanced_editlist)
3833 current_dts = -sc->time_offset;
3836 if (!multiple_edits && !mov->advanced_editlist &&
3837 st->codecpar->codec_id == AV_CODEC_ID_AAC && start_time > 0)
3838 sc->start_pad = start_time;
3841 /* only use old uncompressed audio chunk demuxing when stts specifies it */
3842 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3843 sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
3844 unsigned int current_sample = 0;
3845 unsigned int stts_sample = 0;
3846 unsigned int sample_size;
3847 unsigned int distance = 0;
3848 unsigned int rap_group_index = 0;
3849 unsigned int rap_group_sample = 0;
3850 int64_t last_dts = 0;
3851 int64_t dts_correction = 0;
3852 int rap_group_present = sc->rap_group_count && sc->rap_group;
3853 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
3855 current_dts -= sc->dts_shift;
3856 last_dts = current_dts;
3858 if (!sc->sample_count || st->internal->nb_index_entries)
3860 if (sc->sample_count >= UINT_MAX / sizeof(*st->internal->index_entries) - st->internal->nb_index_entries)
3862 if (av_reallocp_array(&st->internal->index_entries,
3863 st->internal->nb_index_entries + sc->sample_count,
3864 sizeof(*st->internal->index_entries)) < 0) {
3865 st->internal->nb_index_entries = 0;
3868 st->internal->index_entries_allocated_size = (st->internal->nb_index_entries + sc->sample_count) * sizeof(*st->internal->index_entries);
3870 if (ctts_data_old) {
3871 // Expand ctts entries such that we have a 1-1 mapping with samples
3872 if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
3875 sc->ctts_allocated_size = 0;
3876 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size,
3877 sc->sample_count * sizeof(*sc->ctts_data));
3878 if (!sc->ctts_data) {
3879 av_free(ctts_data_old);
3883 memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
3885 for (i = 0; i < ctts_count_old &&
3886 sc->ctts_count < sc->sample_count; i++)
3887 for (j = 0; j < ctts_data_old[i].count &&
3888 sc->ctts_count < sc->sample_count; j++)
3889 add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
3890 &sc->ctts_allocated_size, 1,
3891 ctts_data_old[i].duration);
3892 av_free(ctts_data_old);
3895 for (i = 0; i < sc->chunk_count; i++) {
3896 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
3897 current_offset = sc->chunk_offsets[i];
3898 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3899 i + 1 == sc->stsc_data[stsc_index + 1].first)
3902 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
3903 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
3904 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
3905 sc->stsz_sample_size = sc->sample_size;
3907 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
3908 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
3909 sc->stsz_sample_size = sc->sample_size;
3912 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
3914 if (current_sample >= sc->sample_count) {
3915 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
3919 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
3921 if (stss_index + 1 < sc->keyframe_count)
3923 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
3925 if (stps_index + 1 < sc->stps_count)
3928 if (rap_group_present && rap_group_index < sc->rap_group_count) {
3929 if (sc->rap_group[rap_group_index].index > 0)
3931 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
3932 rap_group_sample = 0;
3936 if (sc->keyframe_absent
3938 && !rap_group_present
3939 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
3943 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
3944 if (sc->pseudo_stream_id == -1 ||
3945 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
3947 if (sample_size > 0x3FFFFFFF) {
3948 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
3951 e = &st->internal->index_entries[st->internal->nb_index_entries++];
3952 e->pos = current_offset;
3953 e->timestamp = current_dts;
3954 e->size = sample_size;
3955 e->min_distance = distance;
3956 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
3957 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
3958 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
3959 current_offset, current_dts, sample_size, distance, keyframe);
3960 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->internal->nb_index_entries < 100)
3961 ff_rfps_add_frame(mov->fc, st, current_dts);
3964 current_offset += sample_size;
3965 stream_size += sample_size;
3967 /* A negative sample duration is invalid based on the spec,
3968 * but some samples need it to correct the DTS. */
3969 if (sc->stts_data[stts_index].duration < 0) {
3970 av_log(mov->fc, AV_LOG_WARNING,
3971 "Invalid SampleDelta %d in STTS, at %d st:%d\n",
3972 sc->stts_data[stts_index].duration, stts_index,
3974 dts_correction += sc->stts_data[stts_index].duration - 1;
3975 sc->stts_data[stts_index].duration = 1;
3977 current_dts += sc->stts_data[stts_index].duration;
3978 if (!dts_correction || current_dts + dts_correction > last_dts) {
3979 current_dts += dts_correction;
3982 /* Avoid creating non-monotonous DTS */
3983 dts_correction += current_dts - last_dts - 1;
3984 current_dts = last_dts + 1;
3986 last_dts = current_dts;
3990 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
3996 if (st->duration > 0)
3997 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
3999 unsigned chunk_samples, total = 0;
4001 if (!sc->chunk_count)
4004 // compute total chunk count
4005 for (i = 0; i < sc->stsc_count; i++) {
4006 unsigned count, chunk_count;
4008 chunk_samples = sc->stsc_data[i].count;
4009 if (i != sc->stsc_count - 1 &&
4010 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
4011 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
4015 if (sc->samples_per_frame >= 160) { // gsm
4016 count = chunk_samples / sc->samples_per_frame;
4017 } else if (sc->samples_per_frame > 1) {
4018 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4019 count = (chunk_samples+samples-1) / samples;
4021 count = (chunk_samples+1023) / 1024;
4024 if (mov_stsc_index_valid(i, sc->stsc_count))
4025 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4027 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4028 total += chunk_count * count;
4031 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4032 if (total >= UINT_MAX / sizeof(*st->internal->index_entries) - st->internal->nb_index_entries)
4034 if (av_reallocp_array(&st->internal->index_entries,
4035 st->internal->nb_index_entries + total,
4036 sizeof(*st->internal->index_entries)) < 0) {
4037 st->internal->nb_index_entries = 0;
4040 st->internal->index_entries_allocated_size = (st->internal->nb_index_entries + total) * sizeof(*st->internal->index_entries);
4043 for (i = 0; i < sc->chunk_count; i++) {
4044 current_offset = sc->chunk_offsets[i];
4045 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4046 i + 1 == sc->stsc_data[stsc_index + 1].first)
4048 chunk_samples = sc->stsc_data[stsc_index].count;
4050 while (chunk_samples > 0) {
4052 unsigned size, samples;
4054 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4055 avpriv_request_sample(mov->fc,
4056 "Zero bytes per frame, but %d samples per frame",
4057 sc->samples_per_frame);
4061 if (sc->samples_per_frame >= 160) { // gsm
4062 samples = sc->samples_per_frame;
4063 size = sc->bytes_per_frame;
4065 if (sc->samples_per_frame > 1) {
4066 samples = FFMIN((1024 / sc->samples_per_frame)*
4067 sc->samples_per_frame, chunk_samples);
4068 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
4070 samples = FFMIN(1024, chunk_samples);
4071 size = samples * sc->sample_size;
4075 if (st->internal->nb_index_entries >= total) {
4076 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4079 if (size > 0x3FFFFFFF) {
4080 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4083 e = &st->internal->index_entries[st->internal->nb_index_entries++];
4084 e->pos = current_offset;
4085 e->timestamp = current_dts;
4087 e->min_distance = 0;
4088 e->flags = AVINDEX_KEYFRAME;
4089 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4090 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4093 current_offset += size;
4094 current_dts += samples;
4095 chunk_samples -= samples;
4100 if (!mov->ignore_editlist && mov->advanced_editlist) {
4101 // Fix index according to edit lists.
4102 mov_fix_index(mov, st);
4105 // Update start time of the stream.
4106 if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->internal->nb_index_entries > 0) {
4107 st->start_time = st->internal->index_entries[0].timestamp + sc->dts_shift;
4108 if (sc->ctts_data) {
4109 st->start_time += sc->ctts_data[0].duration;
4113 mov_estimate_video_delay(mov, st);
4116 static int test_same_origin(const char *src, const char *ref) {
4126 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4127 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4129 if (strlen(src) == 0) {
4131 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4132 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4133 strlen(src_host) + 1 >= sizeof(src_host) ||
4134 strlen(ref_host) + 1 >= sizeof(ref_host)) {
4136 } else if (strcmp(src_proto, ref_proto) ||
4137 strcmp(src_auth, ref_auth) ||
4138 strcmp(src_host, ref_host) ||
4139 src_port != ref_port) {
4145 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4147 /* try relative path, we do not try the absolute because it can leak information about our
4148 system to an attacker */
4149 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4150 char filename[1025];
4151 const char *src_path;
4154 /* find a source dir */
4155 src_path = strrchr(src, '/');
4161 /* find a next level down to target */
4162 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4163 if (ref->path[l] == '/') {
4164 if (i == ref->nlvl_to - 1)
4170 /* compose filename if next level down to target was found */
4171 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4172 memcpy(filename, src, src_path - src);
4173 filename[src_path - src] = 0;
4175 for (i = 1; i < ref->nlvl_from; i++)
4176 av_strlcat(filename, "../", sizeof(filename));
4178 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4179 if (!c->use_absolute_path) {
4180 int same_origin = test_same_origin(src, filename);
4183 av_log(c->fc, AV_LOG_ERROR,
4184 "Reference with mismatching origin, %s not tried for security reasons, "
4185 "set demuxer option use_absolute_path to allow it anyway\n",
4187 return AVERROR(ENOENT);
4190 if (strstr(ref->path + l + 1, "..") ||
4191 strstr(ref->path + l + 1, ":") ||
4192 (ref->nlvl_from > 1 && same_origin < 0) ||
4193 (filename[0] == '/' && src_path == src))
4194 return AVERROR(ENOENT);
4197 if (strlen(filename) + 1 == sizeof(filename))
4198 return AVERROR(ENOENT);
4199 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4202 } else if (c->use_absolute_path) {
4203 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4204 "this is a possible security issue\n");
4205 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4208 av_log(c->fc, AV_LOG_ERROR,
4209 "Absolute path %s not tried for security reasons, "
4210 "set demuxer option use_absolute_path to allow absolute paths\n",
4214 return AVERROR(ENOENT);
4217 static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
4219 if (sc->time_scale <= 0) {
4220 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4221 sc->time_scale = c->time_scale;
4222 if (sc->time_scale <= 0)
4227 static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4230 MOVStreamContext *sc;
4233 st = avformat_new_stream(c->fc, NULL);
4234 if (!st) return AVERROR(ENOMEM);
4236 sc = av_mallocz(sizeof(MOVStreamContext));
4237 if (!sc) return AVERROR(ENOMEM);
4240 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
4241 sc->ffindex = st->index;
4242 c->trak_index = st->index;
4244 if ((ret = mov_read_default(c, pb, atom)) < 0)
4249 // Here stsc refers to a chunk not described in stco. This is technically invalid,
4250 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4251 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4253 av_freep(&sc->stsc_data);
4257 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4258 (!sc->sample_size && !sc->sample_count))) ||
4259 (!sc->chunk_count && sc->sample_count)) {
4260 av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4264 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4265 av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4267 return AVERROR_INVALIDDATA;
4270 fix_timescale(c, sc);
4272 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4274 mov_build_index(c, st);
4276 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4277 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4278 if (c->enable_drefs) {
4279 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4280 av_log(c->fc, AV_LOG_ERROR,
4281 "stream %d, error opening alias: path='%s', dir='%s', "
4282 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4283 st->index, dref->path, dref->dir, dref->filename,
4284 dref->volume, dref->nlvl_from, dref->nlvl_to);
4286 av_log(c->fc, AV_LOG_WARNING,
4287 "Skipped opening external track: "
4288 "stream %d, alias: path='%s', dir='%s', "
4289 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4290 "Set enable_drefs to allow this.\n",
4291 st->index, dref->path, dref->dir, dref->filename,
4292 dref->volume, dref->nlvl_from, dref->nlvl_to);
4296 sc->pb_is_copied = 1;
4299 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4300 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4301 sc->height && sc->width &&
4302 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4303 st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4304 ((double)st->codecpar->width * sc->height), INT_MAX);
4307 #if FF_API_R_FRAME_RATE
4308 if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4309 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
4310 sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4314 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4315 if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4316 TAG_IS_AVCI(st->codecpar->codec_tag)) {
4317 ret = ff_generate_avci_extradata(st);
4322 switch (st->codecpar->codec_id) {
4323 #if CONFIG_H261_DECODER
4324 case AV_CODEC_ID_H261:
4326 #if CONFIG_H263_DECODER
4327 case AV_CODEC_ID_H263:
4329 #if CONFIG_MPEG4_DECODER
4330 case AV_CODEC_ID_MPEG4:
4332 st->codecpar->width = 0; /* let decoder init width/height */
4333 st->codecpar->height= 0;
4337 // If the duration of the mp3 packets is not constant, then they could need a parser
4338 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4339 && sc->stts_count > 3
4340 && sc->stts_count*10 > st->nb_frames
4341 && sc->time_scale == st->codecpar->sample_rate) {
4342 st->need_parsing = AVSTREAM_PARSE_FULL;
4344 /* Do not need those anymore. */
4345 av_freep(&sc->chunk_offsets);
4346 av_freep(&sc->sample_sizes);
4347 av_freep(&sc->keyframes);
4348 av_freep(&sc->stts_data);
4349 av_freep(&sc->stps_data);
4350 av_freep(&sc->elst_data);
4351 av_freep(&sc->rap_group);
4356 static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4359 c->itunes_metadata = 1;
4360 ret = mov_read_default(c, pb, atom);
4361 c->itunes_metadata = 0;
4365 static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4374 count = avio_rb32(pb);
4375 if (count > UINT_MAX / sizeof(*c->meta_keys) - 1) {
4376 av_log(c->fc, AV_LOG_ERROR,
4377 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
4378 return AVERROR_INVALIDDATA;
4381 c->meta_keys_count = count + 1;
4382 c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
4384 return AVERROR(ENOMEM);
4386 for (i = 1; i <= count; ++i) {
4387 uint32_t key_size = avio_rb32(pb);
4388 uint32_t type = avio_rl32(pb);
4390 av_log(c->fc, AV_LOG_ERROR,
4391 "The key# %"PRIu32" in meta has invalid size:"
4392 "%"PRIu32"\n", i, key_size);
4393 return AVERROR_INVALIDDATA;
4396 if (type != MKTAG('m','d','t','a')) {
4397 avio_skip(pb, key_size);
4399 c->meta_keys[i] = av_mallocz(key_size + 1);
4400 if (!c->meta_keys[i])
4401 return AVERROR(ENOMEM);
4402 avio_read(pb, c->meta_keys[i], key_size);
4408 static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4410 int64_t end = av_sat_add64(avio_tell(pb), atom.size);
4411 uint8_t *key = NULL, *val = NULL, *mean = NULL;
4415 MOVStreamContext *sc;
4417 if (c->fc->nb_streams < 1)
4419 st = c->fc->streams[c->fc->nb_streams-1];
4422 for (i = 0; i < 3; i++) {
4426 if (end - avio_tell(pb) <= 12)
4429 len = avio_rb32(pb);
4430 tag = avio_rl32(pb);
4431 avio_skip(pb, 4); // flags
4433 if (len < 12 || len - 12 > end - avio_tell(pb))
4437 if (tag == MKTAG('m', 'e', 'a', 'n'))
4439 else if (tag == MKTAG('n', 'a', 'm', 'e'))
4441 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
4451 *p = av_malloc(len + 1);
4453 ret = AVERROR(ENOMEM);
4456 ret = ffio_read_size(pb, *p, len);
4464 if (mean && key && val) {
4465 if (strcmp(key, "iTunSMPB") == 0) {
4466 int priming, remainder, samples;
4467 if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
4468 if(priming>0 && priming<16384)
4469 sc->start_pad = priming;
4472 if (strcmp(key, "cdec") != 0) {
4473 av_dict_set(&c->fc->metadata, key, val,
4474 AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
4478 av_log(c->fc, AV_LOG_VERBOSE,
4479 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
4482 avio_seek(pb, end, SEEK_SET);
4489 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4491 while (atom.size > 8) {
4495 tag = avio_rl32(pb);
4497 if (tag == MKTAG('h','d','l','r')) {
4498 avio_seek(pb, -8, SEEK_CUR);
4500 return mov_read_default(c, pb, atom);
4506 // return 1 when matrix is identity, 0 otherwise
4507 #define IS_MATRIX_IDENT(matrix) \
4508 ( (matrix)[0][0] == (1 << 16) && \
4509 (matrix)[1][1] == (1 << 16) && \
4510 (matrix)[2][2] == (1 << 30) && \
4511 !(matrix)[0][1] && !(matrix)[0][2] && \
4512 !(matrix)[1][0] && !(matrix)[1][2] && \
4513 !(matrix)[2][0] && !(matrix)[2][1])
4515 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4520 int display_matrix[3][3];
4521 int res_display_matrix[3][3] = { { 0 } };
4523 MOVStreamContext *sc;
4527 if (c->fc->nb_streams < 1)
4529 st = c->fc->streams[c->fc->nb_streams-1];
4532 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4533 // avoids corrupting AVStreams mapped to an earlier tkhd.
4535 return AVERROR_INVALIDDATA;
4537 version = avio_r8(pb);
4538 flags = avio_rb24(pb);
4539 st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
4545 avio_rb32(pb); /* creation time */
4546 avio_rb32(pb); /* modification time */
4548 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4549 avio_rb32(pb); /* reserved */
4551 /* highlevel (considering edits) duration in movie timebase */
4552 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4553 avio_rb32(pb); /* reserved */
4554 avio_rb32(pb); /* reserved */
4556 avio_rb16(pb); /* layer */
4557 avio_rb16(pb); /* alternate group */
4558 avio_rb16(pb); /* volume */
4559 avio_rb16(pb); /* reserved */
4561 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4562 // they're kept in fixed point format through all calculations
4563 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4564 // side data, but the scale factor is not needed to calculate aspect ratio
4565 for (i = 0; i < 3; i++) {
4566 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
4567 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
4568 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
4571 width = avio_rb32(pb); // 16.16 fixed point track width
4572 height = avio_rb32(pb); // 16.16 fixed point track height
4573 sc->width = width >> 16;
4574 sc->height = height >> 16;
4576 // apply the moov display matrix (after the tkhd one)
4577 for (i = 0; i < 3; i++) {
4578 const int sh[3] = { 16, 16, 30 };
4579 for (j = 0; j < 3; j++) {
4580 for (e = 0; e < 3; e++) {
4581 res_display_matrix[i][j] +=
4582 ((int64_t) display_matrix[i][e] *
4583 c->movie_display_matrix[e][j]) >> sh[e];
4588 // save the matrix when it is not the default identity
4589 if (!IS_MATRIX_IDENT(res_display_matrix)) {
4592 av_freep(&sc->display_matrix);
4593 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4594 if (!sc->display_matrix)
4595 return AVERROR(ENOMEM);
4597 for (i = 0; i < 3; i++)
4598 for (j = 0; j < 3; j++)
4599 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4601 #if FF_API_OLD_ROTATE_API
4602 rotate = av_display_rotation_get(sc->display_matrix);
4603 if (!isnan(rotate)) {
4604 char rotate_buf[64];
4606 if (rotate < 0) // for backward compatibility
4608 snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate);
4609 av_dict_set(&st->metadata, "rotate", rotate_buf, 0);
4614 // transform the display width/height according to the matrix
4615 // to keep the same scale, use [width height 1<<16]
4616 if (width && height && sc->display_matrix) {
4617 double disp_transform[2];
4619 for (i = 0; i < 2; i++)
4620 disp_transform[i] = hypot(sc->display_matrix[0 + i],
4621 sc->display_matrix[3 + i]);
4623 if (disp_transform[0] > 0 && disp_transform[1] > 0 &&
4624 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4625 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4626 st->sample_aspect_ratio = av_d2q(
4627 disp_transform[0] / disp_transform[1],
4633 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4635 MOVFragment *frag = &c->fragment;
4636 MOVTrackExt *trex = NULL;
4637 int flags, track_id, i;
4638 MOVFragmentStreamInfo * frag_stream_info;
4640 avio_r8(pb); /* version */
4641 flags = avio_rb24(pb);
4643 track_id = avio_rb32(pb);
4645 return AVERROR_INVALIDDATA;
4646 for (i = 0; i < c->trex_count; i++)
4647 if (c->trex_data[i].track_id == track_id) {
4648 trex = &c->trex_data[i];
4652 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4655 c->fragment.found_tfhd = 1;
4656 frag->track_id = track_id;
4657 set_frag_stream(&c->frag_index, track_id);
4659 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4660 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4661 frag->moof_offset : frag->implicit_offset;
4662 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4664 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4665 avio_rb32(pb) : trex->duration;
4666 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4667 avio_rb32(pb) : trex->size;
4668 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4669 avio_rb32(pb) : trex->flags;
4670 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4672 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4673 if (frag_stream_info)
4674 frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
4679 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4684 num = atom.size / 4;
4685 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4686 return AVERROR(ENOMEM);
4688 av_free(c->chapter_tracks);
4689 c->chapter_tracks = new_tracks;
4690 c->nb_chapter_tracks = num;
4692 for (i = 0; i < num && !pb->eof_reached; i++)
4693 c->chapter_tracks[i] = avio_rb32(pb);
4698 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4703 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4704 return AVERROR_INVALIDDATA;
4705 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4706 sizeof(*c->trex_data))) < 0) {
4711 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4713 trex = &c->trex_data[c->trex_count++];
4714 avio_r8(pb); /* version */
4715 avio_rb24(pb); /* flags */
4716 trex->track_id = avio_rb32(pb);
4717 trex->stsd_id = avio_rb32(pb);
4718 trex->duration = avio_rb32(pb);
4719 trex->size = avio_rb32(pb);
4720 trex->flags = avio_rb32(pb);
4724 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4726 MOVFragment *frag = &c->fragment;
4727 AVStream *st = NULL;
4728 MOVStreamContext *sc;
4730 MOVFragmentStreamInfo * frag_stream_info;
4731 int64_t base_media_decode_time;
4733 for (i = 0; i < c->fc->nb_streams; i++) {
4734 if (c->fc->streams[i]->id == frag->track_id) {
4735 st = c->fc->streams[i];
4740 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4744 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4746 version = avio_r8(pb);
4747 avio_rb24(pb); /* flags */
4749 base_media_decode_time = avio_rb64(pb);
4751 base_media_decode_time = avio_rb32(pb);
4754 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4755 if (frag_stream_info)
4756 frag_stream_info->tfdt_dts = base_media_decode_time;
4757 sc->track_end = base_media_decode_time;
4762 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4764 MOVFragment *frag = &c->fragment;
4765 AVStream *st = NULL;
4766 MOVStreamContext *sc;
4769 int64_t dts, pts = AV_NOPTS_VALUE;
4770 int data_offset = 0;
4771 unsigned entries, first_sample_flags = frag->flags;
4772 int flags, distance, i;
4773 int64_t prev_dts = AV_NOPTS_VALUE;
4774 int next_frag_index = -1, index_entry_pos;
4775 size_t requested_size;
4776 size_t old_ctts_allocated_size;
4777 AVIndexEntry *new_entries;
4778 MOVFragmentStreamInfo * frag_stream_info;
4780 if (!frag->found_tfhd) {
4781 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4782 return AVERROR_INVALIDDATA;
4785 for (i = 0; i < c->fc->nb_streams; i++) {
4786 if (c->fc->streams[i]->id == frag->track_id) {
4787 st = c->fc->streams[i];
4792 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4796 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4799 // Find the next frag_index index that has a valid index_entry for
4800 // the current track_id.
4802 // A valid index_entry means the trun for the fragment was read
4803 // and it's samples are in index_entries at the given position.
4804 // New index entries will be inserted before the index_entry found.
4805 index_entry_pos = st->internal->nb_index_entries;
4806 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4807 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4808 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4809 next_frag_index = i;
4810 index_entry_pos = frag_stream_info->index_entry;
4814 av_assert0(index_entry_pos <= st->internal->nb_index_entries);
4816 avio_r8(pb); /* version */
4817 flags = avio_rb24(pb);
4818 entries = avio_rb32(pb);
4819 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4821 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4822 return AVERROR_INVALIDDATA;
4823 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4824 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4826 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4827 if (frag_stream_info) {
4828 if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
4829 dts = frag_stream_info->next_trun_dts - sc->time_offset;
4830 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4831 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4832 pts = frag_stream_info->first_tfra_pts;
4833 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4834 ", using it for pts\n", pts);
4835 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4836 c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
4837 dts = frag_stream_info->first_tfra_pts;
4838 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4839 ", using it for dts\n", pts);
4840 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4841 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4842 // pts = frag_stream_info->sidx_pts;
4843 dts = frag_stream_info->sidx_pts - sc->time_offset;
4844 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4845 ", using it for pts\n", pts);
4846 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4847 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4848 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4849 ", using it for dts\n", dts);
4851 dts = sc->track_end - sc->time_offset;
4852 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4853 ", using it for dts\n", dts);
4856 dts = sc->track_end - sc->time_offset;
4857 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4858 ", using it for dts\n", dts);
4860 offset = frag->base_data_offset + data_offset;
4862 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4864 // realloc space for new index entries
4865 if((uint64_t)st->internal->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4866 entries = UINT_MAX / sizeof(AVIndexEntry) - st->internal->nb_index_entries;
4867 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4872 requested_size = (st->internal->nb_index_entries + entries) * sizeof(AVIndexEntry);
4873 new_entries = av_fast_realloc(st->internal->index_entries,
4874 &st->internal->index_entries_allocated_size,
4877 return AVERROR(ENOMEM);
4878 st->internal->index_entries= new_entries;
4880 requested_size = (st->internal->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4881 old_ctts_allocated_size = sc->ctts_allocated_size;
4882 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4885 return AVERROR(ENOMEM);
4886 sc->ctts_data = ctts_data;
4888 // In case there were samples without ctts entries, ensure they get
4889 // zero valued entries. This ensures clips which mix boxes with and
4890 // without ctts entries don't pickup uninitialized data.
4891 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4892 sc->ctts_allocated_size - old_ctts_allocated_size);
4894 if (index_entry_pos < st->internal->nb_index_entries) {
4895 // Make hole in index_entries and ctts_data for new samples
4896 memmove(st->internal->index_entries + index_entry_pos + entries,
4897 st->internal->index_entries + index_entry_pos,
4898 sizeof(*st->internal->index_entries) *
4899 (st->internal->nb_index_entries - index_entry_pos));
4900 memmove(sc->ctts_data + index_entry_pos + entries,
4901 sc->ctts_data + index_entry_pos,
4902 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4903 if (index_entry_pos < sc->current_sample) {
4904 sc->current_sample += entries;
4908 st->internal->nb_index_entries += entries;
4909 sc->ctts_count = st->internal->nb_index_entries;
4911 // Record the index_entry position in frag_index of this fragment
4912 if (frag_stream_info)
4913 frag_stream_info->index_entry = index_entry_pos;
4915 if (index_entry_pos > 0)
4916 prev_dts = st->internal->index_entries[index_entry_pos-1].timestamp;
4918 for (i = 0; i < entries && !pb->eof_reached; i++) {
4919 unsigned sample_size = frag->size;
4920 int sample_flags = i ? frag->flags : first_sample_flags;
4921 unsigned sample_duration = frag->duration;
4922 unsigned ctts_duration = 0;
4924 int index_entry_flags = 0;
4926 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4927 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4928 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4929 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4931 mov_update_dts_shift(sc, ctts_duration, c->fc);
4932 if (pts != AV_NOPTS_VALUE) {
4933 dts = pts - sc->dts_shift;
4934 if (flags & MOV_TRUN_SAMPLE_CTS) {
4935 dts -= ctts_duration;
4937 dts -= sc->time_offset;
4939 av_log(c->fc, AV_LOG_DEBUG,
4940 "pts %"PRId64" calculated dts %"PRId64
4941 " sc->dts_shift %d ctts.duration %d"
4942 " sc->time_offset %"PRId64
4943 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4945 sc->dts_shift, ctts_duration,
4946 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4947 pts = AV_NOPTS_VALUE;
4950 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4954 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4955 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4958 index_entry_flags |= AVINDEX_KEYFRAME;
4960 // Fragments can overlap in time. Discard overlapping frames after
4962 if (prev_dts >= dts)
4963 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4965 st->internal->index_entries[index_entry_pos].pos = offset;
4966 st->internal->index_entries[index_entry_pos].timestamp = dts;
4967 st->internal->index_entries[index_entry_pos].size= sample_size;
4968 st->internal->index_entries[index_entry_pos].min_distance= distance;
4969 st->internal->index_entries[index_entry_pos].flags = index_entry_flags;
4971 sc->ctts_data[index_entry_pos].count = 1;
4972 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4975 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4976 "size %u, distance %d, keyframe %d\n", st->index,
4977 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4979 dts += sample_duration;
4980 offset += sample_size;
4981 sc->data_size += sample_size;
4983 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4984 1 <= INT_MAX - sc->nb_frames_for_fps
4986 sc->duration_for_fps += sample_duration;
4987 sc->nb_frames_for_fps ++;
4990 if (frag_stream_info)
4991 frag_stream_info->next_trun_dts = dts + sc->time_offset;
4993 // EOF found before reading all entries. Fix the hole this would
4994 // leave in index_entries and ctts_data
4995 int gap = entries - i;
4996 memmove(st->internal->index_entries + index_entry_pos,
4997 st->internal->index_entries + index_entry_pos + gap,
4998 sizeof(*st->internal->index_entries) *
4999 (st->internal->nb_index_entries - (index_entry_pos + gap)));
5000 memmove(sc->ctts_data + index_entry_pos,
5001 sc->ctts_data + index_entry_pos + gap,
5002 sizeof(*sc->ctts_data) *
5003 (sc->ctts_count - (index_entry_pos + gap)));
5005 st->internal->nb_index_entries -= gap;
5006 sc->ctts_count -= gap;
5007 if (index_entry_pos < sc->current_sample) {
5008 sc->current_sample -= gap;
5013 // The end of this new fragment may overlap in time with the start
5014 // of the next fragment in index_entries. Mark the samples in the next
5015 // fragment that overlap with AVINDEX_DISCARD_FRAME
5016 prev_dts = AV_NOPTS_VALUE;
5017 if (index_entry_pos > 0)
5018 prev_dts = st->internal->index_entries[index_entry_pos-1].timestamp;
5019 for (i = index_entry_pos; i < st->internal->nb_index_entries; i++) {
5020 if (prev_dts < st->internal->index_entries[i].timestamp)
5022 st->internal->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
5025 // If a hole was created to insert the new index_entries into,
5026 // the index_entry recorded for all subsequent moof must
5027 // be incremented by the number of entries inserted.
5028 fix_frag_index_entries(&c->frag_index, next_frag_index,
5029 frag->track_id, entries);
5031 if (pb->eof_reached) {
5032 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
5036 frag->implicit_offset = offset;
5038 sc->track_end = dts + sc->time_offset;
5039 if (st->duration < sc->track_end)
5040 st->duration = sc->track_end;
5045 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5047 int64_t stream_size = avio_size(pb);
5048 int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
5049 uint8_t version, is_complete;
5050 unsigned i, j, track_id, item_count;
5051 AVStream *st = NULL;
5052 AVStream *ref_st = NULL;
5053 MOVStreamContext *sc, *ref_sc = NULL;
5054 AVRational timescale;
5056 version = avio_r8(pb);
5058 avpriv_request_sample(c->fc, "sidx version %u", version);
5062 avio_rb24(pb); // flags
5064 track_id = avio_rb32(pb); // Reference ID
5065 for (i = 0; i < c->fc->nb_streams; i++) {
5066 if (c->fc->streams[i]->id == track_id) {
5067 st = c->fc->streams[i];
5072 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5078 timescale = av_make_q(1, avio_rb32(pb));
5080 if (timescale.den <= 0) {
5081 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5082 return AVERROR_INVALIDDATA;
5086 pts = avio_rb32(pb);
5087 offset += avio_rb32(pb);
5089 pts = avio_rb64(pb);
5090 offset += avio_rb64(pb);
5093 avio_rb16(pb); // reserved
5095 item_count = avio_rb16(pb);
5097 for (i = 0; i < item_count; i++) {
5099 MOVFragmentStreamInfo * frag_stream_info;
5100 uint32_t size = avio_rb32(pb);
5101 uint32_t duration = avio_rb32(pb);
5102 if (size & 0x80000000) {
5103 avpriv_request_sample(c->fc, "sidx reference_type 1");
5104 return AVERROR_PATCHWELCOME;
5106 avio_rb32(pb); // sap_flags
5107 timestamp = av_rescale_q(pts, timescale, st->time_base);
5109 index = update_frag_index(c, offset);
5110 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5111 if (frag_stream_info)
5112 frag_stream_info->sidx_pts = timestamp;
5118 st->duration = sc->track_end = pts;
5122 // See if the remaining bytes are just an mfra which we can ignore.
5123 is_complete = offset == stream_size;
5124 if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL)) {
5126 int64_t original_pos = avio_tell(pb);
5127 if (!c->have_read_mfra_size) {
5128 if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
5130 c->mfra_size = avio_rb32(pb);
5131 c->have_read_mfra_size = 1;
5132 if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
5135 if (offset + c->mfra_size == stream_size)
5140 // Find first entry in fragment index that came from an sidx.
5141 // This will pretty much always be the first entry.
5142 for (i = 0; i < c->frag_index.nb_items; i++) {
5143 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5144 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5145 MOVFragmentStreamInfo * si;
5146 si = &item->stream_info[j];
5147 if (si->sidx_pts != AV_NOPTS_VALUE) {
5148 ref_st = c->fc->streams[j];
5149 ref_sc = ref_st->priv_data;
5154 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5155 st = c->fc->streams[i];
5157 if (!sc->has_sidx) {
5158 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5162 c->frag_index.complete = 1;
5168 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5169 /* like the files created with Adobe Premiere 5.0, for samples see */
5170 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5171 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5176 return 0; /* continue */
5177 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5178 avio_skip(pb, atom.size - 4);
5181 atom.type = avio_rl32(pb);
5183 if (atom.type != MKTAG('m','d','a','t')) {
5184 avio_skip(pb, atom.size);
5187 err = mov_read_mdat(c, pb, atom);
5191 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5196 uint8_t *moov_data; /* uncompressed data */
5197 long cmov_len, moov_len;
5200 avio_rb32(pb); /* dcom atom */
5201 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5202 return AVERROR_INVALIDDATA;
5203 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5204 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5205 return AVERROR_INVALIDDATA;
5207 avio_rb32(pb); /* cmvd atom */
5208 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5209 return AVERROR_INVALIDDATA;
5210 moov_len = avio_rb32(pb); /* uncompressed size */
5211 cmov_len = atom.size - 6 * 4;
5213 cmov_data = av_malloc(cmov_len);
5215 return AVERROR(ENOMEM);
5216 moov_data = av_malloc(moov_len);
5219 return AVERROR(ENOMEM);
5221 ret = ffio_read_size(pb, cmov_data, cmov_len);
5223 goto free_and_return;
5225 ret = AVERROR_INVALIDDATA;
5226 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5227 goto free_and_return;
5228 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5229 goto free_and_return;
5230 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5231 atom.type = MKTAG('m','o','o','v');
5232 atom.size = moov_len;
5233 ret = mov_read_default(c, &ctx, atom);
5239 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5240 return AVERROR(ENOSYS);
5244 /* edit list atom */
5245 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5247 MOVStreamContext *sc;
5248 int i, edit_count, version;
5249 int64_t elst_entry_size;
5251 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5253 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5255 version = avio_r8(pb); /* version */
5256 avio_rb24(pb); /* flags */
5257 edit_count = avio_rb32(pb); /* entries */
5260 elst_entry_size = version == 1 ? 20 : 12;
5261 if (atom.size != edit_count * elst_entry_size) {
5262 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5263 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5264 edit_count, atom.size + 8);
5265 return AVERROR_INVALIDDATA;
5267 edit_count = atom.size / elst_entry_size;
5268 if (edit_count * elst_entry_size != atom.size) {
5269 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
5277 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5278 av_free(sc->elst_data);
5280 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5282 return AVERROR(ENOMEM);
5284 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5285 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5286 MOVElst *e = &sc->elst_data[i];
5289 e->duration = avio_rb64(pb);
5290 e->time = avio_rb64(pb);
5293 e->duration = avio_rb32(pb); /* segment duration */
5294 e->time = (int32_t)avio_rb32(pb); /* media time */
5297 e->rate = avio_rb32(pb) / 65536.0;
5299 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5300 e->duration, e->time, e->rate);
5302 if (e->time < 0 && e->time != -1 &&
5303 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5304 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5305 c->fc->nb_streams-1, i, e->time);
5306 return AVERROR_INVALIDDATA;
5314 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5316 MOVStreamContext *sc;
5318 if (c->fc->nb_streams < 1)
5319 return AVERROR_INVALIDDATA;
5320 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5321 sc->timecode_track = avio_rb32(pb);
5325 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5330 if (c->fc->nb_streams < 1)
5332 st = c->fc->streams[c->fc->nb_streams - 1];
5334 if (atom.size < 4) {
5335 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5336 return AVERROR_INVALIDDATA;
5339 /* For now, propagate only the OBUs, if any. Once libavcodec is
5340 updated to handle isobmff style extradata this can be removed. */
5346 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5353 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5356 int version, color_range, color_primaries, color_trc, color_space;
5358 if (c->fc->nb_streams < 1)
5360 st = c->fc->streams[c->fc->nb_streams - 1];
5362 if (atom.size < 5) {
5363 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5364 return AVERROR_INVALIDDATA;
5367 version = avio_r8(pb);
5369 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5372 avio_skip(pb, 3); /* flags */
5374 avio_skip(pb, 2); /* profile + level */
5375 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5376 color_primaries = avio_r8(pb);
5377 color_trc = avio_r8(pb);
5378 color_space = avio_r8(pb);
5379 if (avio_rb16(pb)) /* codecIntializationDataSize */
5380 return AVERROR_INVALIDDATA;
5382 if (!av_color_primaries_name(color_primaries))
5383 color_primaries = AVCOL_PRI_UNSPECIFIED;
5384 if (!av_color_transfer_name(color_trc))
5385 color_trc = AVCOL_TRC_UNSPECIFIED;
5386 if (!av_color_space_name(color_space))
5387 color_space = AVCOL_SPC_UNSPECIFIED;
5389 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5390 st->codecpar->color_primaries = color_primaries;
5391 st->codecpar->color_trc = color_trc;
5392 st->codecpar->color_space = color_space;
5397 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5399 MOVStreamContext *sc;
5402 if (c->fc->nb_streams < 1)
5403 return AVERROR_INVALIDDATA;
5405 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5407 if (atom.size < 5) {
5408 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5409 return AVERROR_INVALIDDATA;
5412 version = avio_r8(pb);
5414 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5417 avio_skip(pb, 3); /* flags */
5419 sc->mastering = av_mastering_display_metadata_alloc();
5421 return AVERROR(ENOMEM);
5423 for (i = 0; i < 3; i++) {
5424 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5425 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5427 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5428 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5430 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5431 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5433 sc->mastering->has_primaries = 1;
5434 sc->mastering->has_luminance = 1;
5439 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5441 MOVStreamContext *sc;
5442 const int mapping[3] = {1, 2, 0};
5443 const int chroma_den = 50000;
5444 const int luma_den = 10000;
5447 if (c->fc->nb_streams < 1)
5448 return AVERROR_INVALIDDATA;
5450 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5452 if (atom.size < 24) {
5453 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5454 return AVERROR_INVALIDDATA;
5457 sc->mastering = av_mastering_display_metadata_alloc();
5459 return AVERROR(ENOMEM);
5461 for (i = 0; i < 3; i++) {
5462 const int j = mapping[i];
5463 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5464 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5466 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5467 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5469 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5470 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5472 sc->mastering->has_luminance = 1;
5473 sc->mastering->has_primaries = 1;
5478 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5480 MOVStreamContext *sc;
5483 if (c->fc->nb_streams < 1)
5484 return AVERROR_INVALIDDATA;
5486 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5488 if (atom.size < 5) {
5489 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5490 return AVERROR_INVALIDDATA;
5493 version = avio_r8(pb);
5495 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5498 avio_skip(pb, 3); /* flags */
5500 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5502 return AVERROR(ENOMEM);
5504 sc->coll->MaxCLL = avio_rb16(pb);
5505 sc->coll->MaxFALL = avio_rb16(pb);
5510 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5512 MOVStreamContext *sc;
5514 if (c->fc->nb_streams < 1)
5515 return AVERROR_INVALIDDATA;
5517 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5519 if (atom.size < 4) {
5520 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5521 return AVERROR_INVALIDDATA;
5524 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5526 return AVERROR(ENOMEM);
5528 sc->coll->MaxCLL = avio_rb16(pb);
5529 sc->coll->MaxFALL = avio_rb16(pb);
5534 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5537 MOVStreamContext *sc;
5538 enum AVStereo3DType type;
5541 if (c->fc->nb_streams < 1)
5544 st = c->fc->streams[c->fc->nb_streams - 1];
5547 if (atom.size < 5) {
5548 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5549 return AVERROR_INVALIDDATA;
5553 return AVERROR_INVALIDDATA;
5555 avio_skip(pb, 4); /* version + flags */
5560 type = AV_STEREO3D_2D;
5563 type = AV_STEREO3D_TOPBOTTOM;
5566 type = AV_STEREO3D_SIDEBYSIDE;
5569 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5573 sc->stereo3d = av_stereo3d_alloc();
5575 return AVERROR(ENOMEM);
5577 sc->stereo3d->type = type;
5581 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5584 MOVStreamContext *sc;
5585 int size, version, layout;
5586 int32_t yaw, pitch, roll;
5587 uint32_t l = 0, t = 0, r = 0, b = 0;
5588 uint32_t tag, padding = 0;
5589 enum AVSphericalProjection projection;
5591 if (c->fc->nb_streams < 1)
5594 st = c->fc->streams[c->fc->nb_streams - 1];
5597 if (atom.size < 8) {
5598 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5599 return AVERROR_INVALIDDATA;
5602 size = avio_rb32(pb);
5603 if (size <= 12 || size > atom.size)
5604 return AVERROR_INVALIDDATA;
5606 tag = avio_rl32(pb);
5607 if (tag != MKTAG('s','v','h','d')) {
5608 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5611 version = avio_r8(pb);
5613 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5617 avio_skip(pb, 3); /* flags */
5618 avio_skip(pb, size - 12); /* metadata_source */
5620 size = avio_rb32(pb);
5621 if (size > atom.size)
5622 return AVERROR_INVALIDDATA;
5624 tag = avio_rl32(pb);
5625 if (tag != MKTAG('p','r','o','j')) {
5626 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5630 size = avio_rb32(pb);
5631 if (size > atom.size)
5632 return AVERROR_INVALIDDATA;
5634 tag = avio_rl32(pb);
5635 if (tag != MKTAG('p','r','h','d')) {
5636 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5639 version = avio_r8(pb);
5641 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5645 avio_skip(pb, 3); /* flags */
5647 /* 16.16 fixed point */
5648 yaw = avio_rb32(pb);
5649 pitch = avio_rb32(pb);
5650 roll = avio_rb32(pb);
5652 size = avio_rb32(pb);
5653 if (size > atom.size)
5654 return AVERROR_INVALIDDATA;
5656 tag = avio_rl32(pb);
5657 version = avio_r8(pb);
5659 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5663 avio_skip(pb, 3); /* flags */
5665 case MKTAG('c','b','m','p'):
5666 layout = avio_rb32(pb);
5668 av_log(c->fc, AV_LOG_WARNING,
5669 "Unsupported cubemap layout %d\n", layout);
5672 projection = AV_SPHERICAL_CUBEMAP;
5673 padding = avio_rb32(pb);
5675 case MKTAG('e','q','u','i'):
5681 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5682 av_log(c->fc, AV_LOG_ERROR,
5683 "Invalid bounding rectangle coordinates "
5684 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5685 return AVERROR_INVALIDDATA;
5688 if (l || t || r || b)
5689 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5691 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5694 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5698 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5700 return AVERROR(ENOMEM);
5702 sc->spherical->projection = projection;
5704 sc->spherical->yaw = yaw;
5705 sc->spherical->pitch = pitch;
5706 sc->spherical->roll = roll;
5708 sc->spherical->padding = padding;
5710 sc->spherical->bound_left = l;
5711 sc->spherical->bound_top = t;
5712 sc->spherical->bound_right = r;
5713 sc->spherical->bound_bottom = b;
5718 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5721 uint8_t *buffer = av_malloc(len + 1);
5725 return AVERROR(ENOMEM);
5728 ret = ffio_read_size(pb, buffer, len);
5732 /* Check for mandatory keys and values, try to support XML as best-effort */
5733 if (!sc->spherical &&
5734 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5735 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5736 av_stristr(val, "true") &&
5737 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5738 av_stristr(val, "true") &&
5739 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5740 av_stristr(val, "equirectangular")) {
5741 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5745 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5747 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5748 enum AVStereo3DType mode;
5750 if (av_stristr(buffer, "left-right"))
5751 mode = AV_STEREO3D_SIDEBYSIDE;
5752 else if (av_stristr(buffer, "top-bottom"))
5753 mode = AV_STEREO3D_TOPBOTTOM;
5755 mode = AV_STEREO3D_2D;
5757 sc->stereo3d = av_stereo3d_alloc();
5761 sc->stereo3d->type = mode;
5765 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5767 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5768 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5770 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5771 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5773 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5781 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5784 MOVStreamContext *sc;
5787 static const uint8_t uuid_isml_manifest[] = {
5788 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5789 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5791 static const uint8_t uuid_xmp[] = {
5792 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5793 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5795 static const uint8_t uuid_spherical[] = {
5796 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5797 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5800 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5801 return AVERROR_INVALIDDATA;
5803 if (c->fc->nb_streams < 1)
5805 st = c->fc->streams[c->fc->nb_streams - 1];
5808 ret = ffio_read_size(pb, uuid, sizeof(uuid));
5811 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5812 uint8_t *buffer, *ptr;
5814 size_t len = atom.size - sizeof(uuid);
5817 return AVERROR_INVALIDDATA;
5819 ret = avio_skip(pb, 4); // zeroes
5822 buffer = av_mallocz(len + 1);
5824 return AVERROR(ENOMEM);
5826 ret = ffio_read_size(pb, buffer, len);
5833 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5834 ptr += sizeof("systemBitrate=\"") - 1;
5835 c->bitrates_count++;
5836 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5838 c->bitrates_count = 0;
5840 return AVERROR(ENOMEM);
5843 ret = strtol(ptr, &endptr, 10);
5844 if (ret < 0 || errno || *endptr != '"') {
5845 c->bitrates[c->bitrates_count - 1] = 0;
5847 c->bitrates[c->bitrates_count - 1] = ret;
5852 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5854 size_t len = atom.size - sizeof(uuid);
5855 if (c->export_xmp) {
5856 buffer = av_mallocz(len + 1);
5858 return AVERROR(ENOMEM);
5860 ret = ffio_read_size(pb, buffer, len);
5866 av_dict_set(&c->fc->metadata, "xmp",
5867 buffer, AV_DICT_DONT_STRDUP_VAL);
5869 // skip all uuid atom, which makes it fast for long uuid-xmp file
5870 ret = avio_skip(pb, len);
5874 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5875 size_t len = atom.size - sizeof(uuid);
5876 ret = mov_parse_uuid_spherical(sc, pb, len);
5880 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5886 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5889 uint8_t content[16];
5894 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5900 && !memcmp(content, "Anevia\x1A\x1A", 8)
5901 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5902 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5908 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5910 uint32_t format = avio_rl32(pb);
5911 MOVStreamContext *sc;
5915 if (c->fc->nb_streams < 1)
5917 st = c->fc->streams[c->fc->nb_streams - 1];
5922 case MKTAG('e','n','c','v'): // encrypted video
5923 case MKTAG('e','n','c','a'): // encrypted audio
5924 id = mov_codec_id(st, format);
5925 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5926 st->codecpar->codec_id != id) {
5927 av_log(c->fc, AV_LOG_WARNING,
5928 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5929 (char*)&format, st->codecpar->codec_id);
5933 st->codecpar->codec_id = id;
5934 sc->format = format;
5938 if (format != sc->format) {
5939 av_log(c->fc, AV_LOG_WARNING,
5940 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5941 (char*)&format, (char*)&sc->format);
5950 * Gets the current encryption info and associated current stream context. If
5951 * we are parsing a track fragment, this will return the specific encryption
5952 * info for this fragment; otherwise this will return the global encryption
5953 * info for the current stream.
5955 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5957 MOVFragmentStreamInfo *frag_stream_info;
5961 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5962 if (frag_stream_info) {
5963 for (i = 0; i < c->fc->nb_streams; i++) {
5964 if (c->fc->streams[i]->id == frag_stream_info->id) {
5965 st = c->fc->streams[i];
5969 if (i == c->fc->nb_streams)
5971 *sc = st->priv_data;
5973 if (!frag_stream_info->encryption_index) {
5974 // If this stream isn't encrypted, don't create the index.
5975 if (!(*sc)->cenc.default_encrypted_sample)
5977 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5978 if (!frag_stream_info->encryption_index)
5979 return AVERROR(ENOMEM);
5981 *encryption_index = frag_stream_info->encryption_index;
5984 // No current track fragment, using stream level encryption info.
5986 if (c->fc->nb_streams < 1)
5988 st = c->fc->streams[c->fc->nb_streams - 1];
5989 *sc = st->priv_data;
5991 if (!(*sc)->cenc.encryption_index) {
5992 // If this stream isn't encrypted, don't create the index.
5993 if (!(*sc)->cenc.default_encrypted_sample)
5995 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5996 if (!(*sc)->cenc.encryption_index)
5997 return AVERROR(ENOMEM);
6000 *encryption_index = (*sc)->cenc.encryption_index;
6005 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
6008 unsigned int subsample_count;
6009 AVSubsampleEncryptionInfo *subsamples;
6011 if (!sc->cenc.default_encrypted_sample) {
6012 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
6013 return AVERROR_INVALIDDATA;
6016 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
6018 return AVERROR(ENOMEM);
6020 if (sc->cenc.per_sample_iv_size != 0) {
6021 if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
6022 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
6023 av_encryption_info_free(*sample);
6029 if (use_subsamples) {
6030 subsample_count = avio_rb16(pb);
6031 av_free((*sample)->subsamples);
6032 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
6033 if (!(*sample)->subsamples) {
6034 av_encryption_info_free(*sample);
6036 return AVERROR(ENOMEM);
6039 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
6040 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
6041 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
6044 if (pb->eof_reached) {
6045 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
6046 av_encryption_info_free(*sample);
6048 return AVERROR_INVALIDDATA;
6050 (*sample)->subsample_count = subsample_count;
6056 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6058 AVEncryptionInfo **encrypted_samples;
6059 MOVEncryptionIndex *encryption_index;
6060 MOVStreamContext *sc;
6061 int use_subsamples, ret;
6062 unsigned int sample_count, i, alloc_size = 0;
6064 ret = get_current_encryption_info(c, &encryption_index, &sc);
6068 if (encryption_index->nb_encrypted_samples) {
6069 // This can happen if we have both saio/saiz and senc atoms.
6070 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6074 avio_r8(pb); /* version */
6075 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6077 sample_count = avio_rb32(pb);
6078 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6079 return AVERROR(ENOMEM);
6081 for (i = 0; i < sample_count; i++) {
6082 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6083 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6084 min_samples * sizeof(*encrypted_samples));
6085 if (encrypted_samples) {
6086 encryption_index->encrypted_samples = encrypted_samples;
6088 ret = mov_read_sample_encryption_info(
6089 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6091 ret = AVERROR(ENOMEM);
6093 if (pb->eof_reached) {
6094 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6095 ret = AVERROR_INVALIDDATA;
6100 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6101 av_freep(&encryption_index->encrypted_samples);
6105 encryption_index->nb_encrypted_samples = sample_count;
6110 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6112 AVEncryptionInfo **sample, **encrypted_samples;
6114 size_t sample_count, sample_info_size, i;
6116 unsigned int alloc_size = 0;
6118 if (encryption_index->nb_encrypted_samples)
6120 sample_count = encryption_index->auxiliary_info_sample_count;
6121 if (encryption_index->auxiliary_offsets_count != 1) {
6122 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6123 return AVERROR_PATCHWELCOME;
6125 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6126 return AVERROR(ENOMEM);
6128 prev_pos = avio_tell(pb);
6129 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6130 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6131 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6135 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6136 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6137 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6138 min_samples * sizeof(*encrypted_samples));
6139 if (!encrypted_samples) {
6140 ret = AVERROR(ENOMEM);
6143 encryption_index->encrypted_samples = encrypted_samples;
6145 sample = &encryption_index->encrypted_samples[i];
6146 sample_info_size = encryption_index->auxiliary_info_default_size
6147 ? encryption_index->auxiliary_info_default_size
6148 : encryption_index->auxiliary_info_sizes[i];
6150 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6154 if (pb->eof_reached) {
6155 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6156 ret = AVERROR_INVALIDDATA;
6158 encryption_index->nb_encrypted_samples = sample_count;
6162 avio_seek(pb, prev_pos, SEEK_SET);
6164 for (; i > 0; i--) {
6165 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6167 av_freep(&encryption_index->encrypted_samples);
6173 * Tries to read the given number of bytes from the stream and puts it in a
6174 * newly allocated buffer. This reads in small chunks to avoid allocating large
6175 * memory if the file contains an invalid/malicious size value.
6177 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6179 const unsigned int block_size = 1024 * 1024;
6180 uint8_t *buffer = NULL;
6181 unsigned int alloc_size = 0, offset = 0;
6182 while (offset < size) {
6183 unsigned int new_size =
6184 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6185 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6186 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6189 return AVERROR(ENOMEM);
6191 buffer = new_buffer;
6193 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6195 return AVERROR_INVALIDDATA;
6204 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6206 MOVEncryptionIndex *encryption_index;
6207 MOVStreamContext *sc;
6209 unsigned int sample_count, aux_info_type, aux_info_param;
6211 ret = get_current_encryption_info(c, &encryption_index, &sc);
6215 if (encryption_index->nb_encrypted_samples) {
6216 // This can happen if we have both saio/saiz and senc atoms.
6217 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6221 if (encryption_index->auxiliary_info_sample_count) {
6222 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6223 return AVERROR_INVALIDDATA;
6226 avio_r8(pb); /* version */
6227 if (avio_rb24(pb) & 0x01) { /* flags */
6228 aux_info_type = avio_rb32(pb);
6229 aux_info_param = avio_rb32(pb);
6230 if (sc->cenc.default_encrypted_sample) {
6231 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6232 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6235 if (aux_info_param != 0) {
6236 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6240 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6241 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6242 aux_info_type == MKBETAG('c','e','n','s') ||
6243 aux_info_type == MKBETAG('c','b','c','1') ||
6244 aux_info_type == MKBETAG('c','b','c','s')) &&
6245 aux_info_param == 0) {
6246 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6247 return AVERROR_INVALIDDATA;
6252 } else if (!sc->cenc.default_encrypted_sample) {
6253 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6257 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6258 sample_count = avio_rb32(pb);
6259 encryption_index->auxiliary_info_sample_count = sample_count;
6261 if (encryption_index->auxiliary_info_default_size == 0) {
6262 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6264 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6269 if (encryption_index->auxiliary_offsets_count) {
6270 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6276 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6278 uint64_t *auxiliary_offsets;
6279 MOVEncryptionIndex *encryption_index;
6280 MOVStreamContext *sc;
6282 unsigned int version, entry_count, aux_info_type, aux_info_param;
6283 unsigned int alloc_size = 0;
6285 ret = get_current_encryption_info(c, &encryption_index, &sc);
6289 if (encryption_index->nb_encrypted_samples) {
6290 // This can happen if we have both saio/saiz and senc atoms.
6291 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6295 if (encryption_index->auxiliary_offsets_count) {
6296 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6297 return AVERROR_INVALIDDATA;
6300 version = avio_r8(pb); /* version */
6301 if (avio_rb24(pb) & 0x01) { /* flags */
6302 aux_info_type = avio_rb32(pb);
6303 aux_info_param = avio_rb32(pb);
6304 if (sc->cenc.default_encrypted_sample) {
6305 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6306 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6309 if (aux_info_param != 0) {
6310 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6314 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6315 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6316 aux_info_type == MKBETAG('c','e','n','s') ||
6317 aux_info_type == MKBETAG('c','b','c','1') ||
6318 aux_info_type == MKBETAG('c','b','c','s')) &&
6319 aux_info_param == 0) {
6320 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6321 return AVERROR_INVALIDDATA;
6326 } else if (!sc->cenc.default_encrypted_sample) {
6327 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6331 entry_count = avio_rb32(pb);
6332 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6333 return AVERROR(ENOMEM);
6335 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6336 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6337 auxiliary_offsets = av_fast_realloc(
6338 encryption_index->auxiliary_offsets, &alloc_size,
6339 min_offsets * sizeof(*auxiliary_offsets));
6340 if (!auxiliary_offsets) {
6341 av_freep(&encryption_index->auxiliary_offsets);
6342 return AVERROR(ENOMEM);
6344 encryption_index->auxiliary_offsets = auxiliary_offsets;
6347 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6349 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6351 if (c->frag_index.current >= 0) {
6352 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6356 if (pb->eof_reached) {
6357 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6358 av_freep(&encryption_index->auxiliary_offsets);
6359 return AVERROR_INVALIDDATA;
6362 encryption_index->auxiliary_offsets_count = entry_count;
6364 if (encryption_index->auxiliary_info_sample_count) {
6365 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6371 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6373 AVEncryptionInitInfo *info, *old_init_info;
6376 uint8_t *side_data, *extra_data, *old_side_data;
6377 size_t side_data_size;
6378 int ret = 0, old_side_data_size;
6379 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6381 if (c->fc->nb_streams < 1)
6383 st = c->fc->streams[c->fc->nb_streams-1];
6385 version = avio_r8(pb); /* version */
6386 avio_rb24(pb); /* flags */
6388 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6389 /* key_id_size */ 16, /* data_size */ 0);
6391 return AVERROR(ENOMEM);
6393 if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
6394 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6399 kid_count = avio_rb32(pb);
6400 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
6401 ret = AVERROR(ENOMEM);
6405 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6406 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6407 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6408 min_kid_count * sizeof(*key_ids));
6410 ret = AVERROR(ENOMEM);
6413 info->key_ids = key_ids;
6415 info->key_ids[i] = av_mallocz(16);
6416 if (!info->key_ids[i]) {
6417 ret = AVERROR(ENOMEM);
6420 info->num_key_ids = i + 1;
6422 if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
6423 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6428 if (pb->eof_reached) {
6429 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6430 ret = AVERROR_INVALIDDATA;
6435 extra_data_size = avio_rb32(pb);
6436 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6440 av_freep(&info->data); // malloc(0) may still allocate something.
6441 info->data = extra_data;
6442 info->data_size = extra_data_size;
6444 // If there is existing initialization data, append to the list.
6445 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6446 if (old_side_data) {
6447 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6448 if (old_init_info) {
6449 // Append to the end of the list.
6450 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6456 info = old_init_info;
6458 // Assume existing side-data will be valid, so the only error we could get is OOM.
6459 ret = AVERROR(ENOMEM);
6464 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6466 ret = AVERROR(ENOMEM);
6469 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6470 side_data, side_data_size);
6475 av_encryption_init_info_free(info);
6479 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6482 MOVStreamContext *sc;
6484 if (c->fc->nb_streams < 1)
6486 st = c->fc->streams[c->fc->nb_streams-1];
6489 if (sc->pseudo_stream_id != 0) {
6490 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6491 return AVERROR_PATCHWELCOME;
6495 return AVERROR_INVALIDDATA;
6497 avio_rb32(pb); /* version and flags */
6499 if (!sc->cenc.default_encrypted_sample) {
6500 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6501 if (!sc->cenc.default_encrypted_sample) {
6502 return AVERROR(ENOMEM);
6506 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6510 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6513 MOVStreamContext *sc;
6514 unsigned int version, pattern, is_protected, iv_size;
6516 if (c->fc->nb_streams < 1)
6518 st = c->fc->streams[c->fc->nb_streams-1];
6521 if (sc->pseudo_stream_id != 0) {
6522 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6523 return AVERROR_PATCHWELCOME;
6526 if (!sc->cenc.default_encrypted_sample) {
6527 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6528 if (!sc->cenc.default_encrypted_sample) {
6529 return AVERROR(ENOMEM);
6534 return AVERROR_INVALIDDATA;
6536 version = avio_r8(pb); /* version */
6537 avio_rb24(pb); /* flags */
6539 avio_r8(pb); /* reserved */
6540 pattern = avio_r8(pb);
6543 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6544 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6547 is_protected = avio_r8(pb);
6548 if (is_protected && !sc->cenc.encryption_index) {
6549 // The whole stream should be by-default encrypted.
6550 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6551 if (!sc->cenc.encryption_index)
6552 return AVERROR(ENOMEM);
6554 sc->cenc.per_sample_iv_size = avio_r8(pb);
6555 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6556 sc->cenc.per_sample_iv_size != 16) {
6557 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6558 return AVERROR_INVALIDDATA;
6560 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6561 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6562 return AVERROR_INVALIDDATA;
6565 if (is_protected && !sc->cenc.per_sample_iv_size) {
6566 iv_size = avio_r8(pb);
6567 if (iv_size != 8 && iv_size != 16) {
6568 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6569 return AVERROR_INVALIDDATA;
6572 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6573 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6574 return AVERROR_INVALIDDATA;
6581 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6584 int last, type, size, ret;
6587 if (c->fc->nb_streams < 1)
6589 st = c->fc->streams[c->fc->nb_streams-1];
6591 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6592 return AVERROR_INVALIDDATA;
6594 /* Check FlacSpecificBox version. */
6595 if (avio_r8(pb) != 0)
6596 return AVERROR_INVALIDDATA;
6598 avio_rb24(pb); /* Flags */
6600 avio_read(pb, buf, sizeof(buf));
6601 flac_parse_block_header(buf, &last, &type, &size);
6603 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6604 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6605 return AVERROR_INVALIDDATA;
6608 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6613 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6618 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6622 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6623 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6624 return AVERROR_PATCHWELCOME;
6627 if (!sc->cenc.aes_ctr) {
6628 /* initialize the cipher */
6629 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6630 if (!sc->cenc.aes_ctr) {
6631 return AVERROR(ENOMEM);
6634 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6640 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6642 if (!sample->subsample_count) {
6643 /* decrypt the whole packet */
6644 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6648 for (i = 0; i < sample->subsample_count; i++) {
6649 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6650 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6651 return AVERROR_INVALIDDATA;
6654 /* skip the clear bytes */
6655 input += sample->subsamples[i].bytes_of_clear_data;
6656 size -= sample->subsamples[i].bytes_of_clear_data;
6658 /* decrypt the encrypted bytes */
6659 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6660 input += sample->subsamples[i].bytes_of_protected_data;
6661 size -= sample->subsamples[i].bytes_of_protected_data;
6665 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6666 return AVERROR_INVALIDDATA;
6672 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6674 MOVFragmentStreamInfo *frag_stream_info;
6675 MOVEncryptionIndex *encryption_index;
6676 AVEncryptionInfo *encrypted_sample;
6677 int encrypted_index, ret;
6679 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6680 encrypted_index = current_index;
6681 encryption_index = NULL;
6682 if (frag_stream_info) {
6683 // Note this only supports encryption info in the first sample descriptor.
6684 if (mov->fragment.stsd_id == 1) {
6685 if (frag_stream_info->encryption_index) {
6686 encrypted_index = current_index - frag_stream_info->index_entry;
6687 encryption_index = frag_stream_info->encryption_index;
6689 encryption_index = sc->cenc.encryption_index;
6693 encryption_index = sc->cenc.encryption_index;
6696 if (encryption_index) {
6697 if (encryption_index->auxiliary_info_sample_count &&
6698 !encryption_index->nb_encrypted_samples) {
6699 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6700 return AVERROR_INVALIDDATA;
6702 if (encryption_index->auxiliary_offsets_count &&
6703 !encryption_index->nb_encrypted_samples) {
6704 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6705 return AVERROR_INVALIDDATA;
6708 if (!encryption_index->nb_encrypted_samples) {
6709 // Full-sample encryption with default settings.
6710 encrypted_sample = sc->cenc.default_encrypted_sample;
6711 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6712 // Per-sample setting override.
6713 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6715 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6716 return AVERROR_INVALIDDATA;
6719 if (mov->decryption_key) {
6720 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6723 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6725 return AVERROR(ENOMEM);
6726 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6736 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6738 const int OPUS_SEEK_PREROLL_MS = 80;
6744 if (c->fc->nb_streams < 1)
6746 st = c->fc->streams[c->fc->nb_streams-1];
6748 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6749 return AVERROR_INVALIDDATA;
6751 /* Check OpusSpecificBox version. */
6752 if (avio_r8(pb) != 0) {
6753 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6754 return AVERROR_INVALIDDATA;
6757 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6758 size = atom.size + 8;
6760 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
6763 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6764 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6765 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6766 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6768 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6769 little-endian; aside from the preceeding magic and version they're
6770 otherwise currently identical. Data after output gain at offset 16
6771 doesn't need to be bytewapped. */
6772 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6773 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6774 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6775 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6777 st->codecpar->initial_padding = pre_skip;
6778 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6779 (AVRational){1, 1000},
6780 (AVRational){1, 48000});
6785 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6788 unsigned format_info;
6789 int channel_assignment, channel_assignment1, channel_assignment2;
6792 if (c->fc->nb_streams < 1)
6794 st = c->fc->streams[c->fc->nb_streams-1];
6797 return AVERROR_INVALIDDATA;
6799 format_info = avio_rb32(pb);
6801 ratebits = (format_info >> 28) & 0xF;
6802 channel_assignment1 = (format_info >> 15) & 0x1F;
6803 channel_assignment2 = format_info & 0x1FFF;
6804 if (channel_assignment2)
6805 channel_assignment = channel_assignment2;
6807 channel_assignment = channel_assignment1;
6809 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6810 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6811 st->codecpar->channels = truehd_channels(channel_assignment);
6812 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6817 static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6821 AVDOVIDecoderConfigurationRecord *dovi;
6825 if (c->fc->nb_streams < 1)
6827 st = c->fc->streams[c->fc->nb_streams-1];
6829 if ((uint64_t)atom.size > (1<<30) || atom.size < 4)
6830 return AVERROR_INVALIDDATA;
6832 dovi = av_dovi_alloc(&dovi_size);
6834 return AVERROR(ENOMEM);
6836 dovi->dv_version_major = avio_r8(pb);
6837 dovi->dv_version_minor = avio_r8(pb);
6839 buf = avio_rb16(pb);
6840 dovi->dv_profile = (buf >> 9) & 0x7f; // 7 bits
6841 dovi->dv_level = (buf >> 3) & 0x3f; // 6 bits
6842 dovi->rpu_present_flag = (buf >> 2) & 0x01; // 1 bit
6843 dovi->el_present_flag = (buf >> 1) & 0x01; // 1 bit
6844 dovi->bl_present_flag = buf & 0x01; // 1 bit
6845 if (atom.size >= 24) { // 4 + 4 + 4 * 4
6847 dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits
6849 // 0 stands for None
6850 // Dolby Vision V1.2.93 profiles and levels
6851 dovi->dv_bl_signal_compatibility_id = 0;
6854 ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF,
6855 (uint8_t *)dovi, dovi_size);
6861 av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC box, version: %d.%d, profile: %d, level: %d, "
6862 "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n",
6863 dovi->dv_version_major, dovi->dv_version_minor,
6864 dovi->dv_profile, dovi->dv_level,
6865 dovi->rpu_present_flag,
6866 dovi->el_present_flag,
6867 dovi->bl_present_flag,
6868 dovi->dv_bl_signal_compatibility_id
6874 static const MOVParseTableEntry mov_default_parse_table[] = {
6875 { MKTAG('A','C','L','R'), mov_read_aclr },
6876 { MKTAG('A','P','R','G'), mov_read_avid },
6877 { MKTAG('A','A','L','P'), mov_read_avid },
6878 { MKTAG('A','R','E','S'), mov_read_ares },
6879 { MKTAG('a','v','s','s'), mov_read_avss },
6880 { MKTAG('a','v','1','C'), mov_read_av1c },
6881 { MKTAG('c','h','p','l'), mov_read_chpl },
6882 { MKTAG('c','o','6','4'), mov_read_stco },
6883 { MKTAG('c','o','l','r'), mov_read_colr },
6884 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6885 { MKTAG('d','i','n','f'), mov_read_default },
6886 { MKTAG('D','p','x','E'), mov_read_dpxe },
6887 { MKTAG('d','r','e','f'), mov_read_dref },
6888 { MKTAG('e','d','t','s'), mov_read_default },
6889 { MKTAG('e','l','s','t'), mov_read_elst },
6890 { MKTAG('e','n','d','a'), mov_read_enda },
6891 { MKTAG('f','i','e','l'), mov_read_fiel },
6892 { MKTAG('a','d','r','m'), mov_read_adrm },
6893 { MKTAG('f','t','y','p'), mov_read_ftyp },
6894 { MKTAG('g','l','b','l'), mov_read_glbl },
6895 { MKTAG('h','d','l','r'), mov_read_hdlr },
6896 { MKTAG('i','l','s','t'), mov_read_ilst },
6897 { MKTAG('j','p','2','h'), mov_read_jp2h },
6898 { MKTAG('m','d','a','t'), mov_read_mdat },
6899 { MKTAG('m','d','h','d'), mov_read_mdhd },
6900 { MKTAG('m','d','i','a'), mov_read_default },
6901 { MKTAG('m','e','t','a'), mov_read_meta },
6902 { MKTAG('m','i','n','f'), mov_read_default },
6903 { MKTAG('m','o','o','f'), mov_read_moof },
6904 { MKTAG('m','o','o','v'), mov_read_moov },
6905 { MKTAG('m','v','e','x'), mov_read_default },
6906 { MKTAG('m','v','h','d'), mov_read_mvhd },
6907 { MKTAG('S','M','I',' '), mov_read_svq3 },
6908 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6909 { MKTAG('a','v','c','C'), mov_read_glbl },
6910 { MKTAG('p','a','s','p'), mov_read_pasp },
6911 { MKTAG('s','i','d','x'), mov_read_sidx },
6912 { MKTAG('s','t','b','l'), mov_read_default },
6913 { MKTAG('s','t','c','o'), mov_read_stco },
6914 { MKTAG('s','t','p','s'), mov_read_stps },
6915 { MKTAG('s','t','r','f'), mov_read_strf },
6916 { MKTAG('s','t','s','c'), mov_read_stsc },
6917 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6918 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6919 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6920 { MKTAG('s','t','t','s'), mov_read_stts },
6921 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6922 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
6923 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6924 { MKTAG('t','f','d','t'), mov_read_tfdt },
6925 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6926 { MKTAG('t','r','a','k'), mov_read_trak },
6927 { MKTAG('t','r','a','f'), mov_read_default },
6928 { MKTAG('t','r','e','f'), mov_read_default },
6929 { MKTAG('t','m','c','d'), mov_read_tmcd },
6930 { MKTAG('c','h','a','p'), mov_read_chap },
6931 { MKTAG('t','r','e','x'), mov_read_trex },
6932 { MKTAG('t','r','u','n'), mov_read_trun },
6933 { MKTAG('u','d','t','a'), mov_read_default },
6934 { MKTAG('w','a','v','e'), mov_read_wave },
6935 { MKTAG('e','s','d','s'), mov_read_esds },
6936 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6937 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6938 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6939 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6940 { MKTAG('w','f','e','x'), mov_read_wfex },
6941 { MKTAG('c','m','o','v'), mov_read_cmov },
6942 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6943 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6944 { MKTAG('s','b','g','p'), mov_read_sbgp },
6945 { MKTAG('h','v','c','C'), mov_read_glbl },
6946 { MKTAG('u','u','i','d'), mov_read_uuid },
6947 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6948 { MKTAG('f','r','e','e'), mov_read_free },
6949 { MKTAG('-','-','-','-'), mov_read_custom },
6950 { MKTAG('s','i','n','f'), mov_read_default },
6951 { MKTAG('f','r','m','a'), mov_read_frma },
6952 { MKTAG('s','e','n','c'), mov_read_senc },
6953 { MKTAG('s','a','i','z'), mov_read_saiz },
6954 { MKTAG('s','a','i','o'), mov_read_saio },
6955 { MKTAG('p','s','s','h'), mov_read_pssh },
6956 { MKTAG('s','c','h','m'), mov_read_schm },
6957 { MKTAG('s','c','h','i'), mov_read_default },
6958 { MKTAG('t','e','n','c'), mov_read_tenc },
6959 { MKTAG('d','f','L','a'), mov_read_dfla },
6960 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6961 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6962 { MKTAG('d','O','p','s'), mov_read_dops },
6963 { MKTAG('d','m','l','p'), mov_read_dmlp },
6964 { MKTAG('S','m','D','m'), mov_read_smdm },
6965 { MKTAG('C','o','L','L'), mov_read_coll },
6966 { MKTAG('v','p','c','C'), mov_read_vpcc },
6967 { MKTAG('m','d','c','v'), mov_read_mdcv },
6968 { MKTAG('c','l','l','i'), mov_read_clli },
6969 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
6970 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
6974 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6976 int64_t total_size = 0;
6980 if (c->atom_depth > 10) {
6981 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6982 return AVERROR_INVALIDDATA;
6987 atom.size = INT64_MAX;
6988 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6989 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
6992 if (atom.size >= 8) {
6993 a.size = avio_rb32(pb);
6994 a.type = avio_rl32(pb);
6995 if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
6996 a.type == MKTAG('h','o','o','v')) &&
6998 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
7001 type = avio_rl32(pb);
7004 avio_seek(pb, -8, SEEK_CUR);
7005 if (type == MKTAG('m','v','h','d') ||
7006 type == MKTAG('c','m','o','v')) {
7007 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
7008 a.type = MKTAG('m','o','o','v');
7011 if (atom.type != MKTAG('r','o','o','t') &&
7012 atom.type != MKTAG('m','o','o','v')) {
7013 if (a.type == MKTAG('t','r','a','k') ||
7014 a.type == MKTAG('m','d','a','t')) {
7015 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
7022 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
7023 a.size = avio_rb64(pb) - 8;
7027 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
7028 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
7030 a.size = atom.size - total_size + 8;
7035 a.size = FFMIN(a.size, atom.size - total_size);
7037 for (i = 0; mov_default_parse_table[i].type; i++)
7038 if (mov_default_parse_table[i].type == a.type) {
7039 parse = mov_default_parse_table[i].parse;
7043 // container is user data
7044 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
7045 atom.type == MKTAG('i','l','s','t')))
7046 parse = mov_read_udta_string;
7048 // Supports parsing the QuickTime Metadata Keys.
7049 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
7050 if (!parse && c->found_hdlr_mdta &&
7051 atom.type == MKTAG('m','e','t','a') &&
7052 a.type == MKTAG('k','e','y','s') &&
7053 c->meta_keys_count == 0) {
7054 parse = mov_read_keys;
7057 if (!parse) { /* skip leaf atoms data */
7058 avio_skip(pb, a.size);
7060 int64_t start_pos = avio_tell(pb);
7062 int err = parse(c, pb, a);
7067 if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
7068 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
7069 start_pos + a.size == avio_size(pb))) {
7070 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
7071 c->next_root_atom = start_pos + a.size;
7075 left = a.size - avio_tell(pb) + start_pos;
7076 if (left > 0) /* skip garbage at atom end */
7077 avio_skip(pb, left);
7078 else if (left < 0) {
7079 av_log(c->fc, AV_LOG_WARNING,
7080 "overread end of atom '%s' by %"PRId64" bytes\n",
7081 av_fourcc2str(a.type), -left);
7082 avio_seek(pb, left, SEEK_CUR);
7086 total_size += a.size;
7089 if (total_size < atom.size && atom.size < 0x7ffff)
7090 avio_skip(pb, atom.size - total_size);
7096 static int mov_probe(const AVProbeData *p)
7101 int moov_offset = -1;
7103 /* check file header */
7108 /* ignore invalid offset */
7109 if ((offset + 8) > (unsigned int)p->buf_size)
7111 size = AV_RB32(p->buf + offset);
7112 if (size == 1 && offset + 16 > (unsigned int)p->buf_size) {
7113 size = AV_RB64(p->buf+offset + 8);
7115 } else if (size == 0) {
7116 size = p->buf_size - offset;
7118 if (size < minsize) {
7122 tag = AV_RL32(p->buf + offset + 4);
7124 /* check for obvious tags */
7125 case MKTAG('m','o','o','v'):
7126 moov_offset = offset + 4;
7127 case MKTAG('m','d','a','t'):
7128 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
7129 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
7130 case MKTAG('f','t','y','p'):
7131 if (tag == MKTAG('f','t','y','p') &&
7132 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
7133 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
7135 score = FFMAX(score, 5);
7137 score = AVPROBE_SCORE_MAX;
7140 /* those are more common words, so rate then a bit less */
7141 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
7142 case MKTAG('w','i','d','e'):
7143 case MKTAG('f','r','e','e'):
7144 case MKTAG('j','u','n','k'):
7145 case MKTAG('p','i','c','t'):
7146 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
7148 case MKTAG(0x82,0x82,0x7f,0x7d):
7149 case MKTAG('s','k','i','p'):
7150 case MKTAG('u','u','i','d'):
7151 case MKTAG('p','r','f','l'):
7152 /* if we only find those cause probedata is too small at least rate them */
7153 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7158 if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
7159 /* moov atom in the header - we should make sure that this is not a
7160 * MOV-packed MPEG-PS */
7161 offset = moov_offset;
7163 while (offset < (p->buf_size - 16)) { /* Sufficient space */
7164 /* We found an actual hdlr atom */
7165 if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7166 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7167 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
7168 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7169 /* We found a media handler reference atom describing an
7170 * MPEG-PS-in-MOV, return a
7171 * low score to force expanding the probe window until
7172 * mpegps_probe finds what it needs */
7184 // must be done after parsing all trak because there's no order requirement
7185 static void mov_read_chapters(AVFormatContext *s)
7187 MOVContext *mov = s->priv_data;
7189 MOVStreamContext *sc;
7194 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7195 chapter_track = mov->chapter_tracks[j];
7197 for (i = 0; i < s->nb_streams; i++)
7198 if (s->streams[i]->id == chapter_track) {
7203 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7208 cur_pos = avio_tell(sc->pb);
7210 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7211 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7212 if (st->internal->nb_index_entries) {
7213 // Retrieve the first frame, if possible
7214 AVIndexEntry *sample = &st->internal->index_entries[0];
7215 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7216 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7220 if (av_get_packet(sc->pb, &st->attached_pic, sample->size) < 0)
7223 st->attached_pic.stream_index = st->index;
7224 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
7227 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7228 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7229 st->discard = AVDISCARD_ALL;
7230 for (i = 0; i < st->internal->nb_index_entries; i++) {
7231 AVIndexEntry *sample = &st->internal->index_entries[i];
7232 int64_t end = i+1 < st->internal->nb_index_entries ? st->internal->index_entries[i+1].timestamp : st->duration;
7237 if (end < sample->timestamp) {
7238 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7239 end = AV_NOPTS_VALUE;
7242 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7243 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7247 // the first two bytes are the length of the title
7248 len = avio_rb16(sc->pb);
7249 if (len > sample->size-2)
7251 title_len = 2*len + 1;
7252 if (!(title = av_mallocz(title_len)))
7255 // The samples could theoretically be in any encoding if there's an encd
7256 // atom following, but in practice are only utf-8 or utf-16, distinguished
7257 // instead by the presence of a BOM
7261 ch = avio_rb16(sc->pb);
7263 avio_get_str16be(sc->pb, len, title, title_len);
7264 else if (ch == 0xfffe)
7265 avio_get_str16le(sc->pb, len, title, title_len);
7268 if (len == 1 || len == 2)
7271 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7275 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7280 avio_seek(sc->pb, cur_pos, SEEK_SET);
7284 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7285 uint32_t value, int flags)
7288 char buf[AV_TIMECODE_STR_SIZE];
7289 AVRational rate = st->avg_frame_rate;
7290 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7293 av_dict_set(&st->metadata, "timecode",
7294 av_timecode_make_string(&tc, buf, value), 0);
7298 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7300 MOVStreamContext *sc = st->priv_data;
7301 char buf[AV_TIMECODE_STR_SIZE];
7302 int64_t cur_pos = avio_tell(sc->pb);
7303 int hh, mm, ss, ff, drop;
7305 if (!st->internal->nb_index_entries)
7308 avio_seek(sc->pb, st->internal->index_entries->pos, SEEK_SET);
7309 avio_skip(s->pb, 13);
7310 hh = avio_r8(s->pb);
7311 mm = avio_r8(s->pb);
7312 ss = avio_r8(s->pb);
7313 drop = avio_r8(s->pb);
7314 ff = avio_r8(s->pb);
7315 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7316 hh, mm, ss, drop ? ';' : ':', ff);
7317 av_dict_set(&st->metadata, "timecode", buf, 0);
7319 avio_seek(sc->pb, cur_pos, SEEK_SET);
7323 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7325 MOVStreamContext *sc = st->priv_data;
7327 int64_t cur_pos = avio_tell(sc->pb);
7330 if (!st->internal->nb_index_entries)
7333 avio_seek(sc->pb, st->internal->index_entries->pos, SEEK_SET);
7334 value = avio_rb32(s->pb);
7336 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7337 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7338 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7340 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7341 * not the case) and thus assume "frame number format" instead of QT one.
7342 * No sample with tmcd track can be found with a QT timecode at the moment,
7343 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7345 parse_timecode_in_framenum_format(s, st, value, flags);
7347 avio_seek(sc->pb, cur_pos, SEEK_SET);
7351 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7353 if (!index || !*index) return;
7354 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7355 av_encryption_info_free((*index)->encrypted_samples[i]);
7357 av_freep(&(*index)->encrypted_samples);
7358 av_freep(&(*index)->auxiliary_info_sizes);
7359 av_freep(&(*index)->auxiliary_offsets);
7363 static int mov_read_close(AVFormatContext *s)
7365 MOVContext *mov = s->priv_data;
7368 for (i = 0; i < s->nb_streams; i++) {
7369 AVStream *st = s->streams[i];
7370 MOVStreamContext *sc = st->priv_data;
7375 av_freep(&sc->ctts_data);
7376 for (j = 0; j < sc->drefs_count; j++) {
7377 av_freep(&sc->drefs[j].path);
7378 av_freep(&sc->drefs[j].dir);
7380 av_freep(&sc->drefs);
7382 sc->drefs_count = 0;
7384 if (!sc->pb_is_copied)
7385 ff_format_io_close(s, &sc->pb);
7388 av_freep(&sc->chunk_offsets);
7389 av_freep(&sc->stsc_data);
7390 av_freep(&sc->sample_sizes);
7391 av_freep(&sc->keyframes);
7392 av_freep(&sc->stts_data);
7393 av_freep(&sc->sdtp_data);
7394 av_freep(&sc->stps_data);
7395 av_freep(&sc->elst_data);
7396 av_freep(&sc->rap_group);
7397 av_freep(&sc->display_matrix);
7398 av_freep(&sc->index_ranges);
7401 for (j = 0; j < sc->stsd_count; j++)
7402 av_free(sc->extradata[j]);
7403 av_freep(&sc->extradata);
7404 av_freep(&sc->extradata_size);
7406 mov_free_encryption_index(&sc->cenc.encryption_index);
7407 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7408 av_aes_ctr_free(sc->cenc.aes_ctr);
7410 av_freep(&sc->stereo3d);
7411 av_freep(&sc->spherical);
7412 av_freep(&sc->mastering);
7413 av_freep(&sc->coll);
7416 av_freep(&mov->dv_demux);
7417 avformat_free_context(mov->dv_fctx);
7418 mov->dv_fctx = NULL;
7420 if (mov->meta_keys) {
7421 for (i = 1; i < mov->meta_keys_count; i++) {
7422 av_freep(&mov->meta_keys[i]);
7424 av_freep(&mov->meta_keys);
7427 av_freep(&mov->trex_data);
7428 av_freep(&mov->bitrates);
7430 for (i = 0; i < mov->frag_index.nb_items; i++) {
7431 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7432 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7433 mov_free_encryption_index(&frag[j].encryption_index);
7435 av_freep(&mov->frag_index.item[i].stream_info);
7437 av_freep(&mov->frag_index.item);
7439 av_freep(&mov->aes_decrypt);
7440 av_freep(&mov->chapter_tracks);
7445 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7449 for (i = 0; i < s->nb_streams; i++) {
7450 AVStream *st = s->streams[i];
7451 MOVStreamContext *sc = st->priv_data;
7453 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7454 sc->timecode_track == tmcd_id)
7460 /* look for a tmcd track not referenced by any video track, and export it globally */
7461 static void export_orphan_timecode(AVFormatContext *s)
7465 for (i = 0; i < s->nb_streams; i++) {
7466 AVStream *st = s->streams[i];
7468 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7469 !tmcd_is_referenced(s, i + 1)) {
7470 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7472 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7479 static int read_tfra(MOVContext *mov, AVIOContext *f)
7481 int version, fieldlength, i, j;
7482 int64_t pos = avio_tell(f);
7483 uint32_t size = avio_rb32(f);
7484 unsigned track_id, item_count;
7486 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7489 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7491 version = avio_r8(f);
7493 track_id = avio_rb32(f);
7494 fieldlength = avio_rb32(f);
7495 item_count = avio_rb32(f);
7496 for (i = 0; i < item_count; i++) {
7497 int64_t time, offset;
7499 MOVFragmentStreamInfo * frag_stream_info;
7502 return AVERROR_INVALIDDATA;
7506 time = avio_rb64(f);
7507 offset = avio_rb64(f);
7509 time = avio_rb32(f);
7510 offset = avio_rb32(f);
7513 // The first sample of each stream in a fragment is always a random
7514 // access sample. So it's entry in the tfra can be used as the
7515 // initial PTS of the fragment.
7516 index = update_frag_index(mov, offset);
7517 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7518 if (frag_stream_info &&
7519 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7520 frag_stream_info->first_tfra_pts = time;
7522 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7524 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7526 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7530 avio_seek(f, pos + size, SEEK_SET);
7534 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7536 int64_t stream_size = avio_size(f);
7537 int64_t original_pos = avio_tell(f);
7540 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7544 c->mfra_size = avio_rb32(f);
7545 c->have_read_mfra_size = 1;
7546 if (!c->mfra_size || c->mfra_size > stream_size) {
7547 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7550 if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
7554 if (avio_rb32(f) != c->mfra_size) {
7555 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7558 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7559 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7562 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7564 ret = read_tfra(c, f);
7569 c->frag_index.complete = 1;
7571 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7573 av_log(c->fc, AV_LOG_ERROR,
7574 "failed to seek back after looking for mfra\n");
7580 static int mov_read_header(AVFormatContext *s)
7582 MOVContext *mov = s->priv_data;
7583 AVIOContext *pb = s->pb;
7585 MOVAtom atom = { AV_RL32("root") };
7588 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7589 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7590 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7591 return AVERROR(EINVAL);
7595 mov->trak_index = -1;
7596 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7597 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7598 atom.size = avio_size(pb);
7600 atom.size = INT64_MAX;
7602 /* check MOV header */
7604 if (mov->moov_retry)
7605 avio_seek(pb, 0, SEEK_SET);
7606 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7607 av_log(s, AV_LOG_ERROR, "error reading header\n");
7610 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7611 if (!mov->found_moov) {
7612 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7613 err = AVERROR_INVALIDDATA;
7616 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7618 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7619 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7620 mov_read_chapters(s);
7621 for (i = 0; i < s->nb_streams; i++)
7622 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7623 mov_read_timecode_track(s, s->streams[i]);
7624 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7625 mov_read_rtmd_track(s, s->streams[i]);
7629 /* copy timecode metadata from tmcd tracks to the related video streams */
7630 for (i = 0; i < s->nb_streams; i++) {
7631 AVStream *st = s->streams[i];
7632 MOVStreamContext *sc = st->priv_data;
7633 if (sc->timecode_track > 0) {
7634 AVDictionaryEntry *tcr;
7635 int tmcd_st_id = -1;
7637 for (j = 0; j < s->nb_streams; j++)
7638 if (s->streams[j]->id == sc->timecode_track)
7641 if (tmcd_st_id < 0 || tmcd_st_id == i)
7643 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7645 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7648 export_orphan_timecode(s);
7650 for (i = 0; i < s->nb_streams; i++) {
7651 AVStream *st = s->streams[i];
7652 MOVStreamContext *sc = st->priv_data;
7653 fix_timescale(mov, sc);
7654 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
7655 st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7656 st->internal->skip_samples = sc->start_pad;
7658 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7659 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7660 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7661 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7662 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7663 st->codecpar->width = sc->width;
7664 st->codecpar->height = sc->height;
7666 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7667 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7671 if (mov->handbrake_version &&
7672 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7673 st->codecpar->codec_id == AV_CODEC_ID_MP3) {
7674 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7675 st->need_parsing = AVSTREAM_PARSE_FULL;
7679 if (mov->trex_data) {
7680 for (i = 0; i < s->nb_streams; i++) {
7681 AVStream *st = s->streams[i];
7682 MOVStreamContext *sc = st->priv_data;
7683 if (st->duration > 0) {
7684 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7685 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7686 sc->data_size, sc->time_scale);
7687 err = AVERROR_INVALIDDATA;
7690 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7695 if (mov->use_mfra_for > 0) {
7696 for (i = 0; i < s->nb_streams; i++) {
7697 AVStream *st = s->streams[i];
7698 MOVStreamContext *sc = st->priv_data;
7699 if (sc->duration_for_fps > 0) {
7700 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7701 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7702 sc->data_size, sc->time_scale);
7703 err = AVERROR_INVALIDDATA;
7706 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7707 sc->duration_for_fps;
7712 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7713 if (mov->bitrates[i]) {
7714 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7718 ff_rfps_calculate(s);
7720 for (i = 0; i < s->nb_streams; i++) {
7721 AVStream *st = s->streams[i];
7722 MOVStreamContext *sc = st->priv_data;
7724 switch (st->codecpar->codec_type) {
7725 case AVMEDIA_TYPE_AUDIO:
7726 err = ff_replaygain_export(st, s->metadata);
7730 case AVMEDIA_TYPE_VIDEO:
7731 if (sc->display_matrix) {
7732 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7733 sizeof(int32_t) * 9);
7737 sc->display_matrix = NULL;
7740 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7741 (uint8_t *)sc->stereo3d,
7742 sizeof(*sc->stereo3d));
7746 sc->stereo3d = NULL;
7748 if (sc->spherical) {
7749 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7750 (uint8_t *)sc->spherical,
7751 sc->spherical_size);
7755 sc->spherical = NULL;
7757 if (sc->mastering) {
7758 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7759 (uint8_t *)sc->mastering,
7760 sizeof(*sc->mastering));
7764 sc->mastering = NULL;
7767 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7768 (uint8_t *)sc->coll,
7778 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7780 for (i = 0; i < mov->frag_index.nb_items; i++)
7781 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7782 mov->frag_index.item[i].headers_read = 1;
7790 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7792 AVIndexEntry *sample = NULL;
7793 int64_t best_dts = INT64_MAX;
7795 for (i = 0; i < s->nb_streams; i++) {
7796 AVStream *avst = s->streams[i];
7797 MOVStreamContext *msc = avst->priv_data;
7798 if (msc->pb && msc->current_sample < avst->internal->nb_index_entries) {
7799 AVIndexEntry *current_sample = &avst->internal->index_entries[msc->current_sample];
7800 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7801 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7802 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7803 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7804 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
7805 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7806 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7807 sample = current_sample;
7816 static int should_retry(AVIOContext *pb, int error_code) {
7817 if (error_code == AVERROR_EOF || avio_feof(pb))
7823 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7826 MOVContext *mov = s->priv_data;
7828 if (index >= 0 && index < mov->frag_index.nb_items)
7829 target = mov->frag_index.item[index].moof_offset;
7830 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7831 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7832 return AVERROR_INVALIDDATA;
7835 mov->next_root_atom = 0;
7836 if (index < 0 || index >= mov->frag_index.nb_items)
7837 index = search_frag_moof_offset(&mov->frag_index, target);
7838 if (index < mov->frag_index.nb_items &&
7839 mov->frag_index.item[index].moof_offset == target) {
7840 if (index + 1 < mov->frag_index.nb_items)
7841 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7842 if (mov->frag_index.item[index].headers_read)
7844 mov->frag_index.item[index].headers_read = 1;
7847 mov->found_mdat = 0;
7849 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7852 if (avio_feof(s->pb))
7854 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7859 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7861 uint8_t *side, *extradata;
7864 /* Save the current index. */
7865 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7867 /* Notify the decoder that extradata changed. */
7868 extradata_size = sc->extradata_size[sc->last_stsd_index];
7869 extradata = sc->extradata[sc->last_stsd_index];
7870 if (extradata_size > 0 && extradata) {
7871 side = av_packet_new_side_data(pkt,
7872 AV_PKT_DATA_NEW_EXTRADATA,
7875 return AVERROR(ENOMEM);
7876 memcpy(side, extradata, extradata_size);
7882 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int size)
7887 return AVERROR_INVALIDDATA;
7888 new_size = ((size - 8) / 2) * 3;
7889 ret = av_new_packet(pkt, new_size);
7894 for (int j = 0; j < new_size; j += 3) {
7895 pkt->data[j] = 0xFC;
7896 pkt->data[j+1] = avio_r8(pb);
7897 pkt->data[j+2] = avio_r8(pb);
7903 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7905 MOVContext *mov = s->priv_data;
7906 MOVStreamContext *sc;
7907 AVIndexEntry *sample;
7908 AVStream *st = NULL;
7909 int64_t current_index;
7913 sample = mov_find_next_sample(s, &st);
7914 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7915 if (!mov->next_root_atom)
7917 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7922 /* must be done just before reading, to avoid infinite loop on sample */
7923 current_index = sc->current_index;
7924 mov_current_sample_inc(sc);
7926 if (mov->next_root_atom) {
7927 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7928 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7931 if (st->discard != AVDISCARD_ALL) {
7932 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7933 if (ret64 != sample->pos) {
7934 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7935 sc->ffindex, sample->pos);
7936 if (should_retry(sc->pb, ret64)) {
7937 mov_current_sample_dec(sc);
7939 return AVERROR_INVALIDDATA;
7942 if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
7943 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7947 if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
7948 ret = get_eia608_packet(sc->pb, pkt, sample->size);
7950 ret = av_get_packet(sc->pb, pkt, sample->size);
7952 if (should_retry(sc->pb, ret)) {
7953 mov_current_sample_dec(sc);
7957 #if CONFIG_DV_DEMUXER
7958 if (mov->dv_demux && sc->dv_audio_container) {
7959 AVBufferRef *buf = pkt->buf;
7960 ret = avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7962 av_packet_unref(pkt);
7965 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7970 if (sc->has_palette) {
7973 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7975 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7977 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7978 sc->has_palette = 0;
7981 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7982 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7983 st->need_parsing = AVSTREAM_PARSE_FULL;
7987 pkt->stream_index = sc->ffindex;
7988 pkt->dts = sample->timestamp;
7989 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7990 pkt->flags |= AV_PKT_FLAG_DISCARD;
7992 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7993 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
7994 /* update ctts context */
7996 if (sc->ctts_index < sc->ctts_count &&
7997 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
7999 sc->ctts_sample = 0;
8002 int64_t next_dts = (sc->current_sample < st->internal->nb_index_entries) ?
8003 st->internal->index_entries[sc->current_sample].timestamp : st->duration;
8005 if (next_dts >= pkt->dts)
8006 pkt->duration = next_dts - pkt->dts;
8007 pkt->pts = pkt->dts;
8009 if (st->discard == AVDISCARD_ALL)
8011 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
8012 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
8013 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
8014 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
8016 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
8017 pkt->pos = sample->pos;
8019 /* Multiple stsd handling. */
8020 if (sc->stsc_data) {
8021 /* Keep track of the stsc index for the given sample, then check
8022 * if the stsd index is different from the last used one. */
8024 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
8025 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
8027 sc->stsc_sample = 0;
8028 /* Do not check indexes after a switch. */
8029 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
8030 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
8031 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
8032 ret = mov_change_extradata(sc, pkt);
8039 aax_filter(pkt->data, pkt->size, mov);
8041 ret = cenc_filter(mov, st, sc, pkt, current_index);
8049 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
8051 MOVContext *mov = s->priv_data;
8054 if (!mov->frag_index.complete)
8057 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
8060 if (!mov->frag_index.item[index].headers_read)
8061 return mov_switch_root(s, -1, index);
8062 if (index + 1 < mov->frag_index.nb_items)
8063 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
8068 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
8070 MOVStreamContext *sc = st->priv_data;
8071 int sample, time_sample, ret;
8074 // Here we consider timestamp to be PTS, hence try to offset it so that we
8075 // can search over the DTS timeline.
8076 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
8078 ret = mov_seek_fragment(s, st, timestamp);
8082 sample = av_index_search_timestamp(st, timestamp, flags);
8083 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
8084 if (sample < 0 && st->internal->nb_index_entries && timestamp < st->internal->index_entries[0].timestamp)
8086 if (sample < 0) /* not sure what to do */
8087 return AVERROR_INVALIDDATA;
8088 mov_current_sample_set(sc, sample);
8089 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
8090 /* adjust ctts index */
8091 if (sc->ctts_data) {
8093 for (i = 0; i < sc->ctts_count; i++) {
8094 int next = time_sample + sc->ctts_data[i].count;
8095 if (next > sc->current_sample) {
8097 sc->ctts_sample = sc->current_sample - time_sample;
8104 /* adjust stsd index */
8105 if (sc->chunk_count) {
8107 for (i = 0; i < sc->stsc_count; i++) {
8108 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
8109 if (next > sc->current_sample) {
8111 sc->stsc_sample = sc->current_sample - time_sample;
8114 av_assert0(next == (int)next);
8122 static int64_t mov_get_skip_samples(AVStream *st, int sample)
8124 MOVStreamContext *sc = st->priv_data;
8125 int64_t first_ts = st->internal->index_entries[0].timestamp;
8126 int64_t ts = st->internal->index_entries[sample].timestamp;
8129 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO)
8132 /* compute skip samples according to stream start_pad, seek ts and first ts */
8133 off = av_rescale_q(ts - first_ts, st->time_base,
8134 (AVRational){1, st->codecpar->sample_rate});
8135 return FFMAX(sc->start_pad - off, 0);
8138 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
8140 MOVContext *mc = s->priv_data;
8145 if (stream_index >= s->nb_streams)
8146 return AVERROR_INVALIDDATA;
8148 st = s->streams[stream_index];
8149 sample = mov_seek_stream(s, st, sample_time, flags);
8153 if (mc->seek_individually) {
8154 /* adjust seek timestamp to found sample timestamp */
8155 int64_t seek_timestamp = st->internal->index_entries[sample].timestamp;
8156 st->internal->skip_samples = mov_get_skip_samples(st, sample);
8158 for (i = 0; i < s->nb_streams; i++) {
8162 if (stream_index == i)
8165 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
8166 sample = mov_seek_stream(s, st, timestamp, flags);
8168 st->internal->skip_samples = mov_get_skip_samples(st, sample);
8171 for (i = 0; i < s->nb_streams; i++) {
8172 MOVStreamContext *sc;
8175 mov_current_sample_set(sc, 0);
8178 MOVStreamContext *sc;
8179 AVIndexEntry *entry = mov_find_next_sample(s, &st);
8181 return AVERROR_INVALIDDATA;
8183 if (sc->ffindex == stream_index && sc->current_sample == sample)
8185 mov_current_sample_inc(sc);
8191 #define OFFSET(x) offsetof(MOVContext, x)
8192 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
8193 static const AVOption mov_options[] = {
8194 {"use_absolute_path",
8195 "allow using absolute path when opening alias, this is a possible security issue",
8196 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
8198 {"seek_streams_individually",
8199 "Seek each stream individually to the closest point",
8200 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
8202 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
8204 {"advanced_editlist",
8205 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
8206 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
8208 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8211 "use mfra for fragment timestamps",
8212 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8213 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8215 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8216 FLAGS, "use_mfra_for" },
8217 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8218 FLAGS, "use_mfra_for" },
8219 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8220 FLAGS, "use_mfra_for" },
8221 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8222 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8223 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8224 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8225 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8226 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8227 { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
8228 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8229 { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
8230 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8231 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8232 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8233 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8234 .flags = AV_OPT_FLAG_DECODING_PARAM },
8235 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8236 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8237 {.i64 = 0}, 0, 1, FLAGS },
8242 static const AVClass mov_class = {
8243 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8244 .item_name = av_default_item_name,
8245 .option = mov_options,
8246 .version = LIBAVUTIL_VERSION_INT,
8249 AVInputFormat ff_mov_demuxer = {
8250 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8251 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8252 .priv_class = &mov_class,
8253 .priv_data_size = sizeof(MOVContext),
8254 .extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
8255 .read_probe = mov_probe,
8256 .read_header = mov_read_header,
8257 .read_packet = mov_read_packet,
8258 .read_close = mov_read_close,
8259 .read_seek = mov_read_seek,
8260 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,