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)
186 MOVStreamContext *sc;
191 case 0xd: id = AV_CODEC_ID_MJPEG; break;
192 case 0xe: id = AV_CODEC_ID_PNG; break;
193 case 0x1b: id = AV_CODEC_ID_BMP; break;
195 av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
200 st = avformat_new_stream(c->fc, NULL);
202 return AVERROR(ENOMEM);
203 sc = av_mallocz(sizeof(*sc));
205 return AVERROR(ENOMEM);
208 ret = av_get_packet(pb, &pkt, len);
212 if (pkt.size >= 8 && id != AV_CODEC_ID_BMP) {
213 if (AV_RB64(pkt.data) == 0x89504e470d0a1a0a) {
214 id = AV_CODEC_ID_PNG;
216 id = AV_CODEC_ID_MJPEG;
220 st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
222 st->attached_pic = pkt;
223 st->attached_pic.stream_index = st->index;
224 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
226 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
227 st->codecpar->codec_id = id;
233 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
235 char language[4] = { 0 };
236 char buf[200], place[100];
237 uint16_t langcode = 0;
238 double longitude, latitude, altitude;
239 const char *key = "location";
241 if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
242 av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
243 return AVERROR_INVALIDDATA;
246 avio_skip(pb, 4); // version+flags
247 langcode = avio_rb16(pb);
248 ff_mov_lang_to_iso639(langcode, language);
251 len -= avio_get_str(pb, len, place, sizeof(place));
253 av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
254 return AVERROR_INVALIDDATA;
256 avio_skip(pb, 1); // role
260 av_log(c->fc, AV_LOG_ERROR,
261 "loci too short (%u bytes left, need at least %d)\n", len, 12);
262 return AVERROR_INVALIDDATA;
264 longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
265 latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
266 altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
268 // Try to output in the same format as the ?xyz field
269 snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
271 av_strlcatf(buf, sizeof(buf), "%+f", altitude);
272 av_strlcatf(buf, sizeof(buf), "/%s", place);
274 if (*language && strcmp(language, "und")) {
276 snprintf(key2, sizeof(key2), "%s-%s", key, language);
277 av_dict_set(&c->fc->metadata, key2, buf, 0);
279 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
280 return av_dict_set(&c->fc->metadata, key, buf, 0);
283 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
289 if (c->ignore_chapters)
292 n_hmmt = avio_rb32(pb);
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)
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 snprintf(tmp_key, 5, "%.4s", (char*)&atom.type);
455 if (atom.size < 0 || str_size >= INT_MAX/2)
456 return AVERROR_INVALIDDATA;
458 // Allocates enough space if data_type is a int32 or float32 number, otherwise
459 // worst-case requirement for output string in case of utf8 coded input
460 num = (data_type >= 21 && data_type <= 23);
461 str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
462 str = av_mallocz(str_size_alloc);
464 return AVERROR(ENOMEM);
467 parse(c, pb, str_size, key);
469 if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
470 mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
471 } else if (data_type == 21) { // BE signed integer, variable size
474 val = (int8_t)avio_r8(pb);
475 else if (str_size == 2)
476 val = (int16_t)avio_rb16(pb);
477 else if (str_size == 3)
478 val = ((int32_t)(avio_rb24(pb)<<8))>>8;
479 else if (str_size == 4)
480 val = (int32_t)avio_rb32(pb);
481 if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
482 av_log(c->fc, AV_LOG_ERROR,
483 "Failed to store the number (%d) in string.\n", val);
485 return AVERROR_INVALIDDATA;
487 } else if (data_type == 22) { // BE unsigned integer, variable size
488 unsigned int val = 0;
491 else if (str_size == 2)
493 else if (str_size == 3)
495 else if (str_size == 4)
497 if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
498 av_log(c->fc, AV_LOG_ERROR,
499 "Failed to store the number (%u) in string.\n", val);
501 return AVERROR_INVALIDDATA;
503 } else if (data_type == 23 && str_size >= 4) { // BE float32
504 float val = av_int2float(avio_rb32(pb));
505 if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
506 av_log(c->fc, AV_LOG_ERROR,
507 "Failed to store the float32 number (%f) in string.\n", val);
509 return AVERROR_INVALIDDATA;
512 int ret = ffio_read_size(pb, str, str_size);
519 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
520 av_dict_set(&c->fc->metadata, key, str, 0);
521 if (*language && strcmp(language, "und")) {
522 snprintf(key2, sizeof(key2), "%s-%s", key, language);
523 av_dict_set(&c->fc->metadata, key2, str, 0);
525 if (!strcmp(key, "encoder")) {
526 int major, minor, micro;
527 if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, µ) == 3) {
528 c->handbrake_version = 1000000*major + 1000*minor + micro;
537 static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
540 int i, nb_chapters, str_len, version;
544 if (c->ignore_chapters)
547 if ((atom.size -= 5) < 0)
550 version = avio_r8(pb);
553 avio_rb32(pb); // ???
554 nb_chapters = avio_r8(pb);
556 for (i = 0; i < nb_chapters; i++) {
560 start = avio_rb64(pb);
561 str_len = avio_r8(pb);
563 if ((atom.size -= 9+str_len) < 0)
566 ret = ffio_read_size(pb, str, str_len);
570 avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
575 #define MIN_DATA_ENTRY_BOX_SIZE 12
576 static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
579 MOVStreamContext *sc;
582 if (c->fc->nb_streams < 1)
584 st = c->fc->streams[c->fc->nb_streams-1];
587 avio_rb32(pb); // version + flags
588 entries = avio_rb32(pb);
590 entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
591 entries >= UINT_MAX / sizeof(*sc->drefs))
592 return AVERROR_INVALIDDATA;
596 sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
598 return AVERROR(ENOMEM);
599 sc->drefs_count = entries;
601 for (i = 0; i < entries; i++) {
602 MOVDref *dref = &sc->drefs[i];
603 uint32_t size = avio_rb32(pb);
604 int64_t next = avio_tell(pb) + size - 4;
607 return AVERROR_INVALIDDATA;
609 dref->type = avio_rl32(pb);
610 avio_rb32(pb); // version + flags
612 if (dref->type == MKTAG('a','l','i','s') && size > 150) {
613 /* macintosh alias record */
614 uint16_t volume_len, len;
620 volume_len = avio_r8(pb);
621 volume_len = FFMIN(volume_len, 27);
622 ret = ffio_read_size(pb, dref->volume, 27);
625 dref->volume[volume_len] = 0;
626 av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
631 len = FFMIN(len, 63);
632 ret = ffio_read_size(pb, dref->filename, 63);
635 dref->filename[len] = 0;
636 av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
640 /* read next level up_from_alias/down_to_target */
641 dref->nlvl_from = avio_rb16(pb);
642 dref->nlvl_to = avio_rb16(pb);
643 av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
644 dref->nlvl_from, dref->nlvl_to);
648 for (type = 0; type != -1 && avio_tell(pb) < next; ) {
651 type = avio_rb16(pb);
653 av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
656 if (type == 2) { // absolute path
658 dref->path = av_mallocz(len+1);
660 return AVERROR(ENOMEM);
662 ret = ffio_read_size(pb, dref->path, len);
664 av_freep(&dref->path);
667 if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
669 memmove(dref->path, dref->path+volume_len, len);
672 // trim string of any ending zeros
673 for (j = len - 1; j >= 0; j--) {
674 if (dref->path[j] == 0)
679 for (j = 0; j < len; j++)
680 if (dref->path[j] == ':' || dref->path[j] == 0)
682 av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
683 } else if (type == 0) { // directory name
685 dref->dir = av_malloc(len+1);
687 return AVERROR(ENOMEM);
689 ret = ffio_read_size(pb, dref->dir, len);
691 av_freep(&dref->dir);
695 for (j = 0; j < len; j++)
696 if (dref->dir[j] == ':')
698 av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
703 av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
708 avio_seek(pb, next, SEEK_SET);
713 static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
722 avio_r8(pb); /* version */
723 avio_rb24(pb); /* flags */
726 ctype = avio_rl32(pb);
727 type = avio_rl32(pb); /* component subtype */
729 av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
730 av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
732 if (c->trak_index < 0) { // meta not inside a trak
733 if (type == MKTAG('m','d','t','a')) {
734 c->found_hdlr_mdta = 1;
739 st = c->fc->streams[c->fc->nb_streams-1];
741 if (type == MKTAG('v','i','d','e'))
742 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
743 else if (type == MKTAG('s','o','u','n'))
744 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
745 else if (type == MKTAG('m','1','a',' '))
746 st->codecpar->codec_id = AV_CODEC_ID_MP2;
747 else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
748 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
750 avio_rb32(pb); /* component manufacture */
751 avio_rb32(pb); /* component flags */
752 avio_rb32(pb); /* component flags mask */
754 title_size = atom.size - 24;
755 if (title_size > 0) {
756 if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
757 return AVERROR_INVALIDDATA;
758 title_str = av_malloc(title_size + 1); /* Add null terminator */
760 return AVERROR(ENOMEM);
762 ret = ffio_read_size(pb, title_str, title_size);
764 av_freep(&title_str);
767 title_str[title_size] = 0;
769 int off = (!c->isom && title_str[0] == title_size - 1);
770 // flag added so as to not set stream handler name if already set from mdia->hdlr
771 av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
773 av_freep(&title_str);
779 static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
781 return ff_mov_read_esds(c->fc, pb);
784 static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
787 enum AVAudioServiceType *ast;
788 int ac3info, acmod, lfeon, bsmod;
790 if (c->fc->nb_streams < 1)
792 st = c->fc->streams[c->fc->nb_streams-1];
794 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
797 return AVERROR(ENOMEM);
799 ac3info = avio_rb24(pb);
800 bsmod = (ac3info >> 14) & 0x7;
801 acmod = (ac3info >> 11) & 0x7;
802 lfeon = (ac3info >> 10) & 0x1;
803 st->codecpar->channels = ((int[]){2,1,2,3,3,4,4,5})[acmod] + lfeon;
804 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
806 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
808 if (st->codecpar->channels > 1 && bsmod == 0x7)
809 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
811 #if FF_API_LAVF_AVCTX
812 FF_DISABLE_DEPRECATION_WARNINGS
813 st->codec->audio_service_type = *ast;
814 FF_ENABLE_DEPRECATION_WARNINGS
820 static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
823 enum AVAudioServiceType *ast;
824 int eac3info, acmod, lfeon, bsmod;
826 if (c->fc->nb_streams < 1)
828 st = c->fc->streams[c->fc->nb_streams-1];
830 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
833 return AVERROR(ENOMEM);
835 /* No need to parse fields for additional independent substreams and its
836 * associated dependent substreams since libavcodec's E-AC-3 decoder
837 * does not support them yet. */
838 avio_rb16(pb); /* data_rate and num_ind_sub */
839 eac3info = avio_rb24(pb);
840 bsmod = (eac3info >> 12) & 0x1f;
841 acmod = (eac3info >> 9) & 0x7;
842 lfeon = (eac3info >> 8) & 0x1;
843 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
845 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
846 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
848 if (st->codecpar->channels > 1 && bsmod == 0x7)
849 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
851 #if FF_API_LAVF_AVCTX
852 FF_DISABLE_DEPRECATION_WARNINGS
853 st->codec->audio_service_type = *ast;
854 FF_ENABLE_DEPRECATION_WARNINGS
860 static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
862 const uint32_t ddts_size = 20;
865 uint32_t frame_duration_code = 0;
866 uint32_t channel_layout_code = 0;
869 buf = av_malloc(ddts_size + AV_INPUT_BUFFER_PADDING_SIZE);
871 return AVERROR(ENOMEM);
873 if (avio_read(pb, buf, ddts_size) < ddts_size) {
875 return AVERROR_INVALIDDATA;
878 init_get_bits(&gb, buf, 8*ddts_size);
880 if (c->fc->nb_streams < 1) {
884 st = c->fc->streams[c->fc->nb_streams-1];
886 st->codecpar->sample_rate = get_bits_long(&gb, 32);
887 if (st->codecpar->sample_rate <= 0) {
888 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
890 return AVERROR_INVALIDDATA;
892 skip_bits_long(&gb, 32); /* max bitrate */
893 st->codecpar->bit_rate = get_bits_long(&gb, 32);
894 st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
895 frame_duration_code = get_bits(&gb, 2);
896 skip_bits(&gb, 30); /* various fields */
897 channel_layout_code = get_bits(&gb, 16);
899 st->codecpar->frame_size =
900 (frame_duration_code == 0) ? 512 :
901 (frame_duration_code == 1) ? 1024 :
902 (frame_duration_code == 2) ? 2048 :
903 (frame_duration_code == 3) ? 4096 : 0;
905 if (channel_layout_code > 0xff) {
906 av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout");
908 st->codecpar->channel_layout =
909 ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
910 ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
911 ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
912 ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
913 ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
914 ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0);
916 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
922 static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
926 if (c->fc->nb_streams < 1)
928 st = c->fc->streams[c->fc->nb_streams-1];
933 /* skip version and flags */
936 ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
941 static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
946 if (c->fc->nb_streams < 1)
948 st = c->fc->streams[c->fc->nb_streams-1];
950 if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
951 av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
956 static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
958 const int num = avio_rb32(pb);
959 const int den = avio_rb32(pb);
962 if (c->fc->nb_streams < 1)
964 st = c->fc->streams[c->fc->nb_streams-1];
966 if ((st->sample_aspect_ratio.den != 1 || st->sample_aspect_ratio.num) && // default
967 (den != st->sample_aspect_ratio.den || num != st->sample_aspect_ratio.num)) {
968 av_log(c->fc, AV_LOG_WARNING,
969 "sample aspect ratio already set to %d:%d, ignoring 'pasp' atom (%d:%d)\n",
970 st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
972 } else if (den != 0) {
973 av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den,
979 /* this atom contains actual media data */
980 static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
982 if (atom.size == 0) /* wrong one (MP4) */
985 return 0; /* now go for moov */
988 #define DRM_BLOB_SIZE 56
990 static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
992 uint8_t intermediate_key[20];
993 uint8_t intermediate_iv[20];
996 uint8_t file_checksum[20];
997 uint8_t calculated_checksum[20];
1001 uint8_t *activation_bytes = c->activation_bytes;
1002 uint8_t *fixed_key = c->audible_fixed_key;
1006 sha = av_sha_alloc();
1008 return AVERROR(ENOMEM);
1009 av_free(c->aes_decrypt);
1010 c->aes_decrypt = av_aes_alloc();
1011 if (!c->aes_decrypt) {
1012 ret = AVERROR(ENOMEM);
1016 /* drm blob processing */
1017 avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1018 avio_read(pb, input, DRM_BLOB_SIZE);
1019 avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1020 avio_read(pb, file_checksum, 20);
1022 av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == "); // required by external tools
1023 for (i = 0; i < 20; i++)
1024 av_log(c->fc, AV_LOG_INFO, "%02x", file_checksum[i]);
1025 av_log(c->fc, AV_LOG_INFO, "\n");
1027 /* verify activation data */
1028 if (!activation_bytes) {
1029 av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1030 ret = 0; /* allow ffprobe to continue working on .aax files */
1033 if (c->activation_bytes_size != 4) {
1034 av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1035 ret = AVERROR(EINVAL);
1039 /* verify fixed key */
1040 if (c->audible_fixed_key_size != 16) {
1041 av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1042 ret = AVERROR(EINVAL);
1046 /* AAX (and AAX+) key derivation */
1047 av_sha_init(sha, 160);
1048 av_sha_update(sha, fixed_key, 16);
1049 av_sha_update(sha, activation_bytes, 4);
1050 av_sha_final(sha, intermediate_key);
1051 av_sha_init(sha, 160);
1052 av_sha_update(sha, fixed_key, 16);
1053 av_sha_update(sha, intermediate_key, 20);
1054 av_sha_update(sha, activation_bytes, 4);
1055 av_sha_final(sha, intermediate_iv);
1056 av_sha_init(sha, 160);
1057 av_sha_update(sha, intermediate_key, 16);
1058 av_sha_update(sha, intermediate_iv, 16);
1059 av_sha_final(sha, calculated_checksum);
1060 if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1061 av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1062 ret = AVERROR_INVALIDDATA;
1065 av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1066 av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1067 for (i = 0; i < 4; i++) {
1068 // file data (in output) is stored in big-endian mode
1069 if (activation_bytes[i] != output[3 - i]) { // critical error
1070 av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1071 ret = AVERROR_INVALIDDATA;
1075 memcpy(c->file_key, output + 8, 16);
1076 memcpy(input, output + 26, 16);
1077 av_sha_init(sha, 160);
1078 av_sha_update(sha, input, 16);
1079 av_sha_update(sha, c->file_key, 16);
1080 av_sha_update(sha, fixed_key, 16);
1081 av_sha_final(sha, c->file_iv);
1089 // Audible AAX (and AAX+) bytestream decryption
1090 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1093 unsigned char iv[16];
1095 memcpy(iv, c->file_iv, 16); // iv is overwritten
1096 blocks = size >> 4; // trailing bytes are not encrypted!
1097 av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1098 av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1103 /* read major brand, minor version and compatible brands and store them as metadata */
1104 static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1107 int comp_brand_size;
1108 char* comp_brands_str;
1109 uint8_t type[5] = {0};
1110 int ret = ffio_read_size(pb, type, 4);
1114 if (strcmp(type, "qt "))
1116 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1117 av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1118 minor_ver = avio_rb32(pb); /* minor version */
1119 av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1121 comp_brand_size = atom.size - 8;
1122 if (comp_brand_size < 0)
1123 return AVERROR_INVALIDDATA;
1124 comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1125 if (!comp_brands_str)
1126 return AVERROR(ENOMEM);
1128 ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1130 av_freep(&comp_brands_str);
1133 comp_brands_str[comp_brand_size] = 0;
1134 av_dict_set(&c->fc->metadata, "compatible_brands",
1135 comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1140 /* this atom should contain all header atoms */
1141 static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1145 if (c->found_moov) {
1146 av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1147 avio_skip(pb, atom.size);
1151 if ((ret = mov_read_default(c, pb, atom)) < 0)
1153 /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1154 /* so we don't parse the whole file if over a network */
1156 return 0; /* now go for mdat */
1159 static MOVFragmentStreamInfo * get_frag_stream_info(
1160 MOVFragmentIndex *frag_index,
1165 MOVFragmentIndexItem * item;
1167 if (index < 0 || index >= frag_index->nb_items)
1169 item = &frag_index->item[index];
1170 for (i = 0; i < item->nb_stream_info; i++)
1171 if (item->stream_info[i].id == id)
1172 return &item->stream_info[i];
1174 // This shouldn't happen
1178 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1181 MOVFragmentIndexItem * item;
1183 if (frag_index->current < 0 ||
1184 frag_index->current >= frag_index->nb_items)
1187 item = &frag_index->item[frag_index->current];
1188 for (i = 0; i < item->nb_stream_info; i++)
1189 if (item->stream_info[i].id == id) {
1194 // id not found. This shouldn't happen.
1198 static MOVFragmentStreamInfo * get_current_frag_stream_info(
1199 MOVFragmentIndex *frag_index)
1201 MOVFragmentIndexItem *item;
1202 if (frag_index->current < 0 ||
1203 frag_index->current >= frag_index->nb_items)
1206 item = &frag_index->item[frag_index->current];
1207 if (item->current >= 0 && item->current < item->nb_stream_info)
1208 return &item->stream_info[item->current];
1210 // This shouldn't happen
1214 static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
1217 int64_t moof_offset;
1219 // Optimize for appending new entries
1220 if (!frag_index->nb_items ||
1221 frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1222 return frag_index->nb_items;
1225 b = frag_index->nb_items;
1229 moof_offset = frag_index->item[m].moof_offset;
1230 if (moof_offset >= offset)
1232 if (moof_offset <= offset)
1238 static int64_t get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
1240 av_assert0(frag_stream_info);
1241 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1242 return frag_stream_info->sidx_pts;
1243 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1244 return frag_stream_info->first_tfra_pts;
1245 return frag_stream_info->tfdt_dts;
1248 static int64_t get_frag_time(MOVFragmentIndex *frag_index,
1249 int index, int track_id)
1251 MOVFragmentStreamInfo * frag_stream_info;
1255 if (track_id >= 0) {
1256 frag_stream_info = get_frag_stream_info(frag_index, index, track_id);
1257 return frag_stream_info->sidx_pts;
1260 for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1261 frag_stream_info = &frag_index->item[index].stream_info[i];
1262 timestamp = get_stream_info_time(frag_stream_info);
1263 if (timestamp != AV_NOPTS_VALUE)
1266 return AV_NOPTS_VALUE;
1269 static int search_frag_timestamp(MOVFragmentIndex *frag_index,
1270 AVStream *st, int64_t timestamp)
1277 // If the stream is referenced by any sidx, limit the search
1278 // to fragments that referenced this stream in the sidx
1279 MOVStreamContext *sc = st->priv_data;
1285 b = frag_index->nb_items;
1288 m0 = m = (a + b) >> 1;
1291 (frag_time = get_frag_time(frag_index, m, id)) == AV_NOPTS_VALUE)
1294 if (m < b && frag_time <= timestamp)
1303 static int update_frag_index(MOVContext *c, int64_t offset)
1306 MOVFragmentIndexItem * item;
1307 MOVFragmentStreamInfo * frag_stream_info;
1309 // If moof_offset already exists in frag_index, return index to it
1310 index = search_frag_moof_offset(&c->frag_index, offset);
1311 if (index < c->frag_index.nb_items &&
1312 c->frag_index.item[index].moof_offset == offset)
1315 // offset is not yet in frag index.
1316 // Insert new item at index (sorted by moof offset)
1317 item = av_fast_realloc(c->frag_index.item,
1318 &c->frag_index.allocated_size,
1319 (c->frag_index.nb_items + 1) *
1320 sizeof(*c->frag_index.item));
1323 c->frag_index.item = item;
1325 frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1326 sizeof(*item->stream_info));
1327 if (!frag_stream_info)
1330 for (i = 0; i < c->fc->nb_streams; i++) {
1331 // Avoid building frag index if streams lack track id.
1332 if (c->fc->streams[i]->id < 0) {
1333 av_free(frag_stream_info);
1334 return AVERROR_INVALIDDATA;
1337 frag_stream_info[i].id = c->fc->streams[i]->id;
1338 frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1339 frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1340 frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1341 frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1342 frag_stream_info[i].index_entry = -1;
1343 frag_stream_info[i].encryption_index = NULL;
1346 if (index < c->frag_index.nb_items)
1347 memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1348 (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1350 item = &c->frag_index.item[index];
1351 item->headers_read = 0;
1353 item->nb_stream_info = c->fc->nb_streams;
1354 item->moof_offset = offset;
1355 item->stream_info = frag_stream_info;
1356 c->frag_index.nb_items++;
1361 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1362 int id, int entries)
1365 MOVFragmentStreamInfo * frag_stream_info;
1369 for (i = index; i < frag_index->nb_items; i++) {
1370 frag_stream_info = get_frag_stream_info(frag_index, i, id);
1371 if (frag_stream_info && frag_stream_info->index_entry >= 0)
1372 frag_stream_info->index_entry += entries;
1376 static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1378 // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1379 c->fragment.found_tfhd = 0;
1381 if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1382 c->has_looked_for_mfra = 1;
1383 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1385 av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1387 if ((ret = mov_read_mfra(c, pb)) < 0) {
1388 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1389 "read the mfra (may be a live ismv)\n");
1392 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1393 "seekable, can not look for mfra\n");
1396 c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1397 av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1398 c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1399 return mov_read_default(c, pb, atom);
1402 static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time, void *logctx)
1405 if(time >= 2082844800)
1406 time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1408 if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1409 av_log(logctx, AV_LOG_DEBUG, "creation_time is not representable\n");
1413 avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1417 static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1420 MOVStreamContext *sc;
1422 char language[4] = {0};
1424 int64_t creation_time;
1426 if (c->fc->nb_streams < 1)
1428 st = c->fc->streams[c->fc->nb_streams-1];
1431 if (sc->time_scale) {
1432 av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1433 return AVERROR_INVALIDDATA;
1436 version = avio_r8(pb);
1438 avpriv_request_sample(c->fc, "Version %d", version);
1439 return AVERROR_PATCHWELCOME;
1441 avio_rb24(pb); /* flags */
1443 creation_time = avio_rb64(pb);
1446 creation_time = avio_rb32(pb);
1447 avio_rb32(pb); /* modification time */
1449 mov_metadata_creation_time(&st->metadata, creation_time, c->fc);
1451 sc->time_scale = avio_rb32(pb);
1452 if (sc->time_scale <= 0) {
1453 av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1456 st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1458 lang = avio_rb16(pb); /* language */
1459 if (ff_mov_lang_to_iso639(lang, language))
1460 av_dict_set(&st->metadata, "language", language, 0);
1461 avio_rb16(pb); /* quality */
1466 static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1469 int64_t creation_time;
1470 int version = avio_r8(pb); /* version */
1471 avio_rb24(pb); /* flags */
1474 creation_time = avio_rb64(pb);
1477 creation_time = avio_rb32(pb);
1478 avio_rb32(pb); /* modification time */
1480 mov_metadata_creation_time(&c->fc->metadata, creation_time, c->fc);
1481 c->time_scale = avio_rb32(pb); /* time scale */
1482 if (c->time_scale <= 0) {
1483 av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1486 av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1488 c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1489 // set the AVCodecContext duration because the duration of individual tracks
1490 // may be inaccurate
1491 if (c->time_scale > 0 && !c->trex_data)
1492 c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale);
1493 avio_rb32(pb); /* preferred scale */
1495 avio_rb16(pb); /* preferred volume */
1497 avio_skip(pb, 10); /* reserved */
1499 /* movie display matrix, store it in main context and use it later on */
1500 for (i = 0; i < 3; i++) {
1501 c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1502 c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1503 c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1506 avio_rb32(pb); /* preview time */
1507 avio_rb32(pb); /* preview duration */
1508 avio_rb32(pb); /* poster time */
1509 avio_rb32(pb); /* selection time */
1510 avio_rb32(pb); /* selection duration */
1511 avio_rb32(pb); /* current time */
1512 avio_rb32(pb); /* next track ID */
1517 static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1522 if (c->fc->nb_streams < 1)
1524 st = c->fc->streams[c->fc->nb_streams-1];
1526 little_endian = avio_rb16(pb) & 0xFF;
1527 av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1528 if (little_endian == 1) {
1529 switch (st->codecpar->codec_id) {
1530 case AV_CODEC_ID_PCM_S24BE:
1531 st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE;
1533 case AV_CODEC_ID_PCM_S32BE:
1534 st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE;
1536 case AV_CODEC_ID_PCM_F32BE:
1537 st->codecpar->codec_id = AV_CODEC_ID_PCM_F32LE;
1539 case AV_CODEC_ID_PCM_F64BE:
1540 st->codecpar->codec_id = AV_CODEC_ID_PCM_F64LE;
1549 static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1552 uint8_t *icc_profile;
1553 char color_parameter_type[5] = { 0 };
1554 uint16_t color_primaries, color_trc, color_matrix;
1557 if (c->fc->nb_streams < 1)
1559 st = c->fc->streams[c->fc->nb_streams - 1];
1561 ret = ffio_read_size(pb, color_parameter_type, 4);
1564 if (strncmp(color_parameter_type, "nclx", 4) &&
1565 strncmp(color_parameter_type, "nclc", 4) &&
1566 strncmp(color_parameter_type, "prof", 4)) {
1567 av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
1568 color_parameter_type);
1572 if (!strncmp(color_parameter_type, "prof", 4)) {
1573 icc_profile = av_stream_new_side_data(st, AV_PKT_DATA_ICC_PROFILE, atom.size - 4);
1575 return AVERROR(ENOMEM);
1576 ret = ffio_read_size(pb, icc_profile, atom.size - 4);
1581 color_primaries = avio_rb16(pb);
1582 color_trc = avio_rb16(pb);
1583 color_matrix = avio_rb16(pb);
1585 av_log(c->fc, AV_LOG_TRACE,
1586 "%s: pri %d trc %d matrix %d",
1587 color_parameter_type, color_primaries, color_trc, color_matrix);
1589 if (!strncmp(color_parameter_type, "nclx", 4)) {
1590 uint8_t color_range = avio_r8(pb) >> 7;
1591 av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
1593 st->codecpar->color_range = AVCOL_RANGE_JPEG;
1595 st->codecpar->color_range = AVCOL_RANGE_MPEG;
1598 if (!av_color_primaries_name(color_primaries))
1599 color_primaries = AVCOL_PRI_UNSPECIFIED;
1600 if (!av_color_transfer_name(color_trc))
1601 color_trc = AVCOL_TRC_UNSPECIFIED;
1602 if (!av_color_space_name(color_matrix))
1603 color_matrix = AVCOL_SPC_UNSPECIFIED;
1605 st->codecpar->color_primaries = color_primaries;
1606 st->codecpar->color_trc = color_trc;
1607 st->codecpar->color_space = color_matrix;
1608 av_log(c->fc, AV_LOG_TRACE, "\n");
1613 static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1616 unsigned mov_field_order;
1617 enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
1619 if (c->fc->nb_streams < 1) // will happen with jp2 files
1621 st = c->fc->streams[c->fc->nb_streams-1];
1623 return AVERROR_INVALIDDATA;
1624 mov_field_order = avio_rb16(pb);
1625 if ((mov_field_order & 0xFF00) == 0x0100)
1626 decoded_field_order = AV_FIELD_PROGRESSIVE;
1627 else if ((mov_field_order & 0xFF00) == 0x0200) {
1628 switch (mov_field_order & 0xFF) {
1629 case 0x01: decoded_field_order = AV_FIELD_TT;
1631 case 0x06: decoded_field_order = AV_FIELD_BB;
1633 case 0x09: decoded_field_order = AV_FIELD_TB;
1635 case 0x0E: decoded_field_order = AV_FIELD_BT;
1639 if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
1640 av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
1642 st->codecpar->field_order = decoded_field_order;
1647 static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
1650 uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
1651 if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
1652 return AVERROR_INVALIDDATA;
1653 if ((err = av_reallocp(&par->extradata, size)) < 0) {
1654 par->extradata_size = 0;
1657 par->extradata_size = size - AV_INPUT_BUFFER_PADDING_SIZE;
1661 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
1662 static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1663 AVCodecParameters *par, uint8_t *buf)
1665 int64_t result = atom.size;
1668 AV_WB32(buf , atom.size + 8);
1669 AV_WL32(buf + 4, atom.type);
1670 err = ffio_read_size(pb, buf + 8, atom.size);
1672 par->extradata_size -= atom.size;
1674 } else if (err < atom.size) {
1675 av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
1676 par->extradata_size -= atom.size - err;
1679 memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1683 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
1684 static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1685 enum AVCodecID codec_id)
1688 uint64_t original_size;
1691 if (c->fc->nb_streams < 1) // will happen with jp2 files
1693 st = c->fc->streams[c->fc->nb_streams-1];
1695 if (st->codecpar->codec_id != codec_id)
1696 return 0; /* unexpected codec_id - don't mess with extradata */
1698 original_size = st->codecpar->extradata_size;
1699 err = mov_realloc_extradata(st->codecpar, atom);
1703 err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
1706 return 0; // Note: this is the original behavior to ignore truncation.
1709 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
1710 static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1712 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
1715 static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1717 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS);
1720 static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1722 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
1725 static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1727 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
1730 static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1732 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
1734 ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
1738 static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1740 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
1742 if (!ret && c->fc->nb_streams >= 1) {
1743 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1744 if (par->extradata_size >= 40) {
1745 par->height = AV_RB16(&par->extradata[36]);
1746 par->width = AV_RB16(&par->extradata[38]);
1752 static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1754 if (c->fc->nb_streams >= 1) {
1755 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1756 if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
1757 par->codec_id == AV_CODEC_ID_H264 &&
1761 cid = avio_rb16(pb);
1762 /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
1763 if (cid == 0xd4d || cid == 0xd4e)
1766 } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
1767 par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
1768 par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
1772 num = avio_rb32(pb);
1773 den = avio_rb32(pb);
1774 if (num <= 0 || den <= 0)
1776 switch (avio_rb32(pb)) {
1778 if (den >= INT_MAX / 2)
1782 c->fc->streams[c->fc->nb_streams-1]->display_aspect_ratio.num = num;
1783 c->fc->streams[c->fc->nb_streams-1]->display_aspect_ratio.den = den;
1790 return mov_read_avid(c, pb, atom);
1793 static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1797 uint64_t original_size;
1798 if (c->fc->nb_streams >= 1) {
1799 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1800 if (par->codec_id == AV_CODEC_ID_H264)
1802 if (atom.size == 16) {
1803 original_size = par->extradata_size;
1804 ret = mov_realloc_extradata(par, atom);
1806 length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
1807 if (length == atom.size) {
1808 const uint8_t range_value = par->extradata[original_size + 19];
1809 switch (range_value) {
1811 par->color_range = AVCOL_RANGE_MPEG;
1814 par->color_range = AVCOL_RANGE_JPEG;
1817 av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
1820 ff_dlog(c->fc, "color_range: %d\n", par->color_range);
1822 /* For some reason the whole atom was not added to the extradata */
1823 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
1826 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
1829 av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
1836 static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1838 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
1841 static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1846 if (c->fc->nb_streams < 1)
1848 st = c->fc->streams[c->fc->nb_streams-1];
1850 if ((uint64_t)atom.size > (1<<30))
1851 return AVERROR_INVALIDDATA;
1853 if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
1854 st->codecpar->codec_id == AV_CODEC_ID_QDMC ||
1855 st->codecpar->codec_id == AV_CODEC_ID_SPEEX) {
1856 // pass all frma atom to codec, needed at least for QDMC and QDM2
1857 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1860 } else if (atom.size > 8) { /* to read frma, esds atoms */
1861 if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
1863 ret = ffio_ensure_seekback(pb, 8);
1866 buffer = avio_rb64(pb);
1868 if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
1869 && buffer >> 32 <= atom.size
1870 && buffer >> 32 >= 8) {
1873 } else if (!st->codecpar->extradata_size) {
1874 #define ALAC_EXTRADATA_SIZE 36
1875 st->codecpar->extradata = av_mallocz(ALAC_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
1876 if (!st->codecpar->extradata)
1877 return AVERROR(ENOMEM);
1878 st->codecpar->extradata_size = ALAC_EXTRADATA_SIZE;
1879 AV_WB32(st->codecpar->extradata , ALAC_EXTRADATA_SIZE);
1880 AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
1881 AV_WB64(st->codecpar->extradata + 12, buffer);
1882 avio_read(pb, st->codecpar->extradata + 20, 16);
1883 avio_skip(pb, atom.size - 24);
1887 if ((ret = mov_read_default(c, pb, atom)) < 0)
1890 avio_skip(pb, atom.size);
1895 * This function reads atom content and puts data in extradata without tag
1896 * nor size unlike mov_read_extradata.
1898 static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1903 if (c->fc->nb_streams < 1)
1905 st = c->fc->streams[c->fc->nb_streams-1];
1907 if ((uint64_t)atom.size > (1<<30))
1908 return AVERROR_INVALIDDATA;
1910 if (atom.size >= 10) {
1911 // Broken files created by legacy versions of libavformat will
1912 // wrap a whole fiel atom inside of a glbl atom.
1913 unsigned size = avio_rb32(pb);
1914 unsigned type = avio_rl32(pb);
1915 avio_seek(pb, -8, SEEK_CUR);
1916 if (type == MKTAG('f','i','e','l') && size == atom.size)
1917 return mov_read_default(c, pb, atom);
1919 if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
1920 av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
1923 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1926 if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
1927 /* HEVC-based Dolby Vision derived from hvc1.
1928 Happens to match with an identifier
1929 previously utilized for DV. Thus, if we have
1930 the hvcC extradata box available as specified,
1931 set codec to HEVC */
1932 st->codecpar->codec_id = AV_CODEC_ID_HEVC;
1937 static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1940 uint8_t profile_level;
1943 if (c->fc->nb_streams < 1)
1945 st = c->fc->streams[c->fc->nb_streams-1];
1947 if (atom.size >= (1<<28) || atom.size < 7)
1948 return AVERROR_INVALIDDATA;
1950 profile_level = avio_r8(pb);
1951 if ((profile_level & 0xf0) != 0xc0)
1954 avio_seek(pb, 6, SEEK_CUR);
1955 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
1963 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
1964 * but can have extradata appended at the end after the 40 bytes belonging
1967 static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1972 if (c->fc->nb_streams < 1)
1974 if (atom.size <= 40)
1976 st = c->fc->streams[c->fc->nb_streams-1];
1978 if ((uint64_t)atom.size > (1<<30))
1979 return AVERROR_INVALIDDATA;
1982 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
1989 static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1992 MOVStreamContext *sc;
1993 unsigned int i, entries;
1995 if (c->trak_index < 0) {
1996 av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
1999 if (c->fc->nb_streams < 1)
2001 st = c->fc->streams[c->fc->nb_streams-1];
2004 avio_r8(pb); /* version */
2005 avio_rb24(pb); /* flags */
2007 entries = avio_rb32(pb);
2012 if (sc->chunk_offsets)
2013 av_log(c->fc, AV_LOG_WARNING, "Duplicated STCO atom\n");
2014 av_free(sc->chunk_offsets);
2015 sc->chunk_count = 0;
2016 sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2017 if (!sc->chunk_offsets)
2018 return AVERROR(ENOMEM);
2019 sc->chunk_count = entries;
2021 if (atom.type == MKTAG('s','t','c','o'))
2022 for (i = 0; i < entries && !pb->eof_reached; i++)
2023 sc->chunk_offsets[i] = avio_rb32(pb);
2024 else if (atom.type == MKTAG('c','o','6','4'))
2025 for (i = 0; i < entries && !pb->eof_reached; i++)
2026 sc->chunk_offsets[i] = avio_rb64(pb);
2028 return AVERROR_INVALIDDATA;
2030 sc->chunk_count = i;
2032 if (pb->eof_reached) {
2033 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2040 static int mov_codec_id(AVStream *st, uint32_t format)
2042 int id = ff_codec_get_id(ff_codec_movaudio_tags, format);
2045 ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2046 (format & 0xFFFF) == 'T' + ('S' << 8)))
2047 id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format) & 0xFFFF);
2049 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2050 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2051 } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2052 /* skip old ASF MPEG-4 tag */
2053 format && format != MKTAG('m','p','4','s')) {
2054 id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2056 id = ff_codec_get_id(ff_codec_bmp_tags, format);
2058 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
2059 else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2060 (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE &&
2061 st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2062 id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
2064 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
2066 id = ff_codec_get_id(ff_codec_movdata_tags, format);
2070 st->codecpar->codec_tag = format;
2075 static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
2076 AVStream *st, MOVStreamContext *sc)
2078 uint8_t codec_name[32] = { 0 };
2082 /* The first 16 bytes of the video sample description are already
2083 * read in ff_mov_read_stsd_entries() */
2084 stsd_start = avio_tell(pb) - 16;
2086 avio_rb16(pb); /* version */
2087 avio_rb16(pb); /* revision level */
2088 avio_rb32(pb); /* vendor */
2089 avio_rb32(pb); /* temporal quality */
2090 avio_rb32(pb); /* spatial quality */
2092 st->codecpar->width = avio_rb16(pb); /* width */
2093 st->codecpar->height = avio_rb16(pb); /* height */
2095 avio_rb32(pb); /* horiz resolution */
2096 avio_rb32(pb); /* vert resolution */
2097 avio_rb32(pb); /* data size, always 0 */
2098 avio_rb16(pb); /* frames per samples */
2100 len = avio_r8(pb); /* codec name, pascal string */
2103 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2105 avio_skip(pb, 31 - len);
2108 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2110 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2111 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2112 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2113 st->codecpar->width &= ~1;
2114 st->codecpar->height &= ~1;
2116 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2117 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2118 !strncmp(codec_name, "Sorenson H263", 13))
2119 st->codecpar->codec_id = AV_CODEC_ID_FLV1;
2121 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2123 avio_seek(pb, stsd_start, SEEK_SET);
2125 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2126 st->codecpar->bits_per_coded_sample &= 0x1F;
2127 sc->has_palette = 1;
2131 static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
2132 AVStream *st, MOVStreamContext *sc)
2134 int bits_per_sample, flags;
2135 uint16_t version = avio_rb16(pb);
2136 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2138 avio_rb16(pb); /* revision level */
2139 avio_rb32(pb); /* vendor */
2141 st->codecpar->channels = avio_rb16(pb); /* channel count */
2142 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2143 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", st->codecpar->channels);
2145 sc->audio_cid = avio_rb16(pb);
2146 avio_rb16(pb); /* packet size = 0 */
2148 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2150 // Read QT version 1 fields. In version 0 these do not exist.
2151 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2153 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2154 (sc->stsd_version == 0 && version > 0)) {
2156 sc->samples_per_frame = avio_rb32(pb);
2157 avio_rb32(pb); /* bytes per packet */
2158 sc->bytes_per_frame = avio_rb32(pb);
2159 avio_rb32(pb); /* bytes per sample */
2160 } else if (version == 2) {
2161 avio_rb32(pb); /* sizeof struct only */
2162 st->codecpar->sample_rate = av_int2double(avio_rb64(pb));
2163 st->codecpar->channels = avio_rb32(pb);
2164 avio_rb32(pb); /* always 0x7F000000 */
2165 st->codecpar->bits_per_coded_sample = avio_rb32(pb);
2167 flags = avio_rb32(pb); /* lpcm format specific flag */
2168 sc->bytes_per_frame = avio_rb32(pb);
2169 sc->samples_per_frame = avio_rb32(pb);
2170 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2171 st->codecpar->codec_id =
2172 ff_mov_get_lpcm_codec_id(st->codecpar->bits_per_coded_sample,
2175 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2176 /* can't correctly handle variable sized packet as audio unit */
2177 switch (st->codecpar->codec_id) {
2178 case AV_CODEC_ID_MP2:
2179 case AV_CODEC_ID_MP3:
2180 st->need_parsing = AVSTREAM_PARSE_FULL;
2186 if (sc->format == 0) {
2187 if (st->codecpar->bits_per_coded_sample == 8)
2188 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2189 else if (st->codecpar->bits_per_coded_sample == 16)
2190 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2193 switch (st->codecpar->codec_id) {
2194 case AV_CODEC_ID_PCM_S8:
2195 case AV_CODEC_ID_PCM_U8:
2196 if (st->codecpar->bits_per_coded_sample == 16)
2197 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16BE;
2199 case AV_CODEC_ID_PCM_S16LE:
2200 case AV_CODEC_ID_PCM_S16BE:
2201 if (st->codecpar->bits_per_coded_sample == 8)
2202 st->codecpar->codec_id = AV_CODEC_ID_PCM_S8;
2203 else if (st->codecpar->bits_per_coded_sample == 24)
2204 st->codecpar->codec_id =
2205 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2206 AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
2207 else if (st->codecpar->bits_per_coded_sample == 32)
2208 st->codecpar->codec_id =
2209 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2210 AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
2212 /* set values for old format before stsd version 1 appeared */
2213 case AV_CODEC_ID_MACE3:
2214 sc->samples_per_frame = 6;
2215 sc->bytes_per_frame = 2 * st->codecpar->channels;
2217 case AV_CODEC_ID_MACE6:
2218 sc->samples_per_frame = 6;
2219 sc->bytes_per_frame = 1 * st->codecpar->channels;
2221 case AV_CODEC_ID_ADPCM_IMA_QT:
2222 sc->samples_per_frame = 64;
2223 sc->bytes_per_frame = 34 * st->codecpar->channels;
2225 case AV_CODEC_ID_GSM:
2226 sc->samples_per_frame = 160;
2227 sc->bytes_per_frame = 33;
2233 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2234 if (bits_per_sample) {
2235 st->codecpar->bits_per_coded_sample = bits_per_sample;
2236 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->channels;
2240 static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
2241 AVStream *st, MOVStreamContext *sc,
2244 // ttxt stsd contains display flags, justification, background
2245 // color, fonts, and default styles, so fake an atom to read it
2246 MOVAtom fake_atom = { .size = size };
2247 // mp4s contains a regular esds atom
2248 if (st->codecpar->codec_tag != AV_RL32("mp4s"))
2249 mov_read_glbl(c, pb, fake_atom);
2250 st->codecpar->width = sc->width;
2251 st->codecpar->height = sc->height;
2254 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2259 y = (ycbcr >> 16) & 0xFF;
2260 cr = (ycbcr >> 8) & 0xFF;
2263 b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
2264 g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
2265 r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
2267 return (r << 16) | (g << 8) | b;
2270 static int mov_rewrite_dvd_sub_extradata(AVStream *st)
2272 char buf[256] = {0};
2273 uint8_t *src = st->codecpar->extradata;
2276 if (st->codecpar->extradata_size != 64)
2279 if (st->codecpar->width > 0 && st->codecpar->height > 0)
2280 snprintf(buf, sizeof(buf), "size: %dx%d\n",
2281 st->codecpar->width, st->codecpar->height);
2282 av_strlcat(buf, "palette: ", sizeof(buf));
2284 for (i = 0; i < 16; i++) {
2285 uint32_t yuv = AV_RB32(src + i * 4);
2286 uint32_t rgba = yuv_to_rgba(yuv);
2288 av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2291 if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2294 ret = ff_alloc_extradata(st->codecpar, strlen(buf));
2297 memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2302 static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
2303 AVStream *st, MOVStreamContext *sc,
2308 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2309 if ((int)size != size)
2310 return AVERROR(ENOMEM);
2312 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2316 MOVStreamContext *tmcd_ctx = st->priv_data;
2318 val = AV_RB32(st->codecpar->extradata + 4);
2319 tmcd_ctx->tmcd_flags = val;
2320 st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2321 st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2322 #if FF_API_LAVF_AVCTX
2323 FF_DISABLE_DEPRECATION_WARNINGS
2324 st->codec->time_base = av_inv_q(st->avg_frame_rate);
2325 FF_ENABLE_DEPRECATION_WARNINGS
2327 /* adjust for per frame dur in counter mode */
2328 if (tmcd_ctx->tmcd_flags & 0x0008) {
2329 int timescale = AV_RB32(st->codecpar->extradata + 8);
2330 int framedur = AV_RB32(st->codecpar->extradata + 12);
2331 st->avg_frame_rate.num *= timescale;
2332 st->avg_frame_rate.den *= framedur;
2333 #if FF_API_LAVF_AVCTX
2334 FF_DISABLE_DEPRECATION_WARNINGS
2335 st->codec->time_base.den *= timescale;
2336 st->codec->time_base.num *= framedur;
2337 FF_ENABLE_DEPRECATION_WARNINGS
2341 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2342 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2343 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2344 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2345 if (str_size > 0 && size >= (int)str_size + 26) {
2346 char *reel_name = av_malloc(str_size + 1);
2348 return AVERROR(ENOMEM);
2349 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2350 reel_name[str_size] = 0; /* Add null terminator */
2351 /* don't add reel_name if emtpy string */
2352 if (*reel_name == 0) {
2355 av_dict_set(&st->metadata, "reel_name", reel_name, AV_DICT_DONT_STRDUP_VAL);
2362 /* other codec type, just skip (rtp, mp4s ...) */
2363 avio_skip(pb, size);
2368 static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
2369 AVStream *st, MOVStreamContext *sc)
2371 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2372 !st->codecpar->sample_rate && sc->time_scale > 1)
2373 st->codecpar->sample_rate = sc->time_scale;
2375 /* special codec parameters handling */
2376 switch (st->codecpar->codec_id) {
2377 #if CONFIG_DV_DEMUXER
2378 case AV_CODEC_ID_DVAUDIO:
2379 c->dv_fctx = avformat_alloc_context();
2381 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2382 return AVERROR(ENOMEM);
2384 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2386 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2387 return AVERROR(ENOMEM);
2389 sc->dv_audio_container = 1;
2390 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
2393 /* no ifdef since parameters are always those */
2394 case AV_CODEC_ID_QCELP:
2395 st->codecpar->channels = 1;
2396 // force sample rate for qcelp when not stored in mov
2397 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2398 st->codecpar->sample_rate = 8000;
2399 // FIXME: Why is the following needed for some files?
2400 sc->samples_per_frame = 160;
2401 if (!sc->bytes_per_frame)
2402 sc->bytes_per_frame = 35;
2404 case AV_CODEC_ID_AMR_NB:
2405 st->codecpar->channels = 1;
2406 /* force sample rate for amr, stsd in 3gp does not store sample rate */
2407 st->codecpar->sample_rate = 8000;
2409 case AV_CODEC_ID_AMR_WB:
2410 st->codecpar->channels = 1;
2411 st->codecpar->sample_rate = 16000;
2413 case AV_CODEC_ID_MP2:
2414 case AV_CODEC_ID_MP3:
2415 /* force type after stsd for m1a hdlr */
2416 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2418 case AV_CODEC_ID_GSM:
2419 case AV_CODEC_ID_ADPCM_MS:
2420 case AV_CODEC_ID_ADPCM_IMA_WAV:
2421 case AV_CODEC_ID_ILBC:
2422 case AV_CODEC_ID_MACE3:
2423 case AV_CODEC_ID_MACE6:
2424 case AV_CODEC_ID_QDM2:
2425 st->codecpar->block_align = sc->bytes_per_frame;
2427 case AV_CODEC_ID_ALAC:
2428 if (st->codecpar->extradata_size == 36) {
2429 st->codecpar->channels = AV_RB8 (st->codecpar->extradata + 21);
2430 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2433 case AV_CODEC_ID_AC3:
2434 case AV_CODEC_ID_EAC3:
2435 case AV_CODEC_ID_MPEG1VIDEO:
2436 case AV_CODEC_ID_VC1:
2437 case AV_CODEC_ID_VP8:
2438 case AV_CODEC_ID_VP9:
2439 st->need_parsing = AVSTREAM_PARSE_FULL;
2447 static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
2448 int codec_tag, int format,
2451 int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2454 (codec_tag != format &&
2455 // AVID 1:1 samples with differing data format and codec tag exist
2456 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
2457 // prores is allowed to have differing data format and codec tag
2458 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
2460 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
2461 (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id
2462 : codec_tag != MKTAG('j','p','e','g')))) {
2463 /* Multiple fourcc, we skip JPEG. This is not correct, we should
2464 * export it as a separate AVStream but this needs a few changes
2465 * in the MOV demuxer, patch welcome. */
2467 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
2468 avio_skip(pb, size);
2475 int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
2478 MOVStreamContext *sc;
2479 int pseudo_stream_id;
2481 av_assert0 (c->fc->nb_streams >= 1);
2482 st = c->fc->streams[c->fc->nb_streams-1];
2485 for (pseudo_stream_id = 0;
2486 pseudo_stream_id < entries && !pb->eof_reached;
2487 pseudo_stream_id++) {
2488 //Parsing Sample description table
2490 int ret, dref_id = 1;
2491 MOVAtom a = { AV_RL32("stsd") };
2492 int64_t start_pos = avio_tell(pb);
2493 int64_t size = avio_rb32(pb); /* size */
2494 uint32_t format = avio_rl32(pb); /* data format */
2497 avio_rb32(pb); /* reserved */
2498 avio_rb16(pb); /* reserved */
2499 dref_id = avio_rb16(pb);
2500 } else if (size <= 7) {
2501 av_log(c->fc, AV_LOG_ERROR,
2502 "invalid size %"PRId64" in stsd\n", size);
2503 return AVERROR_INVALIDDATA;
2506 if (mov_skip_multiple_stsd(c, pb, st->codecpar->codec_tag, format,
2507 size - (avio_tell(pb) - start_pos))) {
2512 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
2513 sc->dref_id= dref_id;
2514 sc->format = format;
2516 id = mov_codec_id(st, format);
2518 av_log(c->fc, AV_LOG_TRACE,
2519 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
2520 av_fourcc2str(format), st->codecpar->codec_type);
2522 st->codecpar->codec_id = id;
2523 if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) {
2524 mov_parse_stsd_video(c, pb, st, sc);
2525 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
2526 mov_parse_stsd_audio(c, pb, st, sc);
2527 if (st->codecpar->sample_rate < 0) {
2528 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
2529 return AVERROR_INVALIDDATA;
2531 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
2532 mov_parse_stsd_subtitle(c, pb, st, sc,
2533 size - (avio_tell(pb) - start_pos));
2535 ret = mov_parse_stsd_data(c, pb, st, sc,
2536 size - (avio_tell(pb) - start_pos));
2540 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
2541 a.size = size - (avio_tell(pb) - start_pos);
2543 if ((ret = mov_read_default(c, pb, a)) < 0)
2545 } else if (a.size > 0)
2546 avio_skip(pb, a.size);
2548 if (sc->extradata && st->codecpar->extradata) {
2549 int extra_size = st->codecpar->extradata_size;
2551 /* Move the current stream extradata to the stream context one. */
2552 sc->extradata_size[pseudo_stream_id] = extra_size;
2553 sc->extradata[pseudo_stream_id] = av_malloc(extra_size + AV_INPUT_BUFFER_PADDING_SIZE);
2554 if (!sc->extradata[pseudo_stream_id])
2555 return AVERROR(ENOMEM);
2556 memcpy(sc->extradata[pseudo_stream_id], st->codecpar->extradata, extra_size);
2557 av_freep(&st->codecpar->extradata);
2558 st->codecpar->extradata_size = 0;
2563 if (pb->eof_reached) {
2564 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
2571 static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2574 MOVStreamContext *sc;
2577 if (c->fc->nb_streams < 1)
2579 st = c->fc->streams[c->fc->nb_streams - 1];
2582 sc->stsd_version = avio_r8(pb);
2583 avio_rb24(pb); /* flags */
2584 entries = avio_rb32(pb);
2586 /* Each entry contains a size (4 bytes) and format (4 bytes). */
2587 if (entries <= 0 || entries > atom.size / 8) {
2588 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
2589 return AVERROR_INVALIDDATA;
2592 if (sc->extradata) {
2593 av_log(c->fc, AV_LOG_ERROR,
2594 "Duplicate stsd found in this track.\n");
2595 return AVERROR_INVALIDDATA;
2598 /* Prepare space for hosting multiple extradata. */
2599 sc->extradata = av_mallocz_array(entries, sizeof(*sc->extradata));
2601 return AVERROR(ENOMEM);
2603 sc->extradata_size = av_mallocz_array(entries, sizeof(*sc->extradata_size));
2604 if (!sc->extradata_size) {
2605 ret = AVERROR(ENOMEM);
2609 ret = ff_mov_read_stsd_entries(c, pb, entries);
2613 /* Restore back the primary extradata. */
2614 av_freep(&st->codecpar->extradata);
2615 st->codecpar->extradata_size = sc->extradata_size[0];
2616 if (sc->extradata_size[0]) {
2617 st->codecpar->extradata = av_mallocz(sc->extradata_size[0] + AV_INPUT_BUFFER_PADDING_SIZE);
2618 if (!st->codecpar->extradata)
2619 return AVERROR(ENOMEM);
2620 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
2623 return mov_finalize_stsd_codec(c, pb, st, sc);
2625 if (sc->extradata) {
2627 for (j = 0; j < sc->stsd_count; j++)
2628 av_freep(&sc->extradata[j]);
2631 av_freep(&sc->extradata);
2632 av_freep(&sc->extradata_size);
2636 static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2639 MOVStreamContext *sc;
2640 unsigned int i, entries;
2642 if (c->fc->nb_streams < 1)
2644 st = c->fc->streams[c->fc->nb_streams-1];
2647 avio_r8(pb); /* version */
2648 avio_rb24(pb); /* flags */
2650 entries = avio_rb32(pb);
2651 if ((uint64_t)entries * 12 + 4 > atom.size)
2652 return AVERROR_INVALIDDATA;
2654 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
2659 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSC atom\n");
2660 av_free(sc->stsc_data);
2662 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
2664 return AVERROR(ENOMEM);
2666 for (i = 0; i < entries && !pb->eof_reached; i++) {
2667 sc->stsc_data[i].first = avio_rb32(pb);
2668 sc->stsc_data[i].count = avio_rb32(pb);
2669 sc->stsc_data[i].id = avio_rb32(pb);
2673 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
2674 int64_t first_min = i + 1;
2675 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
2676 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
2677 sc->stsc_data[i].first < first_min ||
2678 sc->stsc_data[i].count < 1 ||
2679 sc->stsc_data[i].id < 1) {
2680 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);
2681 if (i+1 >= sc->stsc_count) {
2682 if (sc->stsc_data[i].count == 0 && i > 0) {
2686 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
2687 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
2688 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
2689 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
2690 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
2693 av_assert0(sc->stsc_data[i+1].first >= 2);
2694 // We replace this entry by the next valid
2695 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
2696 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
2697 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
2701 if (pb->eof_reached) {
2702 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
2709 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
2711 return index < count - 1;
2714 /* Compute the samples value for the stsc entry at the given index. */
2715 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
2719 if (mov_stsc_index_valid(index, sc->stsc_count))
2720 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
2722 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
2723 av_assert0(sc->stsc_data[index].first <= sc->chunk_count);
2724 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
2727 return sc->stsc_data[index].count * (int64_t)chunk_count;
2730 static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2733 MOVStreamContext *sc;
2734 unsigned i, entries;
2736 if (c->fc->nb_streams < 1)
2738 st = c->fc->streams[c->fc->nb_streams-1];
2741 avio_rb32(pb); // version + flags
2743 entries = avio_rb32(pb);
2745 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
2746 av_free(sc->stps_data);
2748 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
2750 return AVERROR(ENOMEM);
2752 for (i = 0; i < entries && !pb->eof_reached; i++) {
2753 sc->stps_data[i] = avio_rb32(pb);
2758 if (pb->eof_reached) {
2759 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
2766 static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2769 MOVStreamContext *sc;
2770 unsigned int i, entries;
2772 if (c->fc->nb_streams < 1)
2774 st = c->fc->streams[c->fc->nb_streams-1];
2777 avio_r8(pb); /* version */
2778 avio_rb24(pb); /* flags */
2780 entries = avio_rb32(pb);
2782 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
2786 sc->keyframe_absent = 1;
2787 if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
2788 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2792 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
2793 if (entries >= UINT_MAX / sizeof(int))
2794 return AVERROR_INVALIDDATA;
2795 av_freep(&sc->keyframes);
2796 sc->keyframe_count = 0;
2797 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
2799 return AVERROR(ENOMEM);
2801 for (i = 0; i < entries && !pb->eof_reached; i++) {
2802 sc->keyframes[i] = avio_rb32(pb);
2805 sc->keyframe_count = i;
2807 if (pb->eof_reached) {
2808 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
2815 static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2818 MOVStreamContext *sc;
2819 unsigned int i, entries, sample_size, field_size, num_bytes;
2824 if (c->fc->nb_streams < 1)
2826 st = c->fc->streams[c->fc->nb_streams-1];
2829 avio_r8(pb); /* version */
2830 avio_rb24(pb); /* flags */
2832 if (atom.type == MKTAG('s','t','s','z')) {
2833 sample_size = avio_rb32(pb);
2834 if (!sc->sample_size) /* do not overwrite value computed in stsd */
2835 sc->sample_size = sample_size;
2836 sc->stsz_sample_size = sample_size;
2840 avio_rb24(pb); /* reserved */
2841 field_size = avio_r8(pb);
2843 entries = avio_rb32(pb);
2845 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
2847 sc->sample_count = entries;
2851 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
2852 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
2853 return AVERROR_INVALIDDATA;
2858 if (entries >= (UINT_MAX - 4) / field_size)
2859 return AVERROR_INVALIDDATA;
2860 if (sc->sample_sizes)
2861 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
2862 av_free(sc->sample_sizes);
2863 sc->sample_count = 0;
2864 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
2865 if (!sc->sample_sizes)
2866 return AVERROR(ENOMEM);
2868 num_bytes = (entries*field_size+4)>>3;
2870 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
2872 av_freep(&sc->sample_sizes);
2873 return AVERROR(ENOMEM);
2876 ret = ffio_read_size(pb, buf, num_bytes);
2878 av_freep(&sc->sample_sizes);
2880 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
2884 init_get_bits(&gb, buf, 8*num_bytes);
2886 for (i = 0; i < entries && !pb->eof_reached; i++) {
2887 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
2888 sc->data_size += sc->sample_sizes[i];
2891 sc->sample_count = i;
2895 if (pb->eof_reached) {
2896 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSZ atom\n");
2903 static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2906 MOVStreamContext *sc;
2907 unsigned int i, entries, alloc_size = 0;
2909 int64_t total_sample_count=0;
2911 if (c->fc->nb_streams < 1)
2913 st = c->fc->streams[c->fc->nb_streams-1];
2916 avio_r8(pb); /* version */
2917 avio_rb24(pb); /* flags */
2918 entries = avio_rb32(pb);
2920 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
2921 c->fc->nb_streams-1, entries);
2924 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
2925 av_freep(&sc->stts_data);
2927 if (entries >= INT_MAX / sizeof(*sc->stts_data))
2928 return AVERROR(ENOMEM);
2930 for (i = 0; i < entries && !pb->eof_reached; i++) {
2931 int sample_duration;
2932 unsigned int sample_count;
2933 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
2934 MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
2935 min_entries * sizeof(*sc->stts_data));
2937 av_freep(&sc->stts_data);
2939 return AVERROR(ENOMEM);
2941 sc->stts_count = min_entries;
2942 sc->stts_data = stts_data;
2944 sample_count=avio_rb32(pb);
2945 sample_duration = avio_rb32(pb);
2947 sc->stts_data[i].count= sample_count;
2948 sc->stts_data[i].duration= sample_duration;
2950 av_log(c->fc, AV_LOG_TRACE, "sample_count=%d, sample_duration=%d\n",
2951 sample_count, sample_duration);
2953 duration+=(int64_t)sample_duration*(uint64_t)sample_count;
2954 total_sample_count+=sample_count;
2960 duration <= INT64_MAX - sc->duration_for_fps &&
2961 total_sample_count <= INT_MAX - sc->nb_frames_for_fps
2963 sc->duration_for_fps += duration;
2964 sc->nb_frames_for_fps += total_sample_count;
2967 if (pb->eof_reached) {
2968 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
2972 st->nb_frames= total_sample_count;
2974 st->duration= FFMIN(st->duration, duration);
2975 sc->track_end = duration;
2979 static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2982 MOVStreamContext *sc;
2985 if (c->fc->nb_streams < 1)
2987 st = c->fc->streams[c->fc->nb_streams - 1];
2990 avio_r8(pb); /* version */
2991 avio_rb24(pb); /* flags */
2992 entries = atom.size - 4;
2994 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
2995 c->fc->nb_streams - 1, entries);
2998 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
2999 av_freep(&sc->sdtp_data);
3002 sc->sdtp_data = av_mallocz(entries);
3004 return AVERROR(ENOMEM);
3006 for (i = 0; i < entries && !pb->eof_reached; i++)
3007 sc->sdtp_data[i] = avio_r8(pb);
3013 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3016 if (duration == INT_MIN) {
3017 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3020 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3024 static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3027 MOVStreamContext *sc;
3028 unsigned int i, entries, ctts_count = 0;
3030 if (c->fc->nb_streams < 1)
3032 st = c->fc->streams[c->fc->nb_streams-1];
3035 avio_r8(pb); /* version */
3036 avio_rb24(pb); /* flags */
3037 entries = avio_rb32(pb);
3039 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3043 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3044 return AVERROR_INVALIDDATA;
3045 av_freep(&sc->ctts_data);
3046 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3048 return AVERROR(ENOMEM);
3050 for (i = 0; i < entries && !pb->eof_reached; i++) {
3051 int count =avio_rb32(pb);
3052 int duration =avio_rb32(pb);
3055 av_log(c->fc, AV_LOG_TRACE,
3056 "ignoring CTTS entry with count=%d duration=%d\n",
3061 add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3064 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3067 if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3068 av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3069 av_freep(&sc->ctts_data);
3075 mov_update_dts_shift(sc, duration, c->fc);
3078 sc->ctts_count = ctts_count;
3080 if (pb->eof_reached) {
3081 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3085 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3090 static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3093 MOVStreamContext *sc;
3094 unsigned int i, entries;
3096 uint32_t grouping_type;
3098 if (c->fc->nb_streams < 1)
3100 st = c->fc->streams[c->fc->nb_streams-1];
3103 version = avio_r8(pb); /* version */
3104 avio_rb24(pb); /* flags */
3105 grouping_type = avio_rl32(pb);
3106 if (grouping_type != MKTAG( 'r','a','p',' '))
3107 return 0; /* only support 'rap ' grouping */
3109 avio_rb32(pb); /* grouping_type_parameter */
3111 entries = avio_rb32(pb);
3115 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP atom\n");
3116 av_free(sc->rap_group);
3117 sc->rap_group_count = 0;
3118 sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group));
3120 return AVERROR(ENOMEM);
3122 for (i = 0; i < entries && !pb->eof_reached; i++) {
3123 sc->rap_group[i].count = avio_rb32(pb); /* sample_count */
3124 sc->rap_group[i].index = avio_rb32(pb); /* group_description_index */
3127 sc->rap_group_count = i;
3129 if (pb->eof_reached) {
3130 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3138 * Get ith edit list entry (media time, duration).
3140 static int get_edit_list_entry(MOVContext *mov,
3141 const MOVStreamContext *msc,
3142 unsigned int edit_list_index,
3143 int64_t *edit_list_media_time,
3144 int64_t *edit_list_duration,
3145 int64_t global_timescale)
3147 if (edit_list_index == msc->elst_count) {
3150 *edit_list_media_time = msc->elst_data[edit_list_index].time;
3151 *edit_list_duration = msc->elst_data[edit_list_index].duration;
3153 /* duration is in global timescale units;convert to msc timescale */
3154 if (global_timescale == 0) {
3155 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3158 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3164 * Find the closest previous frame to the timestamp_pts, in e_old index
3165 * entries. Searching for just any frame / just key frames can be controlled by
3166 * last argument 'flag'.
3167 * Note that if ctts_data is not NULL, we will always search for a key frame
3168 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3169 * return the first frame of the video.
3171 * Here the timestamp_pts is considered to be a presentation timestamp and
3172 * the timestamp of index entries are considered to be decoding timestamps.
3174 * Returns 0 if successful in finding a frame, else returns -1.
3175 * Places the found index corresponding output arg.
3177 * If ctts_old is not NULL, then refines the searched entry by searching
3178 * backwards from the found timestamp, to find the frame with correct PTS.
3180 * Places the found ctts_index and ctts_sample in corresponding output args.
3182 static int find_prev_closest_index(AVStream *st,
3183 AVIndexEntry *e_old,
3187 int64_t timestamp_pts,
3190 int64_t* ctts_index,
3191 int64_t* ctts_sample)
3193 MOVStreamContext *msc = st->priv_data;
3194 AVIndexEntry *e_keep = st->index_entries;
3195 int nb_keep = st->nb_index_entries;
3197 int64_t index_ctts_count;
3201 // If dts_shift > 0, then all the index timestamps will have to be offset by
3202 // at least dts_shift amount to obtain PTS.
3203 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3204 if (msc->dts_shift > 0) {
3205 timestamp_pts -= msc->dts_shift;
3208 st->index_entries = e_old;
3209 st->nb_index_entries = nb_old;
3210 *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3212 // Keep going backwards in the index entries until the timestamp is the same.
3214 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3216 if ((flag & AVSEEK_FLAG_ANY) ||
3217 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3223 // If we have CTTS then refine the search, by searching backwards over PTS
3224 // computed by adding corresponding CTTS durations to index timestamps.
3225 if (ctts_data && *index >= 0) {
3226 av_assert0(ctts_index);
3227 av_assert0(ctts_sample);
3228 // Find out the ctts_index for the found frame.
3231 for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3232 if (*ctts_index < ctts_count) {
3234 if (ctts_data[*ctts_index].count == *ctts_sample) {
3241 while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3242 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3243 // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3244 // compensated by dts_shift above.
3245 if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3246 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3251 if (*ctts_sample == 0) {
3253 if (*ctts_index >= 0)
3254 *ctts_sample = ctts_data[*ctts_index].count - 1;
3261 /* restore AVStream state*/
3262 st->index_entries = e_keep;
3263 st->nb_index_entries = nb_keep;
3264 return *index >= 0 ? 0 : -1;
3268 * Add index entry with the given values, to the end of st->index_entries.
3269 * Returns the new size st->index_entries if successful, else returns -1.
3271 * This function is similar to ff_add_index_entry in libavformat/utils.c
3272 * except that here we are always unconditionally adding an index entry to
3273 * the end, instead of searching the entries list and skipping the add if
3274 * there is an existing entry with the same timestamp.
3275 * This is needed because the mov_fix_index calls this func with the same
3276 * unincremented timestamp for successive discarded frames.
3278 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3279 int size, int distance, int flags)
3281 AVIndexEntry *entries, *ie;
3283 const size_t min_size_needed = (st->nb_index_entries + 1) * sizeof(AVIndexEntry);
3285 // Double the allocation each time, to lower memory fragmentation.
3286 // Another difference from ff_add_index_entry function.
3287 const size_t requested_size =
3288 min_size_needed > st->index_entries_allocated_size ?
3289 FFMAX(min_size_needed, 2 * st->index_entries_allocated_size) :
3292 if((unsigned)st->nb_index_entries + 1 >= UINT_MAX / sizeof(AVIndexEntry))
3295 entries = av_fast_realloc(st->index_entries,
3296 &st->index_entries_allocated_size,
3301 st->index_entries= entries;
3303 index= st->nb_index_entries++;
3304 ie= &entries[index];
3307 ie->timestamp = timestamp;
3308 ie->min_distance= distance;
3315 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3316 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3318 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3319 int64_t* frame_duration_buffer,
3320 int frame_duration_buffer_size) {
3322 av_assert0(end_index >= 0 && end_index <= st->nb_index_entries);
3323 for (i = 0; i < frame_duration_buffer_size; i++) {
3324 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3325 st->index_entries[end_index - 1 - i].timestamp = end_ts;
3330 * Append a new ctts entry to ctts_data.
3331 * Returns the new ctts_count if successful, else returns -1.
3333 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3334 int count, int duration)
3336 MOVStts *ctts_buf_new;
3337 const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVStts);
3338 const size_t requested_size =
3339 min_size_needed > *allocated_size ?
3340 FFMAX(min_size_needed, 2 * (*allocated_size)) :
3343 if((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
3346 ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3351 *ctts_data = ctts_buf_new;
3353 ctts_buf_new[*ctts_count].count = count;
3354 ctts_buf_new[*ctts_count].duration = duration;
3356 *ctts_count = (*ctts_count) + 1;
3360 #define MAX_REORDER_DELAY 16
3361 static void mov_estimate_video_delay(MOVContext *c, AVStream* st) {
3362 MOVStreamContext *msc = st->priv_data;
3365 int ctts_sample = 0;
3366 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3368 int j, r, num_swaps;
3370 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3371 pts_buf[j] = INT64_MIN;
3373 if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3374 st->codecpar->codec_id == AV_CODEC_ID_H264) {
3375 st->codecpar->video_delay = 0;
3376 for(ind = 0; ind < st->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3377 // Point j to the last elem of the buffer and insert the current pts there.
3379 buf_start = (buf_start + 1);
3380 if (buf_start == MAX_REORDER_DELAY + 1)
3383 pts_buf[j] = st->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3385 // The timestamps that are already in the sorted buffer, and are greater than the
3386 // current pts, are exactly the timestamps that need to be buffered to output PTS
3387 // in correct sorted order.
3388 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3389 // can be computed as the maximum no. of swaps any particular timestamp needs to
3390 // go through, to keep this buffer in sorted order.
3392 while (j != buf_start) {
3394 if (r < 0) r = MAX_REORDER_DELAY;
3395 if (pts_buf[j] < pts_buf[r]) {
3396 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3403 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3406 if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3411 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3412 st->codecpar->video_delay, st->index);
3416 static void mov_current_sample_inc(MOVStreamContext *sc)
3418 sc->current_sample++;
3419 sc->current_index++;
3420 if (sc->index_ranges &&
3421 sc->current_index >= sc->current_index_range->end &&
3422 sc->current_index_range->end) {
3423 sc->current_index_range++;
3424 sc->current_index = sc->current_index_range->start;
3428 static void mov_current_sample_dec(MOVStreamContext *sc)
3430 sc->current_sample--;
3431 sc->current_index--;
3432 if (sc->index_ranges &&
3433 sc->current_index < sc->current_index_range->start &&
3434 sc->current_index_range > sc->index_ranges) {
3435 sc->current_index_range--;
3436 sc->current_index = sc->current_index_range->end - 1;
3440 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3444 sc->current_sample = current_sample;
3445 sc->current_index = current_sample;
3446 if (!sc->index_ranges) {
3450 for (sc->current_index_range = sc->index_ranges;
3451 sc->current_index_range->end;
3452 sc->current_index_range++) {
3453 range_size = sc->current_index_range->end - sc->current_index_range->start;
3454 if (range_size > current_sample) {
3455 sc->current_index = sc->current_index_range->start + current_sample;
3458 current_sample -= range_size;
3463 * Fix st->index_entries, so that it contains only the entries (and the entries
3464 * which are needed to decode them) that fall in the edit list time ranges.
3465 * Also fixes the timestamps of the index entries to match the timeline
3466 * specified the edit lists.
3468 static void mov_fix_index(MOVContext *mov, AVStream *st)
3470 MOVStreamContext *msc = st->priv_data;
3471 AVIndexEntry *e_old = st->index_entries;
3472 int nb_old = st->nb_index_entries;
3473 const AVIndexEntry *e_old_end = e_old + nb_old;
3474 const AVIndexEntry *current = NULL;
3475 MOVStts *ctts_data_old = msc->ctts_data;
3476 int64_t ctts_index_old = 0;
3477 int64_t ctts_sample_old = 0;
3478 int64_t ctts_count_old = msc->ctts_count;
3479 int64_t edit_list_media_time = 0;
3480 int64_t edit_list_duration = 0;
3481 int64_t frame_duration = 0;
3482 int64_t edit_list_dts_counter = 0;
3483 int64_t edit_list_dts_entry_end = 0;
3484 int64_t edit_list_start_ctts_sample = 0;
3486 int64_t curr_ctts = 0;
3487 int64_t empty_edits_sum_duration = 0;
3488 int64_t edit_list_index = 0;
3491 int64_t start_dts = 0;
3492 int64_t edit_list_start_encountered = 0;
3493 int64_t search_timestamp = 0;
3494 int64_t* frame_duration_buffer = NULL;
3495 int num_discarded_begin = 0;
3496 int first_non_zero_audio_edit = -1;
3497 int packet_skip_samples = 0;
3498 MOVIndexRange *current_index_range;
3500 int found_keyframe_after_edit = 0;
3501 int found_non_empty_edit = 0;
3503 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
3507 // allocate the index ranges array
3508 msc->index_ranges = av_malloc((msc->elst_count + 1) * sizeof(msc->index_ranges[0]));
3509 if (!msc->index_ranges) {
3510 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
3513 msc->current_index_range = msc->index_ranges;
3514 current_index_range = msc->index_ranges - 1;
3516 // Clean AVStream from traces of old index
3517 st->index_entries = NULL;
3518 st->index_entries_allocated_size = 0;
3519 st->nb_index_entries = 0;
3521 // Clean ctts fields of MOVStreamContext
3522 msc->ctts_data = NULL;
3523 msc->ctts_count = 0;
3524 msc->ctts_index = 0;
3525 msc->ctts_sample = 0;
3526 msc->ctts_allocated_size = 0;
3528 // Reinitialize min_corrected_pts so that it can be computed again.
3529 msc->min_corrected_pts = -1;
3531 // If the dts_shift is positive (in case of negative ctts values in mov),
3532 // then negate the DTS by dts_shift
3533 if (msc->dts_shift > 0) {
3534 edit_list_dts_entry_end -= msc->dts_shift;
3535 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
3538 start_dts = edit_list_dts_entry_end;
3540 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
3541 &edit_list_duration, mov->time_scale)) {
3542 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
3543 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
3545 edit_list_dts_counter = edit_list_dts_entry_end;
3546 edit_list_dts_entry_end += edit_list_duration;
3547 num_discarded_begin = 0;
3548 if (!found_non_empty_edit && edit_list_media_time == -1) {
3549 empty_edits_sum_duration += edit_list_duration;
3552 found_non_empty_edit = 1;
3554 // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
3555 // according to the edit list below.
3556 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3557 if (first_non_zero_audio_edit < 0) {
3558 first_non_zero_audio_edit = 1;
3560 first_non_zero_audio_edit = 0;
3563 if (first_non_zero_audio_edit > 0)
3564 st->skip_samples = msc->start_pad = 0;
3567 // While reordering frame index according to edit list we must handle properly
3568 // the scenario when edit list entry starts from none key frame.
3569 // We find closest previous key frame and preserve it and consequent frames in index.
3570 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
3571 search_timestamp = edit_list_media_time;
3572 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3573 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
3574 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
3575 // edit_list_media_time to cover the decoder delay.
3576 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
3579 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
3580 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3581 av_log(mov->fc, AV_LOG_WARNING,
3582 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
3583 st->index, edit_list_index, search_timestamp);
3584 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
3585 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3586 av_log(mov->fc, AV_LOG_WARNING,
3587 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
3588 st->index, edit_list_index, search_timestamp);
3591 ctts_sample_old = 0;
3594 current = e_old + index;
3595 edit_list_start_ctts_sample = ctts_sample_old;
3597 // Iterate over index and arrange it according to edit list
3598 edit_list_start_encountered = 0;
3599 found_keyframe_after_edit = 0;
3600 for (; current < e_old_end; current++, index++) {
3601 // check if frame outside edit list mark it for discard
3602 frame_duration = (current + 1 < e_old_end) ?
3603 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
3605 flags = current->flags;
3607 // frames (pts) before or after edit list
3608 curr_cts = current->timestamp + msc->dts_shift;
3611 if (ctts_data_old && ctts_index_old < ctts_count_old) {
3612 curr_ctts = ctts_data_old[ctts_index_old].duration;
3613 av_log(mov->fc, AV_LOG_DEBUG, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
3614 curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
3615 curr_cts += curr_ctts;
3617 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
3618 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3619 &msc->ctts_allocated_size,
3620 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3621 ctts_data_old[ctts_index_old].duration) == -1) {
3622 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3624 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3625 ctts_data_old[ctts_index_old].duration);
3629 ctts_sample_old = 0;
3630 edit_list_start_ctts_sample = 0;
3634 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
3635 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
3636 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
3637 first_non_zero_audio_edit > 0) {
3638 packet_skip_samples = edit_list_media_time - curr_cts;
3639 st->skip_samples += packet_skip_samples;
3641 // Shift the index entry timestamp by packet_skip_samples to be correct.
3642 edit_list_dts_counter -= packet_skip_samples;
3643 if (edit_list_start_encountered == 0) {
3644 edit_list_start_encountered = 1;
3645 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
3646 // discarded packets.
3647 if (frame_duration_buffer) {
3648 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3649 frame_duration_buffer, num_discarded_begin);
3650 av_freep(&frame_duration_buffer);
3654 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
3656 flags |= AVINDEX_DISCARD_FRAME;
3657 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
3659 if (edit_list_start_encountered == 0) {
3660 num_discarded_begin++;
3661 frame_duration_buffer = av_realloc(frame_duration_buffer,
3662 num_discarded_begin * sizeof(int64_t));
3663 if (!frame_duration_buffer) {
3664 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
3667 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
3669 // Increment skip_samples for the first non-zero audio edit list
3670 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3671 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
3672 st->skip_samples += frame_duration;
3677 if (msc->min_corrected_pts < 0) {
3678 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
3680 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
3682 if (edit_list_start_encountered == 0) {
3683 edit_list_start_encountered = 1;
3684 // Make timestamps strictly monotonically increasing by rewriting timestamps for
3685 // discarded packets.
3686 if (frame_duration_buffer) {
3687 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3688 frame_duration_buffer, num_discarded_begin);
3689 av_freep(&frame_duration_buffer);
3694 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
3695 current->min_distance, flags) == -1) {
3696 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
3700 // Update the index ranges array
3701 if (current_index_range < msc->index_ranges || index != current_index_range->end) {
3702 current_index_range++;
3703 current_index_range->start = index;
3705 current_index_range->end = index + 1;
3707 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
3708 if (edit_list_start_encountered > 0) {
3709 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
3712 // Break when found first key frame after edit entry completion
3713 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
3714 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
3715 if (ctts_data_old) {
3716 // If we have CTTS and this is the first keyframe after edit elist,
3717 // wait for one more, because there might be trailing B-frames after this I-frame
3718 // that do belong to the edit.
3719 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
3720 found_keyframe_after_edit = 1;
3723 if (ctts_sample_old != 0) {
3724 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3725 &msc->ctts_allocated_size,
3726 ctts_sample_old - edit_list_start_ctts_sample,
3727 ctts_data_old[ctts_index_old].duration) == -1) {
3728 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3729 ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
3730 ctts_data_old[ctts_index_old].duration);
3739 // If there are empty edits, then msc->min_corrected_pts might be positive
3740 // intentionally. So we subtract the sum duration of emtpy edits here.
3741 msc->min_corrected_pts -= empty_edits_sum_duration;
3743 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
3744 // dts by that amount to make the first pts zero.
3745 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
3746 if (msc->min_corrected_pts > 0) {
3747 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
3748 for (i = 0; i < st->nb_index_entries; ++i) {
3749 st->index_entries[i].timestamp -= msc->min_corrected_pts;
3753 // Start time should be equal to zero or the duration of any empty edits.
3754 st->start_time = empty_edits_sum_duration;
3756 // Update av stream length, if it ends up shorter than the track's media duration
3757 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
3758 msc->start_pad = st->skip_samples;
3760 // Free the old index and the old CTTS structures
3762 av_free(ctts_data_old);
3763 av_freep(&frame_duration_buffer);
3765 // Null terminate the index ranges array
3766 current_index_range++;
3767 current_index_range->start = 0;
3768 current_index_range->end = 0;
3769 msc->current_index = msc->index_ranges[0].start;
3772 static void mov_build_index(MOVContext *mov, AVStream *st)
3774 MOVStreamContext *sc = st->priv_data;
3775 int64_t current_offset;
3776 int64_t current_dts = 0;
3777 unsigned int stts_index = 0;
3778 unsigned int stsc_index = 0;
3779 unsigned int stss_index = 0;
3780 unsigned int stps_index = 0;
3782 uint64_t stream_size = 0;
3783 MOVStts *ctts_data_old = sc->ctts_data;
3784 unsigned int ctts_count_old = sc->ctts_count;
3786 if (sc->elst_count) {
3787 int i, edit_start_index = 0, multiple_edits = 0;
3788 int64_t empty_duration = 0; // empty duration of the first edit list entry
3789 int64_t start_time = 0; // start time of the media
3791 for (i = 0; i < sc->elst_count; i++) {
3792 const MOVElst *e = &sc->elst_data[i];
3793 if (i == 0 && e->time == -1) {
3794 /* if empty, the first entry is the start time of the stream
3795 * relative to the presentation itself */
3796 empty_duration = e->duration;
3797 edit_start_index = 1;
3798 } else if (i == edit_start_index && e->time >= 0) {
3799 start_time = e->time;
3805 if (multiple_edits && !mov->advanced_editlist)
3806 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
3807 "Use -advanced_editlist to correctly decode otherwise "
3808 "a/v desync might occur\n");
3810 /* adjust first dts according to edit list */
3811 if ((empty_duration || start_time) && mov->time_scale > 0) {
3813 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
3814 sc->time_offset = start_time - empty_duration;
3815 sc->min_corrected_pts = start_time;
3816 if (!mov->advanced_editlist)
3817 current_dts = -sc->time_offset;
3820 if (!multiple_edits && !mov->advanced_editlist &&
3821 st->codecpar->codec_id == AV_CODEC_ID_AAC && start_time > 0)
3822 sc->start_pad = start_time;
3825 /* only use old uncompressed audio chunk demuxing when stts specifies it */
3826 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3827 sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
3828 unsigned int current_sample = 0;
3829 unsigned int stts_sample = 0;
3830 unsigned int sample_size;
3831 unsigned int distance = 0;
3832 unsigned int rap_group_index = 0;
3833 unsigned int rap_group_sample = 0;
3834 int64_t last_dts = 0;
3835 int64_t dts_correction = 0;
3836 int rap_group_present = sc->rap_group_count && sc->rap_group;
3837 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
3839 current_dts -= sc->dts_shift;
3840 last_dts = current_dts;
3842 if (!sc->sample_count || st->nb_index_entries)
3844 if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
3846 if (av_reallocp_array(&st->index_entries,
3847 st->nb_index_entries + sc->sample_count,
3848 sizeof(*st->index_entries)) < 0) {
3849 st->nb_index_entries = 0;
3852 st->index_entries_allocated_size = (st->nb_index_entries + sc->sample_count) * sizeof(*st->index_entries);
3854 if (ctts_data_old) {
3855 // Expand ctts entries such that we have a 1-1 mapping with samples
3856 if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
3859 sc->ctts_allocated_size = 0;
3860 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size,
3861 sc->sample_count * sizeof(*sc->ctts_data));
3862 if (!sc->ctts_data) {
3863 av_free(ctts_data_old);
3867 memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
3869 for (i = 0; i < ctts_count_old &&
3870 sc->ctts_count < sc->sample_count; i++)
3871 for (j = 0; j < ctts_data_old[i].count &&
3872 sc->ctts_count < sc->sample_count; j++)
3873 add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
3874 &sc->ctts_allocated_size, 1,
3875 ctts_data_old[i].duration);
3876 av_free(ctts_data_old);
3879 for (i = 0; i < sc->chunk_count; i++) {
3880 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
3881 current_offset = sc->chunk_offsets[i];
3882 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3883 i + 1 == sc->stsc_data[stsc_index + 1].first)
3886 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
3887 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
3888 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
3889 sc->stsz_sample_size = sc->sample_size;
3891 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
3892 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
3893 sc->stsz_sample_size = sc->sample_size;
3896 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
3898 if (current_sample >= sc->sample_count) {
3899 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
3903 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
3905 if (stss_index + 1 < sc->keyframe_count)
3907 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
3909 if (stps_index + 1 < sc->stps_count)
3912 if (rap_group_present && rap_group_index < sc->rap_group_count) {
3913 if (sc->rap_group[rap_group_index].index > 0)
3915 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
3916 rap_group_sample = 0;
3920 if (sc->keyframe_absent
3922 && !rap_group_present
3923 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
3927 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
3928 if (sc->pseudo_stream_id == -1 ||
3929 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
3931 if (sample_size > 0x3FFFFFFF) {
3932 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
3935 e = &st->index_entries[st->nb_index_entries++];
3936 e->pos = current_offset;
3937 e->timestamp = current_dts;
3938 e->size = sample_size;
3939 e->min_distance = distance;
3940 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
3941 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
3942 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
3943 current_offset, current_dts, sample_size, distance, keyframe);
3944 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries < 100)
3945 ff_rfps_add_frame(mov->fc, st, current_dts);
3948 current_offset += sample_size;
3949 stream_size += sample_size;
3951 /* A negative sample duration is invalid based on the spec,
3952 * but some samples need it to correct the DTS. */
3953 if (sc->stts_data[stts_index].duration < 0) {
3954 av_log(mov->fc, AV_LOG_WARNING,
3955 "Invalid SampleDelta %d in STTS, at %d st:%d\n",
3956 sc->stts_data[stts_index].duration, stts_index,
3958 dts_correction += sc->stts_data[stts_index].duration - 1;
3959 sc->stts_data[stts_index].duration = 1;
3961 current_dts += sc->stts_data[stts_index].duration;
3962 if (!dts_correction || current_dts + dts_correction > last_dts) {
3963 current_dts += dts_correction;
3966 /* Avoid creating non-monotonous DTS */
3967 dts_correction += current_dts - last_dts - 1;
3968 current_dts = last_dts + 1;
3970 last_dts = current_dts;
3974 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
3980 if (st->duration > 0)
3981 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
3983 unsigned chunk_samples, total = 0;
3985 if (!sc->chunk_count)
3988 // compute total chunk count
3989 for (i = 0; i < sc->stsc_count; i++) {
3990 unsigned count, chunk_count;
3992 chunk_samples = sc->stsc_data[i].count;
3993 if (i != sc->stsc_count - 1 &&
3994 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
3995 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
3999 if (sc->samples_per_frame >= 160) { // gsm
4000 count = chunk_samples / sc->samples_per_frame;
4001 } else if (sc->samples_per_frame > 1) {
4002 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4003 count = (chunk_samples+samples-1) / samples;
4005 count = (chunk_samples+1023) / 1024;
4008 if (mov_stsc_index_valid(i, sc->stsc_count))
4009 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4011 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4012 total += chunk_count * count;
4015 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4016 if (total >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
4018 if (av_reallocp_array(&st->index_entries,
4019 st->nb_index_entries + total,
4020 sizeof(*st->index_entries)) < 0) {
4021 st->nb_index_entries = 0;
4024 st->index_entries_allocated_size = (st->nb_index_entries + total) * sizeof(*st->index_entries);
4027 for (i = 0; i < sc->chunk_count; i++) {
4028 current_offset = sc->chunk_offsets[i];
4029 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4030 i + 1 == sc->stsc_data[stsc_index + 1].first)
4032 chunk_samples = sc->stsc_data[stsc_index].count;
4034 while (chunk_samples > 0) {
4036 unsigned size, samples;
4038 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4039 avpriv_request_sample(mov->fc,
4040 "Zero bytes per frame, but %d samples per frame",
4041 sc->samples_per_frame);
4045 if (sc->samples_per_frame >= 160) { // gsm
4046 samples = sc->samples_per_frame;
4047 size = sc->bytes_per_frame;
4049 if (sc->samples_per_frame > 1) {
4050 samples = FFMIN((1024 / sc->samples_per_frame)*
4051 sc->samples_per_frame, chunk_samples);
4052 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
4054 samples = FFMIN(1024, chunk_samples);
4055 size = samples * sc->sample_size;
4059 if (st->nb_index_entries >= total) {
4060 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4063 if (size > 0x3FFFFFFF) {
4064 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4067 e = &st->index_entries[st->nb_index_entries++];
4068 e->pos = current_offset;
4069 e->timestamp = current_dts;
4071 e->min_distance = 0;
4072 e->flags = AVINDEX_KEYFRAME;
4073 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4074 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4077 current_offset += size;
4078 current_dts += samples;
4079 chunk_samples -= samples;
4084 if (!mov->ignore_editlist && mov->advanced_editlist) {
4085 // Fix index according to edit lists.
4086 mov_fix_index(mov, st);
4089 // Update start time of the stream.
4090 if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries > 0) {
4091 st->start_time = st->index_entries[0].timestamp + sc->dts_shift;
4092 if (sc->ctts_data) {
4093 st->start_time += sc->ctts_data[0].duration;
4097 mov_estimate_video_delay(mov, st);
4100 static int test_same_origin(const char *src, const char *ref) {
4110 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4111 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4113 if (strlen(src) == 0) {
4115 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4116 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4117 strlen(src_host) + 1 >= sizeof(src_host) ||
4118 strlen(ref_host) + 1 >= sizeof(ref_host)) {
4120 } else if (strcmp(src_proto, ref_proto) ||
4121 strcmp(src_auth, ref_auth) ||
4122 strcmp(src_host, ref_host) ||
4123 src_port != ref_port) {
4129 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4131 /* try relative path, we do not try the absolute because it can leak information about our
4132 system to an attacker */
4133 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4134 char filename[1025];
4135 const char *src_path;
4138 /* find a source dir */
4139 src_path = strrchr(src, '/');
4145 /* find a next level down to target */
4146 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4147 if (ref->path[l] == '/') {
4148 if (i == ref->nlvl_to - 1)
4154 /* compose filename if next level down to target was found */
4155 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4156 memcpy(filename, src, src_path - src);
4157 filename[src_path - src] = 0;
4159 for (i = 1; i < ref->nlvl_from; i++)
4160 av_strlcat(filename, "../", sizeof(filename));
4162 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4163 if (!c->use_absolute_path) {
4164 int same_origin = test_same_origin(src, filename);
4167 av_log(c->fc, AV_LOG_ERROR,
4168 "Reference with mismatching origin, %s not tried for security reasons, "
4169 "set demuxer option use_absolute_path to allow it anyway\n",
4171 return AVERROR(ENOENT);
4174 if(strstr(ref->path + l + 1, "..") ||
4175 strstr(ref->path + l + 1, ":") ||
4176 (ref->nlvl_from > 1 && same_origin < 0) ||
4177 (filename[0] == '/' && src_path == src))
4178 return AVERROR(ENOENT);
4181 if (strlen(filename) + 1 == sizeof(filename))
4182 return AVERROR(ENOENT);
4183 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4186 } else if (c->use_absolute_path) {
4187 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4188 "this is a possible security issue\n");
4189 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4192 av_log(c->fc, AV_LOG_ERROR,
4193 "Absolute path %s not tried for security reasons, "
4194 "set demuxer option use_absolute_path to allow absolute paths\n",
4198 return AVERROR(ENOENT);
4201 static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
4203 if (sc->time_scale <= 0) {
4204 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4205 sc->time_scale = c->time_scale;
4206 if (sc->time_scale <= 0)
4211 static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4214 MOVStreamContext *sc;
4217 st = avformat_new_stream(c->fc, NULL);
4218 if (!st) return AVERROR(ENOMEM);
4220 sc = av_mallocz(sizeof(MOVStreamContext));
4221 if (!sc) return AVERROR(ENOMEM);
4224 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
4225 sc->ffindex = st->index;
4226 c->trak_index = st->index;
4228 if ((ret = mov_read_default(c, pb, atom)) < 0)
4233 // Here stsc refers to a chunk not described in stco. This is technically invalid,
4234 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4235 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4237 av_freep(&sc->stsc_data);
4241 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4242 (!sc->sample_size && !sc->sample_count))) ||
4243 (!sc->chunk_count && sc->sample_count)) {
4244 av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4248 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4249 av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4251 return AVERROR_INVALIDDATA;
4254 fix_timescale(c, sc);
4256 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4258 mov_build_index(c, st);
4260 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4261 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4262 if (c->enable_drefs) {
4263 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4264 av_log(c->fc, AV_LOG_ERROR,
4265 "stream %d, error opening alias: path='%s', dir='%s', "
4266 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4267 st->index, dref->path, dref->dir, dref->filename,
4268 dref->volume, dref->nlvl_from, dref->nlvl_to);
4270 av_log(c->fc, AV_LOG_WARNING,
4271 "Skipped opening external track: "
4272 "stream %d, alias: path='%s', dir='%s', "
4273 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4274 "Set enable_drefs to allow this.\n",
4275 st->index, dref->path, dref->dir, dref->filename,
4276 dref->volume, dref->nlvl_from, dref->nlvl_to);
4280 sc->pb_is_copied = 1;
4283 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4284 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4285 sc->height && sc->width &&
4286 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4287 st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4288 ((double)st->codecpar->width * sc->height), INT_MAX);
4291 #if FF_API_R_FRAME_RATE
4292 if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4293 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
4294 sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4298 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4299 if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4300 TAG_IS_AVCI(st->codecpar->codec_tag)) {
4301 ret = ff_generate_avci_extradata(st);
4306 switch (st->codecpar->codec_id) {
4307 #if CONFIG_H261_DECODER
4308 case AV_CODEC_ID_H261:
4310 #if CONFIG_H263_DECODER
4311 case AV_CODEC_ID_H263:
4313 #if CONFIG_MPEG4_DECODER
4314 case AV_CODEC_ID_MPEG4:
4316 st->codecpar->width = 0; /* let decoder init width/height */
4317 st->codecpar->height= 0;
4321 // If the duration of the mp3 packets is not constant, then they could need a parser
4322 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4323 && sc->stts_count > 3
4324 && sc->stts_count*10 > st->nb_frames
4325 && sc->time_scale == st->codecpar->sample_rate) {
4326 st->need_parsing = AVSTREAM_PARSE_FULL;
4328 /* Do not need those anymore. */
4329 av_freep(&sc->chunk_offsets);
4330 av_freep(&sc->sample_sizes);
4331 av_freep(&sc->keyframes);
4332 av_freep(&sc->stts_data);
4333 av_freep(&sc->stps_data);
4334 av_freep(&sc->elst_data);
4335 av_freep(&sc->rap_group);
4340 static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4343 c->itunes_metadata = 1;
4344 ret = mov_read_default(c, pb, atom);
4345 c->itunes_metadata = 0;
4349 static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4358 count = avio_rb32(pb);
4359 if (count > UINT_MAX / sizeof(*c->meta_keys) - 1) {
4360 av_log(c->fc, AV_LOG_ERROR,
4361 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
4362 return AVERROR_INVALIDDATA;
4365 c->meta_keys_count = count + 1;
4366 c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
4368 return AVERROR(ENOMEM);
4370 for (i = 1; i <= count; ++i) {
4371 uint32_t key_size = avio_rb32(pb);
4372 uint32_t type = avio_rl32(pb);
4374 av_log(c->fc, AV_LOG_ERROR,
4375 "The key# %"PRIu32" in meta has invalid size:"
4376 "%"PRIu32"\n", i, key_size);
4377 return AVERROR_INVALIDDATA;
4380 if (type != MKTAG('m','d','t','a')) {
4381 avio_skip(pb, key_size);
4383 c->meta_keys[i] = av_mallocz(key_size + 1);
4384 if (!c->meta_keys[i])
4385 return AVERROR(ENOMEM);
4386 avio_read(pb, c->meta_keys[i], key_size);
4392 static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4394 int64_t end = avio_tell(pb) + atom.size;
4395 uint8_t *key = NULL, *val = NULL, *mean = NULL;
4399 MOVStreamContext *sc;
4401 if (c->fc->nb_streams < 1)
4403 st = c->fc->streams[c->fc->nb_streams-1];
4406 for (i = 0; i < 3; i++) {
4410 if (end - avio_tell(pb) <= 12)
4413 len = avio_rb32(pb);
4414 tag = avio_rl32(pb);
4415 avio_skip(pb, 4); // flags
4417 if (len < 12 || len - 12 > end - avio_tell(pb))
4421 if (tag == MKTAG('m', 'e', 'a', 'n'))
4423 else if (tag == MKTAG('n', 'a', 'm', 'e'))
4425 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
4432 *p = av_malloc(len + 1);
4434 ret = AVERROR(ENOMEM);
4437 ret = ffio_read_size(pb, *p, len);
4445 if (mean && key && val) {
4446 if (strcmp(key, "iTunSMPB") == 0) {
4447 int priming, remainder, samples;
4448 if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
4449 if(priming>0 && priming<16384)
4450 sc->start_pad = priming;
4453 if (strcmp(key, "cdec") != 0) {
4454 av_dict_set(&c->fc->metadata, key, val,
4455 AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
4459 av_log(c->fc, AV_LOG_VERBOSE,
4460 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
4463 avio_seek(pb, end, SEEK_SET);
4470 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4472 while (atom.size > 8) {
4476 tag = avio_rl32(pb);
4478 if (tag == MKTAG('h','d','l','r')) {
4479 avio_seek(pb, -8, SEEK_CUR);
4481 return mov_read_default(c, pb, atom);
4487 // return 1 when matrix is identity, 0 otherwise
4488 #define IS_MATRIX_IDENT(matrix) \
4489 ( (matrix)[0][0] == (1 << 16) && \
4490 (matrix)[1][1] == (1 << 16) && \
4491 (matrix)[2][2] == (1 << 30) && \
4492 !(matrix)[0][1] && !(matrix)[0][2] && \
4493 !(matrix)[1][0] && !(matrix)[1][2] && \
4494 !(matrix)[2][0] && !(matrix)[2][1])
4496 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4501 int display_matrix[3][3];
4502 int res_display_matrix[3][3] = { { 0 } };
4504 MOVStreamContext *sc;
4508 if (c->fc->nb_streams < 1)
4510 st = c->fc->streams[c->fc->nb_streams-1];
4513 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4514 // avoids corrupting AVStreams mapped to an earlier tkhd.
4516 return AVERROR_INVALIDDATA;
4518 version = avio_r8(pb);
4519 flags = avio_rb24(pb);
4520 st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
4526 avio_rb32(pb); /* creation time */
4527 avio_rb32(pb); /* modification time */
4529 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4530 avio_rb32(pb); /* reserved */
4532 /* highlevel (considering edits) duration in movie timebase */
4533 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4534 avio_rb32(pb); /* reserved */
4535 avio_rb32(pb); /* reserved */
4537 avio_rb16(pb); /* layer */
4538 avio_rb16(pb); /* alternate group */
4539 avio_rb16(pb); /* volume */
4540 avio_rb16(pb); /* reserved */
4542 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4543 // they're kept in fixed point format through all calculations
4544 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4545 // side data, but the scale factor is not needed to calculate aspect ratio
4546 for (i = 0; i < 3; i++) {
4547 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
4548 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
4549 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
4552 width = avio_rb32(pb); // 16.16 fixed point track width
4553 height = avio_rb32(pb); // 16.16 fixed point track height
4554 sc->width = width >> 16;
4555 sc->height = height >> 16;
4557 // apply the moov display matrix (after the tkhd one)
4558 for (i = 0; i < 3; i++) {
4559 const int sh[3] = { 16, 16, 30 };
4560 for (j = 0; j < 3; j++) {
4561 for (e = 0; e < 3; e++) {
4562 res_display_matrix[i][j] +=
4563 ((int64_t) display_matrix[i][e] *
4564 c->movie_display_matrix[e][j]) >> sh[e];
4569 // save the matrix when it is not the default identity
4570 if (!IS_MATRIX_IDENT(res_display_matrix)) {
4573 av_freep(&sc->display_matrix);
4574 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4575 if (!sc->display_matrix)
4576 return AVERROR(ENOMEM);
4578 for (i = 0; i < 3; i++)
4579 for (j = 0; j < 3; j++)
4580 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4582 #if FF_API_OLD_ROTATE_API
4583 rotate = av_display_rotation_get(sc->display_matrix);
4584 if (!isnan(rotate)) {
4585 char rotate_buf[64];
4587 if (rotate < 0) // for backward compatibility
4589 snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate);
4590 av_dict_set(&st->metadata, "rotate", rotate_buf, 0);
4595 // transform the display width/height according to the matrix
4596 // to keep the same scale, use [width height 1<<16]
4597 if (width && height && sc->display_matrix) {
4598 double disp_transform[2];
4600 for (i = 0; i < 2; i++)
4601 disp_transform[i] = hypot(sc->display_matrix[0 + i],
4602 sc->display_matrix[3 + i]);
4604 if (disp_transform[0] > 0 && disp_transform[1] > 0 &&
4605 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4606 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4607 st->sample_aspect_ratio = av_d2q(
4608 disp_transform[0] / disp_transform[1],
4614 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4616 MOVFragment *frag = &c->fragment;
4617 MOVTrackExt *trex = NULL;
4618 int flags, track_id, i;
4619 MOVFragmentStreamInfo * frag_stream_info;
4621 avio_r8(pb); /* version */
4622 flags = avio_rb24(pb);
4624 track_id = avio_rb32(pb);
4626 return AVERROR_INVALIDDATA;
4627 for (i = 0; i < c->trex_count; i++)
4628 if (c->trex_data[i].track_id == track_id) {
4629 trex = &c->trex_data[i];
4633 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4636 c->fragment.found_tfhd = 1;
4637 frag->track_id = track_id;
4638 set_frag_stream(&c->frag_index, track_id);
4640 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4641 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4642 frag->moof_offset : frag->implicit_offset;
4643 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4645 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4646 avio_rb32(pb) : trex->duration;
4647 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4648 avio_rb32(pb) : trex->size;
4649 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4650 avio_rb32(pb) : trex->flags;
4651 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4653 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4654 if (frag_stream_info)
4655 frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
4660 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4665 num = atom.size / 4;
4666 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4667 return AVERROR(ENOMEM);
4669 av_free(c->chapter_tracks);
4670 c->chapter_tracks = new_tracks;
4671 c->nb_chapter_tracks = num;
4673 for (i = 0; i < num && !pb->eof_reached; i++)
4674 c->chapter_tracks[i] = avio_rb32(pb);
4679 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4684 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4685 return AVERROR_INVALIDDATA;
4686 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4687 sizeof(*c->trex_data))) < 0) {
4692 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4694 trex = &c->trex_data[c->trex_count++];
4695 avio_r8(pb); /* version */
4696 avio_rb24(pb); /* flags */
4697 trex->track_id = avio_rb32(pb);
4698 trex->stsd_id = avio_rb32(pb);
4699 trex->duration = avio_rb32(pb);
4700 trex->size = avio_rb32(pb);
4701 trex->flags = avio_rb32(pb);
4705 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4707 MOVFragment *frag = &c->fragment;
4708 AVStream *st = NULL;
4709 MOVStreamContext *sc;
4711 MOVFragmentStreamInfo * frag_stream_info;
4712 int64_t base_media_decode_time;
4714 for (i = 0; i < c->fc->nb_streams; i++) {
4715 if (c->fc->streams[i]->id == frag->track_id) {
4716 st = c->fc->streams[i];
4721 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4725 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4727 version = avio_r8(pb);
4728 avio_rb24(pb); /* flags */
4730 base_media_decode_time = avio_rb64(pb);
4732 base_media_decode_time = avio_rb32(pb);
4735 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4736 if (frag_stream_info)
4737 frag_stream_info->tfdt_dts = base_media_decode_time;
4738 sc->track_end = base_media_decode_time;
4743 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4745 MOVFragment *frag = &c->fragment;
4746 AVStream *st = NULL;
4747 MOVStreamContext *sc;
4750 int64_t dts, pts = AV_NOPTS_VALUE;
4751 int data_offset = 0;
4752 unsigned entries, first_sample_flags = frag->flags;
4753 int flags, distance, i;
4754 int64_t prev_dts = AV_NOPTS_VALUE;
4755 int next_frag_index = -1, index_entry_pos;
4756 size_t requested_size;
4757 size_t old_ctts_allocated_size;
4758 AVIndexEntry *new_entries;
4759 MOVFragmentStreamInfo * frag_stream_info;
4761 if (!frag->found_tfhd) {
4762 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4763 return AVERROR_INVALIDDATA;
4766 for (i = 0; i < c->fc->nb_streams; i++) {
4767 if (c->fc->streams[i]->id == frag->track_id) {
4768 st = c->fc->streams[i];
4773 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4777 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4780 // Find the next frag_index index that has a valid index_entry for
4781 // the current track_id.
4783 // A valid index_entry means the trun for the fragment was read
4784 // and it's samples are in index_entries at the given position.
4785 // New index entries will be inserted before the index_entry found.
4786 index_entry_pos = st->nb_index_entries;
4787 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4788 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4789 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4790 next_frag_index = i;
4791 index_entry_pos = frag_stream_info->index_entry;
4795 av_assert0(index_entry_pos <= st->nb_index_entries);
4797 avio_r8(pb); /* version */
4798 flags = avio_rb24(pb);
4799 entries = avio_rb32(pb);
4800 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4802 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4803 return AVERROR_INVALIDDATA;
4804 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4805 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4807 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4808 if (frag_stream_info)
4810 if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
4811 dts = frag_stream_info->next_trun_dts - sc->time_offset;
4812 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4813 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4814 pts = frag_stream_info->first_tfra_pts;
4815 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4816 ", using it for pts\n", pts);
4817 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4818 c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
4819 dts = frag_stream_info->first_tfra_pts;
4820 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4821 ", using it for dts\n", pts);
4822 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4823 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4824 // pts = frag_stream_info->sidx_pts;
4825 dts = frag_stream_info->sidx_pts - sc->time_offset;
4826 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4827 ", using it for pts\n", pts);
4828 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4829 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4830 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4831 ", using it for dts\n", dts);
4833 dts = sc->track_end - sc->time_offset;
4834 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4835 ", using it for dts\n", dts);
4838 dts = sc->track_end - sc->time_offset;
4839 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4840 ", using it for dts\n", dts);
4842 offset = frag->base_data_offset + data_offset;
4844 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4846 // realloc space for new index entries
4847 if((uint64_t)st->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4848 entries = UINT_MAX / sizeof(AVIndexEntry) - st->nb_index_entries;
4849 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4854 requested_size = (st->nb_index_entries + entries) * sizeof(AVIndexEntry);
4855 new_entries = av_fast_realloc(st->index_entries,
4856 &st->index_entries_allocated_size,
4859 return AVERROR(ENOMEM);
4860 st->index_entries= new_entries;
4862 requested_size = (st->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4863 old_ctts_allocated_size = sc->ctts_allocated_size;
4864 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4867 return AVERROR(ENOMEM);
4868 sc->ctts_data = ctts_data;
4870 // In case there were samples without ctts entries, ensure they get
4871 // zero valued entries. This ensures clips which mix boxes with and
4872 // without ctts entries don't pickup uninitialized data.
4873 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4874 sc->ctts_allocated_size - old_ctts_allocated_size);
4876 if (index_entry_pos < st->nb_index_entries) {
4877 // Make hole in index_entries and ctts_data for new samples
4878 memmove(st->index_entries + index_entry_pos + entries,
4879 st->index_entries + index_entry_pos,
4880 sizeof(*st->index_entries) *
4881 (st->nb_index_entries - index_entry_pos));
4882 memmove(sc->ctts_data + index_entry_pos + entries,
4883 sc->ctts_data + index_entry_pos,
4884 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4885 if (index_entry_pos < sc->current_sample) {
4886 sc->current_sample += entries;
4890 st->nb_index_entries += entries;
4891 sc->ctts_count = st->nb_index_entries;
4893 // Record the index_entry position in frag_index of this fragment
4894 if (frag_stream_info)
4895 frag_stream_info->index_entry = index_entry_pos;
4897 if (index_entry_pos > 0)
4898 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4900 for (i = 0; i < entries && !pb->eof_reached; i++) {
4901 unsigned sample_size = frag->size;
4902 int sample_flags = i ? frag->flags : first_sample_flags;
4903 unsigned sample_duration = frag->duration;
4904 unsigned ctts_duration = 0;
4906 int index_entry_flags = 0;
4908 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4909 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4910 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4911 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4913 mov_update_dts_shift(sc, ctts_duration, c->fc);
4914 if (pts != AV_NOPTS_VALUE) {
4915 dts = pts - sc->dts_shift;
4916 if (flags & MOV_TRUN_SAMPLE_CTS) {
4917 dts -= ctts_duration;
4919 dts -= sc->time_offset;
4921 av_log(c->fc, AV_LOG_DEBUG,
4922 "pts %"PRId64" calculated dts %"PRId64
4923 " sc->dts_shift %d ctts.duration %d"
4924 " sc->time_offset %"PRId64
4925 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4927 sc->dts_shift, ctts_duration,
4928 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4929 pts = AV_NOPTS_VALUE;
4932 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4936 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4937 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4940 index_entry_flags |= AVINDEX_KEYFRAME;
4942 // Fragments can overlap in time. Discard overlapping frames after
4944 if (prev_dts >= dts)
4945 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4947 st->index_entries[index_entry_pos].pos = offset;
4948 st->index_entries[index_entry_pos].timestamp = dts;
4949 st->index_entries[index_entry_pos].size= sample_size;
4950 st->index_entries[index_entry_pos].min_distance= distance;
4951 st->index_entries[index_entry_pos].flags = index_entry_flags;
4953 sc->ctts_data[index_entry_pos].count = 1;
4954 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4957 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4958 "size %u, distance %d, keyframe %d\n", st->index,
4959 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4961 dts += sample_duration;
4962 offset += sample_size;
4963 sc->data_size += sample_size;
4965 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4966 1 <= INT_MAX - sc->nb_frames_for_fps
4968 sc->duration_for_fps += sample_duration;
4969 sc->nb_frames_for_fps ++;
4972 if (frag_stream_info)
4973 frag_stream_info->next_trun_dts = dts + sc->time_offset;
4975 // EOF found before reading all entries. Fix the hole this would
4976 // leave in index_entries and ctts_data
4977 int gap = entries - i;
4978 memmove(st->index_entries + index_entry_pos,
4979 st->index_entries + index_entry_pos + gap,
4980 sizeof(*st->index_entries) *
4981 (st->nb_index_entries - (index_entry_pos + gap)));
4982 memmove(sc->ctts_data + index_entry_pos,
4983 sc->ctts_data + index_entry_pos + gap,
4984 sizeof(*sc->ctts_data) *
4985 (sc->ctts_count - (index_entry_pos + gap)));
4987 st->nb_index_entries -= gap;
4988 sc->ctts_count -= gap;
4989 if (index_entry_pos < sc->current_sample) {
4990 sc->current_sample -= gap;
4995 // The end of this new fragment may overlap in time with the start
4996 // of the next fragment in index_entries. Mark the samples in the next
4997 // fragment that overlap with AVINDEX_DISCARD_FRAME
4998 prev_dts = AV_NOPTS_VALUE;
4999 if (index_entry_pos > 0)
5000 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
5001 for (i = index_entry_pos; i < st->nb_index_entries; i++) {
5002 if (prev_dts < st->index_entries[i].timestamp)
5004 st->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
5007 // If a hole was created to insert the new index_entries into,
5008 // the index_entry recorded for all subsequent moof must
5009 // be incremented by the number of entries inserted.
5010 fix_frag_index_entries(&c->frag_index, next_frag_index,
5011 frag->track_id, entries);
5013 if (pb->eof_reached) {
5014 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
5018 frag->implicit_offset = offset;
5020 sc->track_end = dts + sc->time_offset;
5021 if (st->duration < sc->track_end)
5022 st->duration = sc->track_end;
5027 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5029 int64_t offset = avio_tell(pb) + atom.size, pts, timestamp;
5031 unsigned i, j, track_id, item_count;
5032 AVStream *st = NULL;
5033 AVStream *ref_st = NULL;
5034 MOVStreamContext *sc, *ref_sc = NULL;
5035 AVRational timescale;
5037 version = avio_r8(pb);
5039 avpriv_request_sample(c->fc, "sidx version %u", version);
5043 avio_rb24(pb); // flags
5045 track_id = avio_rb32(pb); // Reference ID
5046 for (i = 0; i < c->fc->nb_streams; i++) {
5047 if (c->fc->streams[i]->id == track_id) {
5048 st = c->fc->streams[i];
5053 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5059 timescale = av_make_q(1, avio_rb32(pb));
5061 if (timescale.den <= 0) {
5062 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5063 return AVERROR_INVALIDDATA;
5067 pts = avio_rb32(pb);
5068 offset += avio_rb32(pb);
5070 pts = avio_rb64(pb);
5071 offset += avio_rb64(pb);
5074 avio_rb16(pb); // reserved
5076 item_count = avio_rb16(pb);
5078 for (i = 0; i < item_count; i++) {
5080 MOVFragmentStreamInfo * frag_stream_info;
5081 uint32_t size = avio_rb32(pb);
5082 uint32_t duration = avio_rb32(pb);
5083 if (size & 0x80000000) {
5084 avpriv_request_sample(c->fc, "sidx reference_type 1");
5085 return AVERROR_PATCHWELCOME;
5087 avio_rb32(pb); // sap_flags
5088 timestamp = av_rescale_q(pts, timescale, st->time_base);
5090 index = update_frag_index(c, offset);
5091 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5092 if (frag_stream_info)
5093 frag_stream_info->sidx_pts = timestamp;
5099 st->duration = sc->track_end = pts;
5103 if (offset == avio_size(pb)) {
5104 // Find first entry in fragment index that came from an sidx.
5105 // This will pretty much always be the first entry.
5106 for (i = 0; i < c->frag_index.nb_items; i++) {
5107 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5108 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5109 MOVFragmentStreamInfo * si;
5110 si = &item->stream_info[j];
5111 if (si->sidx_pts != AV_NOPTS_VALUE) {
5112 ref_st = c->fc->streams[j];
5113 ref_sc = ref_st->priv_data;
5118 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5119 st = c->fc->streams[i];
5121 if (!sc->has_sidx) {
5122 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5126 c->frag_index.complete = 1;
5132 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5133 /* like the files created with Adobe Premiere 5.0, for samples see */
5134 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5135 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5140 return 0; /* continue */
5141 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5142 avio_skip(pb, atom.size - 4);
5145 atom.type = avio_rl32(pb);
5147 if (atom.type != MKTAG('m','d','a','t')) {
5148 avio_skip(pb, atom.size);
5151 err = mov_read_mdat(c, pb, atom);
5155 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5160 uint8_t *moov_data; /* uncompressed data */
5161 long cmov_len, moov_len;
5164 avio_rb32(pb); /* dcom atom */
5165 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5166 return AVERROR_INVALIDDATA;
5167 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5168 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5169 return AVERROR_INVALIDDATA;
5171 avio_rb32(pb); /* cmvd atom */
5172 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5173 return AVERROR_INVALIDDATA;
5174 moov_len = avio_rb32(pb); /* uncompressed size */
5175 cmov_len = atom.size - 6 * 4;
5177 cmov_data = av_malloc(cmov_len);
5179 return AVERROR(ENOMEM);
5180 moov_data = av_malloc(moov_len);
5183 return AVERROR(ENOMEM);
5185 ret = ffio_read_size(pb, cmov_data, cmov_len);
5187 goto free_and_return;
5189 ret = AVERROR_INVALIDDATA;
5190 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5191 goto free_and_return;
5192 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5193 goto free_and_return;
5194 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5195 atom.type = MKTAG('m','o','o','v');
5196 atom.size = moov_len;
5197 ret = mov_read_default(c, &ctx, atom);
5203 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5204 return AVERROR(ENOSYS);
5208 /* edit list atom */
5209 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5211 MOVStreamContext *sc;
5212 int i, edit_count, version;
5213 int64_t elst_entry_size;
5215 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5217 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5219 version = avio_r8(pb); /* version */
5220 avio_rb24(pb); /* flags */
5221 edit_count = avio_rb32(pb); /* entries */
5224 elst_entry_size = version == 1 ? 20 : 12;
5225 if (atom.size != edit_count * elst_entry_size) {
5226 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5227 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5228 edit_count, atom.size + 8);
5229 return AVERROR_INVALIDDATA;
5231 edit_count = atom.size / elst_entry_size;
5232 if (edit_count * elst_entry_size != atom.size) {
5233 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.", atom.size, edit_count);
5241 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5242 av_free(sc->elst_data);
5244 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5246 return AVERROR(ENOMEM);
5248 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5249 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5250 MOVElst *e = &sc->elst_data[i];
5253 e->duration = avio_rb64(pb);
5254 e->time = avio_rb64(pb);
5257 e->duration = avio_rb32(pb); /* segment duration */
5258 e->time = (int32_t)avio_rb32(pb); /* media time */
5261 e->rate = avio_rb32(pb) / 65536.0;
5263 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5264 e->duration, e->time, e->rate);
5266 if (e->time < 0 && e->time != -1 &&
5267 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5268 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5269 c->fc->nb_streams-1, i, e->time);
5270 return AVERROR_INVALIDDATA;
5278 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5280 MOVStreamContext *sc;
5282 if (c->fc->nb_streams < 1)
5283 return AVERROR_INVALIDDATA;
5284 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5285 sc->timecode_track = avio_rb32(pb);
5289 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5294 if (c->fc->nb_streams < 1)
5296 st = c->fc->streams[c->fc->nb_streams - 1];
5298 if (atom.size < 4) {
5299 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5300 return AVERROR_INVALIDDATA;
5303 /* For now, propagate only the OBUs, if any. Once libavcodec is
5304 updated to handle isobmff style extradata this can be removed. */
5310 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5317 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5320 int version, color_range, color_primaries, color_trc, color_space;
5322 if (c->fc->nb_streams < 1)
5324 st = c->fc->streams[c->fc->nb_streams - 1];
5326 if (atom.size < 5) {
5327 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5328 return AVERROR_INVALIDDATA;
5331 version = avio_r8(pb);
5333 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5336 avio_skip(pb, 3); /* flags */
5338 avio_skip(pb, 2); /* profile + level */
5339 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5340 color_primaries = avio_r8(pb);
5341 color_trc = avio_r8(pb);
5342 color_space = avio_r8(pb);
5343 if (avio_rb16(pb)) /* codecIntializationDataSize */
5344 return AVERROR_INVALIDDATA;
5346 if (!av_color_primaries_name(color_primaries))
5347 color_primaries = AVCOL_PRI_UNSPECIFIED;
5348 if (!av_color_transfer_name(color_trc))
5349 color_trc = AVCOL_TRC_UNSPECIFIED;
5350 if (!av_color_space_name(color_space))
5351 color_space = AVCOL_SPC_UNSPECIFIED;
5353 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5354 st->codecpar->color_primaries = color_primaries;
5355 st->codecpar->color_trc = color_trc;
5356 st->codecpar->color_space = color_space;
5361 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5363 MOVStreamContext *sc;
5366 if (c->fc->nb_streams < 1)
5367 return AVERROR_INVALIDDATA;
5369 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5371 if (atom.size < 5) {
5372 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5373 return AVERROR_INVALIDDATA;
5376 version = avio_r8(pb);
5378 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5381 avio_skip(pb, 3); /* flags */
5383 sc->mastering = av_mastering_display_metadata_alloc();
5385 return AVERROR(ENOMEM);
5387 for (i = 0; i < 3; i++) {
5388 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5389 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5391 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5392 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5394 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5395 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5397 sc->mastering->has_primaries = 1;
5398 sc->mastering->has_luminance = 1;
5403 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5405 MOVStreamContext *sc;
5406 const int mapping[3] = {1, 2, 0};
5407 const int chroma_den = 50000;
5408 const int luma_den = 10000;
5411 if (c->fc->nb_streams < 1)
5412 return AVERROR_INVALIDDATA;
5414 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5416 if (atom.size < 24) {
5417 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5418 return AVERROR_INVALIDDATA;
5421 sc->mastering = av_mastering_display_metadata_alloc();
5423 return AVERROR(ENOMEM);
5425 for (i = 0; i < 3; i++) {
5426 const int j = mapping[i];
5427 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5428 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5430 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5431 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5433 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5434 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5436 sc->mastering->has_luminance = 1;
5437 sc->mastering->has_primaries = 1;
5442 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5444 MOVStreamContext *sc;
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 < 5) {
5453 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5454 return AVERROR_INVALIDDATA;
5457 version = avio_r8(pb);
5459 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5462 avio_skip(pb, 3); /* flags */
5464 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5466 return AVERROR(ENOMEM);
5468 sc->coll->MaxCLL = avio_rb16(pb);
5469 sc->coll->MaxFALL = avio_rb16(pb);
5474 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5476 MOVStreamContext *sc;
5478 if (c->fc->nb_streams < 1)
5479 return AVERROR_INVALIDDATA;
5481 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5483 if (atom.size < 4) {
5484 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5485 return AVERROR_INVALIDDATA;
5488 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5490 return AVERROR(ENOMEM);
5492 sc->coll->MaxCLL = avio_rb16(pb);
5493 sc->coll->MaxFALL = avio_rb16(pb);
5498 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5501 MOVStreamContext *sc;
5502 enum AVStereo3DType type;
5505 if (c->fc->nb_streams < 1)
5508 st = c->fc->streams[c->fc->nb_streams - 1];
5511 if (atom.size < 5) {
5512 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5513 return AVERROR_INVALIDDATA;
5515 avio_skip(pb, 4); /* version + flags */
5520 type = AV_STEREO3D_2D;
5523 type = AV_STEREO3D_TOPBOTTOM;
5526 type = AV_STEREO3D_SIDEBYSIDE;
5529 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5533 sc->stereo3d = av_stereo3d_alloc();
5535 return AVERROR(ENOMEM);
5537 sc->stereo3d->type = type;
5541 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5544 MOVStreamContext *sc;
5545 int size, version, layout;
5546 int32_t yaw, pitch, roll;
5547 uint32_t l = 0, t = 0, r = 0, b = 0;
5548 uint32_t tag, padding = 0;
5549 enum AVSphericalProjection projection;
5551 if (c->fc->nb_streams < 1)
5554 st = c->fc->streams[c->fc->nb_streams - 1];
5557 if (atom.size < 8) {
5558 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5559 return AVERROR_INVALIDDATA;
5562 size = avio_rb32(pb);
5563 if (size <= 12 || size > atom.size)
5564 return AVERROR_INVALIDDATA;
5566 tag = avio_rl32(pb);
5567 if (tag != MKTAG('s','v','h','d')) {
5568 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5571 version = avio_r8(pb);
5573 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5577 avio_skip(pb, 3); /* flags */
5578 avio_skip(pb, size - 12); /* metadata_source */
5580 size = avio_rb32(pb);
5581 if (size > atom.size)
5582 return AVERROR_INVALIDDATA;
5584 tag = avio_rl32(pb);
5585 if (tag != MKTAG('p','r','o','j')) {
5586 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5590 size = avio_rb32(pb);
5591 if (size > atom.size)
5592 return AVERROR_INVALIDDATA;
5594 tag = avio_rl32(pb);
5595 if (tag != MKTAG('p','r','h','d')) {
5596 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5599 version = avio_r8(pb);
5601 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5605 avio_skip(pb, 3); /* flags */
5607 /* 16.16 fixed point */
5608 yaw = avio_rb32(pb);
5609 pitch = avio_rb32(pb);
5610 roll = avio_rb32(pb);
5612 size = avio_rb32(pb);
5613 if (size > atom.size)
5614 return AVERROR_INVALIDDATA;
5616 tag = avio_rl32(pb);
5617 version = avio_r8(pb);
5619 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5623 avio_skip(pb, 3); /* flags */
5625 case MKTAG('c','b','m','p'):
5626 layout = avio_rb32(pb);
5628 av_log(c->fc, AV_LOG_WARNING,
5629 "Unsupported cubemap layout %d\n", layout);
5632 projection = AV_SPHERICAL_CUBEMAP;
5633 padding = avio_rb32(pb);
5635 case MKTAG('e','q','u','i'):
5641 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5642 av_log(c->fc, AV_LOG_ERROR,
5643 "Invalid bounding rectangle coordinates "
5644 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5645 return AVERROR_INVALIDDATA;
5648 if (l || t || r || b)
5649 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5651 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5654 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5658 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5660 return AVERROR(ENOMEM);
5662 sc->spherical->projection = projection;
5664 sc->spherical->yaw = yaw;
5665 sc->spherical->pitch = pitch;
5666 sc->spherical->roll = roll;
5668 sc->spherical->padding = padding;
5670 sc->spherical->bound_left = l;
5671 sc->spherical->bound_top = t;
5672 sc->spherical->bound_right = r;
5673 sc->spherical->bound_bottom = b;
5678 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5681 uint8_t *buffer = av_malloc(len + 1);
5685 return AVERROR(ENOMEM);
5688 ret = ffio_read_size(pb, buffer, len);
5692 /* Check for mandatory keys and values, try to support XML as best-effort */
5693 if (!sc->spherical &&
5694 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5695 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5696 av_stristr(val, "true") &&
5697 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5698 av_stristr(val, "true") &&
5699 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5700 av_stristr(val, "equirectangular")) {
5701 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5705 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5707 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5708 enum AVStereo3DType mode;
5710 if (av_stristr(buffer, "left-right"))
5711 mode = AV_STEREO3D_SIDEBYSIDE;
5712 else if (av_stristr(buffer, "top-bottom"))
5713 mode = AV_STEREO3D_TOPBOTTOM;
5715 mode = AV_STEREO3D_2D;
5717 sc->stereo3d = av_stereo3d_alloc();
5721 sc->stereo3d->type = mode;
5725 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5727 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5728 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5730 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5731 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5733 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5741 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5744 MOVStreamContext *sc;
5747 static const uint8_t uuid_isml_manifest[] = {
5748 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5749 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5751 static const uint8_t uuid_xmp[] = {
5752 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5753 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5755 static const uint8_t uuid_spherical[] = {
5756 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5757 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5760 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5761 return AVERROR_INVALIDDATA;
5763 if (c->fc->nb_streams < 1)
5765 st = c->fc->streams[c->fc->nb_streams - 1];
5768 ret = avio_read(pb, uuid, sizeof(uuid));
5771 } else if (ret != sizeof(uuid)) {
5772 return AVERROR_INVALIDDATA;
5774 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5775 uint8_t *buffer, *ptr;
5777 size_t len = atom.size - sizeof(uuid);
5780 return AVERROR_INVALIDDATA;
5782 ret = avio_skip(pb, 4); // zeroes
5785 buffer = av_mallocz(len + 1);
5787 return AVERROR(ENOMEM);
5789 ret = avio_read(pb, buffer, len);
5793 } else if (ret != len) {
5795 return AVERROR_INVALIDDATA;
5799 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5800 ptr += sizeof("systemBitrate=\"") - 1;
5801 c->bitrates_count++;
5802 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5804 c->bitrates_count = 0;
5806 return AVERROR(ENOMEM);
5809 ret = strtol(ptr, &endptr, 10);
5810 if (ret < 0 || errno || *endptr != '"') {
5811 c->bitrates[c->bitrates_count - 1] = 0;
5813 c->bitrates[c->bitrates_count - 1] = ret;
5818 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5820 size_t len = atom.size - sizeof(uuid);
5821 if (c->export_xmp) {
5822 buffer = av_mallocz(len + 1);
5824 return AVERROR(ENOMEM);
5826 ret = avio_read(pb, buffer, len);
5830 } else if (ret != len) {
5832 return AVERROR_INVALIDDATA;
5835 av_dict_set(&c->fc->metadata, "xmp",
5836 buffer, AV_DICT_DONT_STRDUP_VAL);
5838 // skip all uuid atom, which makes it fast for long uuid-xmp file
5839 ret = avio_skip(pb, len);
5843 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5844 size_t len = atom.size - sizeof(uuid);
5845 ret = mov_parse_uuid_spherical(sc, pb, len);
5849 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5855 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5858 uint8_t content[16];
5863 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5869 && !memcmp(content, "Anevia\x1A\x1A", 8)
5870 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5871 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5877 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5879 uint32_t format = avio_rl32(pb);
5880 MOVStreamContext *sc;
5884 if (c->fc->nb_streams < 1)
5886 st = c->fc->streams[c->fc->nb_streams - 1];
5891 case MKTAG('e','n','c','v'): // encrypted video
5892 case MKTAG('e','n','c','a'): // encrypted audio
5893 id = mov_codec_id(st, format);
5894 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5895 st->codecpar->codec_id != id) {
5896 av_log(c->fc, AV_LOG_WARNING,
5897 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5898 (char*)&format, st->codecpar->codec_id);
5902 st->codecpar->codec_id = id;
5903 sc->format = format;
5907 if (format != sc->format) {
5908 av_log(c->fc, AV_LOG_WARNING,
5909 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5910 (char*)&format, (char*)&sc->format);
5919 * Gets the current encryption info and associated current stream context. If
5920 * we are parsing a track fragment, this will return the specific encryption
5921 * info for this fragment; otherwise this will return the global encryption
5922 * info for the current stream.
5924 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5926 MOVFragmentStreamInfo *frag_stream_info;
5930 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5931 if (frag_stream_info) {
5932 for (i = 0; i < c->fc->nb_streams; i++) {
5933 if (c->fc->streams[i]->id == frag_stream_info->id) {
5934 st = c->fc->streams[i];
5938 if (i == c->fc->nb_streams)
5940 *sc = st->priv_data;
5942 if (!frag_stream_info->encryption_index) {
5943 // If this stream isn't encrypted, don't create the index.
5944 if (!(*sc)->cenc.default_encrypted_sample)
5946 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5947 if (!frag_stream_info->encryption_index)
5948 return AVERROR(ENOMEM);
5950 *encryption_index = frag_stream_info->encryption_index;
5953 // No current track fragment, using stream level encryption info.
5955 if (c->fc->nb_streams < 1)
5957 st = c->fc->streams[c->fc->nb_streams - 1];
5958 *sc = st->priv_data;
5960 if (!(*sc)->cenc.encryption_index) {
5961 // If this stream isn't encrypted, don't create the index.
5962 if (!(*sc)->cenc.default_encrypted_sample)
5964 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5965 if (!(*sc)->cenc.encryption_index)
5966 return AVERROR(ENOMEM);
5969 *encryption_index = (*sc)->cenc.encryption_index;
5974 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
5977 unsigned int subsample_count;
5978 AVSubsampleEncryptionInfo *subsamples;
5980 if (!sc->cenc.default_encrypted_sample) {
5981 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
5982 return AVERROR_INVALIDDATA;
5985 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
5987 return AVERROR(ENOMEM);
5989 if (sc->cenc.per_sample_iv_size != 0) {
5990 if (avio_read(pb, (*sample)->iv, sc->cenc.per_sample_iv_size) != sc->cenc.per_sample_iv_size) {
5991 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
5992 av_encryption_info_free(*sample);
5994 return AVERROR_INVALIDDATA;
5998 if (use_subsamples) {
5999 subsample_count = avio_rb16(pb);
6000 av_free((*sample)->subsamples);
6001 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
6002 if (!(*sample)->subsamples) {
6003 av_encryption_info_free(*sample);
6005 return AVERROR(ENOMEM);
6008 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
6009 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
6010 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
6013 if (pb->eof_reached) {
6014 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
6015 av_encryption_info_free(*sample);
6017 return AVERROR_INVALIDDATA;
6019 (*sample)->subsample_count = subsample_count;
6025 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6027 AVEncryptionInfo **encrypted_samples;
6028 MOVEncryptionIndex *encryption_index;
6029 MOVStreamContext *sc;
6030 int use_subsamples, ret;
6031 unsigned int sample_count, i, alloc_size = 0;
6033 ret = get_current_encryption_info(c, &encryption_index, &sc);
6037 if (encryption_index->nb_encrypted_samples) {
6038 // This can happen if we have both saio/saiz and senc atoms.
6039 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6043 avio_r8(pb); /* version */
6044 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6046 sample_count = avio_rb32(pb);
6047 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6048 return AVERROR(ENOMEM);
6050 for (i = 0; i < sample_count; i++) {
6051 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6052 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6053 min_samples * sizeof(*encrypted_samples));
6054 if (encrypted_samples) {
6055 encryption_index->encrypted_samples = encrypted_samples;
6057 ret = mov_read_sample_encryption_info(
6058 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6060 ret = AVERROR(ENOMEM);
6062 if (pb->eof_reached) {
6063 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6064 ret = AVERROR_INVALIDDATA;
6069 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6070 av_freep(&encryption_index->encrypted_samples);
6074 encryption_index->nb_encrypted_samples = sample_count;
6079 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6081 AVEncryptionInfo **sample, **encrypted_samples;
6083 size_t sample_count, sample_info_size, i;
6085 unsigned int alloc_size = 0;
6087 if (encryption_index->nb_encrypted_samples)
6089 sample_count = encryption_index->auxiliary_info_sample_count;
6090 if (encryption_index->auxiliary_offsets_count != 1) {
6091 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6092 return AVERROR_PATCHWELCOME;
6094 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6095 return AVERROR(ENOMEM);
6097 prev_pos = avio_tell(pb);
6098 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6099 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6100 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6104 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6105 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6106 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6107 min_samples * sizeof(*encrypted_samples));
6108 if (!encrypted_samples) {
6109 ret = AVERROR(ENOMEM);
6112 encryption_index->encrypted_samples = encrypted_samples;
6114 sample = &encryption_index->encrypted_samples[i];
6115 sample_info_size = encryption_index->auxiliary_info_default_size
6116 ? encryption_index->auxiliary_info_default_size
6117 : encryption_index->auxiliary_info_sizes[i];
6119 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6123 if (pb->eof_reached) {
6124 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6125 ret = AVERROR_INVALIDDATA;
6127 encryption_index->nb_encrypted_samples = sample_count;
6131 avio_seek(pb, prev_pos, SEEK_SET);
6133 for (; i > 0; i--) {
6134 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6136 av_freep(&encryption_index->encrypted_samples);
6142 * Tries to read the given number of bytes from the stream and puts it in a
6143 * newly allocated buffer. This reads in small chunks to avoid allocating large
6144 * memory if the file contains an invalid/malicious size value.
6146 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6148 const unsigned int block_size = 1024 * 1024;
6149 uint8_t *buffer = NULL;
6150 unsigned int alloc_size = 0, offset = 0;
6151 while (offset < size) {
6152 unsigned int new_size =
6153 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6154 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6155 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6158 return AVERROR(ENOMEM);
6160 buffer = new_buffer;
6162 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6164 return AVERROR_INVALIDDATA;
6173 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6175 MOVEncryptionIndex *encryption_index;
6176 MOVStreamContext *sc;
6178 unsigned int sample_count, aux_info_type, aux_info_param;
6180 ret = get_current_encryption_info(c, &encryption_index, &sc);
6184 if (encryption_index->nb_encrypted_samples) {
6185 // This can happen if we have both saio/saiz and senc atoms.
6186 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6190 if (encryption_index->auxiliary_info_sample_count) {
6191 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6192 return AVERROR_INVALIDDATA;
6195 avio_r8(pb); /* version */
6196 if (avio_rb24(pb) & 0x01) { /* flags */
6197 aux_info_type = avio_rb32(pb);
6198 aux_info_param = avio_rb32(pb);
6199 if (sc->cenc.default_encrypted_sample) {
6200 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6201 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6204 if (aux_info_param != 0) {
6205 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6209 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6210 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6211 aux_info_type == MKBETAG('c','e','n','s') ||
6212 aux_info_type == MKBETAG('c','b','c','1') ||
6213 aux_info_type == MKBETAG('c','b','c','s')) &&
6214 aux_info_param == 0) {
6215 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6216 return AVERROR_INVALIDDATA;
6221 } else if (!sc->cenc.default_encrypted_sample) {
6222 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6226 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6227 sample_count = avio_rb32(pb);
6228 encryption_index->auxiliary_info_sample_count = sample_count;
6230 if (encryption_index->auxiliary_info_default_size == 0) {
6231 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6233 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6238 if (encryption_index->auxiliary_offsets_count) {
6239 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6245 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6247 uint64_t *auxiliary_offsets;
6248 MOVEncryptionIndex *encryption_index;
6249 MOVStreamContext *sc;
6251 unsigned int version, entry_count, aux_info_type, aux_info_param;
6252 unsigned int alloc_size = 0;
6254 ret = get_current_encryption_info(c, &encryption_index, &sc);
6258 if (encryption_index->nb_encrypted_samples) {
6259 // This can happen if we have both saio/saiz and senc atoms.
6260 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6264 if (encryption_index->auxiliary_offsets_count) {
6265 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6266 return AVERROR_INVALIDDATA;
6269 version = avio_r8(pb); /* version */
6270 if (avio_rb24(pb) & 0x01) { /* flags */
6271 aux_info_type = avio_rb32(pb);
6272 aux_info_param = avio_rb32(pb);
6273 if (sc->cenc.default_encrypted_sample) {
6274 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6275 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6278 if (aux_info_param != 0) {
6279 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6283 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6284 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6285 aux_info_type == MKBETAG('c','e','n','s') ||
6286 aux_info_type == MKBETAG('c','b','c','1') ||
6287 aux_info_type == MKBETAG('c','b','c','s')) &&
6288 aux_info_param == 0) {
6289 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6290 return AVERROR_INVALIDDATA;
6295 } else if (!sc->cenc.default_encrypted_sample) {
6296 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6300 entry_count = avio_rb32(pb);
6301 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6302 return AVERROR(ENOMEM);
6304 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6305 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6306 auxiliary_offsets = av_fast_realloc(
6307 encryption_index->auxiliary_offsets, &alloc_size,
6308 min_offsets * sizeof(*auxiliary_offsets));
6309 if (!auxiliary_offsets) {
6310 av_freep(&encryption_index->auxiliary_offsets);
6311 return AVERROR(ENOMEM);
6313 encryption_index->auxiliary_offsets = auxiliary_offsets;
6316 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6318 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6320 if (c->frag_index.current >= 0) {
6321 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6325 if (pb->eof_reached) {
6326 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6327 av_freep(&encryption_index->auxiliary_offsets);
6328 return AVERROR_INVALIDDATA;
6331 encryption_index->auxiliary_offsets_count = entry_count;
6333 if (encryption_index->auxiliary_info_sample_count) {
6334 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6340 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6342 AVEncryptionInitInfo *info, *old_init_info;
6345 uint8_t *side_data, *extra_data, *old_side_data;
6346 size_t side_data_size;
6347 int ret = 0, old_side_data_size;
6348 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6350 if (c->fc->nb_streams < 1)
6352 st = c->fc->streams[c->fc->nb_streams-1];
6354 version = avio_r8(pb); /* version */
6355 avio_rb24(pb); /* flags */
6357 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6358 /* key_id_size */ 16, /* data_size */ 0);
6360 return AVERROR(ENOMEM);
6362 if (avio_read(pb, info->system_id, 16) != 16) {
6363 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6364 ret = AVERROR_INVALIDDATA;
6369 kid_count = avio_rb32(pb);
6370 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
6371 ret = AVERROR(ENOMEM);
6375 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6376 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6377 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6378 min_kid_count * sizeof(*key_ids));
6380 ret = AVERROR(ENOMEM);
6383 info->key_ids = key_ids;
6385 info->key_ids[i] = av_mallocz(16);
6386 if (!info->key_ids[i]) {
6387 ret = AVERROR(ENOMEM);
6390 info->num_key_ids = i + 1;
6392 if (avio_read(pb, info->key_ids[i], 16) != 16) {
6393 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6394 ret = AVERROR_INVALIDDATA;
6399 if (pb->eof_reached) {
6400 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6401 ret = AVERROR_INVALIDDATA;
6406 extra_data_size = avio_rb32(pb);
6407 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6411 av_freep(&info->data); // malloc(0) may still allocate something.
6412 info->data = extra_data;
6413 info->data_size = extra_data_size;
6415 // If there is existing initialization data, append to the list.
6416 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6417 if (old_side_data) {
6418 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6419 if (old_init_info) {
6420 // Append to the end of the list.
6421 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6427 info = old_init_info;
6429 // Assume existing side-data will be valid, so the only error we could get is OOM.
6430 ret = AVERROR(ENOMEM);
6435 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6437 ret = AVERROR(ENOMEM);
6440 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6441 side_data, side_data_size);
6446 av_encryption_init_info_free(info);
6450 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6453 MOVStreamContext *sc;
6455 if (c->fc->nb_streams < 1)
6457 st = c->fc->streams[c->fc->nb_streams-1];
6460 if (sc->pseudo_stream_id != 0) {
6461 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6462 return AVERROR_PATCHWELCOME;
6466 return AVERROR_INVALIDDATA;
6468 avio_rb32(pb); /* version and flags */
6470 if (!sc->cenc.default_encrypted_sample) {
6471 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6472 if (!sc->cenc.default_encrypted_sample) {
6473 return AVERROR(ENOMEM);
6477 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6481 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6484 MOVStreamContext *sc;
6485 unsigned int version, pattern, is_protected, iv_size;
6487 if (c->fc->nb_streams < 1)
6489 st = c->fc->streams[c->fc->nb_streams-1];
6492 if (sc->pseudo_stream_id != 0) {
6493 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6494 return AVERROR_PATCHWELCOME;
6497 if (!sc->cenc.default_encrypted_sample) {
6498 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6499 if (!sc->cenc.default_encrypted_sample) {
6500 return AVERROR(ENOMEM);
6505 return AVERROR_INVALIDDATA;
6507 version = avio_r8(pb); /* version */
6508 avio_rb24(pb); /* flags */
6510 avio_r8(pb); /* reserved */
6511 pattern = avio_r8(pb);
6514 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6515 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6518 is_protected = avio_r8(pb);
6519 if (is_protected && !sc->cenc.encryption_index) {
6520 // The whole stream should be by-default encrypted.
6521 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6522 if (!sc->cenc.encryption_index)
6523 return AVERROR(ENOMEM);
6525 sc->cenc.per_sample_iv_size = avio_r8(pb);
6526 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6527 sc->cenc.per_sample_iv_size != 16) {
6528 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6529 return AVERROR_INVALIDDATA;
6531 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6532 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6533 return AVERROR_INVALIDDATA;
6536 if (is_protected && !sc->cenc.per_sample_iv_size) {
6537 iv_size = avio_r8(pb);
6538 if (iv_size != 8 && iv_size != 16) {
6539 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6540 return AVERROR_INVALIDDATA;
6543 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6544 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6545 return AVERROR_INVALIDDATA;
6552 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6555 int last, type, size, ret;
6558 if (c->fc->nb_streams < 1)
6560 st = c->fc->streams[c->fc->nb_streams-1];
6562 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6563 return AVERROR_INVALIDDATA;
6565 /* Check FlacSpecificBox version. */
6566 if (avio_r8(pb) != 0)
6567 return AVERROR_INVALIDDATA;
6569 avio_rb24(pb); /* Flags */
6571 avio_read(pb, buf, sizeof(buf));
6572 flac_parse_block_header(buf, &last, &type, &size);
6574 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6575 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6576 return AVERROR_INVALIDDATA;
6579 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6584 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6589 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6593 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6594 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6595 return AVERROR_PATCHWELCOME;
6598 if (!sc->cenc.aes_ctr) {
6599 /* initialize the cipher */
6600 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6601 if (!sc->cenc.aes_ctr) {
6602 return AVERROR(ENOMEM);
6605 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6611 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6613 if (!sample->subsample_count)
6615 /* decrypt the whole packet */
6616 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6620 for (i = 0; i < sample->subsample_count; i++)
6622 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6623 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6624 return AVERROR_INVALIDDATA;
6627 /* skip the clear bytes */
6628 input += sample->subsamples[i].bytes_of_clear_data;
6629 size -= sample->subsamples[i].bytes_of_clear_data;
6631 /* decrypt the encrypted bytes */
6632 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6633 input += sample->subsamples[i].bytes_of_protected_data;
6634 size -= sample->subsamples[i].bytes_of_protected_data;
6638 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6639 return AVERROR_INVALIDDATA;
6645 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6647 MOVFragmentStreamInfo *frag_stream_info;
6648 MOVEncryptionIndex *encryption_index;
6649 AVEncryptionInfo *encrypted_sample;
6650 int encrypted_index, ret;
6652 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6653 encrypted_index = current_index;
6654 encryption_index = NULL;
6655 if (frag_stream_info) {
6656 // Note this only supports encryption info in the first sample descriptor.
6657 if (mov->fragment.stsd_id == 1) {
6658 if (frag_stream_info->encryption_index) {
6659 encrypted_index = current_index - frag_stream_info->index_entry;
6660 encryption_index = frag_stream_info->encryption_index;
6662 encryption_index = sc->cenc.encryption_index;
6666 encryption_index = sc->cenc.encryption_index;
6669 if (encryption_index) {
6670 if (encryption_index->auxiliary_info_sample_count &&
6671 !encryption_index->nb_encrypted_samples) {
6672 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6673 return AVERROR_INVALIDDATA;
6675 if (encryption_index->auxiliary_offsets_count &&
6676 !encryption_index->nb_encrypted_samples) {
6677 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6678 return AVERROR_INVALIDDATA;
6681 if (!encryption_index->nb_encrypted_samples) {
6682 // Full-sample encryption with default settings.
6683 encrypted_sample = sc->cenc.default_encrypted_sample;
6684 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6685 // Per-sample setting override.
6686 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6688 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6689 return AVERROR_INVALIDDATA;
6692 if (mov->decryption_key) {
6693 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6696 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6698 return AVERROR(ENOMEM);
6699 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6709 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6711 const int OPUS_SEEK_PREROLL_MS = 80;
6717 if (c->fc->nb_streams < 1)
6719 st = c->fc->streams[c->fc->nb_streams-1];
6721 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6722 return AVERROR_INVALIDDATA;
6724 /* Check OpusSpecificBox version. */
6725 if (avio_r8(pb) != 0) {
6726 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6727 return AVERROR_INVALIDDATA;
6730 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6731 size = atom.size + 8;
6733 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
6736 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6737 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6738 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6739 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6741 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6742 little-endian; aside from the preceeding magic and version they're
6743 otherwise currently identical. Data after output gain at offset 16
6744 doesn't need to be bytewapped. */
6745 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6746 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6747 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6748 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6750 st->codecpar->initial_padding = pre_skip;
6751 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6752 (AVRational){1, 1000},
6753 (AVRational){1, 48000});
6758 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6761 unsigned format_info;
6762 int channel_assignment, channel_assignment1, channel_assignment2;
6765 if (c->fc->nb_streams < 1)
6767 st = c->fc->streams[c->fc->nb_streams-1];
6770 return AVERROR_INVALIDDATA;
6772 format_info = avio_rb32(pb);
6774 ratebits = (format_info >> 28) & 0xF;
6775 channel_assignment1 = (format_info >> 15) & 0x1F;
6776 channel_assignment2 = format_info & 0x1FFF;
6777 if (channel_assignment2)
6778 channel_assignment = channel_assignment2;
6780 channel_assignment = channel_assignment1;
6782 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6783 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6784 st->codecpar->channels = truehd_channels(channel_assignment);
6785 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6790 static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6794 AVDOVIDecoderConfigurationRecord *dovi;
6798 if (c->fc->nb_streams < 1)
6800 st = c->fc->streams[c->fc->nb_streams-1];
6802 if ((uint64_t)atom.size > (1<<30) || atom.size < 4)
6803 return AVERROR_INVALIDDATA;
6805 dovi = av_dovi_alloc(&dovi_size);
6807 return AVERROR(ENOMEM);
6809 dovi->dv_version_major = avio_r8(pb);
6810 dovi->dv_version_minor = avio_r8(pb);
6812 buf = avio_rb16(pb);
6813 dovi->dv_profile = (buf >> 9) & 0x7f; // 7 bits
6814 dovi->dv_level = (buf >> 3) & 0x3f; // 6 bits
6815 dovi->rpu_present_flag = (buf >> 2) & 0x01; // 1 bit
6816 dovi->el_present_flag = (buf >> 1) & 0x01; // 1 bit
6817 dovi->bl_present_flag = buf & 0x01; // 1 bit
6818 if (atom.size >= 24) { // 4 + 4 + 4 * 4
6820 dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits
6822 // 0 stands for None
6823 // Dolby Vision V1.2.93 profiles and levels
6824 dovi->dv_bl_signal_compatibility_id = 0;
6827 ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF,
6828 (uint8_t *)dovi, dovi_size);
6834 av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC box, version: %d.%d, profile: %d, level: %d, "
6835 "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n",
6836 dovi->dv_version_major, dovi->dv_version_minor,
6837 dovi->dv_profile, dovi->dv_level,
6838 dovi->rpu_present_flag,
6839 dovi->el_present_flag,
6840 dovi->bl_present_flag,
6841 dovi->dv_bl_signal_compatibility_id
6847 static const MOVParseTableEntry mov_default_parse_table[] = {
6848 { MKTAG('A','C','L','R'), mov_read_aclr },
6849 { MKTAG('A','P','R','G'), mov_read_avid },
6850 { MKTAG('A','A','L','P'), mov_read_avid },
6851 { MKTAG('A','R','E','S'), mov_read_ares },
6852 { MKTAG('a','v','s','s'), mov_read_avss },
6853 { MKTAG('a','v','1','C'), mov_read_av1c },
6854 { MKTAG('c','h','p','l'), mov_read_chpl },
6855 { MKTAG('c','o','6','4'), mov_read_stco },
6856 { MKTAG('c','o','l','r'), mov_read_colr },
6857 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6858 { MKTAG('d','i','n','f'), mov_read_default },
6859 { MKTAG('D','p','x','E'), mov_read_dpxe },
6860 { MKTAG('d','r','e','f'), mov_read_dref },
6861 { MKTAG('e','d','t','s'), mov_read_default },
6862 { MKTAG('e','l','s','t'), mov_read_elst },
6863 { MKTAG('e','n','d','a'), mov_read_enda },
6864 { MKTAG('f','i','e','l'), mov_read_fiel },
6865 { MKTAG('a','d','r','m'), mov_read_adrm },
6866 { MKTAG('f','t','y','p'), mov_read_ftyp },
6867 { MKTAG('g','l','b','l'), mov_read_glbl },
6868 { MKTAG('h','d','l','r'), mov_read_hdlr },
6869 { MKTAG('i','l','s','t'), mov_read_ilst },
6870 { MKTAG('j','p','2','h'), mov_read_jp2h },
6871 { MKTAG('m','d','a','t'), mov_read_mdat },
6872 { MKTAG('m','d','h','d'), mov_read_mdhd },
6873 { MKTAG('m','d','i','a'), mov_read_default },
6874 { MKTAG('m','e','t','a'), mov_read_meta },
6875 { MKTAG('m','i','n','f'), mov_read_default },
6876 { MKTAG('m','o','o','f'), mov_read_moof },
6877 { MKTAG('m','o','o','v'), mov_read_moov },
6878 { MKTAG('m','v','e','x'), mov_read_default },
6879 { MKTAG('m','v','h','d'), mov_read_mvhd },
6880 { MKTAG('S','M','I',' '), mov_read_svq3 },
6881 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6882 { MKTAG('a','v','c','C'), mov_read_glbl },
6883 { MKTAG('p','a','s','p'), mov_read_pasp },
6884 { MKTAG('s','i','d','x'), mov_read_sidx },
6885 { MKTAG('s','t','b','l'), mov_read_default },
6886 { MKTAG('s','t','c','o'), mov_read_stco },
6887 { MKTAG('s','t','p','s'), mov_read_stps },
6888 { MKTAG('s','t','r','f'), mov_read_strf },
6889 { MKTAG('s','t','s','c'), mov_read_stsc },
6890 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6891 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6892 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6893 { MKTAG('s','t','t','s'), mov_read_stts },
6894 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6895 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
6896 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6897 { MKTAG('t','f','d','t'), mov_read_tfdt },
6898 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6899 { MKTAG('t','r','a','k'), mov_read_trak },
6900 { MKTAG('t','r','a','f'), mov_read_default },
6901 { MKTAG('t','r','e','f'), mov_read_default },
6902 { MKTAG('t','m','c','d'), mov_read_tmcd },
6903 { MKTAG('c','h','a','p'), mov_read_chap },
6904 { MKTAG('t','r','e','x'), mov_read_trex },
6905 { MKTAG('t','r','u','n'), mov_read_trun },
6906 { MKTAG('u','d','t','a'), mov_read_default },
6907 { MKTAG('w','a','v','e'), mov_read_wave },
6908 { MKTAG('e','s','d','s'), mov_read_esds },
6909 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6910 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6911 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6912 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6913 { MKTAG('w','f','e','x'), mov_read_wfex },
6914 { MKTAG('c','m','o','v'), mov_read_cmov },
6915 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6916 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6917 { MKTAG('s','b','g','p'), mov_read_sbgp },
6918 { MKTAG('h','v','c','C'), mov_read_glbl },
6919 { MKTAG('u','u','i','d'), mov_read_uuid },
6920 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6921 { MKTAG('f','r','e','e'), mov_read_free },
6922 { MKTAG('-','-','-','-'), mov_read_custom },
6923 { MKTAG('s','i','n','f'), mov_read_default },
6924 { MKTAG('f','r','m','a'), mov_read_frma },
6925 { MKTAG('s','e','n','c'), mov_read_senc },
6926 { MKTAG('s','a','i','z'), mov_read_saiz },
6927 { MKTAG('s','a','i','o'), mov_read_saio },
6928 { MKTAG('p','s','s','h'), mov_read_pssh },
6929 { MKTAG('s','c','h','m'), mov_read_schm },
6930 { MKTAG('s','c','h','i'), mov_read_default },
6931 { MKTAG('t','e','n','c'), mov_read_tenc },
6932 { MKTAG('d','f','L','a'), mov_read_dfla },
6933 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6934 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6935 { MKTAG('d','O','p','s'), mov_read_dops },
6936 { MKTAG('d','m','l','p'), mov_read_dmlp },
6937 { MKTAG('S','m','D','m'), mov_read_smdm },
6938 { MKTAG('C','o','L','L'), mov_read_coll },
6939 { MKTAG('v','p','c','C'), mov_read_vpcc },
6940 { MKTAG('m','d','c','v'), mov_read_mdcv },
6941 { MKTAG('c','l','l','i'), mov_read_clli },
6942 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
6943 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
6947 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6949 int64_t total_size = 0;
6953 if (c->atom_depth > 10) {
6954 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6955 return AVERROR_INVALIDDATA;
6960 atom.size = INT64_MAX;
6961 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6962 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
6965 if (atom.size >= 8) {
6966 a.size = avio_rb32(pb);
6967 a.type = avio_rl32(pb);
6968 if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
6969 a.type == MKTAG('h','o','o','v')) &&
6971 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
6973 uint32_t *type = (uint32_t *)buf + 1;
6974 if (avio_read(pb, buf, 8) != 8)
6975 return AVERROR_INVALIDDATA;
6976 avio_seek(pb, -8, SEEK_CUR);
6977 if (*type == MKTAG('m','v','h','d') ||
6978 *type == MKTAG('c','m','o','v')) {
6979 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
6980 a.type = MKTAG('m','o','o','v');
6983 if (atom.type != MKTAG('r','o','o','t') &&
6984 atom.type != MKTAG('m','o','o','v'))
6986 if (a.type == MKTAG('t','r','a','k') || a.type == MKTAG('m','d','a','t'))
6988 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
6995 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
6996 a.size = avio_rb64(pb) - 8;
7000 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
7001 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
7003 a.size = atom.size - total_size + 8;
7008 a.size = FFMIN(a.size, atom.size - total_size);
7010 for (i = 0; mov_default_parse_table[i].type; i++)
7011 if (mov_default_parse_table[i].type == a.type) {
7012 parse = mov_default_parse_table[i].parse;
7016 // container is user data
7017 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
7018 atom.type == MKTAG('i','l','s','t')))
7019 parse = mov_read_udta_string;
7021 // Supports parsing the QuickTime Metadata Keys.
7022 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
7023 if (!parse && c->found_hdlr_mdta &&
7024 atom.type == MKTAG('m','e','t','a') &&
7025 a.type == MKTAG('k','e','y','s')) {
7026 parse = mov_read_keys;
7029 if (!parse) { /* skip leaf atoms data */
7030 avio_skip(pb, a.size);
7032 int64_t start_pos = avio_tell(pb);
7034 int err = parse(c, pb, a);
7039 if (c->found_moov && c->found_mdat &&
7040 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
7041 start_pos + a.size == avio_size(pb))) {
7042 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
7043 c->next_root_atom = start_pos + a.size;
7047 left = a.size - avio_tell(pb) + start_pos;
7048 if (left > 0) /* skip garbage at atom end */
7049 avio_skip(pb, left);
7050 else if (left < 0) {
7051 av_log(c->fc, AV_LOG_WARNING,
7052 "overread end of atom '%.4s' by %"PRId64" bytes\n",
7053 (char*)&a.type, -left);
7054 avio_seek(pb, left, SEEK_CUR);
7058 total_size += a.size;
7061 if (total_size < atom.size && atom.size < 0x7ffff)
7062 avio_skip(pb, atom.size - total_size);
7068 static int mov_probe(const AVProbeData *p)
7073 int moov_offset = -1;
7075 /* check file header */
7078 /* ignore invalid offset */
7079 if ((offset + 8) > (unsigned int)p->buf_size)
7081 tag = AV_RL32(p->buf + offset + 4);
7083 /* check for obvious tags */
7084 case MKTAG('m','o','o','v'):
7085 moov_offset = offset + 4;
7086 case MKTAG('m','d','a','t'):
7087 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
7088 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
7089 case MKTAG('f','t','y','p'):
7090 if (AV_RB32(p->buf+offset) < 8 &&
7091 (AV_RB32(p->buf+offset) != 1 ||
7092 offset + 12 > (unsigned int)p->buf_size ||
7093 AV_RB64(p->buf+offset + 8) == 0)) {
7094 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7095 } else if (tag == MKTAG('f','t','y','p') &&
7096 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
7097 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
7099 score = FFMAX(score, 5);
7101 score = AVPROBE_SCORE_MAX;
7103 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7105 /* those are more common words, so rate then a bit less */
7106 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
7107 case MKTAG('w','i','d','e'):
7108 case MKTAG('f','r','e','e'):
7109 case MKTAG('j','u','n','k'):
7110 case MKTAG('p','i','c','t'):
7111 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
7112 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7114 case MKTAG(0x82,0x82,0x7f,0x7d):
7115 case MKTAG('s','k','i','p'):
7116 case MKTAG('u','u','i','d'):
7117 case MKTAG('p','r','f','l'):
7118 /* if we only find those cause probedata is too small at least rate them */
7119 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7120 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7123 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7126 if(score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
7127 /* moov atom in the header - we should make sure that this is not a
7128 * MOV-packed MPEG-PS */
7129 offset = moov_offset;
7131 while(offset < (p->buf_size - 16)){ /* Sufficient space */
7132 /* We found an actual hdlr atom */
7133 if(AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7134 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7135 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')){
7136 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7137 /* We found a media handler reference atom describing an
7138 * MPEG-PS-in-MOV, return a
7139 * low score to force expanding the probe window until
7140 * mpegps_probe finds what it needs */
7151 // must be done after parsing all trak because there's no order requirement
7152 static void mov_read_chapters(AVFormatContext *s)
7154 MOVContext *mov = s->priv_data;
7156 MOVStreamContext *sc;
7161 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7162 chapter_track = mov->chapter_tracks[j];
7164 for (i = 0; i < s->nb_streams; i++)
7165 if (s->streams[i]->id == chapter_track) {
7170 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7175 cur_pos = avio_tell(sc->pb);
7177 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7178 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7179 if (st->nb_index_entries) {
7180 // Retrieve the first frame, if possible
7182 AVIndexEntry *sample = &st->index_entries[0];
7183 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7184 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7188 if (av_get_packet(sc->pb, &pkt, sample->size) < 0)
7191 st->attached_pic = pkt;
7192 st->attached_pic.stream_index = st->index;
7193 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
7196 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7197 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7198 st->discard = AVDISCARD_ALL;
7199 for (i = 0; i < st->nb_index_entries; i++) {
7200 AVIndexEntry *sample = &st->index_entries[i];
7201 int64_t end = i+1 < st->nb_index_entries ? st->index_entries[i+1].timestamp : st->duration;
7206 if (end < sample->timestamp) {
7207 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7208 end = AV_NOPTS_VALUE;
7211 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7212 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7216 // the first two bytes are the length of the title
7217 len = avio_rb16(sc->pb);
7218 if (len > sample->size-2)
7220 title_len = 2*len + 1;
7221 if (!(title = av_mallocz(title_len)))
7224 // The samples could theoretically be in any encoding if there's an encd
7225 // atom following, but in practice are only utf-8 or utf-16, distinguished
7226 // instead by the presence of a BOM
7230 ch = avio_rb16(sc->pb);
7232 avio_get_str16be(sc->pb, len, title, title_len);
7233 else if (ch == 0xfffe)
7234 avio_get_str16le(sc->pb, len, title, title_len);
7237 if (len == 1 || len == 2)
7240 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7244 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7249 avio_seek(sc->pb, cur_pos, SEEK_SET);
7253 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7254 uint32_t value, int flags)
7257 char buf[AV_TIMECODE_STR_SIZE];
7258 AVRational rate = st->avg_frame_rate;
7259 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7262 av_dict_set(&st->metadata, "timecode",
7263 av_timecode_make_string(&tc, buf, value), 0);
7267 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7269 MOVStreamContext *sc = st->priv_data;
7270 char buf[AV_TIMECODE_STR_SIZE];
7271 int64_t cur_pos = avio_tell(sc->pb);
7272 int hh, mm, ss, ff, drop;
7274 if (!st->nb_index_entries)
7277 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7278 avio_skip(s->pb, 13);
7279 hh = avio_r8(s->pb);
7280 mm = avio_r8(s->pb);
7281 ss = avio_r8(s->pb);
7282 drop = avio_r8(s->pb);
7283 ff = avio_r8(s->pb);
7284 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7285 hh, mm, ss, drop ? ';' : ':', ff);
7286 av_dict_set(&st->metadata, "timecode", buf, 0);
7288 avio_seek(sc->pb, cur_pos, SEEK_SET);
7292 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7294 MOVStreamContext *sc = st->priv_data;
7296 int64_t cur_pos = avio_tell(sc->pb);
7299 if (!st->nb_index_entries)
7302 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7303 value = avio_rb32(s->pb);
7305 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7306 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7307 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7309 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7310 * not the case) and thus assume "frame number format" instead of QT one.
7311 * No sample with tmcd track can be found with a QT timecode at the moment,
7312 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7314 parse_timecode_in_framenum_format(s, st, value, flags);
7316 avio_seek(sc->pb, cur_pos, SEEK_SET);
7320 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7322 if (!index || !*index) return;
7323 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7324 av_encryption_info_free((*index)->encrypted_samples[i]);
7326 av_freep(&(*index)->encrypted_samples);
7327 av_freep(&(*index)->auxiliary_info_sizes);
7328 av_freep(&(*index)->auxiliary_offsets);
7332 static int mov_read_close(AVFormatContext *s)
7334 MOVContext *mov = s->priv_data;
7337 for (i = 0; i < s->nb_streams; i++) {
7338 AVStream *st = s->streams[i];
7339 MOVStreamContext *sc = st->priv_data;
7344 av_freep(&sc->ctts_data);
7345 for (j = 0; j < sc->drefs_count; j++) {
7346 av_freep(&sc->drefs[j].path);
7347 av_freep(&sc->drefs[j].dir);
7349 av_freep(&sc->drefs);
7351 sc->drefs_count = 0;
7353 if (!sc->pb_is_copied)
7354 ff_format_io_close(s, &sc->pb);
7357 av_freep(&sc->chunk_offsets);
7358 av_freep(&sc->stsc_data);
7359 av_freep(&sc->sample_sizes);
7360 av_freep(&sc->keyframes);
7361 av_freep(&sc->stts_data);
7362 av_freep(&sc->sdtp_data);
7363 av_freep(&sc->stps_data);
7364 av_freep(&sc->elst_data);
7365 av_freep(&sc->rap_group);
7366 av_freep(&sc->display_matrix);
7367 av_freep(&sc->index_ranges);
7370 for (j = 0; j < sc->stsd_count; j++)
7371 av_free(sc->extradata[j]);
7372 av_freep(&sc->extradata);
7373 av_freep(&sc->extradata_size);
7375 mov_free_encryption_index(&sc->cenc.encryption_index);
7376 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7377 av_aes_ctr_free(sc->cenc.aes_ctr);
7379 av_freep(&sc->stereo3d);
7380 av_freep(&sc->spherical);
7381 av_freep(&sc->mastering);
7382 av_freep(&sc->coll);
7385 if (mov->dv_demux) {
7386 avformat_free_context(mov->dv_fctx);
7387 mov->dv_fctx = NULL;
7390 if (mov->meta_keys) {
7391 for (i = 1; i < mov->meta_keys_count; i++) {
7392 av_freep(&mov->meta_keys[i]);
7394 av_freep(&mov->meta_keys);
7397 av_freep(&mov->trex_data);
7398 av_freep(&mov->bitrates);
7400 for (i = 0; i < mov->frag_index.nb_items; i++) {
7401 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7402 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7403 mov_free_encryption_index(&frag[j].encryption_index);
7405 av_freep(&mov->frag_index.item[i].stream_info);
7407 av_freep(&mov->frag_index.item);
7409 av_freep(&mov->aes_decrypt);
7410 av_freep(&mov->chapter_tracks);
7415 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7419 for (i = 0; i < s->nb_streams; i++) {
7420 AVStream *st = s->streams[i];
7421 MOVStreamContext *sc = st->priv_data;
7423 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7424 sc->timecode_track == tmcd_id)
7430 /* look for a tmcd track not referenced by any video track, and export it globally */
7431 static void export_orphan_timecode(AVFormatContext *s)
7435 for (i = 0; i < s->nb_streams; i++) {
7436 AVStream *st = s->streams[i];
7438 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7439 !tmcd_is_referenced(s, i + 1)) {
7440 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7442 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7449 static int read_tfra(MOVContext *mov, AVIOContext *f)
7451 int version, fieldlength, i, j;
7452 int64_t pos = avio_tell(f);
7453 uint32_t size = avio_rb32(f);
7454 unsigned track_id, item_count;
7456 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7459 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7461 version = avio_r8(f);
7463 track_id = avio_rb32(f);
7464 fieldlength = avio_rb32(f);
7465 item_count = avio_rb32(f);
7466 for (i = 0; i < item_count; i++) {
7467 int64_t time, offset;
7469 MOVFragmentStreamInfo * frag_stream_info;
7472 return AVERROR_INVALIDDATA;
7476 time = avio_rb64(f);
7477 offset = avio_rb64(f);
7479 time = avio_rb32(f);
7480 offset = avio_rb32(f);
7483 // The first sample of each stream in a fragment is always a random
7484 // access sample. So it's entry in the tfra can be used as the
7485 // initial PTS of the fragment.
7486 index = update_frag_index(mov, offset);
7487 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7488 if (frag_stream_info &&
7489 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7490 frag_stream_info->first_tfra_pts = time;
7492 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7494 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7496 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7500 avio_seek(f, pos + size, SEEK_SET);
7504 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7506 int64_t stream_size = avio_size(f);
7507 int64_t original_pos = avio_tell(f);
7511 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7515 mfra_size = avio_rb32(f);
7516 if (mfra_size < 0 || mfra_size > stream_size) {
7517 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7520 if ((seek_ret = avio_seek(f, -mfra_size, SEEK_CUR)) < 0) {
7524 if (avio_rb32(f) != mfra_size) {
7525 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7528 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7529 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7532 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7534 ret = read_tfra(c, f);
7540 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7542 av_log(c->fc, AV_LOG_ERROR,
7543 "failed to seek back after looking for mfra\n");
7549 static int mov_read_header(AVFormatContext *s)
7551 MOVContext *mov = s->priv_data;
7552 AVIOContext *pb = s->pb;
7554 MOVAtom atom = { AV_RL32("root") };
7557 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7558 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7559 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7560 return AVERROR(EINVAL);
7564 mov->trak_index = -1;
7565 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7566 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7567 atom.size = avio_size(pb);
7569 atom.size = INT64_MAX;
7571 /* check MOV header */
7573 if (mov->moov_retry)
7574 avio_seek(pb, 0, SEEK_SET);
7575 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7576 av_log(s, AV_LOG_ERROR, "error reading header\n");
7580 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7581 if (!mov->found_moov) {
7582 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7584 return AVERROR_INVALIDDATA;
7586 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7588 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7589 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7590 mov_read_chapters(s);
7591 for (i = 0; i < s->nb_streams; i++)
7592 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7593 mov_read_timecode_track(s, s->streams[i]);
7594 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7595 mov_read_rtmd_track(s, s->streams[i]);
7599 /* copy timecode metadata from tmcd tracks to the related video streams */
7600 for (i = 0; i < s->nb_streams; i++) {
7601 AVStream *st = s->streams[i];
7602 MOVStreamContext *sc = st->priv_data;
7603 if (sc->timecode_track > 0) {
7604 AVDictionaryEntry *tcr;
7605 int tmcd_st_id = -1;
7607 for (j = 0; j < s->nb_streams; j++)
7608 if (s->streams[j]->id == sc->timecode_track)
7611 if (tmcd_st_id < 0 || tmcd_st_id == i)
7613 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7615 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7618 export_orphan_timecode(s);
7620 for (i = 0; i < s->nb_streams; i++) {
7621 AVStream *st = s->streams[i];
7622 MOVStreamContext *sc = st->priv_data;
7623 fix_timescale(mov, sc);
7624 if(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7625 st->skip_samples = sc->start_pad;
7627 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7628 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7629 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7630 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7631 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7632 st->codecpar->width = sc->width;
7633 st->codecpar->height = sc->height;
7635 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7636 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7640 if (mov->handbrake_version &&
7641 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7642 st->codecpar->codec_id == AV_CODEC_ID_MP3
7644 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7645 st->need_parsing = AVSTREAM_PARSE_FULL;
7649 if (mov->trex_data) {
7650 for (i = 0; i < s->nb_streams; i++) {
7651 AVStream *st = s->streams[i];
7652 MOVStreamContext *sc = st->priv_data;
7653 if (st->duration > 0) {
7654 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7655 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7656 sc->data_size, sc->time_scale);
7658 return AVERROR_INVALIDDATA;
7660 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7665 if (mov->use_mfra_for > 0) {
7666 for (i = 0; i < s->nb_streams; i++) {
7667 AVStream *st = s->streams[i];
7668 MOVStreamContext *sc = st->priv_data;
7669 if (sc->duration_for_fps > 0) {
7670 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7671 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7672 sc->data_size, sc->time_scale);
7674 return AVERROR_INVALIDDATA;
7676 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7677 sc->duration_for_fps;
7682 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7683 if (mov->bitrates[i]) {
7684 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7688 ff_rfps_calculate(s);
7690 for (i = 0; i < s->nb_streams; i++) {
7691 AVStream *st = s->streams[i];
7692 MOVStreamContext *sc = st->priv_data;
7694 switch (st->codecpar->codec_type) {
7695 case AVMEDIA_TYPE_AUDIO:
7696 err = ff_replaygain_export(st, s->metadata);
7702 case AVMEDIA_TYPE_VIDEO:
7703 if (sc->display_matrix) {
7704 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7705 sizeof(int32_t) * 9);
7709 sc->display_matrix = NULL;
7712 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7713 (uint8_t *)sc->stereo3d,
7714 sizeof(*sc->stereo3d));
7718 sc->stereo3d = NULL;
7720 if (sc->spherical) {
7721 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7722 (uint8_t *)sc->spherical,
7723 sc->spherical_size);
7727 sc->spherical = NULL;
7729 if (sc->mastering) {
7730 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7731 (uint8_t *)sc->mastering,
7732 sizeof(*sc->mastering));
7736 sc->mastering = NULL;
7739 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7740 (uint8_t *)sc->coll,
7750 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7752 for (i = 0; i < mov->frag_index.nb_items; i++)
7753 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7754 mov->frag_index.item[i].headers_read = 1;
7759 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7761 AVIndexEntry *sample = NULL;
7762 int64_t best_dts = INT64_MAX;
7764 for (i = 0; i < s->nb_streams; i++) {
7765 AVStream *avst = s->streams[i];
7766 MOVStreamContext *msc = avst->priv_data;
7767 if (msc->pb && msc->current_sample < avst->nb_index_entries) {
7768 AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample];
7769 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7770 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7771 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7772 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7773 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb &&
7774 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7775 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7776 sample = current_sample;
7785 static int should_retry(AVIOContext *pb, int error_code) {
7786 if (error_code == AVERROR_EOF || avio_feof(pb))
7792 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7795 MOVContext *mov = s->priv_data;
7797 if (index >= 0 && index < mov->frag_index.nb_items)
7798 target = mov->frag_index.item[index].moof_offset;
7799 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7800 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7801 return AVERROR_INVALIDDATA;
7804 mov->next_root_atom = 0;
7805 if (index < 0 || index >= mov->frag_index.nb_items)
7806 index = search_frag_moof_offset(&mov->frag_index, target);
7807 if (index < mov->frag_index.nb_items &&
7808 mov->frag_index.item[index].moof_offset == target) {
7809 if (index + 1 < mov->frag_index.nb_items)
7810 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7811 if (mov->frag_index.item[index].headers_read)
7813 mov->frag_index.item[index].headers_read = 1;
7816 mov->found_mdat = 0;
7818 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7821 if (avio_feof(s->pb))
7823 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7828 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7830 uint8_t *side, *extradata;
7833 /* Save the current index. */
7834 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7836 /* Notify the decoder that extradata changed. */
7837 extradata_size = sc->extradata_size[sc->last_stsd_index];
7838 extradata = sc->extradata[sc->last_stsd_index];
7839 if (extradata_size > 0 && extradata) {
7840 side = av_packet_new_side_data(pkt,
7841 AV_PKT_DATA_NEW_EXTRADATA,
7844 return AVERROR(ENOMEM);
7845 memcpy(side, extradata, extradata_size);
7851 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7853 MOVContext *mov = s->priv_data;
7854 MOVStreamContext *sc;
7855 AVIndexEntry *sample;
7856 AVStream *st = NULL;
7857 int64_t current_index;
7861 sample = mov_find_next_sample(s, &st);
7862 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7863 if (!mov->next_root_atom)
7865 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7870 /* must be done just before reading, to avoid infinite loop on sample */
7871 current_index = sc->current_index;
7872 mov_current_sample_inc(sc);
7874 if (mov->next_root_atom) {
7875 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7876 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7879 if (st->discard != AVDISCARD_ALL) {
7880 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7881 if (ret64 != sample->pos) {
7882 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7883 sc->ffindex, sample->pos);
7884 if (should_retry(sc->pb, ret64)) {
7885 mov_current_sample_dec(sc);
7887 return AVERROR_INVALIDDATA;
7890 if( st->discard == AVDISCARD_NONKEY && 0==(sample->flags & AVINDEX_KEYFRAME) ) {
7891 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7895 ret = av_get_packet(sc->pb, pkt, sample->size);
7897 if (should_retry(sc->pb, ret)) {
7898 mov_current_sample_dec(sc);
7902 if (sc->has_palette) {
7905 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7907 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7909 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7910 sc->has_palette = 0;
7913 #if CONFIG_DV_DEMUXER
7914 if (mov->dv_demux && sc->dv_audio_container) {
7915 avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7916 av_freep(&pkt->data);
7918 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7923 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7924 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7925 st->need_parsing = AVSTREAM_PARSE_FULL;
7929 pkt->stream_index = sc->ffindex;
7930 pkt->dts = sample->timestamp;
7931 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7932 pkt->flags |= AV_PKT_FLAG_DISCARD;
7934 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7935 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
7936 /* update ctts context */
7938 if (sc->ctts_index < sc->ctts_count &&
7939 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
7941 sc->ctts_sample = 0;
7944 int64_t next_dts = (sc->current_sample < st->nb_index_entries) ?
7945 st->index_entries[sc->current_sample].timestamp : st->duration;
7947 if (next_dts >= pkt->dts)
7948 pkt->duration = next_dts - pkt->dts;
7949 pkt->pts = pkt->dts;
7951 if (st->discard == AVDISCARD_ALL)
7953 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
7954 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
7955 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
7956 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
7958 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
7959 pkt->pos = sample->pos;
7961 /* Multiple stsd handling. */
7962 if (sc->stsc_data) {
7963 /* Keep track of the stsc index for the given sample, then check
7964 * if the stsd index is different from the last used one. */
7966 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
7967 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
7969 sc->stsc_sample = 0;
7970 /* Do not check indexes after a switch. */
7971 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
7972 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
7973 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
7974 ret = mov_change_extradata(sc, pkt);
7981 aax_filter(pkt->data, pkt->size, mov);
7983 ret = cenc_filter(mov, st, sc, pkt, current_index);
7991 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
7993 MOVContext *mov = s->priv_data;
7996 if (!mov->frag_index.complete)
7999 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
8002 if (!mov->frag_index.item[index].headers_read)
8003 return mov_switch_root(s, -1, index);
8004 if (index + 1 < mov->frag_index.nb_items)
8005 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
8010 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
8012 MOVStreamContext *sc = st->priv_data;
8013 int sample, time_sample, ret;
8016 // Here we consider timestamp to be PTS, hence try to offset it so that we
8017 // can search over the DTS timeline.
8018 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
8020 ret = mov_seek_fragment(s, st, timestamp);
8024 sample = av_index_search_timestamp(st, timestamp, flags);
8025 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
8026 if (sample < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp)
8028 if (sample < 0) /* not sure what to do */
8029 return AVERROR_INVALIDDATA;
8030 mov_current_sample_set(sc, sample);
8031 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
8032 /* adjust ctts index */
8033 if (sc->ctts_data) {
8035 for (i = 0; i < sc->ctts_count; i++) {
8036 int next = time_sample + sc->ctts_data[i].count;
8037 if (next > sc->current_sample) {
8039 sc->ctts_sample = sc->current_sample - time_sample;
8046 /* adjust stsd index */
8047 if (sc->chunk_count) {
8049 for (i = 0; i < sc->stsc_count; i++) {
8050 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
8051 if (next > sc->current_sample) {
8053 sc->stsc_sample = sc->current_sample - time_sample;
8056 av_assert0(next == (int)next);
8064 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
8066 MOVContext *mc = s->priv_data;
8071 if (stream_index >= s->nb_streams)
8072 return AVERROR_INVALIDDATA;
8074 st = s->streams[stream_index];
8075 sample = mov_seek_stream(s, st, sample_time, flags);
8079 if (mc->seek_individually) {
8080 /* adjust seek timestamp to found sample timestamp */
8081 int64_t seek_timestamp = st->index_entries[sample].timestamp;
8083 for (i = 0; i < s->nb_streams; i++) {
8085 MOVStreamContext *sc = s->streams[i]->priv_data;
8087 st->skip_samples = (sample_time <= 0) ? sc->start_pad : 0;
8089 if (stream_index == i)
8092 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
8093 mov_seek_stream(s, st, timestamp, flags);
8096 for (i = 0; i < s->nb_streams; i++) {
8097 MOVStreamContext *sc;
8100 mov_current_sample_set(sc, 0);
8103 MOVStreamContext *sc;
8104 AVIndexEntry *entry = mov_find_next_sample(s, &st);
8106 return AVERROR_INVALIDDATA;
8108 if (sc->ffindex == stream_index && sc->current_sample == sample)
8110 mov_current_sample_inc(sc);
8116 #define OFFSET(x) offsetof(MOVContext, x)
8117 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
8118 static const AVOption mov_options[] = {
8119 {"use_absolute_path",
8120 "allow using absolute path when opening alias, this is a possible security issue",
8121 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
8123 {"seek_streams_individually",
8124 "Seek each stream individually to the closest point",
8125 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
8127 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
8129 {"advanced_editlist",
8130 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
8131 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
8133 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8136 "use mfra for fragment timestamps",
8137 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8138 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8140 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8141 FLAGS, "use_mfra_for" },
8142 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8143 FLAGS, "use_mfra_for" },
8144 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8145 FLAGS, "use_mfra_for" },
8146 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8147 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8148 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8149 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8150 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8151 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8152 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8153 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8154 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8155 .flags = AV_OPT_FLAG_DECODING_PARAM },
8156 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8157 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8158 {.i64 = 0}, 0, 1, FLAGS },
8163 static const AVClass mov_class = {
8164 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8165 .item_name = av_default_item_name,
8166 .option = mov_options,
8167 .version = LIBAVUTIL_VERSION_INT,
8170 AVInputFormat ff_mov_demuxer = {
8171 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8172 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8173 .priv_class = &mov_class,
8174 .priv_data_size = sizeof(MOVContext),
8175 .extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
8176 .read_probe = mov_probe,
8177 .read_header = mov_read_header,
8178 .read_packet = mov_read_packet,
8179 .read_close = mov_read_close,
8180 .read_seek = mov_read_seek,
8181 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,