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 if (sc->sample_sizes[i] < 0) {
2889 av_log(c->fc, AV_LOG_ERROR, "Invalid sample size %d\n", sc->sample_sizes[i]);
2890 return AVERROR_INVALIDDATA;
2892 sc->data_size += sc->sample_sizes[i];
2895 sc->sample_count = i;
2899 if (pb->eof_reached) {
2900 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSZ atom\n");
2907 static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2910 MOVStreamContext *sc;
2911 unsigned int i, entries, alloc_size = 0;
2913 int64_t total_sample_count=0;
2915 if (c->fc->nb_streams < 1)
2917 st = c->fc->streams[c->fc->nb_streams-1];
2920 avio_r8(pb); /* version */
2921 avio_rb24(pb); /* flags */
2922 entries = avio_rb32(pb);
2924 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
2925 c->fc->nb_streams-1, entries);
2928 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
2929 av_freep(&sc->stts_data);
2931 if (entries >= INT_MAX / sizeof(*sc->stts_data))
2932 return AVERROR(ENOMEM);
2934 for (i = 0; i < entries && !pb->eof_reached; i++) {
2935 int sample_duration;
2936 unsigned int sample_count;
2937 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
2938 MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
2939 min_entries * sizeof(*sc->stts_data));
2941 av_freep(&sc->stts_data);
2943 return AVERROR(ENOMEM);
2945 sc->stts_count = min_entries;
2946 sc->stts_data = stts_data;
2948 sample_count=avio_rb32(pb);
2949 sample_duration = avio_rb32(pb);
2951 sc->stts_data[i].count= sample_count;
2952 sc->stts_data[i].duration= sample_duration;
2954 av_log(c->fc, AV_LOG_TRACE, "sample_count=%d, sample_duration=%d\n",
2955 sample_count, sample_duration);
2957 duration+=(int64_t)sample_duration*(uint64_t)sample_count;
2958 total_sample_count+=sample_count;
2964 duration <= INT64_MAX - sc->duration_for_fps &&
2965 total_sample_count <= INT_MAX - sc->nb_frames_for_fps
2967 sc->duration_for_fps += duration;
2968 sc->nb_frames_for_fps += total_sample_count;
2971 if (pb->eof_reached) {
2972 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
2976 st->nb_frames= total_sample_count;
2978 st->duration= FFMIN(st->duration, duration);
2979 sc->track_end = duration;
2983 static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2986 MOVStreamContext *sc;
2989 if (c->fc->nb_streams < 1)
2991 st = c->fc->streams[c->fc->nb_streams - 1];
2994 avio_r8(pb); /* version */
2995 avio_rb24(pb); /* flags */
2996 entries = atom.size - 4;
2998 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
2999 c->fc->nb_streams - 1, entries);
3002 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3003 av_freep(&sc->sdtp_data);
3006 sc->sdtp_data = av_mallocz(entries);
3008 return AVERROR(ENOMEM);
3010 for (i = 0; i < entries && !pb->eof_reached; i++)
3011 sc->sdtp_data[i] = avio_r8(pb);
3017 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3020 if (duration == INT_MIN) {
3021 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3024 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3028 static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3031 MOVStreamContext *sc;
3032 unsigned int i, entries, ctts_count = 0;
3034 if (c->fc->nb_streams < 1)
3036 st = c->fc->streams[c->fc->nb_streams-1];
3039 avio_r8(pb); /* version */
3040 avio_rb24(pb); /* flags */
3041 entries = avio_rb32(pb);
3043 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3047 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3048 return AVERROR_INVALIDDATA;
3049 av_freep(&sc->ctts_data);
3050 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3052 return AVERROR(ENOMEM);
3054 for (i = 0; i < entries && !pb->eof_reached; i++) {
3055 int count =avio_rb32(pb);
3056 int duration =avio_rb32(pb);
3059 av_log(c->fc, AV_LOG_TRACE,
3060 "ignoring CTTS entry with count=%d duration=%d\n",
3065 add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3068 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3071 if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3072 av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3073 av_freep(&sc->ctts_data);
3079 mov_update_dts_shift(sc, duration, c->fc);
3082 sc->ctts_count = ctts_count;
3084 if (pb->eof_reached) {
3085 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3089 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3094 static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3097 MOVStreamContext *sc;
3098 unsigned int i, entries;
3100 uint32_t grouping_type;
3102 if (c->fc->nb_streams < 1)
3104 st = c->fc->streams[c->fc->nb_streams-1];
3107 version = avio_r8(pb); /* version */
3108 avio_rb24(pb); /* flags */
3109 grouping_type = avio_rl32(pb);
3110 if (grouping_type != MKTAG( 'r','a','p',' '))
3111 return 0; /* only support 'rap ' grouping */
3113 avio_rb32(pb); /* grouping_type_parameter */
3115 entries = avio_rb32(pb);
3119 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP atom\n");
3120 av_free(sc->rap_group);
3121 sc->rap_group_count = 0;
3122 sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group));
3124 return AVERROR(ENOMEM);
3126 for (i = 0; i < entries && !pb->eof_reached; i++) {
3127 sc->rap_group[i].count = avio_rb32(pb); /* sample_count */
3128 sc->rap_group[i].index = avio_rb32(pb); /* group_description_index */
3131 sc->rap_group_count = i;
3133 if (pb->eof_reached) {
3134 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3142 * Get ith edit list entry (media time, duration).
3144 static int get_edit_list_entry(MOVContext *mov,
3145 const MOVStreamContext *msc,
3146 unsigned int edit_list_index,
3147 int64_t *edit_list_media_time,
3148 int64_t *edit_list_duration,
3149 int64_t global_timescale)
3151 if (edit_list_index == msc->elst_count) {
3154 *edit_list_media_time = msc->elst_data[edit_list_index].time;
3155 *edit_list_duration = msc->elst_data[edit_list_index].duration;
3157 /* duration is in global timescale units;convert to msc timescale */
3158 if (global_timescale == 0) {
3159 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3162 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3168 * Find the closest previous frame to the timestamp_pts, in e_old index
3169 * entries. Searching for just any frame / just key frames can be controlled by
3170 * last argument 'flag'.
3171 * Note that if ctts_data is not NULL, we will always search for a key frame
3172 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3173 * return the first frame of the video.
3175 * Here the timestamp_pts is considered to be a presentation timestamp and
3176 * the timestamp of index entries are considered to be decoding timestamps.
3178 * Returns 0 if successful in finding a frame, else returns -1.
3179 * Places the found index corresponding output arg.
3181 * If ctts_old is not NULL, then refines the searched entry by searching
3182 * backwards from the found timestamp, to find the frame with correct PTS.
3184 * Places the found ctts_index and ctts_sample in corresponding output args.
3186 static int find_prev_closest_index(AVStream *st,
3187 AVIndexEntry *e_old,
3191 int64_t timestamp_pts,
3194 int64_t* ctts_index,
3195 int64_t* ctts_sample)
3197 MOVStreamContext *msc = st->priv_data;
3198 AVIndexEntry *e_keep = st->index_entries;
3199 int nb_keep = st->nb_index_entries;
3201 int64_t index_ctts_count;
3205 // If dts_shift > 0, then all the index timestamps will have to be offset by
3206 // at least dts_shift amount to obtain PTS.
3207 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3208 if (msc->dts_shift > 0) {
3209 timestamp_pts -= msc->dts_shift;
3212 st->index_entries = e_old;
3213 st->nb_index_entries = nb_old;
3214 *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3216 // Keep going backwards in the index entries until the timestamp is the same.
3218 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3220 if ((flag & AVSEEK_FLAG_ANY) ||
3221 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3227 // If we have CTTS then refine the search, by searching backwards over PTS
3228 // computed by adding corresponding CTTS durations to index timestamps.
3229 if (ctts_data && *index >= 0) {
3230 av_assert0(ctts_index);
3231 av_assert0(ctts_sample);
3232 // Find out the ctts_index for the found frame.
3235 for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3236 if (*ctts_index < ctts_count) {
3238 if (ctts_data[*ctts_index].count == *ctts_sample) {
3245 while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3246 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3247 // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3248 // compensated by dts_shift above.
3249 if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3250 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3255 if (*ctts_sample == 0) {
3257 if (*ctts_index >= 0)
3258 *ctts_sample = ctts_data[*ctts_index].count - 1;
3265 /* restore AVStream state*/
3266 st->index_entries = e_keep;
3267 st->nb_index_entries = nb_keep;
3268 return *index >= 0 ? 0 : -1;
3272 * Add index entry with the given values, to the end of st->index_entries.
3273 * Returns the new size st->index_entries if successful, else returns -1.
3275 * This function is similar to ff_add_index_entry in libavformat/utils.c
3276 * except that here we are always unconditionally adding an index entry to
3277 * the end, instead of searching the entries list and skipping the add if
3278 * there is an existing entry with the same timestamp.
3279 * This is needed because the mov_fix_index calls this func with the same
3280 * unincremented timestamp for successive discarded frames.
3282 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3283 int size, int distance, int flags)
3285 AVIndexEntry *entries, *ie;
3287 const size_t min_size_needed = (st->nb_index_entries + 1) * sizeof(AVIndexEntry);
3289 // Double the allocation each time, to lower memory fragmentation.
3290 // Another difference from ff_add_index_entry function.
3291 const size_t requested_size =
3292 min_size_needed > st->index_entries_allocated_size ?
3293 FFMAX(min_size_needed, 2 * st->index_entries_allocated_size) :
3296 if((unsigned)st->nb_index_entries + 1 >= UINT_MAX / sizeof(AVIndexEntry))
3299 entries = av_fast_realloc(st->index_entries,
3300 &st->index_entries_allocated_size,
3305 st->index_entries= entries;
3307 index= st->nb_index_entries++;
3308 ie= &entries[index];
3311 ie->timestamp = timestamp;
3312 ie->min_distance= distance;
3319 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3320 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3322 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3323 int64_t* frame_duration_buffer,
3324 int frame_duration_buffer_size) {
3326 av_assert0(end_index >= 0 && end_index <= st->nb_index_entries);
3327 for (i = 0; i < frame_duration_buffer_size; i++) {
3328 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3329 st->index_entries[end_index - 1 - i].timestamp = end_ts;
3334 * Append a new ctts entry to ctts_data.
3335 * Returns the new ctts_count if successful, else returns -1.
3337 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3338 int count, int duration)
3340 MOVStts *ctts_buf_new;
3341 const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVStts);
3342 const size_t requested_size =
3343 min_size_needed > *allocated_size ?
3344 FFMAX(min_size_needed, 2 * (*allocated_size)) :
3347 if((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
3350 ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3355 *ctts_data = ctts_buf_new;
3357 ctts_buf_new[*ctts_count].count = count;
3358 ctts_buf_new[*ctts_count].duration = duration;
3360 *ctts_count = (*ctts_count) + 1;
3364 #define MAX_REORDER_DELAY 16
3365 static void mov_estimate_video_delay(MOVContext *c, AVStream* st) {
3366 MOVStreamContext *msc = st->priv_data;
3369 int ctts_sample = 0;
3370 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3372 int j, r, num_swaps;
3374 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3375 pts_buf[j] = INT64_MIN;
3377 if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3378 st->codecpar->codec_id == AV_CODEC_ID_H264) {
3379 st->codecpar->video_delay = 0;
3380 for(ind = 0; ind < st->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3381 // Point j to the last elem of the buffer and insert the current pts there.
3383 buf_start = (buf_start + 1);
3384 if (buf_start == MAX_REORDER_DELAY + 1)
3387 pts_buf[j] = st->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3389 // The timestamps that are already in the sorted buffer, and are greater than the
3390 // current pts, are exactly the timestamps that need to be buffered to output PTS
3391 // in correct sorted order.
3392 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3393 // can be computed as the maximum no. of swaps any particular timestamp needs to
3394 // go through, to keep this buffer in sorted order.
3396 while (j != buf_start) {
3398 if (r < 0) r = MAX_REORDER_DELAY;
3399 if (pts_buf[j] < pts_buf[r]) {
3400 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3407 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3410 if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3415 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3416 st->codecpar->video_delay, st->index);
3420 static void mov_current_sample_inc(MOVStreamContext *sc)
3422 sc->current_sample++;
3423 sc->current_index++;
3424 if (sc->index_ranges &&
3425 sc->current_index >= sc->current_index_range->end &&
3426 sc->current_index_range->end) {
3427 sc->current_index_range++;
3428 sc->current_index = sc->current_index_range->start;
3432 static void mov_current_sample_dec(MOVStreamContext *sc)
3434 sc->current_sample--;
3435 sc->current_index--;
3436 if (sc->index_ranges &&
3437 sc->current_index < sc->current_index_range->start &&
3438 sc->current_index_range > sc->index_ranges) {
3439 sc->current_index_range--;
3440 sc->current_index = sc->current_index_range->end - 1;
3444 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3448 sc->current_sample = current_sample;
3449 sc->current_index = current_sample;
3450 if (!sc->index_ranges) {
3454 for (sc->current_index_range = sc->index_ranges;
3455 sc->current_index_range->end;
3456 sc->current_index_range++) {
3457 range_size = sc->current_index_range->end - sc->current_index_range->start;
3458 if (range_size > current_sample) {
3459 sc->current_index = sc->current_index_range->start + current_sample;
3462 current_sample -= range_size;
3467 * Fix st->index_entries, so that it contains only the entries (and the entries
3468 * which are needed to decode them) that fall in the edit list time ranges.
3469 * Also fixes the timestamps of the index entries to match the timeline
3470 * specified the edit lists.
3472 static void mov_fix_index(MOVContext *mov, AVStream *st)
3474 MOVStreamContext *msc = st->priv_data;
3475 AVIndexEntry *e_old = st->index_entries;
3476 int nb_old = st->nb_index_entries;
3477 const AVIndexEntry *e_old_end = e_old + nb_old;
3478 const AVIndexEntry *current = NULL;
3479 MOVStts *ctts_data_old = msc->ctts_data;
3480 int64_t ctts_index_old = 0;
3481 int64_t ctts_sample_old = 0;
3482 int64_t ctts_count_old = msc->ctts_count;
3483 int64_t edit_list_media_time = 0;
3484 int64_t edit_list_duration = 0;
3485 int64_t frame_duration = 0;
3486 int64_t edit_list_dts_counter = 0;
3487 int64_t edit_list_dts_entry_end = 0;
3488 int64_t edit_list_start_ctts_sample = 0;
3490 int64_t curr_ctts = 0;
3491 int64_t empty_edits_sum_duration = 0;
3492 int64_t edit_list_index = 0;
3495 int64_t start_dts = 0;
3496 int64_t edit_list_start_encountered = 0;
3497 int64_t search_timestamp = 0;
3498 int64_t* frame_duration_buffer = NULL;
3499 int num_discarded_begin = 0;
3500 int first_non_zero_audio_edit = -1;
3501 int packet_skip_samples = 0;
3502 MOVIndexRange *current_index_range;
3504 int found_keyframe_after_edit = 0;
3505 int found_non_empty_edit = 0;
3507 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
3511 // allocate the index ranges array
3512 msc->index_ranges = av_malloc((msc->elst_count + 1) * sizeof(msc->index_ranges[0]));
3513 if (!msc->index_ranges) {
3514 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
3517 msc->current_index_range = msc->index_ranges;
3518 current_index_range = msc->index_ranges - 1;
3520 // Clean AVStream from traces of old index
3521 st->index_entries = NULL;
3522 st->index_entries_allocated_size = 0;
3523 st->nb_index_entries = 0;
3525 // Clean ctts fields of MOVStreamContext
3526 msc->ctts_data = NULL;
3527 msc->ctts_count = 0;
3528 msc->ctts_index = 0;
3529 msc->ctts_sample = 0;
3530 msc->ctts_allocated_size = 0;
3532 // Reinitialize min_corrected_pts so that it can be computed again.
3533 msc->min_corrected_pts = -1;
3535 // If the dts_shift is positive (in case of negative ctts values in mov),
3536 // then negate the DTS by dts_shift
3537 if (msc->dts_shift > 0) {
3538 edit_list_dts_entry_end -= msc->dts_shift;
3539 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
3542 start_dts = edit_list_dts_entry_end;
3544 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
3545 &edit_list_duration, mov->time_scale)) {
3546 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
3547 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
3549 edit_list_dts_counter = edit_list_dts_entry_end;
3550 edit_list_dts_entry_end += edit_list_duration;
3551 num_discarded_begin = 0;
3552 if (!found_non_empty_edit && edit_list_media_time == -1) {
3553 empty_edits_sum_duration += edit_list_duration;
3556 found_non_empty_edit = 1;
3558 // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
3559 // according to the edit list below.
3560 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3561 if (first_non_zero_audio_edit < 0) {
3562 first_non_zero_audio_edit = 1;
3564 first_non_zero_audio_edit = 0;
3567 if (first_non_zero_audio_edit > 0)
3568 st->skip_samples = msc->start_pad = 0;
3571 // While reordering frame index according to edit list we must handle properly
3572 // the scenario when edit list entry starts from none key frame.
3573 // We find closest previous key frame and preserve it and consequent frames in index.
3574 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
3575 search_timestamp = edit_list_media_time;
3576 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3577 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
3578 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
3579 // edit_list_media_time to cover the decoder delay.
3580 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
3583 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
3584 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3585 av_log(mov->fc, AV_LOG_WARNING,
3586 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
3587 st->index, edit_list_index, search_timestamp);
3588 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
3589 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3590 av_log(mov->fc, AV_LOG_WARNING,
3591 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
3592 st->index, edit_list_index, search_timestamp);
3595 ctts_sample_old = 0;
3598 current = e_old + index;
3599 edit_list_start_ctts_sample = ctts_sample_old;
3601 // Iterate over index and arrange it according to edit list
3602 edit_list_start_encountered = 0;
3603 found_keyframe_after_edit = 0;
3604 for (; current < e_old_end; current++, index++) {
3605 // check if frame outside edit list mark it for discard
3606 frame_duration = (current + 1 < e_old_end) ?
3607 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
3609 flags = current->flags;
3611 // frames (pts) before or after edit list
3612 curr_cts = current->timestamp + msc->dts_shift;
3615 if (ctts_data_old && ctts_index_old < ctts_count_old) {
3616 curr_ctts = ctts_data_old[ctts_index_old].duration;
3617 av_log(mov->fc, AV_LOG_DEBUG, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
3618 curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
3619 curr_cts += curr_ctts;
3621 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
3622 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3623 &msc->ctts_allocated_size,
3624 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3625 ctts_data_old[ctts_index_old].duration) == -1) {
3626 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3628 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3629 ctts_data_old[ctts_index_old].duration);
3633 ctts_sample_old = 0;
3634 edit_list_start_ctts_sample = 0;
3638 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
3639 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
3640 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
3641 first_non_zero_audio_edit > 0) {
3642 packet_skip_samples = edit_list_media_time - curr_cts;
3643 st->skip_samples += packet_skip_samples;
3645 // Shift the index entry timestamp by packet_skip_samples to be correct.
3646 edit_list_dts_counter -= packet_skip_samples;
3647 if (edit_list_start_encountered == 0) {
3648 edit_list_start_encountered = 1;
3649 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
3650 // discarded packets.
3651 if (frame_duration_buffer) {
3652 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3653 frame_duration_buffer, num_discarded_begin);
3654 av_freep(&frame_duration_buffer);
3658 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
3660 flags |= AVINDEX_DISCARD_FRAME;
3661 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
3663 if (edit_list_start_encountered == 0) {
3664 num_discarded_begin++;
3665 frame_duration_buffer = av_realloc(frame_duration_buffer,
3666 num_discarded_begin * sizeof(int64_t));
3667 if (!frame_duration_buffer) {
3668 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
3671 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
3673 // Increment skip_samples for the first non-zero audio edit list
3674 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3675 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
3676 st->skip_samples += frame_duration;
3681 if (msc->min_corrected_pts < 0) {
3682 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
3684 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
3686 if (edit_list_start_encountered == 0) {
3687 edit_list_start_encountered = 1;
3688 // Make timestamps strictly monotonically increasing by rewriting timestamps for
3689 // discarded packets.
3690 if (frame_duration_buffer) {
3691 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3692 frame_duration_buffer, num_discarded_begin);
3693 av_freep(&frame_duration_buffer);
3698 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
3699 current->min_distance, flags) == -1) {
3700 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
3704 // Update the index ranges array
3705 if (current_index_range < msc->index_ranges || index != current_index_range->end) {
3706 current_index_range++;
3707 current_index_range->start = index;
3709 current_index_range->end = index + 1;
3711 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
3712 if (edit_list_start_encountered > 0) {
3713 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
3716 // Break when found first key frame after edit entry completion
3717 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
3718 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
3719 if (ctts_data_old) {
3720 // If we have CTTS and this is the first keyframe after edit elist,
3721 // wait for one more, because there might be trailing B-frames after this I-frame
3722 // that do belong to the edit.
3723 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
3724 found_keyframe_after_edit = 1;
3727 if (ctts_sample_old != 0) {
3728 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3729 &msc->ctts_allocated_size,
3730 ctts_sample_old - edit_list_start_ctts_sample,
3731 ctts_data_old[ctts_index_old].duration) == -1) {
3732 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3733 ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
3734 ctts_data_old[ctts_index_old].duration);
3743 // If there are empty edits, then msc->min_corrected_pts might be positive
3744 // intentionally. So we subtract the sum duration of emtpy edits here.
3745 msc->min_corrected_pts -= empty_edits_sum_duration;
3747 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
3748 // dts by that amount to make the first pts zero.
3749 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
3750 if (msc->min_corrected_pts > 0) {
3751 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
3752 for (i = 0; i < st->nb_index_entries; ++i) {
3753 st->index_entries[i].timestamp -= msc->min_corrected_pts;
3757 // Start time should be equal to zero or the duration of any empty edits.
3758 st->start_time = empty_edits_sum_duration;
3760 // Update av stream length, if it ends up shorter than the track's media duration
3761 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
3762 msc->start_pad = st->skip_samples;
3764 // Free the old index and the old CTTS structures
3766 av_free(ctts_data_old);
3767 av_freep(&frame_duration_buffer);
3769 // Null terminate the index ranges array
3770 current_index_range++;
3771 current_index_range->start = 0;
3772 current_index_range->end = 0;
3773 msc->current_index = msc->index_ranges[0].start;
3776 static void mov_build_index(MOVContext *mov, AVStream *st)
3778 MOVStreamContext *sc = st->priv_data;
3779 int64_t current_offset;
3780 int64_t current_dts = 0;
3781 unsigned int stts_index = 0;
3782 unsigned int stsc_index = 0;
3783 unsigned int stss_index = 0;
3784 unsigned int stps_index = 0;
3786 uint64_t stream_size = 0;
3787 MOVStts *ctts_data_old = sc->ctts_data;
3788 unsigned int ctts_count_old = sc->ctts_count;
3790 if (sc->elst_count) {
3791 int i, edit_start_index = 0, multiple_edits = 0;
3792 int64_t empty_duration = 0; // empty duration of the first edit list entry
3793 int64_t start_time = 0; // start time of the media
3795 for (i = 0; i < sc->elst_count; i++) {
3796 const MOVElst *e = &sc->elst_data[i];
3797 if (i == 0 && e->time == -1) {
3798 /* if empty, the first entry is the start time of the stream
3799 * relative to the presentation itself */
3800 empty_duration = e->duration;
3801 edit_start_index = 1;
3802 } else if (i == edit_start_index && e->time >= 0) {
3803 start_time = e->time;
3809 if (multiple_edits && !mov->advanced_editlist)
3810 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
3811 "Use -advanced_editlist to correctly decode otherwise "
3812 "a/v desync might occur\n");
3814 /* adjust first dts according to edit list */
3815 if ((empty_duration || start_time) && mov->time_scale > 0) {
3817 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
3818 sc->time_offset = start_time - empty_duration;
3819 sc->min_corrected_pts = start_time;
3820 if (!mov->advanced_editlist)
3821 current_dts = -sc->time_offset;
3824 if (!multiple_edits && !mov->advanced_editlist &&
3825 st->codecpar->codec_id == AV_CODEC_ID_AAC && start_time > 0)
3826 sc->start_pad = start_time;
3829 /* only use old uncompressed audio chunk demuxing when stts specifies it */
3830 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3831 sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
3832 unsigned int current_sample = 0;
3833 unsigned int stts_sample = 0;
3834 unsigned int sample_size;
3835 unsigned int distance = 0;
3836 unsigned int rap_group_index = 0;
3837 unsigned int rap_group_sample = 0;
3838 int64_t last_dts = 0;
3839 int64_t dts_correction = 0;
3840 int rap_group_present = sc->rap_group_count && sc->rap_group;
3841 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
3843 current_dts -= sc->dts_shift;
3844 last_dts = current_dts;
3846 if (!sc->sample_count || st->nb_index_entries)
3848 if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
3850 if (av_reallocp_array(&st->index_entries,
3851 st->nb_index_entries + sc->sample_count,
3852 sizeof(*st->index_entries)) < 0) {
3853 st->nb_index_entries = 0;
3856 st->index_entries_allocated_size = (st->nb_index_entries + sc->sample_count) * sizeof(*st->index_entries);
3858 if (ctts_data_old) {
3859 // Expand ctts entries such that we have a 1-1 mapping with samples
3860 if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
3863 sc->ctts_allocated_size = 0;
3864 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size,
3865 sc->sample_count * sizeof(*sc->ctts_data));
3866 if (!sc->ctts_data) {
3867 av_free(ctts_data_old);
3871 memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
3873 for (i = 0; i < ctts_count_old &&
3874 sc->ctts_count < sc->sample_count; i++)
3875 for (j = 0; j < ctts_data_old[i].count &&
3876 sc->ctts_count < sc->sample_count; j++)
3877 add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
3878 &sc->ctts_allocated_size, 1,
3879 ctts_data_old[i].duration);
3880 av_free(ctts_data_old);
3883 for (i = 0; i < sc->chunk_count; i++) {
3884 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
3885 current_offset = sc->chunk_offsets[i];
3886 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3887 i + 1 == sc->stsc_data[stsc_index + 1].first)
3890 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
3891 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
3892 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
3893 sc->stsz_sample_size = sc->sample_size;
3895 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
3896 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
3897 sc->stsz_sample_size = sc->sample_size;
3900 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
3902 if (current_sample >= sc->sample_count) {
3903 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
3907 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
3909 if (stss_index + 1 < sc->keyframe_count)
3911 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
3913 if (stps_index + 1 < sc->stps_count)
3916 if (rap_group_present && rap_group_index < sc->rap_group_count) {
3917 if (sc->rap_group[rap_group_index].index > 0)
3919 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
3920 rap_group_sample = 0;
3924 if (sc->keyframe_absent
3926 && !rap_group_present
3927 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
3931 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
3932 if (sc->pseudo_stream_id == -1 ||
3933 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
3935 if (sample_size > 0x3FFFFFFF) {
3936 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
3939 e = &st->index_entries[st->nb_index_entries++];
3940 e->pos = current_offset;
3941 e->timestamp = current_dts;
3942 e->size = sample_size;
3943 e->min_distance = distance;
3944 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
3945 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
3946 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
3947 current_offset, current_dts, sample_size, distance, keyframe);
3948 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries < 100)
3949 ff_rfps_add_frame(mov->fc, st, current_dts);
3952 current_offset += sample_size;
3953 stream_size += sample_size;
3955 /* A negative sample duration is invalid based on the spec,
3956 * but some samples need it to correct the DTS. */
3957 if (sc->stts_data[stts_index].duration < 0) {
3958 av_log(mov->fc, AV_LOG_WARNING,
3959 "Invalid SampleDelta %d in STTS, at %d st:%d\n",
3960 sc->stts_data[stts_index].duration, stts_index,
3962 dts_correction += sc->stts_data[stts_index].duration - 1;
3963 sc->stts_data[stts_index].duration = 1;
3965 current_dts += sc->stts_data[stts_index].duration;
3966 if (!dts_correction || current_dts + dts_correction > last_dts) {
3967 current_dts += dts_correction;
3970 /* Avoid creating non-monotonous DTS */
3971 dts_correction += current_dts - last_dts - 1;
3972 current_dts = last_dts + 1;
3974 last_dts = current_dts;
3978 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
3984 if (st->duration > 0)
3985 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
3987 unsigned chunk_samples, total = 0;
3989 if (!sc->chunk_count)
3992 // compute total chunk count
3993 for (i = 0; i < sc->stsc_count; i++) {
3994 unsigned count, chunk_count;
3996 chunk_samples = sc->stsc_data[i].count;
3997 if (i != sc->stsc_count - 1 &&
3998 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
3999 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
4003 if (sc->samples_per_frame >= 160) { // gsm
4004 count = chunk_samples / sc->samples_per_frame;
4005 } else if (sc->samples_per_frame > 1) {
4006 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4007 count = (chunk_samples+samples-1) / samples;
4009 count = (chunk_samples+1023) / 1024;
4012 if (mov_stsc_index_valid(i, sc->stsc_count))
4013 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4015 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4016 total += chunk_count * count;
4019 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4020 if (total >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
4022 if (av_reallocp_array(&st->index_entries,
4023 st->nb_index_entries + total,
4024 sizeof(*st->index_entries)) < 0) {
4025 st->nb_index_entries = 0;
4028 st->index_entries_allocated_size = (st->nb_index_entries + total) * sizeof(*st->index_entries);
4031 for (i = 0; i < sc->chunk_count; i++) {
4032 current_offset = sc->chunk_offsets[i];
4033 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4034 i + 1 == sc->stsc_data[stsc_index + 1].first)
4036 chunk_samples = sc->stsc_data[stsc_index].count;
4038 while (chunk_samples > 0) {
4040 unsigned size, samples;
4042 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4043 avpriv_request_sample(mov->fc,
4044 "Zero bytes per frame, but %d samples per frame",
4045 sc->samples_per_frame);
4049 if (sc->samples_per_frame >= 160) { // gsm
4050 samples = sc->samples_per_frame;
4051 size = sc->bytes_per_frame;
4053 if (sc->samples_per_frame > 1) {
4054 samples = FFMIN((1024 / sc->samples_per_frame)*
4055 sc->samples_per_frame, chunk_samples);
4056 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
4058 samples = FFMIN(1024, chunk_samples);
4059 size = samples * sc->sample_size;
4063 if (st->nb_index_entries >= total) {
4064 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4067 if (size > 0x3FFFFFFF) {
4068 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4071 e = &st->index_entries[st->nb_index_entries++];
4072 e->pos = current_offset;
4073 e->timestamp = current_dts;
4075 e->min_distance = 0;
4076 e->flags = AVINDEX_KEYFRAME;
4077 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4078 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4081 current_offset += size;
4082 current_dts += samples;
4083 chunk_samples -= samples;
4088 if (!mov->ignore_editlist && mov->advanced_editlist) {
4089 // Fix index according to edit lists.
4090 mov_fix_index(mov, st);
4093 // Update start time of the stream.
4094 if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries > 0) {
4095 st->start_time = st->index_entries[0].timestamp + sc->dts_shift;
4096 if (sc->ctts_data) {
4097 st->start_time += sc->ctts_data[0].duration;
4101 mov_estimate_video_delay(mov, st);
4104 static int test_same_origin(const char *src, const char *ref) {
4114 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4115 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4117 if (strlen(src) == 0) {
4119 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4120 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4121 strlen(src_host) + 1 >= sizeof(src_host) ||
4122 strlen(ref_host) + 1 >= sizeof(ref_host)) {
4124 } else if (strcmp(src_proto, ref_proto) ||
4125 strcmp(src_auth, ref_auth) ||
4126 strcmp(src_host, ref_host) ||
4127 src_port != ref_port) {
4133 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4135 /* try relative path, we do not try the absolute because it can leak information about our
4136 system to an attacker */
4137 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4138 char filename[1025];
4139 const char *src_path;
4142 /* find a source dir */
4143 src_path = strrchr(src, '/');
4149 /* find a next level down to target */
4150 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4151 if (ref->path[l] == '/') {
4152 if (i == ref->nlvl_to - 1)
4158 /* compose filename if next level down to target was found */
4159 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4160 memcpy(filename, src, src_path - src);
4161 filename[src_path - src] = 0;
4163 for (i = 1; i < ref->nlvl_from; i++)
4164 av_strlcat(filename, "../", sizeof(filename));
4166 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4167 if (!c->use_absolute_path) {
4168 int same_origin = test_same_origin(src, filename);
4171 av_log(c->fc, AV_LOG_ERROR,
4172 "Reference with mismatching origin, %s not tried for security reasons, "
4173 "set demuxer option use_absolute_path to allow it anyway\n",
4175 return AVERROR(ENOENT);
4178 if(strstr(ref->path + l + 1, "..") ||
4179 strstr(ref->path + l + 1, ":") ||
4180 (ref->nlvl_from > 1 && same_origin < 0) ||
4181 (filename[0] == '/' && src_path == src))
4182 return AVERROR(ENOENT);
4185 if (strlen(filename) + 1 == sizeof(filename))
4186 return AVERROR(ENOENT);
4187 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4190 } else if (c->use_absolute_path) {
4191 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4192 "this is a possible security issue\n");
4193 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4196 av_log(c->fc, AV_LOG_ERROR,
4197 "Absolute path %s not tried for security reasons, "
4198 "set demuxer option use_absolute_path to allow absolute paths\n",
4202 return AVERROR(ENOENT);
4205 static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
4207 if (sc->time_scale <= 0) {
4208 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4209 sc->time_scale = c->time_scale;
4210 if (sc->time_scale <= 0)
4215 static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4218 MOVStreamContext *sc;
4221 st = avformat_new_stream(c->fc, NULL);
4222 if (!st) return AVERROR(ENOMEM);
4224 sc = av_mallocz(sizeof(MOVStreamContext));
4225 if (!sc) return AVERROR(ENOMEM);
4228 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
4229 sc->ffindex = st->index;
4230 c->trak_index = st->index;
4232 if ((ret = mov_read_default(c, pb, atom)) < 0)
4237 // Here stsc refers to a chunk not described in stco. This is technically invalid,
4238 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4239 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4241 av_freep(&sc->stsc_data);
4245 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4246 (!sc->sample_size && !sc->sample_count))) ||
4247 (!sc->chunk_count && sc->sample_count)) {
4248 av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4252 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4253 av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4255 return AVERROR_INVALIDDATA;
4258 fix_timescale(c, sc);
4260 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4262 mov_build_index(c, st);
4264 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4265 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4266 if (c->enable_drefs) {
4267 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4268 av_log(c->fc, AV_LOG_ERROR,
4269 "stream %d, error opening alias: path='%s', dir='%s', "
4270 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4271 st->index, dref->path, dref->dir, dref->filename,
4272 dref->volume, dref->nlvl_from, dref->nlvl_to);
4274 av_log(c->fc, AV_LOG_WARNING,
4275 "Skipped opening external track: "
4276 "stream %d, alias: path='%s', dir='%s', "
4277 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4278 "Set enable_drefs to allow this.\n",
4279 st->index, dref->path, dref->dir, dref->filename,
4280 dref->volume, dref->nlvl_from, dref->nlvl_to);
4284 sc->pb_is_copied = 1;
4287 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4288 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4289 sc->height && sc->width &&
4290 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4291 st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4292 ((double)st->codecpar->width * sc->height), INT_MAX);
4295 #if FF_API_R_FRAME_RATE
4296 if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4297 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
4298 sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4302 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4303 if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4304 TAG_IS_AVCI(st->codecpar->codec_tag)) {
4305 ret = ff_generate_avci_extradata(st);
4310 switch (st->codecpar->codec_id) {
4311 #if CONFIG_H261_DECODER
4312 case AV_CODEC_ID_H261:
4314 #if CONFIG_H263_DECODER
4315 case AV_CODEC_ID_H263:
4317 #if CONFIG_MPEG4_DECODER
4318 case AV_CODEC_ID_MPEG4:
4320 st->codecpar->width = 0; /* let decoder init width/height */
4321 st->codecpar->height= 0;
4325 // If the duration of the mp3 packets is not constant, then they could need a parser
4326 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4327 && sc->stts_count > 3
4328 && sc->stts_count*10 > st->nb_frames
4329 && sc->time_scale == st->codecpar->sample_rate) {
4330 st->need_parsing = AVSTREAM_PARSE_FULL;
4332 /* Do not need those anymore. */
4333 av_freep(&sc->chunk_offsets);
4334 av_freep(&sc->sample_sizes);
4335 av_freep(&sc->keyframes);
4336 av_freep(&sc->stts_data);
4337 av_freep(&sc->stps_data);
4338 av_freep(&sc->elst_data);
4339 av_freep(&sc->rap_group);
4344 static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4347 c->itunes_metadata = 1;
4348 ret = mov_read_default(c, pb, atom);
4349 c->itunes_metadata = 0;
4353 static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4362 count = avio_rb32(pb);
4363 if (count > UINT_MAX / sizeof(*c->meta_keys) - 1) {
4364 av_log(c->fc, AV_LOG_ERROR,
4365 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
4366 return AVERROR_INVALIDDATA;
4369 c->meta_keys_count = count + 1;
4370 c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
4372 return AVERROR(ENOMEM);
4374 for (i = 1; i <= count; ++i) {
4375 uint32_t key_size = avio_rb32(pb);
4376 uint32_t type = avio_rl32(pb);
4378 av_log(c->fc, AV_LOG_ERROR,
4379 "The key# %"PRIu32" in meta has invalid size:"
4380 "%"PRIu32"\n", i, key_size);
4381 return AVERROR_INVALIDDATA;
4384 if (type != MKTAG('m','d','t','a')) {
4385 avio_skip(pb, key_size);
4387 c->meta_keys[i] = av_mallocz(key_size + 1);
4388 if (!c->meta_keys[i])
4389 return AVERROR(ENOMEM);
4390 avio_read(pb, c->meta_keys[i], key_size);
4396 static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4398 int64_t end = avio_tell(pb) + atom.size;
4399 uint8_t *key = NULL, *val = NULL, *mean = NULL;
4403 MOVStreamContext *sc;
4405 if (c->fc->nb_streams < 1)
4407 st = c->fc->streams[c->fc->nb_streams-1];
4410 for (i = 0; i < 3; i++) {
4414 if (end - avio_tell(pb) <= 12)
4417 len = avio_rb32(pb);
4418 tag = avio_rl32(pb);
4419 avio_skip(pb, 4); // flags
4421 if (len < 12 || len - 12 > end - avio_tell(pb))
4425 if (tag == MKTAG('m', 'e', 'a', 'n'))
4427 else if (tag == MKTAG('n', 'a', 'm', 'e'))
4429 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
4436 *p = av_malloc(len + 1);
4438 ret = AVERROR(ENOMEM);
4441 ret = ffio_read_size(pb, *p, len);
4449 if (mean && key && val) {
4450 if (strcmp(key, "iTunSMPB") == 0) {
4451 int priming, remainder, samples;
4452 if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
4453 if(priming>0 && priming<16384)
4454 sc->start_pad = priming;
4457 if (strcmp(key, "cdec") != 0) {
4458 av_dict_set(&c->fc->metadata, key, val,
4459 AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
4463 av_log(c->fc, AV_LOG_VERBOSE,
4464 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
4467 avio_seek(pb, end, SEEK_SET);
4474 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4476 while (atom.size > 8) {
4480 tag = avio_rl32(pb);
4482 if (tag == MKTAG('h','d','l','r')) {
4483 avio_seek(pb, -8, SEEK_CUR);
4485 return mov_read_default(c, pb, atom);
4491 // return 1 when matrix is identity, 0 otherwise
4492 #define IS_MATRIX_IDENT(matrix) \
4493 ( (matrix)[0][0] == (1 << 16) && \
4494 (matrix)[1][1] == (1 << 16) && \
4495 (matrix)[2][2] == (1 << 30) && \
4496 !(matrix)[0][1] && !(matrix)[0][2] && \
4497 !(matrix)[1][0] && !(matrix)[1][2] && \
4498 !(matrix)[2][0] && !(matrix)[2][1])
4500 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4505 int display_matrix[3][3];
4506 int res_display_matrix[3][3] = { { 0 } };
4508 MOVStreamContext *sc;
4512 if (c->fc->nb_streams < 1)
4514 st = c->fc->streams[c->fc->nb_streams-1];
4517 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4518 // avoids corrupting AVStreams mapped to an earlier tkhd.
4520 return AVERROR_INVALIDDATA;
4522 version = avio_r8(pb);
4523 flags = avio_rb24(pb);
4524 st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
4530 avio_rb32(pb); /* creation time */
4531 avio_rb32(pb); /* modification time */
4533 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4534 avio_rb32(pb); /* reserved */
4536 /* highlevel (considering edits) duration in movie timebase */
4537 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4538 avio_rb32(pb); /* reserved */
4539 avio_rb32(pb); /* reserved */
4541 avio_rb16(pb); /* layer */
4542 avio_rb16(pb); /* alternate group */
4543 avio_rb16(pb); /* volume */
4544 avio_rb16(pb); /* reserved */
4546 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4547 // they're kept in fixed point format through all calculations
4548 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4549 // side data, but the scale factor is not needed to calculate aspect ratio
4550 for (i = 0; i < 3; i++) {
4551 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
4552 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
4553 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
4556 width = avio_rb32(pb); // 16.16 fixed point track width
4557 height = avio_rb32(pb); // 16.16 fixed point track height
4558 sc->width = width >> 16;
4559 sc->height = height >> 16;
4561 // apply the moov display matrix (after the tkhd one)
4562 for (i = 0; i < 3; i++) {
4563 const int sh[3] = { 16, 16, 30 };
4564 for (j = 0; j < 3; j++) {
4565 for (e = 0; e < 3; e++) {
4566 res_display_matrix[i][j] +=
4567 ((int64_t) display_matrix[i][e] *
4568 c->movie_display_matrix[e][j]) >> sh[e];
4573 // save the matrix when it is not the default identity
4574 if (!IS_MATRIX_IDENT(res_display_matrix)) {
4577 av_freep(&sc->display_matrix);
4578 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4579 if (!sc->display_matrix)
4580 return AVERROR(ENOMEM);
4582 for (i = 0; i < 3; i++)
4583 for (j = 0; j < 3; j++)
4584 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4586 #if FF_API_OLD_ROTATE_API
4587 rotate = av_display_rotation_get(sc->display_matrix);
4588 if (!isnan(rotate)) {
4589 char rotate_buf[64];
4591 if (rotate < 0) // for backward compatibility
4593 snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate);
4594 av_dict_set(&st->metadata, "rotate", rotate_buf, 0);
4599 // transform the display width/height according to the matrix
4600 // to keep the same scale, use [width height 1<<16]
4601 if (width && height && sc->display_matrix) {
4602 double disp_transform[2];
4604 for (i = 0; i < 2; i++)
4605 disp_transform[i] = hypot(sc->display_matrix[0 + i],
4606 sc->display_matrix[3 + i]);
4608 if (disp_transform[0] > 0 && disp_transform[1] > 0 &&
4609 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4610 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4611 st->sample_aspect_ratio = av_d2q(
4612 disp_transform[0] / disp_transform[1],
4618 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4620 MOVFragment *frag = &c->fragment;
4621 MOVTrackExt *trex = NULL;
4622 int flags, track_id, i;
4623 MOVFragmentStreamInfo * frag_stream_info;
4625 avio_r8(pb); /* version */
4626 flags = avio_rb24(pb);
4628 track_id = avio_rb32(pb);
4630 return AVERROR_INVALIDDATA;
4631 for (i = 0; i < c->trex_count; i++)
4632 if (c->trex_data[i].track_id == track_id) {
4633 trex = &c->trex_data[i];
4637 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4640 c->fragment.found_tfhd = 1;
4641 frag->track_id = track_id;
4642 set_frag_stream(&c->frag_index, track_id);
4644 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4645 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4646 frag->moof_offset : frag->implicit_offset;
4647 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4649 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4650 avio_rb32(pb) : trex->duration;
4651 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4652 avio_rb32(pb) : trex->size;
4653 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4654 avio_rb32(pb) : trex->flags;
4655 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4657 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4658 if (frag_stream_info)
4659 frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
4664 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4669 num = atom.size / 4;
4670 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4671 return AVERROR(ENOMEM);
4673 av_free(c->chapter_tracks);
4674 c->chapter_tracks = new_tracks;
4675 c->nb_chapter_tracks = num;
4677 for (i = 0; i < num && !pb->eof_reached; i++)
4678 c->chapter_tracks[i] = avio_rb32(pb);
4683 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4688 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4689 return AVERROR_INVALIDDATA;
4690 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4691 sizeof(*c->trex_data))) < 0) {
4696 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4698 trex = &c->trex_data[c->trex_count++];
4699 avio_r8(pb); /* version */
4700 avio_rb24(pb); /* flags */
4701 trex->track_id = avio_rb32(pb);
4702 trex->stsd_id = avio_rb32(pb);
4703 trex->duration = avio_rb32(pb);
4704 trex->size = avio_rb32(pb);
4705 trex->flags = avio_rb32(pb);
4709 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4711 MOVFragment *frag = &c->fragment;
4712 AVStream *st = NULL;
4713 MOVStreamContext *sc;
4715 MOVFragmentStreamInfo * frag_stream_info;
4716 int64_t base_media_decode_time;
4718 for (i = 0; i < c->fc->nb_streams; i++) {
4719 if (c->fc->streams[i]->id == frag->track_id) {
4720 st = c->fc->streams[i];
4725 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4729 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4731 version = avio_r8(pb);
4732 avio_rb24(pb); /* flags */
4734 base_media_decode_time = avio_rb64(pb);
4736 base_media_decode_time = avio_rb32(pb);
4739 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4740 if (frag_stream_info)
4741 frag_stream_info->tfdt_dts = base_media_decode_time;
4742 sc->track_end = base_media_decode_time;
4747 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4749 MOVFragment *frag = &c->fragment;
4750 AVStream *st = NULL;
4751 MOVStreamContext *sc;
4754 int64_t dts, pts = AV_NOPTS_VALUE;
4755 int data_offset = 0;
4756 unsigned entries, first_sample_flags = frag->flags;
4757 int flags, distance, i;
4758 int64_t prev_dts = AV_NOPTS_VALUE;
4759 int next_frag_index = -1, index_entry_pos;
4760 size_t requested_size;
4761 size_t old_ctts_allocated_size;
4762 AVIndexEntry *new_entries;
4763 MOVFragmentStreamInfo * frag_stream_info;
4765 if (!frag->found_tfhd) {
4766 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4767 return AVERROR_INVALIDDATA;
4770 for (i = 0; i < c->fc->nb_streams; i++) {
4771 if (c->fc->streams[i]->id == frag->track_id) {
4772 st = c->fc->streams[i];
4777 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4781 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4784 // Find the next frag_index index that has a valid index_entry for
4785 // the current track_id.
4787 // A valid index_entry means the trun for the fragment was read
4788 // and it's samples are in index_entries at the given position.
4789 // New index entries will be inserted before the index_entry found.
4790 index_entry_pos = st->nb_index_entries;
4791 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4792 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4793 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4794 next_frag_index = i;
4795 index_entry_pos = frag_stream_info->index_entry;
4799 av_assert0(index_entry_pos <= st->nb_index_entries);
4801 avio_r8(pb); /* version */
4802 flags = avio_rb24(pb);
4803 entries = avio_rb32(pb);
4804 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4806 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4807 return AVERROR_INVALIDDATA;
4808 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4809 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4811 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4812 if (frag_stream_info)
4814 if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
4815 dts = frag_stream_info->next_trun_dts - sc->time_offset;
4816 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4817 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4818 pts = frag_stream_info->first_tfra_pts;
4819 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4820 ", using it for pts\n", pts);
4821 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4822 c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
4823 dts = frag_stream_info->first_tfra_pts;
4824 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4825 ", using it for dts\n", pts);
4826 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4827 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4828 // pts = frag_stream_info->sidx_pts;
4829 dts = frag_stream_info->sidx_pts - sc->time_offset;
4830 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4831 ", using it for pts\n", pts);
4832 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4833 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4834 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4835 ", using it for dts\n", dts);
4837 dts = sc->track_end - sc->time_offset;
4838 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4839 ", using it for dts\n", dts);
4842 dts = sc->track_end - sc->time_offset;
4843 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4844 ", using it for dts\n", dts);
4846 offset = frag->base_data_offset + data_offset;
4848 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4850 // realloc space for new index entries
4851 if((uint64_t)st->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4852 entries = UINT_MAX / sizeof(AVIndexEntry) - st->nb_index_entries;
4853 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4858 requested_size = (st->nb_index_entries + entries) * sizeof(AVIndexEntry);
4859 new_entries = av_fast_realloc(st->index_entries,
4860 &st->index_entries_allocated_size,
4863 return AVERROR(ENOMEM);
4864 st->index_entries= new_entries;
4866 requested_size = (st->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4867 old_ctts_allocated_size = sc->ctts_allocated_size;
4868 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4871 return AVERROR(ENOMEM);
4872 sc->ctts_data = ctts_data;
4874 // In case there were samples without ctts entries, ensure they get
4875 // zero valued entries. This ensures clips which mix boxes with and
4876 // without ctts entries don't pickup uninitialized data.
4877 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4878 sc->ctts_allocated_size - old_ctts_allocated_size);
4880 if (index_entry_pos < st->nb_index_entries) {
4881 // Make hole in index_entries and ctts_data for new samples
4882 memmove(st->index_entries + index_entry_pos + entries,
4883 st->index_entries + index_entry_pos,
4884 sizeof(*st->index_entries) *
4885 (st->nb_index_entries - index_entry_pos));
4886 memmove(sc->ctts_data + index_entry_pos + entries,
4887 sc->ctts_data + index_entry_pos,
4888 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4889 if (index_entry_pos < sc->current_sample) {
4890 sc->current_sample += entries;
4894 st->nb_index_entries += entries;
4895 sc->ctts_count = st->nb_index_entries;
4897 // Record the index_entry position in frag_index of this fragment
4898 if (frag_stream_info)
4899 frag_stream_info->index_entry = index_entry_pos;
4901 if (index_entry_pos > 0)
4902 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4904 for (i = 0; i < entries && !pb->eof_reached; i++) {
4905 unsigned sample_size = frag->size;
4906 int sample_flags = i ? frag->flags : first_sample_flags;
4907 unsigned sample_duration = frag->duration;
4908 unsigned ctts_duration = 0;
4910 int index_entry_flags = 0;
4912 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4913 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4914 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4915 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4917 mov_update_dts_shift(sc, ctts_duration, c->fc);
4918 if (pts != AV_NOPTS_VALUE) {
4919 dts = pts - sc->dts_shift;
4920 if (flags & MOV_TRUN_SAMPLE_CTS) {
4921 dts -= ctts_duration;
4923 dts -= sc->time_offset;
4925 av_log(c->fc, AV_LOG_DEBUG,
4926 "pts %"PRId64" calculated dts %"PRId64
4927 " sc->dts_shift %d ctts.duration %d"
4928 " sc->time_offset %"PRId64
4929 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4931 sc->dts_shift, ctts_duration,
4932 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4933 pts = AV_NOPTS_VALUE;
4936 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4940 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4941 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4944 index_entry_flags |= AVINDEX_KEYFRAME;
4946 // Fragments can overlap in time. Discard overlapping frames after
4948 if (prev_dts >= dts)
4949 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4951 st->index_entries[index_entry_pos].pos = offset;
4952 st->index_entries[index_entry_pos].timestamp = dts;
4953 st->index_entries[index_entry_pos].size= sample_size;
4954 st->index_entries[index_entry_pos].min_distance= distance;
4955 st->index_entries[index_entry_pos].flags = index_entry_flags;
4957 sc->ctts_data[index_entry_pos].count = 1;
4958 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4961 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4962 "size %u, distance %d, keyframe %d\n", st->index,
4963 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4965 dts += sample_duration;
4966 offset += sample_size;
4967 sc->data_size += sample_size;
4969 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4970 1 <= INT_MAX - sc->nb_frames_for_fps
4972 sc->duration_for_fps += sample_duration;
4973 sc->nb_frames_for_fps ++;
4976 if (frag_stream_info)
4977 frag_stream_info->next_trun_dts = dts + sc->time_offset;
4979 // EOF found before reading all entries. Fix the hole this would
4980 // leave in index_entries and ctts_data
4981 int gap = entries - i;
4982 memmove(st->index_entries + index_entry_pos,
4983 st->index_entries + index_entry_pos + gap,
4984 sizeof(*st->index_entries) *
4985 (st->nb_index_entries - (index_entry_pos + gap)));
4986 memmove(sc->ctts_data + index_entry_pos,
4987 sc->ctts_data + index_entry_pos + gap,
4988 sizeof(*sc->ctts_data) *
4989 (sc->ctts_count - (index_entry_pos + gap)));
4991 st->nb_index_entries -= gap;
4992 sc->ctts_count -= gap;
4993 if (index_entry_pos < sc->current_sample) {
4994 sc->current_sample -= gap;
4999 // The end of this new fragment may overlap in time with the start
5000 // of the next fragment in index_entries. Mark the samples in the next
5001 // fragment that overlap with AVINDEX_DISCARD_FRAME
5002 prev_dts = AV_NOPTS_VALUE;
5003 if (index_entry_pos > 0)
5004 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
5005 for (i = index_entry_pos; i < st->nb_index_entries; i++) {
5006 if (prev_dts < st->index_entries[i].timestamp)
5008 st->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
5011 // If a hole was created to insert the new index_entries into,
5012 // the index_entry recorded for all subsequent moof must
5013 // be incremented by the number of entries inserted.
5014 fix_frag_index_entries(&c->frag_index, next_frag_index,
5015 frag->track_id, entries);
5017 if (pb->eof_reached) {
5018 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
5022 frag->implicit_offset = offset;
5024 sc->track_end = dts + sc->time_offset;
5025 if (st->duration < sc->track_end)
5026 st->duration = sc->track_end;
5031 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5033 int64_t offset = avio_tell(pb) + atom.size, pts, timestamp;
5035 unsigned i, j, track_id, item_count;
5036 AVStream *st = NULL;
5037 AVStream *ref_st = NULL;
5038 MOVStreamContext *sc, *ref_sc = NULL;
5039 AVRational timescale;
5041 version = avio_r8(pb);
5043 avpriv_request_sample(c->fc, "sidx version %u", version);
5047 avio_rb24(pb); // flags
5049 track_id = avio_rb32(pb); // Reference ID
5050 for (i = 0; i < c->fc->nb_streams; i++) {
5051 if (c->fc->streams[i]->id == track_id) {
5052 st = c->fc->streams[i];
5057 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5063 timescale = av_make_q(1, avio_rb32(pb));
5065 if (timescale.den <= 0) {
5066 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5067 return AVERROR_INVALIDDATA;
5071 pts = avio_rb32(pb);
5072 offset += avio_rb32(pb);
5074 pts = avio_rb64(pb);
5075 offset += avio_rb64(pb);
5078 avio_rb16(pb); // reserved
5080 item_count = avio_rb16(pb);
5082 for (i = 0; i < item_count; i++) {
5084 MOVFragmentStreamInfo * frag_stream_info;
5085 uint32_t size = avio_rb32(pb);
5086 uint32_t duration = avio_rb32(pb);
5087 if (size & 0x80000000) {
5088 avpriv_request_sample(c->fc, "sidx reference_type 1");
5089 return AVERROR_PATCHWELCOME;
5091 avio_rb32(pb); // sap_flags
5092 timestamp = av_rescale_q(pts, timescale, st->time_base);
5094 index = update_frag_index(c, offset);
5095 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5096 if (frag_stream_info)
5097 frag_stream_info->sidx_pts = timestamp;
5103 st->duration = sc->track_end = pts;
5107 if (offset == avio_size(pb)) {
5108 // Find first entry in fragment index that came from an sidx.
5109 // This will pretty much always be the first entry.
5110 for (i = 0; i < c->frag_index.nb_items; i++) {
5111 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5112 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5113 MOVFragmentStreamInfo * si;
5114 si = &item->stream_info[j];
5115 if (si->sidx_pts != AV_NOPTS_VALUE) {
5116 ref_st = c->fc->streams[j];
5117 ref_sc = ref_st->priv_data;
5122 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5123 st = c->fc->streams[i];
5125 if (!sc->has_sidx) {
5126 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5130 c->frag_index.complete = 1;
5136 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5137 /* like the files created with Adobe Premiere 5.0, for samples see */
5138 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5139 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5144 return 0; /* continue */
5145 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5146 avio_skip(pb, atom.size - 4);
5149 atom.type = avio_rl32(pb);
5151 if (atom.type != MKTAG('m','d','a','t')) {
5152 avio_skip(pb, atom.size);
5155 err = mov_read_mdat(c, pb, atom);
5159 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5164 uint8_t *moov_data; /* uncompressed data */
5165 long cmov_len, moov_len;
5168 avio_rb32(pb); /* dcom atom */
5169 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5170 return AVERROR_INVALIDDATA;
5171 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5172 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5173 return AVERROR_INVALIDDATA;
5175 avio_rb32(pb); /* cmvd atom */
5176 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5177 return AVERROR_INVALIDDATA;
5178 moov_len = avio_rb32(pb); /* uncompressed size */
5179 cmov_len = atom.size - 6 * 4;
5181 cmov_data = av_malloc(cmov_len);
5183 return AVERROR(ENOMEM);
5184 moov_data = av_malloc(moov_len);
5187 return AVERROR(ENOMEM);
5189 ret = ffio_read_size(pb, cmov_data, cmov_len);
5191 goto free_and_return;
5193 ret = AVERROR_INVALIDDATA;
5194 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5195 goto free_and_return;
5196 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5197 goto free_and_return;
5198 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5199 atom.type = MKTAG('m','o','o','v');
5200 atom.size = moov_len;
5201 ret = mov_read_default(c, &ctx, atom);
5207 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5208 return AVERROR(ENOSYS);
5212 /* edit list atom */
5213 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5215 MOVStreamContext *sc;
5216 int i, edit_count, version;
5217 int64_t elst_entry_size;
5219 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5221 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5223 version = avio_r8(pb); /* version */
5224 avio_rb24(pb); /* flags */
5225 edit_count = avio_rb32(pb); /* entries */
5228 elst_entry_size = version == 1 ? 20 : 12;
5229 if (atom.size != edit_count * elst_entry_size) {
5230 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5231 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5232 edit_count, atom.size + 8);
5233 return AVERROR_INVALIDDATA;
5235 edit_count = atom.size / elst_entry_size;
5236 if (edit_count * elst_entry_size != atom.size) {
5237 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.", atom.size, edit_count);
5245 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5246 av_free(sc->elst_data);
5248 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5250 return AVERROR(ENOMEM);
5252 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5253 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5254 MOVElst *e = &sc->elst_data[i];
5257 e->duration = avio_rb64(pb);
5258 e->time = avio_rb64(pb);
5261 e->duration = avio_rb32(pb); /* segment duration */
5262 e->time = (int32_t)avio_rb32(pb); /* media time */
5265 e->rate = avio_rb32(pb) / 65536.0;
5267 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5268 e->duration, e->time, e->rate);
5270 if (e->time < 0 && e->time != -1 &&
5271 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5272 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5273 c->fc->nb_streams-1, i, e->time);
5274 return AVERROR_INVALIDDATA;
5282 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5284 MOVStreamContext *sc;
5286 if (c->fc->nb_streams < 1)
5287 return AVERROR_INVALIDDATA;
5288 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5289 sc->timecode_track = avio_rb32(pb);
5293 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5298 if (c->fc->nb_streams < 1)
5300 st = c->fc->streams[c->fc->nb_streams - 1];
5302 if (atom.size < 4) {
5303 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5304 return AVERROR_INVALIDDATA;
5307 /* For now, propagate only the OBUs, if any. Once libavcodec is
5308 updated to handle isobmff style extradata this can be removed. */
5314 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5321 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5324 int version, color_range, color_primaries, color_trc, color_space;
5326 if (c->fc->nb_streams < 1)
5328 st = c->fc->streams[c->fc->nb_streams - 1];
5330 if (atom.size < 5) {
5331 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5332 return AVERROR_INVALIDDATA;
5335 version = avio_r8(pb);
5337 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5340 avio_skip(pb, 3); /* flags */
5342 avio_skip(pb, 2); /* profile + level */
5343 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5344 color_primaries = avio_r8(pb);
5345 color_trc = avio_r8(pb);
5346 color_space = avio_r8(pb);
5347 if (avio_rb16(pb)) /* codecIntializationDataSize */
5348 return AVERROR_INVALIDDATA;
5350 if (!av_color_primaries_name(color_primaries))
5351 color_primaries = AVCOL_PRI_UNSPECIFIED;
5352 if (!av_color_transfer_name(color_trc))
5353 color_trc = AVCOL_TRC_UNSPECIFIED;
5354 if (!av_color_space_name(color_space))
5355 color_space = AVCOL_SPC_UNSPECIFIED;
5357 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5358 st->codecpar->color_primaries = color_primaries;
5359 st->codecpar->color_trc = color_trc;
5360 st->codecpar->color_space = color_space;
5365 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5367 MOVStreamContext *sc;
5370 if (c->fc->nb_streams < 1)
5371 return AVERROR_INVALIDDATA;
5373 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5375 if (atom.size < 5) {
5376 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5377 return AVERROR_INVALIDDATA;
5380 version = avio_r8(pb);
5382 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5385 avio_skip(pb, 3); /* flags */
5387 sc->mastering = av_mastering_display_metadata_alloc();
5389 return AVERROR(ENOMEM);
5391 for (i = 0; i < 3; i++) {
5392 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5393 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5395 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5396 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5398 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5399 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5401 sc->mastering->has_primaries = 1;
5402 sc->mastering->has_luminance = 1;
5407 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5409 MOVStreamContext *sc;
5410 const int mapping[3] = {1, 2, 0};
5411 const int chroma_den = 50000;
5412 const int luma_den = 10000;
5415 if (c->fc->nb_streams < 1)
5416 return AVERROR_INVALIDDATA;
5418 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5420 if (atom.size < 24) {
5421 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5422 return AVERROR_INVALIDDATA;
5425 sc->mastering = av_mastering_display_metadata_alloc();
5427 return AVERROR(ENOMEM);
5429 for (i = 0; i < 3; i++) {
5430 const int j = mapping[i];
5431 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5432 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5434 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5435 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5437 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5438 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5440 sc->mastering->has_luminance = 1;
5441 sc->mastering->has_primaries = 1;
5446 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5448 MOVStreamContext *sc;
5451 if (c->fc->nb_streams < 1)
5452 return AVERROR_INVALIDDATA;
5454 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5456 if (atom.size < 5) {
5457 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5458 return AVERROR_INVALIDDATA;
5461 version = avio_r8(pb);
5463 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5466 avio_skip(pb, 3); /* flags */
5468 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5470 return AVERROR(ENOMEM);
5472 sc->coll->MaxCLL = avio_rb16(pb);
5473 sc->coll->MaxFALL = avio_rb16(pb);
5478 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5480 MOVStreamContext *sc;
5482 if (c->fc->nb_streams < 1)
5483 return AVERROR_INVALIDDATA;
5485 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5487 if (atom.size < 4) {
5488 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5489 return AVERROR_INVALIDDATA;
5492 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5494 return AVERROR(ENOMEM);
5496 sc->coll->MaxCLL = avio_rb16(pb);
5497 sc->coll->MaxFALL = avio_rb16(pb);
5502 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5505 MOVStreamContext *sc;
5506 enum AVStereo3DType type;
5509 if (c->fc->nb_streams < 1)
5512 st = c->fc->streams[c->fc->nb_streams - 1];
5515 if (atom.size < 5) {
5516 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5517 return AVERROR_INVALIDDATA;
5519 avio_skip(pb, 4); /* version + flags */
5524 type = AV_STEREO3D_2D;
5527 type = AV_STEREO3D_TOPBOTTOM;
5530 type = AV_STEREO3D_SIDEBYSIDE;
5533 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5537 sc->stereo3d = av_stereo3d_alloc();
5539 return AVERROR(ENOMEM);
5541 sc->stereo3d->type = type;
5545 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5548 MOVStreamContext *sc;
5549 int size, version, layout;
5550 int32_t yaw, pitch, roll;
5551 uint32_t l = 0, t = 0, r = 0, b = 0;
5552 uint32_t tag, padding = 0;
5553 enum AVSphericalProjection projection;
5555 if (c->fc->nb_streams < 1)
5558 st = c->fc->streams[c->fc->nb_streams - 1];
5561 if (atom.size < 8) {
5562 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5563 return AVERROR_INVALIDDATA;
5566 size = avio_rb32(pb);
5567 if (size <= 12 || size > atom.size)
5568 return AVERROR_INVALIDDATA;
5570 tag = avio_rl32(pb);
5571 if (tag != MKTAG('s','v','h','d')) {
5572 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5575 version = avio_r8(pb);
5577 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5581 avio_skip(pb, 3); /* flags */
5582 avio_skip(pb, size - 12); /* metadata_source */
5584 size = avio_rb32(pb);
5585 if (size > atom.size)
5586 return AVERROR_INVALIDDATA;
5588 tag = avio_rl32(pb);
5589 if (tag != MKTAG('p','r','o','j')) {
5590 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5594 size = avio_rb32(pb);
5595 if (size > atom.size)
5596 return AVERROR_INVALIDDATA;
5598 tag = avio_rl32(pb);
5599 if (tag != MKTAG('p','r','h','d')) {
5600 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5603 version = avio_r8(pb);
5605 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5609 avio_skip(pb, 3); /* flags */
5611 /* 16.16 fixed point */
5612 yaw = avio_rb32(pb);
5613 pitch = avio_rb32(pb);
5614 roll = avio_rb32(pb);
5616 size = avio_rb32(pb);
5617 if (size > atom.size)
5618 return AVERROR_INVALIDDATA;
5620 tag = avio_rl32(pb);
5621 version = avio_r8(pb);
5623 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5627 avio_skip(pb, 3); /* flags */
5629 case MKTAG('c','b','m','p'):
5630 layout = avio_rb32(pb);
5632 av_log(c->fc, AV_LOG_WARNING,
5633 "Unsupported cubemap layout %d\n", layout);
5636 projection = AV_SPHERICAL_CUBEMAP;
5637 padding = avio_rb32(pb);
5639 case MKTAG('e','q','u','i'):
5645 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5646 av_log(c->fc, AV_LOG_ERROR,
5647 "Invalid bounding rectangle coordinates "
5648 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5649 return AVERROR_INVALIDDATA;
5652 if (l || t || r || b)
5653 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5655 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5658 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5662 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5664 return AVERROR(ENOMEM);
5666 sc->spherical->projection = projection;
5668 sc->spherical->yaw = yaw;
5669 sc->spherical->pitch = pitch;
5670 sc->spherical->roll = roll;
5672 sc->spherical->padding = padding;
5674 sc->spherical->bound_left = l;
5675 sc->spherical->bound_top = t;
5676 sc->spherical->bound_right = r;
5677 sc->spherical->bound_bottom = b;
5682 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5685 uint8_t *buffer = av_malloc(len + 1);
5689 return AVERROR(ENOMEM);
5692 ret = ffio_read_size(pb, buffer, len);
5696 /* Check for mandatory keys and values, try to support XML as best-effort */
5697 if (!sc->spherical &&
5698 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5699 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5700 av_stristr(val, "true") &&
5701 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5702 av_stristr(val, "true") &&
5703 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5704 av_stristr(val, "equirectangular")) {
5705 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5709 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5711 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5712 enum AVStereo3DType mode;
5714 if (av_stristr(buffer, "left-right"))
5715 mode = AV_STEREO3D_SIDEBYSIDE;
5716 else if (av_stristr(buffer, "top-bottom"))
5717 mode = AV_STEREO3D_TOPBOTTOM;
5719 mode = AV_STEREO3D_2D;
5721 sc->stereo3d = av_stereo3d_alloc();
5725 sc->stereo3d->type = mode;
5729 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5731 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5732 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5734 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5735 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5737 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5745 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5748 MOVStreamContext *sc;
5751 static const uint8_t uuid_isml_manifest[] = {
5752 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5753 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5755 static const uint8_t uuid_xmp[] = {
5756 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5757 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5759 static const uint8_t uuid_spherical[] = {
5760 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5761 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5764 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5765 return AVERROR_INVALIDDATA;
5767 if (c->fc->nb_streams < 1)
5769 st = c->fc->streams[c->fc->nb_streams - 1];
5772 ret = avio_read(pb, uuid, sizeof(uuid));
5775 } else if (ret != sizeof(uuid)) {
5776 return AVERROR_INVALIDDATA;
5778 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5779 uint8_t *buffer, *ptr;
5781 size_t len = atom.size - sizeof(uuid);
5784 return AVERROR_INVALIDDATA;
5786 ret = avio_skip(pb, 4); // zeroes
5789 buffer = av_mallocz(len + 1);
5791 return AVERROR(ENOMEM);
5793 ret = avio_read(pb, buffer, len);
5797 } else if (ret != len) {
5799 return AVERROR_INVALIDDATA;
5803 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5804 ptr += sizeof("systemBitrate=\"") - 1;
5805 c->bitrates_count++;
5806 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5808 c->bitrates_count = 0;
5810 return AVERROR(ENOMEM);
5813 ret = strtol(ptr, &endptr, 10);
5814 if (ret < 0 || errno || *endptr != '"') {
5815 c->bitrates[c->bitrates_count - 1] = 0;
5817 c->bitrates[c->bitrates_count - 1] = ret;
5822 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5824 size_t len = atom.size - sizeof(uuid);
5825 if (c->export_xmp) {
5826 buffer = av_mallocz(len + 1);
5828 return AVERROR(ENOMEM);
5830 ret = avio_read(pb, buffer, len);
5834 } else if (ret != len) {
5836 return AVERROR_INVALIDDATA;
5839 av_dict_set(&c->fc->metadata, "xmp",
5840 buffer, AV_DICT_DONT_STRDUP_VAL);
5842 // skip all uuid atom, which makes it fast for long uuid-xmp file
5843 ret = avio_skip(pb, len);
5847 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5848 size_t len = atom.size - sizeof(uuid);
5849 ret = mov_parse_uuid_spherical(sc, pb, len);
5853 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5859 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5862 uint8_t content[16];
5867 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5873 && !memcmp(content, "Anevia\x1A\x1A", 8)
5874 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5875 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5881 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5883 uint32_t format = avio_rl32(pb);
5884 MOVStreamContext *sc;
5888 if (c->fc->nb_streams < 1)
5890 st = c->fc->streams[c->fc->nb_streams - 1];
5895 case MKTAG('e','n','c','v'): // encrypted video
5896 case MKTAG('e','n','c','a'): // encrypted audio
5897 id = mov_codec_id(st, format);
5898 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5899 st->codecpar->codec_id != id) {
5900 av_log(c->fc, AV_LOG_WARNING,
5901 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5902 (char*)&format, st->codecpar->codec_id);
5906 st->codecpar->codec_id = id;
5907 sc->format = format;
5911 if (format != sc->format) {
5912 av_log(c->fc, AV_LOG_WARNING,
5913 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5914 (char*)&format, (char*)&sc->format);
5923 * Gets the current encryption info and associated current stream context. If
5924 * we are parsing a track fragment, this will return the specific encryption
5925 * info for this fragment; otherwise this will return the global encryption
5926 * info for the current stream.
5928 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5930 MOVFragmentStreamInfo *frag_stream_info;
5934 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5935 if (frag_stream_info) {
5936 for (i = 0; i < c->fc->nb_streams; i++) {
5937 if (c->fc->streams[i]->id == frag_stream_info->id) {
5938 st = c->fc->streams[i];
5942 if (i == c->fc->nb_streams)
5944 *sc = st->priv_data;
5946 if (!frag_stream_info->encryption_index) {
5947 // If this stream isn't encrypted, don't create the index.
5948 if (!(*sc)->cenc.default_encrypted_sample)
5950 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5951 if (!frag_stream_info->encryption_index)
5952 return AVERROR(ENOMEM);
5954 *encryption_index = frag_stream_info->encryption_index;
5957 // No current track fragment, using stream level encryption info.
5959 if (c->fc->nb_streams < 1)
5961 st = c->fc->streams[c->fc->nb_streams - 1];
5962 *sc = st->priv_data;
5964 if (!(*sc)->cenc.encryption_index) {
5965 // If this stream isn't encrypted, don't create the index.
5966 if (!(*sc)->cenc.default_encrypted_sample)
5968 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5969 if (!(*sc)->cenc.encryption_index)
5970 return AVERROR(ENOMEM);
5973 *encryption_index = (*sc)->cenc.encryption_index;
5978 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
5981 unsigned int subsample_count;
5982 AVSubsampleEncryptionInfo *subsamples;
5984 if (!sc->cenc.default_encrypted_sample) {
5985 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
5986 return AVERROR_INVALIDDATA;
5989 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
5991 return AVERROR(ENOMEM);
5993 if (sc->cenc.per_sample_iv_size != 0) {
5994 if (avio_read(pb, (*sample)->iv, sc->cenc.per_sample_iv_size) != sc->cenc.per_sample_iv_size) {
5995 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
5996 av_encryption_info_free(*sample);
5998 return AVERROR_INVALIDDATA;
6002 if (use_subsamples) {
6003 subsample_count = avio_rb16(pb);
6004 av_free((*sample)->subsamples);
6005 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
6006 if (!(*sample)->subsamples) {
6007 av_encryption_info_free(*sample);
6009 return AVERROR(ENOMEM);
6012 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
6013 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
6014 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
6017 if (pb->eof_reached) {
6018 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
6019 av_encryption_info_free(*sample);
6021 return AVERROR_INVALIDDATA;
6023 (*sample)->subsample_count = subsample_count;
6029 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6031 AVEncryptionInfo **encrypted_samples;
6032 MOVEncryptionIndex *encryption_index;
6033 MOVStreamContext *sc;
6034 int use_subsamples, ret;
6035 unsigned int sample_count, i, alloc_size = 0;
6037 ret = get_current_encryption_info(c, &encryption_index, &sc);
6041 if (encryption_index->nb_encrypted_samples) {
6042 // This can happen if we have both saio/saiz and senc atoms.
6043 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6047 avio_r8(pb); /* version */
6048 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6050 sample_count = avio_rb32(pb);
6051 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6052 return AVERROR(ENOMEM);
6054 for (i = 0; i < sample_count; i++) {
6055 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6056 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6057 min_samples * sizeof(*encrypted_samples));
6058 if (encrypted_samples) {
6059 encryption_index->encrypted_samples = encrypted_samples;
6061 ret = mov_read_sample_encryption_info(
6062 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6064 ret = AVERROR(ENOMEM);
6066 if (pb->eof_reached) {
6067 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6068 ret = AVERROR_INVALIDDATA;
6073 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6074 av_freep(&encryption_index->encrypted_samples);
6078 encryption_index->nb_encrypted_samples = sample_count;
6083 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6085 AVEncryptionInfo **sample, **encrypted_samples;
6087 size_t sample_count, sample_info_size, i;
6089 unsigned int alloc_size = 0;
6091 if (encryption_index->nb_encrypted_samples)
6093 sample_count = encryption_index->auxiliary_info_sample_count;
6094 if (encryption_index->auxiliary_offsets_count != 1) {
6095 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6096 return AVERROR_PATCHWELCOME;
6098 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6099 return AVERROR(ENOMEM);
6101 prev_pos = avio_tell(pb);
6102 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6103 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6104 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6108 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6109 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6110 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6111 min_samples * sizeof(*encrypted_samples));
6112 if (!encrypted_samples) {
6113 ret = AVERROR(ENOMEM);
6116 encryption_index->encrypted_samples = encrypted_samples;
6118 sample = &encryption_index->encrypted_samples[i];
6119 sample_info_size = encryption_index->auxiliary_info_default_size
6120 ? encryption_index->auxiliary_info_default_size
6121 : encryption_index->auxiliary_info_sizes[i];
6123 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6127 if (pb->eof_reached) {
6128 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6129 ret = AVERROR_INVALIDDATA;
6131 encryption_index->nb_encrypted_samples = sample_count;
6135 avio_seek(pb, prev_pos, SEEK_SET);
6137 for (; i > 0; i--) {
6138 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6140 av_freep(&encryption_index->encrypted_samples);
6146 * Tries to read the given number of bytes from the stream and puts it in a
6147 * newly allocated buffer. This reads in small chunks to avoid allocating large
6148 * memory if the file contains an invalid/malicious size value.
6150 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6152 const unsigned int block_size = 1024 * 1024;
6153 uint8_t *buffer = NULL;
6154 unsigned int alloc_size = 0, offset = 0;
6155 while (offset < size) {
6156 unsigned int new_size =
6157 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6158 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6159 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6162 return AVERROR(ENOMEM);
6164 buffer = new_buffer;
6166 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6168 return AVERROR_INVALIDDATA;
6177 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6179 MOVEncryptionIndex *encryption_index;
6180 MOVStreamContext *sc;
6182 unsigned int sample_count, aux_info_type, aux_info_param;
6184 ret = get_current_encryption_info(c, &encryption_index, &sc);
6188 if (encryption_index->nb_encrypted_samples) {
6189 // This can happen if we have both saio/saiz and senc atoms.
6190 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6194 if (encryption_index->auxiliary_info_sample_count) {
6195 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6196 return AVERROR_INVALIDDATA;
6199 avio_r8(pb); /* version */
6200 if (avio_rb24(pb) & 0x01) { /* flags */
6201 aux_info_type = avio_rb32(pb);
6202 aux_info_param = avio_rb32(pb);
6203 if (sc->cenc.default_encrypted_sample) {
6204 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6205 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6208 if (aux_info_param != 0) {
6209 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6213 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6214 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6215 aux_info_type == MKBETAG('c','e','n','s') ||
6216 aux_info_type == MKBETAG('c','b','c','1') ||
6217 aux_info_type == MKBETAG('c','b','c','s')) &&
6218 aux_info_param == 0) {
6219 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6220 return AVERROR_INVALIDDATA;
6225 } else if (!sc->cenc.default_encrypted_sample) {
6226 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6230 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6231 sample_count = avio_rb32(pb);
6232 encryption_index->auxiliary_info_sample_count = sample_count;
6234 if (encryption_index->auxiliary_info_default_size == 0) {
6235 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6237 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6242 if (encryption_index->auxiliary_offsets_count) {
6243 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6249 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6251 uint64_t *auxiliary_offsets;
6252 MOVEncryptionIndex *encryption_index;
6253 MOVStreamContext *sc;
6255 unsigned int version, entry_count, aux_info_type, aux_info_param;
6256 unsigned int alloc_size = 0;
6258 ret = get_current_encryption_info(c, &encryption_index, &sc);
6262 if (encryption_index->nb_encrypted_samples) {
6263 // This can happen if we have both saio/saiz and senc atoms.
6264 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6268 if (encryption_index->auxiliary_offsets_count) {
6269 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6270 return AVERROR_INVALIDDATA;
6273 version = avio_r8(pb); /* version */
6274 if (avio_rb24(pb) & 0x01) { /* flags */
6275 aux_info_type = avio_rb32(pb);
6276 aux_info_param = avio_rb32(pb);
6277 if (sc->cenc.default_encrypted_sample) {
6278 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6279 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6282 if (aux_info_param != 0) {
6283 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6287 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6288 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6289 aux_info_type == MKBETAG('c','e','n','s') ||
6290 aux_info_type == MKBETAG('c','b','c','1') ||
6291 aux_info_type == MKBETAG('c','b','c','s')) &&
6292 aux_info_param == 0) {
6293 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6294 return AVERROR_INVALIDDATA;
6299 } else if (!sc->cenc.default_encrypted_sample) {
6300 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6304 entry_count = avio_rb32(pb);
6305 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6306 return AVERROR(ENOMEM);
6308 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6309 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6310 auxiliary_offsets = av_fast_realloc(
6311 encryption_index->auxiliary_offsets, &alloc_size,
6312 min_offsets * sizeof(*auxiliary_offsets));
6313 if (!auxiliary_offsets) {
6314 av_freep(&encryption_index->auxiliary_offsets);
6315 return AVERROR(ENOMEM);
6317 encryption_index->auxiliary_offsets = auxiliary_offsets;
6320 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6322 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6324 if (c->frag_index.current >= 0) {
6325 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6329 if (pb->eof_reached) {
6330 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6331 av_freep(&encryption_index->auxiliary_offsets);
6332 return AVERROR_INVALIDDATA;
6335 encryption_index->auxiliary_offsets_count = entry_count;
6337 if (encryption_index->auxiliary_info_sample_count) {
6338 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6344 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6346 AVEncryptionInitInfo *info, *old_init_info;
6349 uint8_t *side_data, *extra_data, *old_side_data;
6350 size_t side_data_size;
6351 int ret = 0, old_side_data_size;
6352 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6354 if (c->fc->nb_streams < 1)
6356 st = c->fc->streams[c->fc->nb_streams-1];
6358 version = avio_r8(pb); /* version */
6359 avio_rb24(pb); /* flags */
6361 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6362 /* key_id_size */ 16, /* data_size */ 0);
6364 return AVERROR(ENOMEM);
6366 if (avio_read(pb, info->system_id, 16) != 16) {
6367 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6368 ret = AVERROR_INVALIDDATA;
6373 kid_count = avio_rb32(pb);
6374 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
6375 ret = AVERROR(ENOMEM);
6379 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6380 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6381 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6382 min_kid_count * sizeof(*key_ids));
6384 ret = AVERROR(ENOMEM);
6387 info->key_ids = key_ids;
6389 info->key_ids[i] = av_mallocz(16);
6390 if (!info->key_ids[i]) {
6391 ret = AVERROR(ENOMEM);
6394 info->num_key_ids = i + 1;
6396 if (avio_read(pb, info->key_ids[i], 16) != 16) {
6397 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6398 ret = AVERROR_INVALIDDATA;
6403 if (pb->eof_reached) {
6404 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6405 ret = AVERROR_INVALIDDATA;
6410 extra_data_size = avio_rb32(pb);
6411 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6415 av_freep(&info->data); // malloc(0) may still allocate something.
6416 info->data = extra_data;
6417 info->data_size = extra_data_size;
6419 // If there is existing initialization data, append to the list.
6420 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6421 if (old_side_data) {
6422 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6423 if (old_init_info) {
6424 // Append to the end of the list.
6425 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6431 info = old_init_info;
6433 // Assume existing side-data will be valid, so the only error we could get is OOM.
6434 ret = AVERROR(ENOMEM);
6439 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6441 ret = AVERROR(ENOMEM);
6444 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6445 side_data, side_data_size);
6450 av_encryption_init_info_free(info);
6454 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6457 MOVStreamContext *sc;
6459 if (c->fc->nb_streams < 1)
6461 st = c->fc->streams[c->fc->nb_streams-1];
6464 if (sc->pseudo_stream_id != 0) {
6465 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6466 return AVERROR_PATCHWELCOME;
6470 return AVERROR_INVALIDDATA;
6472 avio_rb32(pb); /* version and flags */
6474 if (!sc->cenc.default_encrypted_sample) {
6475 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6476 if (!sc->cenc.default_encrypted_sample) {
6477 return AVERROR(ENOMEM);
6481 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6485 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6488 MOVStreamContext *sc;
6489 unsigned int version, pattern, is_protected, iv_size;
6491 if (c->fc->nb_streams < 1)
6493 st = c->fc->streams[c->fc->nb_streams-1];
6496 if (sc->pseudo_stream_id != 0) {
6497 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6498 return AVERROR_PATCHWELCOME;
6501 if (!sc->cenc.default_encrypted_sample) {
6502 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6503 if (!sc->cenc.default_encrypted_sample) {
6504 return AVERROR(ENOMEM);
6509 return AVERROR_INVALIDDATA;
6511 version = avio_r8(pb); /* version */
6512 avio_rb24(pb); /* flags */
6514 avio_r8(pb); /* reserved */
6515 pattern = avio_r8(pb);
6518 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6519 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6522 is_protected = avio_r8(pb);
6523 if (is_protected && !sc->cenc.encryption_index) {
6524 // The whole stream should be by-default encrypted.
6525 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6526 if (!sc->cenc.encryption_index)
6527 return AVERROR(ENOMEM);
6529 sc->cenc.per_sample_iv_size = avio_r8(pb);
6530 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6531 sc->cenc.per_sample_iv_size != 16) {
6532 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6533 return AVERROR_INVALIDDATA;
6535 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6536 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6537 return AVERROR_INVALIDDATA;
6540 if (is_protected && !sc->cenc.per_sample_iv_size) {
6541 iv_size = avio_r8(pb);
6542 if (iv_size != 8 && iv_size != 16) {
6543 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6544 return AVERROR_INVALIDDATA;
6547 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6548 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6549 return AVERROR_INVALIDDATA;
6556 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6559 int last, type, size, ret;
6562 if (c->fc->nb_streams < 1)
6564 st = c->fc->streams[c->fc->nb_streams-1];
6566 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6567 return AVERROR_INVALIDDATA;
6569 /* Check FlacSpecificBox version. */
6570 if (avio_r8(pb) != 0)
6571 return AVERROR_INVALIDDATA;
6573 avio_rb24(pb); /* Flags */
6575 avio_read(pb, buf, sizeof(buf));
6576 flac_parse_block_header(buf, &last, &type, &size);
6578 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6579 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6580 return AVERROR_INVALIDDATA;
6583 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6588 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6593 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6597 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6598 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6599 return AVERROR_PATCHWELCOME;
6602 if (!sc->cenc.aes_ctr) {
6603 /* initialize the cipher */
6604 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6605 if (!sc->cenc.aes_ctr) {
6606 return AVERROR(ENOMEM);
6609 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6615 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6617 if (!sample->subsample_count)
6619 /* decrypt the whole packet */
6620 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6624 for (i = 0; i < sample->subsample_count; i++)
6626 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6627 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6628 return AVERROR_INVALIDDATA;
6631 /* skip the clear bytes */
6632 input += sample->subsamples[i].bytes_of_clear_data;
6633 size -= sample->subsamples[i].bytes_of_clear_data;
6635 /* decrypt the encrypted bytes */
6636 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6637 input += sample->subsamples[i].bytes_of_protected_data;
6638 size -= sample->subsamples[i].bytes_of_protected_data;
6642 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6643 return AVERROR_INVALIDDATA;
6649 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6651 MOVFragmentStreamInfo *frag_stream_info;
6652 MOVEncryptionIndex *encryption_index;
6653 AVEncryptionInfo *encrypted_sample;
6654 int encrypted_index, ret;
6656 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6657 encrypted_index = current_index;
6658 encryption_index = NULL;
6659 if (frag_stream_info) {
6660 // Note this only supports encryption info in the first sample descriptor.
6661 if (mov->fragment.stsd_id == 1) {
6662 if (frag_stream_info->encryption_index) {
6663 encrypted_index = current_index - frag_stream_info->index_entry;
6664 encryption_index = frag_stream_info->encryption_index;
6666 encryption_index = sc->cenc.encryption_index;
6670 encryption_index = sc->cenc.encryption_index;
6673 if (encryption_index) {
6674 if (encryption_index->auxiliary_info_sample_count &&
6675 !encryption_index->nb_encrypted_samples) {
6676 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6677 return AVERROR_INVALIDDATA;
6679 if (encryption_index->auxiliary_offsets_count &&
6680 !encryption_index->nb_encrypted_samples) {
6681 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6682 return AVERROR_INVALIDDATA;
6685 if (!encryption_index->nb_encrypted_samples) {
6686 // Full-sample encryption with default settings.
6687 encrypted_sample = sc->cenc.default_encrypted_sample;
6688 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6689 // Per-sample setting override.
6690 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6692 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6693 return AVERROR_INVALIDDATA;
6696 if (mov->decryption_key) {
6697 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6700 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6702 return AVERROR(ENOMEM);
6703 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6713 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6715 const int OPUS_SEEK_PREROLL_MS = 80;
6721 if (c->fc->nb_streams < 1)
6723 st = c->fc->streams[c->fc->nb_streams-1];
6725 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6726 return AVERROR_INVALIDDATA;
6728 /* Check OpusSpecificBox version. */
6729 if (avio_r8(pb) != 0) {
6730 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6731 return AVERROR_INVALIDDATA;
6734 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6735 size = atom.size + 8;
6737 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
6740 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6741 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6742 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6743 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6745 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6746 little-endian; aside from the preceeding magic and version they're
6747 otherwise currently identical. Data after output gain at offset 16
6748 doesn't need to be bytewapped. */
6749 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6750 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6751 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6752 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6754 st->codecpar->initial_padding = pre_skip;
6755 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6756 (AVRational){1, 1000},
6757 (AVRational){1, 48000});
6762 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6765 unsigned format_info;
6766 int channel_assignment, channel_assignment1, channel_assignment2;
6769 if (c->fc->nb_streams < 1)
6771 st = c->fc->streams[c->fc->nb_streams-1];
6774 return AVERROR_INVALIDDATA;
6776 format_info = avio_rb32(pb);
6778 ratebits = (format_info >> 28) & 0xF;
6779 channel_assignment1 = (format_info >> 15) & 0x1F;
6780 channel_assignment2 = format_info & 0x1FFF;
6781 if (channel_assignment2)
6782 channel_assignment = channel_assignment2;
6784 channel_assignment = channel_assignment1;
6786 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6787 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6788 st->codecpar->channels = truehd_channels(channel_assignment);
6789 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6794 static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6798 AVDOVIDecoderConfigurationRecord *dovi;
6802 if (c->fc->nb_streams < 1)
6804 st = c->fc->streams[c->fc->nb_streams-1];
6806 if ((uint64_t)atom.size > (1<<30) || atom.size < 4)
6807 return AVERROR_INVALIDDATA;
6809 dovi = av_dovi_alloc(&dovi_size);
6811 return AVERROR(ENOMEM);
6813 dovi->dv_version_major = avio_r8(pb);
6814 dovi->dv_version_minor = avio_r8(pb);
6816 buf = avio_rb16(pb);
6817 dovi->dv_profile = (buf >> 9) & 0x7f; // 7 bits
6818 dovi->dv_level = (buf >> 3) & 0x3f; // 6 bits
6819 dovi->rpu_present_flag = (buf >> 2) & 0x01; // 1 bit
6820 dovi->el_present_flag = (buf >> 1) & 0x01; // 1 bit
6821 dovi->bl_present_flag = buf & 0x01; // 1 bit
6822 if (atom.size >= 24) { // 4 + 4 + 4 * 4
6824 dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits
6826 // 0 stands for None
6827 // Dolby Vision V1.2.93 profiles and levels
6828 dovi->dv_bl_signal_compatibility_id = 0;
6831 ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF,
6832 (uint8_t *)dovi, dovi_size);
6838 av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC box, version: %d.%d, profile: %d, level: %d, "
6839 "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n",
6840 dovi->dv_version_major, dovi->dv_version_minor,
6841 dovi->dv_profile, dovi->dv_level,
6842 dovi->rpu_present_flag,
6843 dovi->el_present_flag,
6844 dovi->bl_present_flag,
6845 dovi->dv_bl_signal_compatibility_id
6851 static const MOVParseTableEntry mov_default_parse_table[] = {
6852 { MKTAG('A','C','L','R'), mov_read_aclr },
6853 { MKTAG('A','P','R','G'), mov_read_avid },
6854 { MKTAG('A','A','L','P'), mov_read_avid },
6855 { MKTAG('A','R','E','S'), mov_read_ares },
6856 { MKTAG('a','v','s','s'), mov_read_avss },
6857 { MKTAG('a','v','1','C'), mov_read_av1c },
6858 { MKTAG('c','h','p','l'), mov_read_chpl },
6859 { MKTAG('c','o','6','4'), mov_read_stco },
6860 { MKTAG('c','o','l','r'), mov_read_colr },
6861 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6862 { MKTAG('d','i','n','f'), mov_read_default },
6863 { MKTAG('D','p','x','E'), mov_read_dpxe },
6864 { MKTAG('d','r','e','f'), mov_read_dref },
6865 { MKTAG('e','d','t','s'), mov_read_default },
6866 { MKTAG('e','l','s','t'), mov_read_elst },
6867 { MKTAG('e','n','d','a'), mov_read_enda },
6868 { MKTAG('f','i','e','l'), mov_read_fiel },
6869 { MKTAG('a','d','r','m'), mov_read_adrm },
6870 { MKTAG('f','t','y','p'), mov_read_ftyp },
6871 { MKTAG('g','l','b','l'), mov_read_glbl },
6872 { MKTAG('h','d','l','r'), mov_read_hdlr },
6873 { MKTAG('i','l','s','t'), mov_read_ilst },
6874 { MKTAG('j','p','2','h'), mov_read_jp2h },
6875 { MKTAG('m','d','a','t'), mov_read_mdat },
6876 { MKTAG('m','d','h','d'), mov_read_mdhd },
6877 { MKTAG('m','d','i','a'), mov_read_default },
6878 { MKTAG('m','e','t','a'), mov_read_meta },
6879 { MKTAG('m','i','n','f'), mov_read_default },
6880 { MKTAG('m','o','o','f'), mov_read_moof },
6881 { MKTAG('m','o','o','v'), mov_read_moov },
6882 { MKTAG('m','v','e','x'), mov_read_default },
6883 { MKTAG('m','v','h','d'), mov_read_mvhd },
6884 { MKTAG('S','M','I',' '), mov_read_svq3 },
6885 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6886 { MKTAG('a','v','c','C'), mov_read_glbl },
6887 { MKTAG('p','a','s','p'), mov_read_pasp },
6888 { MKTAG('s','i','d','x'), mov_read_sidx },
6889 { MKTAG('s','t','b','l'), mov_read_default },
6890 { MKTAG('s','t','c','o'), mov_read_stco },
6891 { MKTAG('s','t','p','s'), mov_read_stps },
6892 { MKTAG('s','t','r','f'), mov_read_strf },
6893 { MKTAG('s','t','s','c'), mov_read_stsc },
6894 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6895 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6896 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6897 { MKTAG('s','t','t','s'), mov_read_stts },
6898 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6899 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
6900 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6901 { MKTAG('t','f','d','t'), mov_read_tfdt },
6902 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6903 { MKTAG('t','r','a','k'), mov_read_trak },
6904 { MKTAG('t','r','a','f'), mov_read_default },
6905 { MKTAG('t','r','e','f'), mov_read_default },
6906 { MKTAG('t','m','c','d'), mov_read_tmcd },
6907 { MKTAG('c','h','a','p'), mov_read_chap },
6908 { MKTAG('t','r','e','x'), mov_read_trex },
6909 { MKTAG('t','r','u','n'), mov_read_trun },
6910 { MKTAG('u','d','t','a'), mov_read_default },
6911 { MKTAG('w','a','v','e'), mov_read_wave },
6912 { MKTAG('e','s','d','s'), mov_read_esds },
6913 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6914 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6915 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6916 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6917 { MKTAG('w','f','e','x'), mov_read_wfex },
6918 { MKTAG('c','m','o','v'), mov_read_cmov },
6919 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6920 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6921 { MKTAG('s','b','g','p'), mov_read_sbgp },
6922 { MKTAG('h','v','c','C'), mov_read_glbl },
6923 { MKTAG('u','u','i','d'), mov_read_uuid },
6924 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6925 { MKTAG('f','r','e','e'), mov_read_free },
6926 { MKTAG('-','-','-','-'), mov_read_custom },
6927 { MKTAG('s','i','n','f'), mov_read_default },
6928 { MKTAG('f','r','m','a'), mov_read_frma },
6929 { MKTAG('s','e','n','c'), mov_read_senc },
6930 { MKTAG('s','a','i','z'), mov_read_saiz },
6931 { MKTAG('s','a','i','o'), mov_read_saio },
6932 { MKTAG('p','s','s','h'), mov_read_pssh },
6933 { MKTAG('s','c','h','m'), mov_read_schm },
6934 { MKTAG('s','c','h','i'), mov_read_default },
6935 { MKTAG('t','e','n','c'), mov_read_tenc },
6936 { MKTAG('d','f','L','a'), mov_read_dfla },
6937 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6938 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6939 { MKTAG('d','O','p','s'), mov_read_dops },
6940 { MKTAG('d','m','l','p'), mov_read_dmlp },
6941 { MKTAG('S','m','D','m'), mov_read_smdm },
6942 { MKTAG('C','o','L','L'), mov_read_coll },
6943 { MKTAG('v','p','c','C'), mov_read_vpcc },
6944 { MKTAG('m','d','c','v'), mov_read_mdcv },
6945 { MKTAG('c','l','l','i'), mov_read_clli },
6946 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
6947 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
6951 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6953 int64_t total_size = 0;
6957 if (c->atom_depth > 10) {
6958 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6959 return AVERROR_INVALIDDATA;
6964 atom.size = INT64_MAX;
6965 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6966 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
6969 if (atom.size >= 8) {
6970 a.size = avio_rb32(pb);
6971 a.type = avio_rl32(pb);
6972 if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
6973 a.type == MKTAG('h','o','o','v')) &&
6975 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
6977 uint32_t *type = (uint32_t *)buf + 1;
6978 if (avio_read(pb, buf, 8) != 8)
6979 return AVERROR_INVALIDDATA;
6980 avio_seek(pb, -8, SEEK_CUR);
6981 if (*type == MKTAG('m','v','h','d') ||
6982 *type == MKTAG('c','m','o','v')) {
6983 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
6984 a.type = MKTAG('m','o','o','v');
6987 if (atom.type != MKTAG('r','o','o','t') &&
6988 atom.type != MKTAG('m','o','o','v'))
6990 if (a.type == MKTAG('t','r','a','k') || a.type == MKTAG('m','d','a','t'))
6992 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
6999 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
7000 a.size = avio_rb64(pb) - 8;
7004 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
7005 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
7007 a.size = atom.size - total_size + 8;
7012 a.size = FFMIN(a.size, atom.size - total_size);
7014 for (i = 0; mov_default_parse_table[i].type; i++)
7015 if (mov_default_parse_table[i].type == a.type) {
7016 parse = mov_default_parse_table[i].parse;
7020 // container is user data
7021 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
7022 atom.type == MKTAG('i','l','s','t')))
7023 parse = mov_read_udta_string;
7025 // Supports parsing the QuickTime Metadata Keys.
7026 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
7027 if (!parse && c->found_hdlr_mdta &&
7028 atom.type == MKTAG('m','e','t','a') &&
7029 a.type == MKTAG('k','e','y','s')) {
7030 parse = mov_read_keys;
7033 if (!parse) { /* skip leaf atoms data */
7034 avio_skip(pb, a.size);
7036 int64_t start_pos = avio_tell(pb);
7038 int err = parse(c, pb, a);
7043 if (c->found_moov && c->found_mdat &&
7044 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
7045 start_pos + a.size == avio_size(pb))) {
7046 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
7047 c->next_root_atom = start_pos + a.size;
7051 left = a.size - avio_tell(pb) + start_pos;
7052 if (left > 0) /* skip garbage at atom end */
7053 avio_skip(pb, left);
7054 else if (left < 0) {
7055 av_log(c->fc, AV_LOG_WARNING,
7056 "overread end of atom '%.4s' by %"PRId64" bytes\n",
7057 (char*)&a.type, -left);
7058 avio_seek(pb, left, SEEK_CUR);
7062 total_size += a.size;
7065 if (total_size < atom.size && atom.size < 0x7ffff)
7066 avio_skip(pb, atom.size - total_size);
7072 static int mov_probe(const AVProbeData *p)
7077 int moov_offset = -1;
7079 /* check file header */
7082 /* ignore invalid offset */
7083 if ((offset + 8) > (unsigned int)p->buf_size)
7085 tag = AV_RL32(p->buf + offset + 4);
7087 /* check for obvious tags */
7088 case MKTAG('m','o','o','v'):
7089 moov_offset = offset + 4;
7090 case MKTAG('m','d','a','t'):
7091 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
7092 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
7093 case MKTAG('f','t','y','p'):
7094 if (AV_RB32(p->buf+offset) < 8 &&
7095 (AV_RB32(p->buf+offset) != 1 ||
7096 offset + 12 > (unsigned int)p->buf_size ||
7097 AV_RB64(p->buf+offset + 8) == 0)) {
7098 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7099 } else if (tag == MKTAG('f','t','y','p') &&
7100 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
7101 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
7103 score = FFMAX(score, 5);
7105 score = AVPROBE_SCORE_MAX;
7107 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7109 /* those are more common words, so rate then a bit less */
7110 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
7111 case MKTAG('w','i','d','e'):
7112 case MKTAG('f','r','e','e'):
7113 case MKTAG('j','u','n','k'):
7114 case MKTAG('p','i','c','t'):
7115 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
7116 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7118 case MKTAG(0x82,0x82,0x7f,0x7d):
7119 case MKTAG('s','k','i','p'):
7120 case MKTAG('u','u','i','d'):
7121 case MKTAG('p','r','f','l'):
7122 /* if we only find those cause probedata is too small at least rate them */
7123 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7124 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7127 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7130 if(score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
7131 /* moov atom in the header - we should make sure that this is not a
7132 * MOV-packed MPEG-PS */
7133 offset = moov_offset;
7135 while(offset < (p->buf_size - 16)){ /* Sufficient space */
7136 /* We found an actual hdlr atom */
7137 if(AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7138 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7139 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')){
7140 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7141 /* We found a media handler reference atom describing an
7142 * MPEG-PS-in-MOV, return a
7143 * low score to force expanding the probe window until
7144 * mpegps_probe finds what it needs */
7155 // must be done after parsing all trak because there's no order requirement
7156 static void mov_read_chapters(AVFormatContext *s)
7158 MOVContext *mov = s->priv_data;
7160 MOVStreamContext *sc;
7165 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7166 chapter_track = mov->chapter_tracks[j];
7168 for (i = 0; i < s->nb_streams; i++)
7169 if (s->streams[i]->id == chapter_track) {
7174 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7179 cur_pos = avio_tell(sc->pb);
7181 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7182 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7183 if (st->nb_index_entries) {
7184 // Retrieve the first frame, if possible
7186 AVIndexEntry *sample = &st->index_entries[0];
7187 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7188 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7192 if (av_get_packet(sc->pb, &pkt, sample->size) < 0)
7195 st->attached_pic = pkt;
7196 st->attached_pic.stream_index = st->index;
7197 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
7200 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7201 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7202 st->discard = AVDISCARD_ALL;
7203 for (i = 0; i < st->nb_index_entries; i++) {
7204 AVIndexEntry *sample = &st->index_entries[i];
7205 int64_t end = i+1 < st->nb_index_entries ? st->index_entries[i+1].timestamp : st->duration;
7210 if (end < sample->timestamp) {
7211 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7212 end = AV_NOPTS_VALUE;
7215 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7216 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7220 // the first two bytes are the length of the title
7221 len = avio_rb16(sc->pb);
7222 if (len > sample->size-2)
7224 title_len = 2*len + 1;
7225 if (!(title = av_mallocz(title_len)))
7228 // The samples could theoretically be in any encoding if there's an encd
7229 // atom following, but in practice are only utf-8 or utf-16, distinguished
7230 // instead by the presence of a BOM
7234 ch = avio_rb16(sc->pb);
7236 avio_get_str16be(sc->pb, len, title, title_len);
7237 else if (ch == 0xfffe)
7238 avio_get_str16le(sc->pb, len, title, title_len);
7241 if (len == 1 || len == 2)
7244 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7248 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7253 avio_seek(sc->pb, cur_pos, SEEK_SET);
7257 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7258 uint32_t value, int flags)
7261 char buf[AV_TIMECODE_STR_SIZE];
7262 AVRational rate = st->avg_frame_rate;
7263 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7266 av_dict_set(&st->metadata, "timecode",
7267 av_timecode_make_string(&tc, buf, value), 0);
7271 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7273 MOVStreamContext *sc = st->priv_data;
7274 char buf[AV_TIMECODE_STR_SIZE];
7275 int64_t cur_pos = avio_tell(sc->pb);
7276 int hh, mm, ss, ff, drop;
7278 if (!st->nb_index_entries)
7281 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7282 avio_skip(s->pb, 13);
7283 hh = avio_r8(s->pb);
7284 mm = avio_r8(s->pb);
7285 ss = avio_r8(s->pb);
7286 drop = avio_r8(s->pb);
7287 ff = avio_r8(s->pb);
7288 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7289 hh, mm, ss, drop ? ';' : ':', ff);
7290 av_dict_set(&st->metadata, "timecode", buf, 0);
7292 avio_seek(sc->pb, cur_pos, SEEK_SET);
7296 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7298 MOVStreamContext *sc = st->priv_data;
7300 int64_t cur_pos = avio_tell(sc->pb);
7303 if (!st->nb_index_entries)
7306 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7307 value = avio_rb32(s->pb);
7309 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7310 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7311 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7313 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7314 * not the case) and thus assume "frame number format" instead of QT one.
7315 * No sample with tmcd track can be found with a QT timecode at the moment,
7316 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7318 parse_timecode_in_framenum_format(s, st, value, flags);
7320 avio_seek(sc->pb, cur_pos, SEEK_SET);
7324 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7326 if (!index || !*index) return;
7327 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7328 av_encryption_info_free((*index)->encrypted_samples[i]);
7330 av_freep(&(*index)->encrypted_samples);
7331 av_freep(&(*index)->auxiliary_info_sizes);
7332 av_freep(&(*index)->auxiliary_offsets);
7336 static int mov_read_close(AVFormatContext *s)
7338 MOVContext *mov = s->priv_data;
7341 for (i = 0; i < s->nb_streams; i++) {
7342 AVStream *st = s->streams[i];
7343 MOVStreamContext *sc = st->priv_data;
7348 av_freep(&sc->ctts_data);
7349 for (j = 0; j < sc->drefs_count; j++) {
7350 av_freep(&sc->drefs[j].path);
7351 av_freep(&sc->drefs[j].dir);
7353 av_freep(&sc->drefs);
7355 sc->drefs_count = 0;
7357 if (!sc->pb_is_copied)
7358 ff_format_io_close(s, &sc->pb);
7361 av_freep(&sc->chunk_offsets);
7362 av_freep(&sc->stsc_data);
7363 av_freep(&sc->sample_sizes);
7364 av_freep(&sc->keyframes);
7365 av_freep(&sc->stts_data);
7366 av_freep(&sc->sdtp_data);
7367 av_freep(&sc->stps_data);
7368 av_freep(&sc->elst_data);
7369 av_freep(&sc->rap_group);
7370 av_freep(&sc->display_matrix);
7371 av_freep(&sc->index_ranges);
7374 for (j = 0; j < sc->stsd_count; j++)
7375 av_free(sc->extradata[j]);
7376 av_freep(&sc->extradata);
7377 av_freep(&sc->extradata_size);
7379 mov_free_encryption_index(&sc->cenc.encryption_index);
7380 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7381 av_aes_ctr_free(sc->cenc.aes_ctr);
7383 av_freep(&sc->stereo3d);
7384 av_freep(&sc->spherical);
7385 av_freep(&sc->mastering);
7386 av_freep(&sc->coll);
7389 if (mov->dv_demux) {
7390 avformat_free_context(mov->dv_fctx);
7391 mov->dv_fctx = NULL;
7394 if (mov->meta_keys) {
7395 for (i = 1; i < mov->meta_keys_count; i++) {
7396 av_freep(&mov->meta_keys[i]);
7398 av_freep(&mov->meta_keys);
7401 av_freep(&mov->trex_data);
7402 av_freep(&mov->bitrates);
7404 for (i = 0; i < mov->frag_index.nb_items; i++) {
7405 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7406 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7407 mov_free_encryption_index(&frag[j].encryption_index);
7409 av_freep(&mov->frag_index.item[i].stream_info);
7411 av_freep(&mov->frag_index.item);
7413 av_freep(&mov->aes_decrypt);
7414 av_freep(&mov->chapter_tracks);
7419 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7423 for (i = 0; i < s->nb_streams; i++) {
7424 AVStream *st = s->streams[i];
7425 MOVStreamContext *sc = st->priv_data;
7427 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7428 sc->timecode_track == tmcd_id)
7434 /* look for a tmcd track not referenced by any video track, and export it globally */
7435 static void export_orphan_timecode(AVFormatContext *s)
7439 for (i = 0; i < s->nb_streams; i++) {
7440 AVStream *st = s->streams[i];
7442 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7443 !tmcd_is_referenced(s, i + 1)) {
7444 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7446 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7453 static int read_tfra(MOVContext *mov, AVIOContext *f)
7455 int version, fieldlength, i, j;
7456 int64_t pos = avio_tell(f);
7457 uint32_t size = avio_rb32(f);
7458 unsigned track_id, item_count;
7460 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7463 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7465 version = avio_r8(f);
7467 track_id = avio_rb32(f);
7468 fieldlength = avio_rb32(f);
7469 item_count = avio_rb32(f);
7470 for (i = 0; i < item_count; i++) {
7471 int64_t time, offset;
7473 MOVFragmentStreamInfo * frag_stream_info;
7476 return AVERROR_INVALIDDATA;
7480 time = avio_rb64(f);
7481 offset = avio_rb64(f);
7483 time = avio_rb32(f);
7484 offset = avio_rb32(f);
7487 // The first sample of each stream in a fragment is always a random
7488 // access sample. So it's entry in the tfra can be used as the
7489 // initial PTS of the fragment.
7490 index = update_frag_index(mov, offset);
7491 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7492 if (frag_stream_info &&
7493 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7494 frag_stream_info->first_tfra_pts = time;
7496 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7498 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7500 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7504 avio_seek(f, pos + size, SEEK_SET);
7508 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7510 int64_t stream_size = avio_size(f);
7511 int64_t original_pos = avio_tell(f);
7515 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7519 mfra_size = avio_rb32(f);
7520 if (mfra_size < 0 || mfra_size > stream_size) {
7521 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7524 if ((seek_ret = avio_seek(f, -mfra_size, SEEK_CUR)) < 0) {
7528 if (avio_rb32(f) != mfra_size) {
7529 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7532 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7533 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7536 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7538 ret = read_tfra(c, f);
7544 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7546 av_log(c->fc, AV_LOG_ERROR,
7547 "failed to seek back after looking for mfra\n");
7553 static int mov_read_header(AVFormatContext *s)
7555 MOVContext *mov = s->priv_data;
7556 AVIOContext *pb = s->pb;
7558 MOVAtom atom = { AV_RL32("root") };
7561 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7562 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7563 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7564 return AVERROR(EINVAL);
7568 mov->trak_index = -1;
7569 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7570 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7571 atom.size = avio_size(pb);
7573 atom.size = INT64_MAX;
7575 /* check MOV header */
7577 if (mov->moov_retry)
7578 avio_seek(pb, 0, SEEK_SET);
7579 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7580 av_log(s, AV_LOG_ERROR, "error reading header\n");
7584 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7585 if (!mov->found_moov) {
7586 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7588 return AVERROR_INVALIDDATA;
7590 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7592 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7593 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7594 mov_read_chapters(s);
7595 for (i = 0; i < s->nb_streams; i++)
7596 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7597 mov_read_timecode_track(s, s->streams[i]);
7598 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7599 mov_read_rtmd_track(s, s->streams[i]);
7603 /* copy timecode metadata from tmcd tracks to the related video streams */
7604 for (i = 0; i < s->nb_streams; i++) {
7605 AVStream *st = s->streams[i];
7606 MOVStreamContext *sc = st->priv_data;
7607 if (sc->timecode_track > 0) {
7608 AVDictionaryEntry *tcr;
7609 int tmcd_st_id = -1;
7611 for (j = 0; j < s->nb_streams; j++)
7612 if (s->streams[j]->id == sc->timecode_track)
7615 if (tmcd_st_id < 0 || tmcd_st_id == i)
7617 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7619 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7622 export_orphan_timecode(s);
7624 for (i = 0; i < s->nb_streams; i++) {
7625 AVStream *st = s->streams[i];
7626 MOVStreamContext *sc = st->priv_data;
7627 fix_timescale(mov, sc);
7628 if(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7629 st->skip_samples = sc->start_pad;
7631 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7632 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7633 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7634 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7635 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7636 st->codecpar->width = sc->width;
7637 st->codecpar->height = sc->height;
7639 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7640 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7644 if (mov->handbrake_version &&
7645 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7646 st->codecpar->codec_id == AV_CODEC_ID_MP3
7648 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7649 st->need_parsing = AVSTREAM_PARSE_FULL;
7653 if (mov->trex_data) {
7654 for (i = 0; i < s->nb_streams; i++) {
7655 AVStream *st = s->streams[i];
7656 MOVStreamContext *sc = st->priv_data;
7657 if (st->duration > 0) {
7658 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7659 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7660 sc->data_size, sc->time_scale);
7662 return AVERROR_INVALIDDATA;
7664 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7669 if (mov->use_mfra_for > 0) {
7670 for (i = 0; i < s->nb_streams; i++) {
7671 AVStream *st = s->streams[i];
7672 MOVStreamContext *sc = st->priv_data;
7673 if (sc->duration_for_fps > 0) {
7674 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7675 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7676 sc->data_size, sc->time_scale);
7678 return AVERROR_INVALIDDATA;
7680 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7681 sc->duration_for_fps;
7686 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7687 if (mov->bitrates[i]) {
7688 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7692 ff_rfps_calculate(s);
7694 for (i = 0; i < s->nb_streams; i++) {
7695 AVStream *st = s->streams[i];
7696 MOVStreamContext *sc = st->priv_data;
7698 switch (st->codecpar->codec_type) {
7699 case AVMEDIA_TYPE_AUDIO:
7700 err = ff_replaygain_export(st, s->metadata);
7706 case AVMEDIA_TYPE_VIDEO:
7707 if (sc->display_matrix) {
7708 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7709 sizeof(int32_t) * 9);
7713 sc->display_matrix = NULL;
7716 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7717 (uint8_t *)sc->stereo3d,
7718 sizeof(*sc->stereo3d));
7722 sc->stereo3d = NULL;
7724 if (sc->spherical) {
7725 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7726 (uint8_t *)sc->spherical,
7727 sc->spherical_size);
7731 sc->spherical = NULL;
7733 if (sc->mastering) {
7734 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7735 (uint8_t *)sc->mastering,
7736 sizeof(*sc->mastering));
7740 sc->mastering = NULL;
7743 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7744 (uint8_t *)sc->coll,
7754 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7756 for (i = 0; i < mov->frag_index.nb_items; i++)
7757 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7758 mov->frag_index.item[i].headers_read = 1;
7763 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7765 AVIndexEntry *sample = NULL;
7766 int64_t best_dts = INT64_MAX;
7768 for (i = 0; i < s->nb_streams; i++) {
7769 AVStream *avst = s->streams[i];
7770 MOVStreamContext *msc = avst->priv_data;
7771 if (msc->pb && msc->current_sample < avst->nb_index_entries) {
7772 AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample];
7773 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7774 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7775 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7776 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7777 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb &&
7778 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7779 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7780 sample = current_sample;
7789 static int should_retry(AVIOContext *pb, int error_code) {
7790 if (error_code == AVERROR_EOF || avio_feof(pb))
7796 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7799 MOVContext *mov = s->priv_data;
7801 if (index >= 0 && index < mov->frag_index.nb_items)
7802 target = mov->frag_index.item[index].moof_offset;
7803 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7804 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7805 return AVERROR_INVALIDDATA;
7808 mov->next_root_atom = 0;
7809 if (index < 0 || index >= mov->frag_index.nb_items)
7810 index = search_frag_moof_offset(&mov->frag_index, target);
7811 if (index < mov->frag_index.nb_items &&
7812 mov->frag_index.item[index].moof_offset == target) {
7813 if (index + 1 < mov->frag_index.nb_items)
7814 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7815 if (mov->frag_index.item[index].headers_read)
7817 mov->frag_index.item[index].headers_read = 1;
7820 mov->found_mdat = 0;
7822 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7825 if (avio_feof(s->pb))
7827 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7832 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7834 uint8_t *side, *extradata;
7837 /* Save the current index. */
7838 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7840 /* Notify the decoder that extradata changed. */
7841 extradata_size = sc->extradata_size[sc->last_stsd_index];
7842 extradata = sc->extradata[sc->last_stsd_index];
7843 if (extradata_size > 0 && extradata) {
7844 side = av_packet_new_side_data(pkt,
7845 AV_PKT_DATA_NEW_EXTRADATA,
7848 return AVERROR(ENOMEM);
7849 memcpy(side, extradata, extradata_size);
7855 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7857 MOVContext *mov = s->priv_data;
7858 MOVStreamContext *sc;
7859 AVIndexEntry *sample;
7860 AVStream *st = NULL;
7861 int64_t current_index;
7865 sample = mov_find_next_sample(s, &st);
7866 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7867 if (!mov->next_root_atom)
7869 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7874 /* must be done just before reading, to avoid infinite loop on sample */
7875 current_index = sc->current_index;
7876 mov_current_sample_inc(sc);
7878 if (mov->next_root_atom) {
7879 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7880 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7883 if (st->discard != AVDISCARD_ALL) {
7884 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7885 if (ret64 != sample->pos) {
7886 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7887 sc->ffindex, sample->pos);
7888 if (should_retry(sc->pb, ret64)) {
7889 mov_current_sample_dec(sc);
7891 return AVERROR_INVALIDDATA;
7894 if( st->discard == AVDISCARD_NONKEY && 0==(sample->flags & AVINDEX_KEYFRAME) ) {
7895 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7899 ret = av_get_packet(sc->pb, pkt, sample->size);
7901 if (should_retry(sc->pb, ret)) {
7902 mov_current_sample_dec(sc);
7906 if (sc->has_palette) {
7909 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7911 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7913 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7914 sc->has_palette = 0;
7917 #if CONFIG_DV_DEMUXER
7918 if (mov->dv_demux && sc->dv_audio_container) {
7919 avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7920 av_freep(&pkt->data);
7922 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7927 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7928 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7929 st->need_parsing = AVSTREAM_PARSE_FULL;
7933 pkt->stream_index = sc->ffindex;
7934 pkt->dts = sample->timestamp;
7935 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7936 pkt->flags |= AV_PKT_FLAG_DISCARD;
7938 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7939 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
7940 /* update ctts context */
7942 if (sc->ctts_index < sc->ctts_count &&
7943 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
7945 sc->ctts_sample = 0;
7948 int64_t next_dts = (sc->current_sample < st->nb_index_entries) ?
7949 st->index_entries[sc->current_sample].timestamp : st->duration;
7951 if (next_dts >= pkt->dts)
7952 pkt->duration = next_dts - pkt->dts;
7953 pkt->pts = pkt->dts;
7955 if (st->discard == AVDISCARD_ALL)
7957 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
7958 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
7959 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
7960 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
7962 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
7963 pkt->pos = sample->pos;
7965 /* Multiple stsd handling. */
7966 if (sc->stsc_data) {
7967 /* Keep track of the stsc index for the given sample, then check
7968 * if the stsd index is different from the last used one. */
7970 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
7971 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
7973 sc->stsc_sample = 0;
7974 /* Do not check indexes after a switch. */
7975 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
7976 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
7977 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
7978 ret = mov_change_extradata(sc, pkt);
7985 aax_filter(pkt->data, pkt->size, mov);
7987 ret = cenc_filter(mov, st, sc, pkt, current_index);
7995 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
7997 MOVContext *mov = s->priv_data;
8000 if (!mov->frag_index.complete)
8003 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
8006 if (!mov->frag_index.item[index].headers_read)
8007 return mov_switch_root(s, -1, index);
8008 if (index + 1 < mov->frag_index.nb_items)
8009 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
8014 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
8016 MOVStreamContext *sc = st->priv_data;
8017 int sample, time_sample, ret;
8020 // Here we consider timestamp to be PTS, hence try to offset it so that we
8021 // can search over the DTS timeline.
8022 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
8024 ret = mov_seek_fragment(s, st, timestamp);
8028 sample = av_index_search_timestamp(st, timestamp, flags);
8029 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
8030 if (sample < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp)
8032 if (sample < 0) /* not sure what to do */
8033 return AVERROR_INVALIDDATA;
8034 mov_current_sample_set(sc, sample);
8035 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
8036 /* adjust ctts index */
8037 if (sc->ctts_data) {
8039 for (i = 0; i < sc->ctts_count; i++) {
8040 int next = time_sample + sc->ctts_data[i].count;
8041 if (next > sc->current_sample) {
8043 sc->ctts_sample = sc->current_sample - time_sample;
8050 /* adjust stsd index */
8051 if (sc->chunk_count) {
8053 for (i = 0; i < sc->stsc_count; i++) {
8054 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
8055 if (next > sc->current_sample) {
8057 sc->stsc_sample = sc->current_sample - time_sample;
8060 av_assert0(next == (int)next);
8068 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
8070 MOVContext *mc = s->priv_data;
8075 if (stream_index >= s->nb_streams)
8076 return AVERROR_INVALIDDATA;
8078 st = s->streams[stream_index];
8079 sample = mov_seek_stream(s, st, sample_time, flags);
8083 if (mc->seek_individually) {
8084 /* adjust seek timestamp to found sample timestamp */
8085 int64_t seek_timestamp = st->index_entries[sample].timestamp;
8087 for (i = 0; i < s->nb_streams; i++) {
8089 MOVStreamContext *sc = s->streams[i]->priv_data;
8091 st->skip_samples = (sample_time <= 0) ? sc->start_pad : 0;
8093 if (stream_index == i)
8096 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
8097 mov_seek_stream(s, st, timestamp, flags);
8100 for (i = 0; i < s->nb_streams; i++) {
8101 MOVStreamContext *sc;
8104 mov_current_sample_set(sc, 0);
8107 MOVStreamContext *sc;
8108 AVIndexEntry *entry = mov_find_next_sample(s, &st);
8110 return AVERROR_INVALIDDATA;
8112 if (sc->ffindex == stream_index && sc->current_sample == sample)
8114 mov_current_sample_inc(sc);
8120 #define OFFSET(x) offsetof(MOVContext, x)
8121 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
8122 static const AVOption mov_options[] = {
8123 {"use_absolute_path",
8124 "allow using absolute path when opening alias, this is a possible security issue",
8125 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
8127 {"seek_streams_individually",
8128 "Seek each stream individually to the closest point",
8129 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
8131 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
8133 {"advanced_editlist",
8134 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
8135 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
8137 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8140 "use mfra for fragment timestamps",
8141 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8142 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8144 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8145 FLAGS, "use_mfra_for" },
8146 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8147 FLAGS, "use_mfra_for" },
8148 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8149 FLAGS, "use_mfra_for" },
8150 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8151 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8152 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8153 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8154 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8155 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8156 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8157 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8158 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8159 .flags = AV_OPT_FLAG_DECODING_PARAM },
8160 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8161 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8162 {.i64 = 0}, 0, 1, FLAGS },
8167 static const AVClass mov_class = {
8168 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8169 .item_name = av_default_item_name,
8170 .option = mov_options,
8171 .version = LIBAVUTIL_VERSION_INT,
8174 AVInputFormat ff_mov_demuxer = {
8175 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8176 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8177 .priv_class = &mov_class,
8178 .priv_data_size = sizeof(MOVContext),
8179 .extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
8180 .read_probe = mov_probe,
8181 .read_header = mov_read_header,
8182 .read_packet = mov_read_packet,
8183 .read_close = mov_read_close,
8184 .read_seek = mov_read_seek,
8185 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,