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 + 30) {
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) {
2890 av_log(c->fc, AV_LOG_ERROR, "Invalid sample size %d\n", sc->sample_sizes[i]);
2891 return AVERROR_INVALIDDATA;
2893 sc->data_size += sc->sample_sizes[i];
2896 sc->sample_count = i;
2900 if (pb->eof_reached) {
2901 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSZ atom\n");
2908 static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2911 MOVStreamContext *sc;
2912 unsigned int i, entries, alloc_size = 0;
2914 int64_t total_sample_count=0;
2916 if (c->fc->nb_streams < 1)
2918 st = c->fc->streams[c->fc->nb_streams-1];
2921 avio_r8(pb); /* version */
2922 avio_rb24(pb); /* flags */
2923 entries = avio_rb32(pb);
2925 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
2926 c->fc->nb_streams-1, entries);
2929 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
2930 av_freep(&sc->stts_data);
2932 if (entries >= INT_MAX / sizeof(*sc->stts_data))
2933 return AVERROR(ENOMEM);
2935 for (i = 0; i < entries && !pb->eof_reached; i++) {
2936 int sample_duration;
2937 unsigned int sample_count;
2938 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
2939 MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
2940 min_entries * sizeof(*sc->stts_data));
2942 av_freep(&sc->stts_data);
2944 return AVERROR(ENOMEM);
2946 sc->stts_count = min_entries;
2947 sc->stts_data = stts_data;
2949 sample_count=avio_rb32(pb);
2950 sample_duration = avio_rb32(pb);
2952 sc->stts_data[i].count= sample_count;
2953 sc->stts_data[i].duration= sample_duration;
2955 av_log(c->fc, AV_LOG_TRACE, "sample_count=%d, sample_duration=%d\n",
2956 sample_count, sample_duration);
2958 duration+=(int64_t)sample_duration*(uint64_t)sample_count;
2959 total_sample_count+=sample_count;
2965 duration <= INT64_MAX - sc->duration_for_fps &&
2966 total_sample_count <= INT_MAX - sc->nb_frames_for_fps
2968 sc->duration_for_fps += duration;
2969 sc->nb_frames_for_fps += total_sample_count;
2972 if (pb->eof_reached) {
2973 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
2977 st->nb_frames= total_sample_count;
2979 st->duration= FFMIN(st->duration, duration);
2980 sc->track_end = duration;
2984 static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2987 MOVStreamContext *sc;
2990 if (c->fc->nb_streams < 1)
2992 st = c->fc->streams[c->fc->nb_streams - 1];
2995 avio_r8(pb); /* version */
2996 avio_rb24(pb); /* flags */
2997 entries = atom.size - 4;
2999 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3000 c->fc->nb_streams - 1, entries);
3003 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3004 av_freep(&sc->sdtp_data);
3007 sc->sdtp_data = av_mallocz(entries);
3009 return AVERROR(ENOMEM);
3011 for (i = 0; i < entries && !pb->eof_reached; i++)
3012 sc->sdtp_data[i] = avio_r8(pb);
3018 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3021 if (duration == INT_MIN) {
3022 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3025 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3029 static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3032 MOVStreamContext *sc;
3033 unsigned int i, entries, ctts_count = 0;
3035 if (c->fc->nb_streams < 1)
3037 st = c->fc->streams[c->fc->nb_streams-1];
3040 avio_r8(pb); /* version */
3041 avio_rb24(pb); /* flags */
3042 entries = avio_rb32(pb);
3044 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3048 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3049 return AVERROR_INVALIDDATA;
3050 av_freep(&sc->ctts_data);
3051 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3053 return AVERROR(ENOMEM);
3055 for (i = 0; i < entries && !pb->eof_reached; i++) {
3056 int count =avio_rb32(pb);
3057 int duration =avio_rb32(pb);
3060 av_log(c->fc, AV_LOG_TRACE,
3061 "ignoring CTTS entry with count=%d duration=%d\n",
3066 add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3069 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3072 if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3073 av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3074 av_freep(&sc->ctts_data);
3080 mov_update_dts_shift(sc, duration, c->fc);
3083 sc->ctts_count = ctts_count;
3085 if (pb->eof_reached) {
3086 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3090 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3095 static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3098 MOVStreamContext *sc;
3099 unsigned int i, entries;
3101 uint32_t grouping_type;
3103 if (c->fc->nb_streams < 1)
3105 st = c->fc->streams[c->fc->nb_streams-1];
3108 version = avio_r8(pb); /* version */
3109 avio_rb24(pb); /* flags */
3110 grouping_type = avio_rl32(pb);
3111 if (grouping_type != MKTAG( 'r','a','p',' '))
3112 return 0; /* only support 'rap ' grouping */
3114 avio_rb32(pb); /* grouping_type_parameter */
3116 entries = avio_rb32(pb);
3120 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP atom\n");
3121 av_free(sc->rap_group);
3122 sc->rap_group_count = 0;
3123 sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group));
3125 return AVERROR(ENOMEM);
3127 for (i = 0; i < entries && !pb->eof_reached; i++) {
3128 sc->rap_group[i].count = avio_rb32(pb); /* sample_count */
3129 sc->rap_group[i].index = avio_rb32(pb); /* group_description_index */
3132 sc->rap_group_count = i;
3134 if (pb->eof_reached) {
3135 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3143 * Get ith edit list entry (media time, duration).
3145 static int get_edit_list_entry(MOVContext *mov,
3146 const MOVStreamContext *msc,
3147 unsigned int edit_list_index,
3148 int64_t *edit_list_media_time,
3149 int64_t *edit_list_duration,
3150 int64_t global_timescale)
3152 if (edit_list_index == msc->elst_count) {
3155 *edit_list_media_time = msc->elst_data[edit_list_index].time;
3156 *edit_list_duration = msc->elst_data[edit_list_index].duration;
3158 /* duration is in global timescale units;convert to msc timescale */
3159 if (global_timescale == 0) {
3160 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3163 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3169 * Find the closest previous frame to the timestamp_pts, in e_old index
3170 * entries. Searching for just any frame / just key frames can be controlled by
3171 * last argument 'flag'.
3172 * Note that if ctts_data is not NULL, we will always search for a key frame
3173 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3174 * return the first frame of the video.
3176 * Here the timestamp_pts is considered to be a presentation timestamp and
3177 * the timestamp of index entries are considered to be decoding timestamps.
3179 * Returns 0 if successful in finding a frame, else returns -1.
3180 * Places the found index corresponding output arg.
3182 * If ctts_old is not NULL, then refines the searched entry by searching
3183 * backwards from the found timestamp, to find the frame with correct PTS.
3185 * Places the found ctts_index and ctts_sample in corresponding output args.
3187 static int find_prev_closest_index(AVStream *st,
3188 AVIndexEntry *e_old,
3192 int64_t timestamp_pts,
3195 int64_t* ctts_index,
3196 int64_t* ctts_sample)
3198 MOVStreamContext *msc = st->priv_data;
3199 AVIndexEntry *e_keep = st->index_entries;
3200 int nb_keep = st->nb_index_entries;
3202 int64_t index_ctts_count;
3206 // If dts_shift > 0, then all the index timestamps will have to be offset by
3207 // at least dts_shift amount to obtain PTS.
3208 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3209 if (msc->dts_shift > 0) {
3210 timestamp_pts -= msc->dts_shift;
3213 st->index_entries = e_old;
3214 st->nb_index_entries = nb_old;
3215 *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3217 // Keep going backwards in the index entries until the timestamp is the same.
3219 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3221 if ((flag & AVSEEK_FLAG_ANY) ||
3222 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3228 // If we have CTTS then refine the search, by searching backwards over PTS
3229 // computed by adding corresponding CTTS durations to index timestamps.
3230 if (ctts_data && *index >= 0) {
3231 av_assert0(ctts_index);
3232 av_assert0(ctts_sample);
3233 // Find out the ctts_index for the found frame.
3236 for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3237 if (*ctts_index < ctts_count) {
3239 if (ctts_data[*ctts_index].count == *ctts_sample) {
3246 while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3247 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3248 // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3249 // compensated by dts_shift above.
3250 if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3251 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3256 if (*ctts_sample == 0) {
3258 if (*ctts_index >= 0)
3259 *ctts_sample = ctts_data[*ctts_index].count - 1;
3266 /* restore AVStream state*/
3267 st->index_entries = e_keep;
3268 st->nb_index_entries = nb_keep;
3269 return *index >= 0 ? 0 : -1;
3273 * Add index entry with the given values, to the end of st->index_entries.
3274 * Returns the new size st->index_entries if successful, else returns -1.
3276 * This function is similar to ff_add_index_entry in libavformat/utils.c
3277 * except that here we are always unconditionally adding an index entry to
3278 * the end, instead of searching the entries list and skipping the add if
3279 * there is an existing entry with the same timestamp.
3280 * This is needed because the mov_fix_index calls this func with the same
3281 * unincremented timestamp for successive discarded frames.
3283 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3284 int size, int distance, int flags)
3286 AVIndexEntry *entries, *ie;
3288 const size_t min_size_needed = (st->nb_index_entries + 1) * sizeof(AVIndexEntry);
3290 // Double the allocation each time, to lower memory fragmentation.
3291 // Another difference from ff_add_index_entry function.
3292 const size_t requested_size =
3293 min_size_needed > st->index_entries_allocated_size ?
3294 FFMAX(min_size_needed, 2 * st->index_entries_allocated_size) :
3297 if((unsigned)st->nb_index_entries + 1 >= UINT_MAX / sizeof(AVIndexEntry))
3300 entries = av_fast_realloc(st->index_entries,
3301 &st->index_entries_allocated_size,
3306 st->index_entries= entries;
3308 index= st->nb_index_entries++;
3309 ie= &entries[index];
3312 ie->timestamp = timestamp;
3313 ie->min_distance= distance;
3320 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3321 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3323 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3324 int64_t* frame_duration_buffer,
3325 int frame_duration_buffer_size) {
3327 av_assert0(end_index >= 0 && end_index <= st->nb_index_entries);
3328 for (i = 0; i < frame_duration_buffer_size; i++) {
3329 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3330 st->index_entries[end_index - 1 - i].timestamp = end_ts;
3335 * Append a new ctts entry to ctts_data.
3336 * Returns the new ctts_count if successful, else returns -1.
3338 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3339 int count, int duration)
3341 MOVStts *ctts_buf_new;
3342 const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVStts);
3343 const size_t requested_size =
3344 min_size_needed > *allocated_size ?
3345 FFMAX(min_size_needed, 2 * (*allocated_size)) :
3348 if((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
3351 ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3356 *ctts_data = ctts_buf_new;
3358 ctts_buf_new[*ctts_count].count = count;
3359 ctts_buf_new[*ctts_count].duration = duration;
3361 *ctts_count = (*ctts_count) + 1;
3365 #define MAX_REORDER_DELAY 16
3366 static void mov_estimate_video_delay(MOVContext *c, AVStream* st) {
3367 MOVStreamContext *msc = st->priv_data;
3370 int ctts_sample = 0;
3371 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3373 int j, r, num_swaps;
3375 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3376 pts_buf[j] = INT64_MIN;
3378 if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3379 st->codecpar->codec_id == AV_CODEC_ID_H264) {
3380 st->codecpar->video_delay = 0;
3381 for(ind = 0; ind < st->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3382 // Point j to the last elem of the buffer and insert the current pts there.
3384 buf_start = (buf_start + 1);
3385 if (buf_start == MAX_REORDER_DELAY + 1)
3388 pts_buf[j] = st->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3390 // The timestamps that are already in the sorted buffer, and are greater than the
3391 // current pts, are exactly the timestamps that need to be buffered to output PTS
3392 // in correct sorted order.
3393 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3394 // can be computed as the maximum no. of swaps any particular timestamp needs to
3395 // go through, to keep this buffer in sorted order.
3397 while (j != buf_start) {
3399 if (r < 0) r = MAX_REORDER_DELAY;
3400 if (pts_buf[j] < pts_buf[r]) {
3401 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3408 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3411 if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3416 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3417 st->codecpar->video_delay, st->index);
3421 static void mov_current_sample_inc(MOVStreamContext *sc)
3423 sc->current_sample++;
3424 sc->current_index++;
3425 if (sc->index_ranges &&
3426 sc->current_index >= sc->current_index_range->end &&
3427 sc->current_index_range->end) {
3428 sc->current_index_range++;
3429 sc->current_index = sc->current_index_range->start;
3433 static void mov_current_sample_dec(MOVStreamContext *sc)
3435 sc->current_sample--;
3436 sc->current_index--;
3437 if (sc->index_ranges &&
3438 sc->current_index < sc->current_index_range->start &&
3439 sc->current_index_range > sc->index_ranges) {
3440 sc->current_index_range--;
3441 sc->current_index = sc->current_index_range->end - 1;
3445 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3449 sc->current_sample = current_sample;
3450 sc->current_index = current_sample;
3451 if (!sc->index_ranges) {
3455 for (sc->current_index_range = sc->index_ranges;
3456 sc->current_index_range->end;
3457 sc->current_index_range++) {
3458 range_size = sc->current_index_range->end - sc->current_index_range->start;
3459 if (range_size > current_sample) {
3460 sc->current_index = sc->current_index_range->start + current_sample;
3463 current_sample -= range_size;
3468 * Fix st->index_entries, so that it contains only the entries (and the entries
3469 * which are needed to decode them) that fall in the edit list time ranges.
3470 * Also fixes the timestamps of the index entries to match the timeline
3471 * specified the edit lists.
3473 static void mov_fix_index(MOVContext *mov, AVStream *st)
3475 MOVStreamContext *msc = st->priv_data;
3476 AVIndexEntry *e_old = st->index_entries;
3477 int nb_old = st->nb_index_entries;
3478 const AVIndexEntry *e_old_end = e_old + nb_old;
3479 const AVIndexEntry *current = NULL;
3480 MOVStts *ctts_data_old = msc->ctts_data;
3481 int64_t ctts_index_old = 0;
3482 int64_t ctts_sample_old = 0;
3483 int64_t ctts_count_old = msc->ctts_count;
3484 int64_t edit_list_media_time = 0;
3485 int64_t edit_list_duration = 0;
3486 int64_t frame_duration = 0;
3487 int64_t edit_list_dts_counter = 0;
3488 int64_t edit_list_dts_entry_end = 0;
3489 int64_t edit_list_start_ctts_sample = 0;
3491 int64_t curr_ctts = 0;
3492 int64_t empty_edits_sum_duration = 0;
3493 int64_t edit_list_index = 0;
3496 int64_t start_dts = 0;
3497 int64_t edit_list_start_encountered = 0;
3498 int64_t search_timestamp = 0;
3499 int64_t* frame_duration_buffer = NULL;
3500 int num_discarded_begin = 0;
3501 int first_non_zero_audio_edit = -1;
3502 int packet_skip_samples = 0;
3503 MOVIndexRange *current_index_range;
3505 int found_keyframe_after_edit = 0;
3506 int found_non_empty_edit = 0;
3508 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
3512 // allocate the index ranges array
3513 msc->index_ranges = av_malloc((msc->elst_count + 1) * sizeof(msc->index_ranges[0]));
3514 if (!msc->index_ranges) {
3515 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
3518 msc->current_index_range = msc->index_ranges;
3519 current_index_range = msc->index_ranges - 1;
3521 // Clean AVStream from traces of old index
3522 st->index_entries = NULL;
3523 st->index_entries_allocated_size = 0;
3524 st->nb_index_entries = 0;
3526 // Clean ctts fields of MOVStreamContext
3527 msc->ctts_data = NULL;
3528 msc->ctts_count = 0;
3529 msc->ctts_index = 0;
3530 msc->ctts_sample = 0;
3531 msc->ctts_allocated_size = 0;
3533 // Reinitialize min_corrected_pts so that it can be computed again.
3534 msc->min_corrected_pts = -1;
3536 // If the dts_shift is positive (in case of negative ctts values in mov),
3537 // then negate the DTS by dts_shift
3538 if (msc->dts_shift > 0) {
3539 edit_list_dts_entry_end -= msc->dts_shift;
3540 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
3543 start_dts = edit_list_dts_entry_end;
3545 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
3546 &edit_list_duration, mov->time_scale)) {
3547 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
3548 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
3550 edit_list_dts_counter = edit_list_dts_entry_end;
3551 edit_list_dts_entry_end += edit_list_duration;
3552 num_discarded_begin = 0;
3553 if (!found_non_empty_edit && edit_list_media_time == -1) {
3554 empty_edits_sum_duration += edit_list_duration;
3557 found_non_empty_edit = 1;
3559 // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
3560 // according to the edit list below.
3561 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3562 if (first_non_zero_audio_edit < 0) {
3563 first_non_zero_audio_edit = 1;
3565 first_non_zero_audio_edit = 0;
3568 if (first_non_zero_audio_edit > 0)
3569 st->skip_samples = msc->start_pad = 0;
3572 // While reordering frame index according to edit list we must handle properly
3573 // the scenario when edit list entry starts from none key frame.
3574 // We find closest previous key frame and preserve it and consequent frames in index.
3575 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
3576 search_timestamp = edit_list_media_time;
3577 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3578 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
3579 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
3580 // edit_list_media_time to cover the decoder delay.
3581 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
3584 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
3585 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3586 av_log(mov->fc, AV_LOG_WARNING,
3587 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
3588 st->index, edit_list_index, search_timestamp);
3589 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
3590 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3591 av_log(mov->fc, AV_LOG_WARNING,
3592 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
3593 st->index, edit_list_index, search_timestamp);
3596 ctts_sample_old = 0;
3599 current = e_old + index;
3600 edit_list_start_ctts_sample = ctts_sample_old;
3602 // Iterate over index and arrange it according to edit list
3603 edit_list_start_encountered = 0;
3604 found_keyframe_after_edit = 0;
3605 for (; current < e_old_end; current++, index++) {
3606 // check if frame outside edit list mark it for discard
3607 frame_duration = (current + 1 < e_old_end) ?
3608 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
3610 flags = current->flags;
3612 // frames (pts) before or after edit list
3613 curr_cts = current->timestamp + msc->dts_shift;
3616 if (ctts_data_old && ctts_index_old < ctts_count_old) {
3617 curr_ctts = ctts_data_old[ctts_index_old].duration;
3618 av_log(mov->fc, AV_LOG_DEBUG, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
3619 curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
3620 curr_cts += curr_ctts;
3622 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
3623 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3624 &msc->ctts_allocated_size,
3625 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3626 ctts_data_old[ctts_index_old].duration) == -1) {
3627 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3629 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3630 ctts_data_old[ctts_index_old].duration);
3634 ctts_sample_old = 0;
3635 edit_list_start_ctts_sample = 0;
3639 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
3640 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
3641 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
3642 first_non_zero_audio_edit > 0) {
3643 packet_skip_samples = edit_list_media_time - curr_cts;
3644 st->skip_samples += packet_skip_samples;
3646 // Shift the index entry timestamp by packet_skip_samples to be correct.
3647 edit_list_dts_counter -= packet_skip_samples;
3648 if (edit_list_start_encountered == 0) {
3649 edit_list_start_encountered = 1;
3650 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
3651 // discarded packets.
3652 if (frame_duration_buffer) {
3653 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3654 frame_duration_buffer, num_discarded_begin);
3655 av_freep(&frame_duration_buffer);
3659 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
3661 flags |= AVINDEX_DISCARD_FRAME;
3662 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
3664 if (edit_list_start_encountered == 0) {
3665 num_discarded_begin++;
3666 frame_duration_buffer = av_realloc(frame_duration_buffer,
3667 num_discarded_begin * sizeof(int64_t));
3668 if (!frame_duration_buffer) {
3669 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
3672 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
3674 // Increment skip_samples for the first non-zero audio edit list
3675 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3676 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
3677 st->skip_samples += frame_duration;
3682 if (msc->min_corrected_pts < 0) {
3683 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
3685 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
3687 if (edit_list_start_encountered == 0) {
3688 edit_list_start_encountered = 1;
3689 // Make timestamps strictly monotonically increasing by rewriting timestamps for
3690 // discarded packets.
3691 if (frame_duration_buffer) {
3692 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3693 frame_duration_buffer, num_discarded_begin);
3694 av_freep(&frame_duration_buffer);
3699 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
3700 current->min_distance, flags) == -1) {
3701 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
3705 // Update the index ranges array
3706 if (current_index_range < msc->index_ranges || index != current_index_range->end) {
3707 current_index_range++;
3708 current_index_range->start = index;
3710 current_index_range->end = index + 1;
3712 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
3713 if (edit_list_start_encountered > 0) {
3714 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
3717 // Break when found first key frame after edit entry completion
3718 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
3719 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
3720 if (ctts_data_old) {
3721 // If we have CTTS and this is the first keyframe after edit elist,
3722 // wait for one more, because there might be trailing B-frames after this I-frame
3723 // that do belong to the edit.
3724 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
3725 found_keyframe_after_edit = 1;
3728 if (ctts_sample_old != 0) {
3729 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3730 &msc->ctts_allocated_size,
3731 ctts_sample_old - edit_list_start_ctts_sample,
3732 ctts_data_old[ctts_index_old].duration) == -1) {
3733 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3734 ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
3735 ctts_data_old[ctts_index_old].duration);
3744 // If there are empty edits, then msc->min_corrected_pts might be positive
3745 // intentionally. So we subtract the sum duration of emtpy edits here.
3746 msc->min_corrected_pts -= empty_edits_sum_duration;
3748 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
3749 // dts by that amount to make the first pts zero.
3750 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
3751 if (msc->min_corrected_pts > 0) {
3752 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
3753 for (i = 0; i < st->nb_index_entries; ++i) {
3754 st->index_entries[i].timestamp -= msc->min_corrected_pts;
3758 // Start time should be equal to zero or the duration of any empty edits.
3759 st->start_time = empty_edits_sum_duration;
3761 // Update av stream length, if it ends up shorter than the track's media duration
3762 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
3763 msc->start_pad = st->skip_samples;
3765 // Free the old index and the old CTTS structures
3767 av_free(ctts_data_old);
3768 av_freep(&frame_duration_buffer);
3770 // Null terminate the index ranges array
3771 current_index_range++;
3772 current_index_range->start = 0;
3773 current_index_range->end = 0;
3774 msc->current_index = msc->index_ranges[0].start;
3777 static void mov_build_index(MOVContext *mov, AVStream *st)
3779 MOVStreamContext *sc = st->priv_data;
3780 int64_t current_offset;
3781 int64_t current_dts = 0;
3782 unsigned int stts_index = 0;
3783 unsigned int stsc_index = 0;
3784 unsigned int stss_index = 0;
3785 unsigned int stps_index = 0;
3787 uint64_t stream_size = 0;
3788 MOVStts *ctts_data_old = sc->ctts_data;
3789 unsigned int ctts_count_old = sc->ctts_count;
3791 if (sc->elst_count) {
3792 int i, edit_start_index = 0, multiple_edits = 0;
3793 int64_t empty_duration = 0; // empty duration of the first edit list entry
3794 int64_t start_time = 0; // start time of the media
3796 for (i = 0; i < sc->elst_count; i++) {
3797 const MOVElst *e = &sc->elst_data[i];
3798 if (i == 0 && e->time == -1) {
3799 /* if empty, the first entry is the start time of the stream
3800 * relative to the presentation itself */
3801 empty_duration = e->duration;
3802 edit_start_index = 1;
3803 } else if (i == edit_start_index && e->time >= 0) {
3804 start_time = e->time;
3810 if (multiple_edits && !mov->advanced_editlist)
3811 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
3812 "Use -advanced_editlist to correctly decode otherwise "
3813 "a/v desync might occur\n");
3815 /* adjust first dts according to edit list */
3816 if ((empty_duration || start_time) && mov->time_scale > 0) {
3818 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
3819 sc->time_offset = start_time - empty_duration;
3820 sc->min_corrected_pts = start_time;
3821 if (!mov->advanced_editlist)
3822 current_dts = -sc->time_offset;
3825 if (!multiple_edits && !mov->advanced_editlist &&
3826 st->codecpar->codec_id == AV_CODEC_ID_AAC && start_time > 0)
3827 sc->start_pad = start_time;
3830 /* only use old uncompressed audio chunk demuxing when stts specifies it */
3831 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3832 sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
3833 unsigned int current_sample = 0;
3834 unsigned int stts_sample = 0;
3835 unsigned int sample_size;
3836 unsigned int distance = 0;
3837 unsigned int rap_group_index = 0;
3838 unsigned int rap_group_sample = 0;
3839 int64_t last_dts = 0;
3840 int64_t dts_correction = 0;
3841 int rap_group_present = sc->rap_group_count && sc->rap_group;
3842 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
3844 current_dts -= sc->dts_shift;
3845 last_dts = current_dts;
3847 if (!sc->sample_count || st->nb_index_entries)
3849 if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
3851 if (av_reallocp_array(&st->index_entries,
3852 st->nb_index_entries + sc->sample_count,
3853 sizeof(*st->index_entries)) < 0) {
3854 st->nb_index_entries = 0;
3857 st->index_entries_allocated_size = (st->nb_index_entries + sc->sample_count) * sizeof(*st->index_entries);
3859 if (ctts_data_old) {
3860 // Expand ctts entries such that we have a 1-1 mapping with samples
3861 if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
3864 sc->ctts_allocated_size = 0;
3865 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size,
3866 sc->sample_count * sizeof(*sc->ctts_data));
3867 if (!sc->ctts_data) {
3868 av_free(ctts_data_old);
3872 memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
3874 for (i = 0; i < ctts_count_old &&
3875 sc->ctts_count < sc->sample_count; i++)
3876 for (j = 0; j < ctts_data_old[i].count &&
3877 sc->ctts_count < sc->sample_count; j++)
3878 add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
3879 &sc->ctts_allocated_size, 1,
3880 ctts_data_old[i].duration);
3881 av_free(ctts_data_old);
3884 for (i = 0; i < sc->chunk_count; i++) {
3885 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
3886 current_offset = sc->chunk_offsets[i];
3887 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3888 i + 1 == sc->stsc_data[stsc_index + 1].first)
3891 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
3892 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
3893 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
3894 sc->stsz_sample_size = sc->sample_size;
3896 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
3897 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
3898 sc->stsz_sample_size = sc->sample_size;
3901 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
3903 if (current_sample >= sc->sample_count) {
3904 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
3908 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
3910 if (stss_index + 1 < sc->keyframe_count)
3912 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
3914 if (stps_index + 1 < sc->stps_count)
3917 if (rap_group_present && rap_group_index < sc->rap_group_count) {
3918 if (sc->rap_group[rap_group_index].index > 0)
3920 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
3921 rap_group_sample = 0;
3925 if (sc->keyframe_absent
3927 && !rap_group_present
3928 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
3932 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
3933 if (sc->pseudo_stream_id == -1 ||
3934 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
3936 if (sample_size > 0x3FFFFFFF) {
3937 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
3940 e = &st->index_entries[st->nb_index_entries++];
3941 e->pos = current_offset;
3942 e->timestamp = current_dts;
3943 e->size = sample_size;
3944 e->min_distance = distance;
3945 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
3946 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
3947 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
3948 current_offset, current_dts, sample_size, distance, keyframe);
3949 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries < 100)
3950 ff_rfps_add_frame(mov->fc, st, current_dts);
3953 current_offset += sample_size;
3954 stream_size += sample_size;
3956 /* A negative sample duration is invalid based on the spec,
3957 * but some samples need it to correct the DTS. */
3958 if (sc->stts_data[stts_index].duration < 0) {
3959 av_log(mov->fc, AV_LOG_WARNING,
3960 "Invalid SampleDelta %d in STTS, at %d st:%d\n",
3961 sc->stts_data[stts_index].duration, stts_index,
3963 dts_correction += sc->stts_data[stts_index].duration - 1;
3964 sc->stts_data[stts_index].duration = 1;
3966 current_dts += sc->stts_data[stts_index].duration;
3967 if (!dts_correction || current_dts + dts_correction > last_dts) {
3968 current_dts += dts_correction;
3971 /* Avoid creating non-monotonous DTS */
3972 dts_correction += current_dts - last_dts - 1;
3973 current_dts = last_dts + 1;
3975 last_dts = current_dts;
3979 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
3985 if (st->duration > 0)
3986 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
3988 unsigned chunk_samples, total = 0;
3990 if (!sc->chunk_count)
3993 // compute total chunk count
3994 for (i = 0; i < sc->stsc_count; i++) {
3995 unsigned count, chunk_count;
3997 chunk_samples = sc->stsc_data[i].count;
3998 if (i != sc->stsc_count - 1 &&
3999 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
4000 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
4004 if (sc->samples_per_frame >= 160) { // gsm
4005 count = chunk_samples / sc->samples_per_frame;
4006 } else if (sc->samples_per_frame > 1) {
4007 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4008 count = (chunk_samples+samples-1) / samples;
4010 count = (chunk_samples+1023) / 1024;
4013 if (mov_stsc_index_valid(i, sc->stsc_count))
4014 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4016 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4017 total += chunk_count * count;
4020 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4021 if (total >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
4023 if (av_reallocp_array(&st->index_entries,
4024 st->nb_index_entries + total,
4025 sizeof(*st->index_entries)) < 0) {
4026 st->nb_index_entries = 0;
4029 st->index_entries_allocated_size = (st->nb_index_entries + total) * sizeof(*st->index_entries);
4032 for (i = 0; i < sc->chunk_count; i++) {
4033 current_offset = sc->chunk_offsets[i];
4034 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4035 i + 1 == sc->stsc_data[stsc_index + 1].first)
4037 chunk_samples = sc->stsc_data[stsc_index].count;
4039 while (chunk_samples > 0) {
4041 unsigned size, samples;
4043 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4044 avpriv_request_sample(mov->fc,
4045 "Zero bytes per frame, but %d samples per frame",
4046 sc->samples_per_frame);
4050 if (sc->samples_per_frame >= 160) { // gsm
4051 samples = sc->samples_per_frame;
4052 size = sc->bytes_per_frame;
4054 if (sc->samples_per_frame > 1) {
4055 samples = FFMIN((1024 / sc->samples_per_frame)*
4056 sc->samples_per_frame, chunk_samples);
4057 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
4059 samples = FFMIN(1024, chunk_samples);
4060 size = samples * sc->sample_size;
4064 if (st->nb_index_entries >= total) {
4065 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4068 if (size > 0x3FFFFFFF) {
4069 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4072 e = &st->index_entries[st->nb_index_entries++];
4073 e->pos = current_offset;
4074 e->timestamp = current_dts;
4076 e->min_distance = 0;
4077 e->flags = AVINDEX_KEYFRAME;
4078 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4079 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4082 current_offset += size;
4083 current_dts += samples;
4084 chunk_samples -= samples;
4089 if (!mov->ignore_editlist && mov->advanced_editlist) {
4090 // Fix index according to edit lists.
4091 mov_fix_index(mov, st);
4094 // Update start time of the stream.
4095 if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries > 0) {
4096 st->start_time = st->index_entries[0].timestamp + sc->dts_shift;
4097 if (sc->ctts_data) {
4098 st->start_time += sc->ctts_data[0].duration;
4102 mov_estimate_video_delay(mov, st);
4105 static int test_same_origin(const char *src, const char *ref) {
4115 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4116 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4118 if (strlen(src) == 0) {
4120 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4121 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4122 strlen(src_host) + 1 >= sizeof(src_host) ||
4123 strlen(ref_host) + 1 >= sizeof(ref_host)) {
4125 } else if (strcmp(src_proto, ref_proto) ||
4126 strcmp(src_auth, ref_auth) ||
4127 strcmp(src_host, ref_host) ||
4128 src_port != ref_port) {
4134 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4136 /* try relative path, we do not try the absolute because it can leak information about our
4137 system to an attacker */
4138 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4139 char filename[1025];
4140 const char *src_path;
4143 /* find a source dir */
4144 src_path = strrchr(src, '/');
4150 /* find a next level down to target */
4151 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4152 if (ref->path[l] == '/') {
4153 if (i == ref->nlvl_to - 1)
4159 /* compose filename if next level down to target was found */
4160 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4161 memcpy(filename, src, src_path - src);
4162 filename[src_path - src] = 0;
4164 for (i = 1; i < ref->nlvl_from; i++)
4165 av_strlcat(filename, "../", sizeof(filename));
4167 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4168 if (!c->use_absolute_path) {
4169 int same_origin = test_same_origin(src, filename);
4172 av_log(c->fc, AV_LOG_ERROR,
4173 "Reference with mismatching origin, %s not tried for security reasons, "
4174 "set demuxer option use_absolute_path to allow it anyway\n",
4176 return AVERROR(ENOENT);
4179 if(strstr(ref->path + l + 1, "..") ||
4180 strstr(ref->path + l + 1, ":") ||
4181 (ref->nlvl_from > 1 && same_origin < 0) ||
4182 (filename[0] == '/' && src_path == src))
4183 return AVERROR(ENOENT);
4186 if (strlen(filename) + 1 == sizeof(filename))
4187 return AVERROR(ENOENT);
4188 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4191 } else if (c->use_absolute_path) {
4192 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4193 "this is a possible security issue\n");
4194 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4197 av_log(c->fc, AV_LOG_ERROR,
4198 "Absolute path %s not tried for security reasons, "
4199 "set demuxer option use_absolute_path to allow absolute paths\n",
4203 return AVERROR(ENOENT);
4206 static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
4208 if (sc->time_scale <= 0) {
4209 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4210 sc->time_scale = c->time_scale;
4211 if (sc->time_scale <= 0)
4216 static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4219 MOVStreamContext *sc;
4222 st = avformat_new_stream(c->fc, NULL);
4223 if (!st) return AVERROR(ENOMEM);
4225 sc = av_mallocz(sizeof(MOVStreamContext));
4226 if (!sc) return AVERROR(ENOMEM);
4229 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
4230 sc->ffindex = st->index;
4231 c->trak_index = st->index;
4233 if ((ret = mov_read_default(c, pb, atom)) < 0)
4238 // Here stsc refers to a chunk not described in stco. This is technically invalid,
4239 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4240 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4242 av_freep(&sc->stsc_data);
4246 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4247 (!sc->sample_size && !sc->sample_count))) ||
4248 (!sc->chunk_count && sc->sample_count)) {
4249 av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4253 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4254 av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4256 return AVERROR_INVALIDDATA;
4259 fix_timescale(c, sc);
4261 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4263 mov_build_index(c, st);
4265 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4266 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4267 if (c->enable_drefs) {
4268 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4269 av_log(c->fc, AV_LOG_ERROR,
4270 "stream %d, error opening alias: path='%s', dir='%s', "
4271 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4272 st->index, dref->path, dref->dir, dref->filename,
4273 dref->volume, dref->nlvl_from, dref->nlvl_to);
4275 av_log(c->fc, AV_LOG_WARNING,
4276 "Skipped opening external track: "
4277 "stream %d, alias: path='%s', dir='%s', "
4278 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4279 "Set enable_drefs to allow this.\n",
4280 st->index, dref->path, dref->dir, dref->filename,
4281 dref->volume, dref->nlvl_from, dref->nlvl_to);
4285 sc->pb_is_copied = 1;
4288 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4289 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4290 sc->height && sc->width &&
4291 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4292 st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4293 ((double)st->codecpar->width * sc->height), INT_MAX);
4296 #if FF_API_R_FRAME_RATE
4297 if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4298 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
4299 sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4303 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4304 if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4305 TAG_IS_AVCI(st->codecpar->codec_tag)) {
4306 ret = ff_generate_avci_extradata(st);
4311 switch (st->codecpar->codec_id) {
4312 #if CONFIG_H261_DECODER
4313 case AV_CODEC_ID_H261:
4315 #if CONFIG_H263_DECODER
4316 case AV_CODEC_ID_H263:
4318 #if CONFIG_MPEG4_DECODER
4319 case AV_CODEC_ID_MPEG4:
4321 st->codecpar->width = 0; /* let decoder init width/height */
4322 st->codecpar->height= 0;
4326 // If the duration of the mp3 packets is not constant, then they could need a parser
4327 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4328 && sc->stts_count > 3
4329 && sc->stts_count*10 > st->nb_frames
4330 && sc->time_scale == st->codecpar->sample_rate) {
4331 st->need_parsing = AVSTREAM_PARSE_FULL;
4333 /* Do not need those anymore. */
4334 av_freep(&sc->chunk_offsets);
4335 av_freep(&sc->sample_sizes);
4336 av_freep(&sc->keyframes);
4337 av_freep(&sc->stts_data);
4338 av_freep(&sc->stps_data);
4339 av_freep(&sc->elst_data);
4340 av_freep(&sc->rap_group);
4345 static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4348 c->itunes_metadata = 1;
4349 ret = mov_read_default(c, pb, atom);
4350 c->itunes_metadata = 0;
4354 static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4363 count = avio_rb32(pb);
4364 if (count > UINT_MAX / sizeof(*c->meta_keys) - 1) {
4365 av_log(c->fc, AV_LOG_ERROR,
4366 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
4367 return AVERROR_INVALIDDATA;
4370 c->meta_keys_count = count + 1;
4371 c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
4373 return AVERROR(ENOMEM);
4375 for (i = 1; i <= count; ++i) {
4376 uint32_t key_size = avio_rb32(pb);
4377 uint32_t type = avio_rl32(pb);
4379 av_log(c->fc, AV_LOG_ERROR,
4380 "The key# %"PRIu32" in meta has invalid size:"
4381 "%"PRIu32"\n", i, key_size);
4382 return AVERROR_INVALIDDATA;
4385 if (type != MKTAG('m','d','t','a')) {
4386 avio_skip(pb, key_size);
4388 c->meta_keys[i] = av_mallocz(key_size + 1);
4389 if (!c->meta_keys[i])
4390 return AVERROR(ENOMEM);
4391 avio_read(pb, c->meta_keys[i], key_size);
4397 static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4399 int64_t end = avio_tell(pb) + atom.size;
4400 uint8_t *key = NULL, *val = NULL, *mean = NULL;
4404 MOVStreamContext *sc;
4406 if (c->fc->nb_streams < 1)
4408 st = c->fc->streams[c->fc->nb_streams-1];
4411 for (i = 0; i < 3; i++) {
4415 if (end - avio_tell(pb) <= 12)
4418 len = avio_rb32(pb);
4419 tag = avio_rl32(pb);
4420 avio_skip(pb, 4); // flags
4422 if (len < 12 || len - 12 > end - avio_tell(pb))
4426 if (tag == MKTAG('m', 'e', 'a', 'n'))
4428 else if (tag == MKTAG('n', 'a', 'm', 'e'))
4430 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
4440 *p = av_malloc(len + 1);
4442 ret = AVERROR(ENOMEM);
4445 ret = ffio_read_size(pb, *p, len);
4453 if (mean && key && val) {
4454 if (strcmp(key, "iTunSMPB") == 0) {
4455 int priming, remainder, samples;
4456 if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
4457 if(priming>0 && priming<16384)
4458 sc->start_pad = priming;
4461 if (strcmp(key, "cdec") != 0) {
4462 av_dict_set(&c->fc->metadata, key, val,
4463 AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
4467 av_log(c->fc, AV_LOG_VERBOSE,
4468 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
4471 avio_seek(pb, end, SEEK_SET);
4478 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4480 while (atom.size > 8) {
4484 tag = avio_rl32(pb);
4486 if (tag == MKTAG('h','d','l','r')) {
4487 avio_seek(pb, -8, SEEK_CUR);
4489 return mov_read_default(c, pb, atom);
4495 // return 1 when matrix is identity, 0 otherwise
4496 #define IS_MATRIX_IDENT(matrix) \
4497 ( (matrix)[0][0] == (1 << 16) && \
4498 (matrix)[1][1] == (1 << 16) && \
4499 (matrix)[2][2] == (1 << 30) && \
4500 !(matrix)[0][1] && !(matrix)[0][2] && \
4501 !(matrix)[1][0] && !(matrix)[1][2] && \
4502 !(matrix)[2][0] && !(matrix)[2][1])
4504 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4509 int display_matrix[3][3];
4510 int res_display_matrix[3][3] = { { 0 } };
4512 MOVStreamContext *sc;
4516 if (c->fc->nb_streams < 1)
4518 st = c->fc->streams[c->fc->nb_streams-1];
4521 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4522 // avoids corrupting AVStreams mapped to an earlier tkhd.
4524 return AVERROR_INVALIDDATA;
4526 version = avio_r8(pb);
4527 flags = avio_rb24(pb);
4528 st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
4534 avio_rb32(pb); /* creation time */
4535 avio_rb32(pb); /* modification time */
4537 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4538 avio_rb32(pb); /* reserved */
4540 /* highlevel (considering edits) duration in movie timebase */
4541 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4542 avio_rb32(pb); /* reserved */
4543 avio_rb32(pb); /* reserved */
4545 avio_rb16(pb); /* layer */
4546 avio_rb16(pb); /* alternate group */
4547 avio_rb16(pb); /* volume */
4548 avio_rb16(pb); /* reserved */
4550 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4551 // they're kept in fixed point format through all calculations
4552 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4553 // side data, but the scale factor is not needed to calculate aspect ratio
4554 for (i = 0; i < 3; i++) {
4555 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
4556 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
4557 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
4560 width = avio_rb32(pb); // 16.16 fixed point track width
4561 height = avio_rb32(pb); // 16.16 fixed point track height
4562 sc->width = width >> 16;
4563 sc->height = height >> 16;
4565 // apply the moov display matrix (after the tkhd one)
4566 for (i = 0; i < 3; i++) {
4567 const int sh[3] = { 16, 16, 30 };
4568 for (j = 0; j < 3; j++) {
4569 for (e = 0; e < 3; e++) {
4570 res_display_matrix[i][j] +=
4571 ((int64_t) display_matrix[i][e] *
4572 c->movie_display_matrix[e][j]) >> sh[e];
4577 // save the matrix when it is not the default identity
4578 if (!IS_MATRIX_IDENT(res_display_matrix)) {
4581 av_freep(&sc->display_matrix);
4582 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4583 if (!sc->display_matrix)
4584 return AVERROR(ENOMEM);
4586 for (i = 0; i < 3; i++)
4587 for (j = 0; j < 3; j++)
4588 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4590 #if FF_API_OLD_ROTATE_API
4591 rotate = av_display_rotation_get(sc->display_matrix);
4592 if (!isnan(rotate)) {
4593 char rotate_buf[64];
4595 if (rotate < 0) // for backward compatibility
4597 snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate);
4598 av_dict_set(&st->metadata, "rotate", rotate_buf, 0);
4603 // transform the display width/height according to the matrix
4604 // to keep the same scale, use [width height 1<<16]
4605 if (width && height && sc->display_matrix) {
4606 double disp_transform[2];
4608 for (i = 0; i < 2; i++)
4609 disp_transform[i] = hypot(sc->display_matrix[0 + i],
4610 sc->display_matrix[3 + i]);
4612 if (disp_transform[0] > 0 && disp_transform[1] > 0 &&
4613 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4614 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4615 st->sample_aspect_ratio = av_d2q(
4616 disp_transform[0] / disp_transform[1],
4622 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4624 MOVFragment *frag = &c->fragment;
4625 MOVTrackExt *trex = NULL;
4626 int flags, track_id, i;
4627 MOVFragmentStreamInfo * frag_stream_info;
4629 avio_r8(pb); /* version */
4630 flags = avio_rb24(pb);
4632 track_id = avio_rb32(pb);
4634 return AVERROR_INVALIDDATA;
4635 for (i = 0; i < c->trex_count; i++)
4636 if (c->trex_data[i].track_id == track_id) {
4637 trex = &c->trex_data[i];
4641 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4644 c->fragment.found_tfhd = 1;
4645 frag->track_id = track_id;
4646 set_frag_stream(&c->frag_index, track_id);
4648 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4649 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4650 frag->moof_offset : frag->implicit_offset;
4651 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4653 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4654 avio_rb32(pb) : trex->duration;
4655 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4656 avio_rb32(pb) : trex->size;
4657 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4658 avio_rb32(pb) : trex->flags;
4659 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4661 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4662 if (frag_stream_info)
4663 frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
4668 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4673 num = atom.size / 4;
4674 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4675 return AVERROR(ENOMEM);
4677 av_free(c->chapter_tracks);
4678 c->chapter_tracks = new_tracks;
4679 c->nb_chapter_tracks = num;
4681 for (i = 0; i < num && !pb->eof_reached; i++)
4682 c->chapter_tracks[i] = avio_rb32(pb);
4687 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4692 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4693 return AVERROR_INVALIDDATA;
4694 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4695 sizeof(*c->trex_data))) < 0) {
4700 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4702 trex = &c->trex_data[c->trex_count++];
4703 avio_r8(pb); /* version */
4704 avio_rb24(pb); /* flags */
4705 trex->track_id = avio_rb32(pb);
4706 trex->stsd_id = avio_rb32(pb);
4707 trex->duration = avio_rb32(pb);
4708 trex->size = avio_rb32(pb);
4709 trex->flags = avio_rb32(pb);
4713 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4715 MOVFragment *frag = &c->fragment;
4716 AVStream *st = NULL;
4717 MOVStreamContext *sc;
4719 MOVFragmentStreamInfo * frag_stream_info;
4720 int64_t base_media_decode_time;
4722 for (i = 0; i < c->fc->nb_streams; i++) {
4723 if (c->fc->streams[i]->id == frag->track_id) {
4724 st = c->fc->streams[i];
4729 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4733 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4735 version = avio_r8(pb);
4736 avio_rb24(pb); /* flags */
4738 base_media_decode_time = avio_rb64(pb);
4740 base_media_decode_time = avio_rb32(pb);
4743 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4744 if (frag_stream_info)
4745 frag_stream_info->tfdt_dts = base_media_decode_time;
4746 sc->track_end = base_media_decode_time;
4751 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4753 MOVFragment *frag = &c->fragment;
4754 AVStream *st = NULL;
4755 MOVStreamContext *sc;
4758 int64_t dts, pts = AV_NOPTS_VALUE;
4759 int data_offset = 0;
4760 unsigned entries, first_sample_flags = frag->flags;
4761 int flags, distance, i;
4762 int64_t prev_dts = AV_NOPTS_VALUE;
4763 int next_frag_index = -1, index_entry_pos;
4764 size_t requested_size;
4765 size_t old_ctts_allocated_size;
4766 AVIndexEntry *new_entries;
4767 MOVFragmentStreamInfo * frag_stream_info;
4769 if (!frag->found_tfhd) {
4770 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4771 return AVERROR_INVALIDDATA;
4774 for (i = 0; i < c->fc->nb_streams; i++) {
4775 if (c->fc->streams[i]->id == frag->track_id) {
4776 st = c->fc->streams[i];
4781 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4785 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4788 // Find the next frag_index index that has a valid index_entry for
4789 // the current track_id.
4791 // A valid index_entry means the trun for the fragment was read
4792 // and it's samples are in index_entries at the given position.
4793 // New index entries will be inserted before the index_entry found.
4794 index_entry_pos = st->nb_index_entries;
4795 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4796 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4797 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4798 next_frag_index = i;
4799 index_entry_pos = frag_stream_info->index_entry;
4803 av_assert0(index_entry_pos <= st->nb_index_entries);
4805 avio_r8(pb); /* version */
4806 flags = avio_rb24(pb);
4807 entries = avio_rb32(pb);
4808 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4810 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4811 return AVERROR_INVALIDDATA;
4812 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4813 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4815 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4816 if (frag_stream_info)
4818 if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
4819 dts = frag_stream_info->next_trun_dts - sc->time_offset;
4820 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4821 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4822 pts = frag_stream_info->first_tfra_pts;
4823 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4824 ", using it for pts\n", pts);
4825 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4826 c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
4827 dts = frag_stream_info->first_tfra_pts;
4828 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4829 ", using it for dts\n", pts);
4830 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4831 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4832 // pts = frag_stream_info->sidx_pts;
4833 dts = frag_stream_info->sidx_pts - sc->time_offset;
4834 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4835 ", using it for pts\n", pts);
4836 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4837 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4838 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4839 ", using it for dts\n", dts);
4841 dts = sc->track_end - sc->time_offset;
4842 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4843 ", using it for dts\n", dts);
4846 dts = sc->track_end - sc->time_offset;
4847 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4848 ", using it for dts\n", dts);
4850 offset = frag->base_data_offset + data_offset;
4852 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4854 // realloc space for new index entries
4855 if((uint64_t)st->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4856 entries = UINT_MAX / sizeof(AVIndexEntry) - st->nb_index_entries;
4857 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4862 requested_size = (st->nb_index_entries + entries) * sizeof(AVIndexEntry);
4863 new_entries = av_fast_realloc(st->index_entries,
4864 &st->index_entries_allocated_size,
4867 return AVERROR(ENOMEM);
4868 st->index_entries= new_entries;
4870 requested_size = (st->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4871 old_ctts_allocated_size = sc->ctts_allocated_size;
4872 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4875 return AVERROR(ENOMEM);
4876 sc->ctts_data = ctts_data;
4878 // In case there were samples without ctts entries, ensure they get
4879 // zero valued entries. This ensures clips which mix boxes with and
4880 // without ctts entries don't pickup uninitialized data.
4881 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4882 sc->ctts_allocated_size - old_ctts_allocated_size);
4884 if (index_entry_pos < st->nb_index_entries) {
4885 // Make hole in index_entries and ctts_data for new samples
4886 memmove(st->index_entries + index_entry_pos + entries,
4887 st->index_entries + index_entry_pos,
4888 sizeof(*st->index_entries) *
4889 (st->nb_index_entries - index_entry_pos));
4890 memmove(sc->ctts_data + index_entry_pos + entries,
4891 sc->ctts_data + index_entry_pos,
4892 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4893 if (index_entry_pos < sc->current_sample) {
4894 sc->current_sample += entries;
4898 st->nb_index_entries += entries;
4899 sc->ctts_count = st->nb_index_entries;
4901 // Record the index_entry position in frag_index of this fragment
4902 if (frag_stream_info)
4903 frag_stream_info->index_entry = index_entry_pos;
4905 if (index_entry_pos > 0)
4906 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4908 for (i = 0; i < entries && !pb->eof_reached; i++) {
4909 unsigned sample_size = frag->size;
4910 int sample_flags = i ? frag->flags : first_sample_flags;
4911 unsigned sample_duration = frag->duration;
4912 unsigned ctts_duration = 0;
4914 int index_entry_flags = 0;
4916 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4917 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4918 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4919 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4921 mov_update_dts_shift(sc, ctts_duration, c->fc);
4922 if (pts != AV_NOPTS_VALUE) {
4923 dts = pts - sc->dts_shift;
4924 if (flags & MOV_TRUN_SAMPLE_CTS) {
4925 dts -= ctts_duration;
4927 dts -= sc->time_offset;
4929 av_log(c->fc, AV_LOG_DEBUG,
4930 "pts %"PRId64" calculated dts %"PRId64
4931 " sc->dts_shift %d ctts.duration %d"
4932 " sc->time_offset %"PRId64
4933 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4935 sc->dts_shift, ctts_duration,
4936 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4937 pts = AV_NOPTS_VALUE;
4940 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4944 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4945 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4948 index_entry_flags |= AVINDEX_KEYFRAME;
4950 // Fragments can overlap in time. Discard overlapping frames after
4952 if (prev_dts >= dts)
4953 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4955 st->index_entries[index_entry_pos].pos = offset;
4956 st->index_entries[index_entry_pos].timestamp = dts;
4957 st->index_entries[index_entry_pos].size= sample_size;
4958 st->index_entries[index_entry_pos].min_distance= distance;
4959 st->index_entries[index_entry_pos].flags = index_entry_flags;
4961 sc->ctts_data[index_entry_pos].count = 1;
4962 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4965 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4966 "size %u, distance %d, keyframe %d\n", st->index,
4967 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4969 dts += sample_duration;
4970 offset += sample_size;
4971 sc->data_size += sample_size;
4973 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4974 1 <= INT_MAX - sc->nb_frames_for_fps
4976 sc->duration_for_fps += sample_duration;
4977 sc->nb_frames_for_fps ++;
4980 if (frag_stream_info)
4981 frag_stream_info->next_trun_dts = dts + sc->time_offset;
4983 // EOF found before reading all entries. Fix the hole this would
4984 // leave in index_entries and ctts_data
4985 int gap = entries - i;
4986 memmove(st->index_entries + index_entry_pos,
4987 st->index_entries + index_entry_pos + gap,
4988 sizeof(*st->index_entries) *
4989 (st->nb_index_entries - (index_entry_pos + gap)));
4990 memmove(sc->ctts_data + index_entry_pos,
4991 sc->ctts_data + index_entry_pos + gap,
4992 sizeof(*sc->ctts_data) *
4993 (sc->ctts_count - (index_entry_pos + gap)));
4995 st->nb_index_entries -= gap;
4996 sc->ctts_count -= gap;
4997 if (index_entry_pos < sc->current_sample) {
4998 sc->current_sample -= gap;
5003 // The end of this new fragment may overlap in time with the start
5004 // of the next fragment in index_entries. Mark the samples in the next
5005 // fragment that overlap with AVINDEX_DISCARD_FRAME
5006 prev_dts = AV_NOPTS_VALUE;
5007 if (index_entry_pos > 0)
5008 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
5009 for (i = index_entry_pos; i < st->nb_index_entries; i++) {
5010 if (prev_dts < st->index_entries[i].timestamp)
5012 st->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
5015 // If a hole was created to insert the new index_entries into,
5016 // the index_entry recorded for all subsequent moof must
5017 // be incremented by the number of entries inserted.
5018 fix_frag_index_entries(&c->frag_index, next_frag_index,
5019 frag->track_id, entries);
5021 if (pb->eof_reached) {
5022 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
5026 frag->implicit_offset = offset;
5028 sc->track_end = dts + sc->time_offset;
5029 if (st->duration < sc->track_end)
5030 st->duration = sc->track_end;
5035 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5037 int64_t offset = avio_tell(pb) + atom.size, pts, timestamp;
5039 unsigned i, j, track_id, item_count;
5040 AVStream *st = NULL;
5041 AVStream *ref_st = NULL;
5042 MOVStreamContext *sc, *ref_sc = NULL;
5043 AVRational timescale;
5045 version = avio_r8(pb);
5047 avpriv_request_sample(c->fc, "sidx version %u", version);
5051 avio_rb24(pb); // flags
5053 track_id = avio_rb32(pb); // Reference ID
5054 for (i = 0; i < c->fc->nb_streams; i++) {
5055 if (c->fc->streams[i]->id == track_id) {
5056 st = c->fc->streams[i];
5061 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5067 timescale = av_make_q(1, avio_rb32(pb));
5069 if (timescale.den <= 0) {
5070 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5071 return AVERROR_INVALIDDATA;
5075 pts = avio_rb32(pb);
5076 offset += avio_rb32(pb);
5078 pts = avio_rb64(pb);
5079 offset += avio_rb64(pb);
5082 avio_rb16(pb); // reserved
5084 item_count = avio_rb16(pb);
5086 for (i = 0; i < item_count; i++) {
5088 MOVFragmentStreamInfo * frag_stream_info;
5089 uint32_t size = avio_rb32(pb);
5090 uint32_t duration = avio_rb32(pb);
5091 if (size & 0x80000000) {
5092 avpriv_request_sample(c->fc, "sidx reference_type 1");
5093 return AVERROR_PATCHWELCOME;
5095 avio_rb32(pb); // sap_flags
5096 timestamp = av_rescale_q(pts, timescale, st->time_base);
5098 index = update_frag_index(c, offset);
5099 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5100 if (frag_stream_info)
5101 frag_stream_info->sidx_pts = timestamp;
5107 st->duration = sc->track_end = pts;
5111 if (offset == avio_size(pb)) {
5112 // Find first entry in fragment index that came from an sidx.
5113 // This will pretty much always be the first entry.
5114 for (i = 0; i < c->frag_index.nb_items; i++) {
5115 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5116 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5117 MOVFragmentStreamInfo * si;
5118 si = &item->stream_info[j];
5119 if (si->sidx_pts != AV_NOPTS_VALUE) {
5120 ref_st = c->fc->streams[j];
5121 ref_sc = ref_st->priv_data;
5126 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5127 st = c->fc->streams[i];
5129 if (!sc->has_sidx) {
5130 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5134 c->frag_index.complete = 1;
5140 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5141 /* like the files created with Adobe Premiere 5.0, for samples see */
5142 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5143 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5148 return 0; /* continue */
5149 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5150 avio_skip(pb, atom.size - 4);
5153 atom.type = avio_rl32(pb);
5155 if (atom.type != MKTAG('m','d','a','t')) {
5156 avio_skip(pb, atom.size);
5159 err = mov_read_mdat(c, pb, atom);
5163 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5168 uint8_t *moov_data; /* uncompressed data */
5169 long cmov_len, moov_len;
5172 avio_rb32(pb); /* dcom atom */
5173 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5174 return AVERROR_INVALIDDATA;
5175 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5176 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5177 return AVERROR_INVALIDDATA;
5179 avio_rb32(pb); /* cmvd atom */
5180 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5181 return AVERROR_INVALIDDATA;
5182 moov_len = avio_rb32(pb); /* uncompressed size */
5183 cmov_len = atom.size - 6 * 4;
5185 cmov_data = av_malloc(cmov_len);
5187 return AVERROR(ENOMEM);
5188 moov_data = av_malloc(moov_len);
5191 return AVERROR(ENOMEM);
5193 ret = ffio_read_size(pb, cmov_data, cmov_len);
5195 goto free_and_return;
5197 ret = AVERROR_INVALIDDATA;
5198 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5199 goto free_and_return;
5200 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5201 goto free_and_return;
5202 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5203 atom.type = MKTAG('m','o','o','v');
5204 atom.size = moov_len;
5205 ret = mov_read_default(c, &ctx, atom);
5211 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5212 return AVERROR(ENOSYS);
5216 /* edit list atom */
5217 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5219 MOVStreamContext *sc;
5220 int i, edit_count, version;
5221 int64_t elst_entry_size;
5223 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5225 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5227 version = avio_r8(pb); /* version */
5228 avio_rb24(pb); /* flags */
5229 edit_count = avio_rb32(pb); /* entries */
5232 elst_entry_size = version == 1 ? 20 : 12;
5233 if (atom.size != edit_count * elst_entry_size) {
5234 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5235 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5236 edit_count, atom.size + 8);
5237 return AVERROR_INVALIDDATA;
5239 edit_count = atom.size / elst_entry_size;
5240 if (edit_count * elst_entry_size != atom.size) {
5241 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.", atom.size, edit_count);
5249 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5250 av_free(sc->elst_data);
5252 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5254 return AVERROR(ENOMEM);
5256 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5257 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5258 MOVElst *e = &sc->elst_data[i];
5261 e->duration = avio_rb64(pb);
5262 e->time = avio_rb64(pb);
5265 e->duration = avio_rb32(pb); /* segment duration */
5266 e->time = (int32_t)avio_rb32(pb); /* media time */
5269 e->rate = avio_rb32(pb) / 65536.0;
5271 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5272 e->duration, e->time, e->rate);
5274 if (e->time < 0 && e->time != -1 &&
5275 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5276 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5277 c->fc->nb_streams-1, i, e->time);
5278 return AVERROR_INVALIDDATA;
5286 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5288 MOVStreamContext *sc;
5290 if (c->fc->nb_streams < 1)
5291 return AVERROR_INVALIDDATA;
5292 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5293 sc->timecode_track = avio_rb32(pb);
5297 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5302 if (c->fc->nb_streams < 1)
5304 st = c->fc->streams[c->fc->nb_streams - 1];
5306 if (atom.size < 4) {
5307 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5308 return AVERROR_INVALIDDATA;
5311 /* For now, propagate only the OBUs, if any. Once libavcodec is
5312 updated to handle isobmff style extradata this can be removed. */
5318 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5325 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5328 int version, color_range, color_primaries, color_trc, color_space;
5330 if (c->fc->nb_streams < 1)
5332 st = c->fc->streams[c->fc->nb_streams - 1];
5334 if (atom.size < 5) {
5335 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5336 return AVERROR_INVALIDDATA;
5339 version = avio_r8(pb);
5341 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5344 avio_skip(pb, 3); /* flags */
5346 avio_skip(pb, 2); /* profile + level */
5347 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5348 color_primaries = avio_r8(pb);
5349 color_trc = avio_r8(pb);
5350 color_space = avio_r8(pb);
5351 if (avio_rb16(pb)) /* codecIntializationDataSize */
5352 return AVERROR_INVALIDDATA;
5354 if (!av_color_primaries_name(color_primaries))
5355 color_primaries = AVCOL_PRI_UNSPECIFIED;
5356 if (!av_color_transfer_name(color_trc))
5357 color_trc = AVCOL_TRC_UNSPECIFIED;
5358 if (!av_color_space_name(color_space))
5359 color_space = AVCOL_SPC_UNSPECIFIED;
5361 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5362 st->codecpar->color_primaries = color_primaries;
5363 st->codecpar->color_trc = color_trc;
5364 st->codecpar->color_space = color_space;
5369 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5371 MOVStreamContext *sc;
5374 if (c->fc->nb_streams < 1)
5375 return AVERROR_INVALIDDATA;
5377 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5379 if (atom.size < 5) {
5380 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5381 return AVERROR_INVALIDDATA;
5384 version = avio_r8(pb);
5386 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5389 avio_skip(pb, 3); /* flags */
5391 sc->mastering = av_mastering_display_metadata_alloc();
5393 return AVERROR(ENOMEM);
5395 for (i = 0; i < 3; i++) {
5396 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5397 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5399 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5400 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5402 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5403 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5405 sc->mastering->has_primaries = 1;
5406 sc->mastering->has_luminance = 1;
5411 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5413 MOVStreamContext *sc;
5414 const int mapping[3] = {1, 2, 0};
5415 const int chroma_den = 50000;
5416 const int luma_den = 10000;
5419 if (c->fc->nb_streams < 1)
5420 return AVERROR_INVALIDDATA;
5422 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5424 if (atom.size < 24) {
5425 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5426 return AVERROR_INVALIDDATA;
5429 sc->mastering = av_mastering_display_metadata_alloc();
5431 return AVERROR(ENOMEM);
5433 for (i = 0; i < 3; i++) {
5434 const int j = mapping[i];
5435 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5436 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5438 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5439 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5441 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5442 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5444 sc->mastering->has_luminance = 1;
5445 sc->mastering->has_primaries = 1;
5450 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5452 MOVStreamContext *sc;
5455 if (c->fc->nb_streams < 1)
5456 return AVERROR_INVALIDDATA;
5458 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5460 if (atom.size < 5) {
5461 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5462 return AVERROR_INVALIDDATA;
5465 version = avio_r8(pb);
5467 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5470 avio_skip(pb, 3); /* flags */
5472 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5474 return AVERROR(ENOMEM);
5476 sc->coll->MaxCLL = avio_rb16(pb);
5477 sc->coll->MaxFALL = avio_rb16(pb);
5482 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5484 MOVStreamContext *sc;
5486 if (c->fc->nb_streams < 1)
5487 return AVERROR_INVALIDDATA;
5489 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5491 if (atom.size < 4) {
5492 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5493 return AVERROR_INVALIDDATA;
5496 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5498 return AVERROR(ENOMEM);
5500 sc->coll->MaxCLL = avio_rb16(pb);
5501 sc->coll->MaxFALL = avio_rb16(pb);
5506 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5509 MOVStreamContext *sc;
5510 enum AVStereo3DType type;
5513 if (c->fc->nb_streams < 1)
5516 st = c->fc->streams[c->fc->nb_streams - 1];
5519 if (atom.size < 5) {
5520 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5521 return AVERROR_INVALIDDATA;
5523 avio_skip(pb, 4); /* version + flags */
5528 type = AV_STEREO3D_2D;
5531 type = AV_STEREO3D_TOPBOTTOM;
5534 type = AV_STEREO3D_SIDEBYSIDE;
5537 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5541 sc->stereo3d = av_stereo3d_alloc();
5543 return AVERROR(ENOMEM);
5545 sc->stereo3d->type = type;
5549 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5552 MOVStreamContext *sc;
5553 int size, version, layout;
5554 int32_t yaw, pitch, roll;
5555 uint32_t l = 0, t = 0, r = 0, b = 0;
5556 uint32_t tag, padding = 0;
5557 enum AVSphericalProjection projection;
5559 if (c->fc->nb_streams < 1)
5562 st = c->fc->streams[c->fc->nb_streams - 1];
5565 if (atom.size < 8) {
5566 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5567 return AVERROR_INVALIDDATA;
5570 size = avio_rb32(pb);
5571 if (size <= 12 || size > atom.size)
5572 return AVERROR_INVALIDDATA;
5574 tag = avio_rl32(pb);
5575 if (tag != MKTAG('s','v','h','d')) {
5576 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5579 version = avio_r8(pb);
5581 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5585 avio_skip(pb, 3); /* flags */
5586 avio_skip(pb, size - 12); /* metadata_source */
5588 size = avio_rb32(pb);
5589 if (size > atom.size)
5590 return AVERROR_INVALIDDATA;
5592 tag = avio_rl32(pb);
5593 if (tag != MKTAG('p','r','o','j')) {
5594 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5598 size = avio_rb32(pb);
5599 if (size > atom.size)
5600 return AVERROR_INVALIDDATA;
5602 tag = avio_rl32(pb);
5603 if (tag != MKTAG('p','r','h','d')) {
5604 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5607 version = avio_r8(pb);
5609 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5613 avio_skip(pb, 3); /* flags */
5615 /* 16.16 fixed point */
5616 yaw = avio_rb32(pb);
5617 pitch = avio_rb32(pb);
5618 roll = avio_rb32(pb);
5620 size = avio_rb32(pb);
5621 if (size > atom.size)
5622 return AVERROR_INVALIDDATA;
5624 tag = avio_rl32(pb);
5625 version = avio_r8(pb);
5627 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5631 avio_skip(pb, 3); /* flags */
5633 case MKTAG('c','b','m','p'):
5634 layout = avio_rb32(pb);
5636 av_log(c->fc, AV_LOG_WARNING,
5637 "Unsupported cubemap layout %d\n", layout);
5640 projection = AV_SPHERICAL_CUBEMAP;
5641 padding = avio_rb32(pb);
5643 case MKTAG('e','q','u','i'):
5649 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5650 av_log(c->fc, AV_LOG_ERROR,
5651 "Invalid bounding rectangle coordinates "
5652 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5653 return AVERROR_INVALIDDATA;
5656 if (l || t || r || b)
5657 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5659 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5662 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5666 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5668 return AVERROR(ENOMEM);
5670 sc->spherical->projection = projection;
5672 sc->spherical->yaw = yaw;
5673 sc->spherical->pitch = pitch;
5674 sc->spherical->roll = roll;
5676 sc->spherical->padding = padding;
5678 sc->spherical->bound_left = l;
5679 sc->spherical->bound_top = t;
5680 sc->spherical->bound_right = r;
5681 sc->spherical->bound_bottom = b;
5686 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5689 uint8_t *buffer = av_malloc(len + 1);
5693 return AVERROR(ENOMEM);
5696 ret = ffio_read_size(pb, buffer, len);
5700 /* Check for mandatory keys and values, try to support XML as best-effort */
5701 if (!sc->spherical &&
5702 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5703 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5704 av_stristr(val, "true") &&
5705 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5706 av_stristr(val, "true") &&
5707 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5708 av_stristr(val, "equirectangular")) {
5709 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5713 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5715 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5716 enum AVStereo3DType mode;
5718 if (av_stristr(buffer, "left-right"))
5719 mode = AV_STEREO3D_SIDEBYSIDE;
5720 else if (av_stristr(buffer, "top-bottom"))
5721 mode = AV_STEREO3D_TOPBOTTOM;
5723 mode = AV_STEREO3D_2D;
5725 sc->stereo3d = av_stereo3d_alloc();
5729 sc->stereo3d->type = mode;
5733 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5735 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5736 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5738 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5739 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5741 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5749 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5752 MOVStreamContext *sc;
5755 static const uint8_t uuid_isml_manifest[] = {
5756 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5757 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5759 static const uint8_t uuid_xmp[] = {
5760 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5761 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5763 static const uint8_t uuid_spherical[] = {
5764 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5765 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5768 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5769 return AVERROR_INVALIDDATA;
5771 if (c->fc->nb_streams < 1)
5773 st = c->fc->streams[c->fc->nb_streams - 1];
5776 ret = avio_read(pb, uuid, sizeof(uuid));
5779 } else if (ret != sizeof(uuid)) {
5780 return AVERROR_INVALIDDATA;
5782 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5783 uint8_t *buffer, *ptr;
5785 size_t len = atom.size - sizeof(uuid);
5788 return AVERROR_INVALIDDATA;
5790 ret = avio_skip(pb, 4); // zeroes
5793 buffer = av_mallocz(len + 1);
5795 return AVERROR(ENOMEM);
5797 ret = avio_read(pb, buffer, len);
5801 } else if (ret != len) {
5803 return AVERROR_INVALIDDATA;
5807 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5808 ptr += sizeof("systemBitrate=\"") - 1;
5809 c->bitrates_count++;
5810 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5812 c->bitrates_count = 0;
5814 return AVERROR(ENOMEM);
5817 ret = strtol(ptr, &endptr, 10);
5818 if (ret < 0 || errno || *endptr != '"') {
5819 c->bitrates[c->bitrates_count - 1] = 0;
5821 c->bitrates[c->bitrates_count - 1] = ret;
5826 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5828 size_t len = atom.size - sizeof(uuid);
5829 if (c->export_xmp) {
5830 buffer = av_mallocz(len + 1);
5832 return AVERROR(ENOMEM);
5834 ret = avio_read(pb, buffer, len);
5838 } else if (ret != len) {
5840 return AVERROR_INVALIDDATA;
5843 av_dict_set(&c->fc->metadata, "xmp",
5844 buffer, AV_DICT_DONT_STRDUP_VAL);
5846 // skip all uuid atom, which makes it fast for long uuid-xmp file
5847 ret = avio_skip(pb, len);
5851 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5852 size_t len = atom.size - sizeof(uuid);
5853 ret = mov_parse_uuid_spherical(sc, pb, len);
5857 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5863 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5866 uint8_t content[16];
5871 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5877 && !memcmp(content, "Anevia\x1A\x1A", 8)
5878 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5879 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5885 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5887 uint32_t format = avio_rl32(pb);
5888 MOVStreamContext *sc;
5892 if (c->fc->nb_streams < 1)
5894 st = c->fc->streams[c->fc->nb_streams - 1];
5899 case MKTAG('e','n','c','v'): // encrypted video
5900 case MKTAG('e','n','c','a'): // encrypted audio
5901 id = mov_codec_id(st, format);
5902 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5903 st->codecpar->codec_id != id) {
5904 av_log(c->fc, AV_LOG_WARNING,
5905 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5906 (char*)&format, st->codecpar->codec_id);
5910 st->codecpar->codec_id = id;
5911 sc->format = format;
5915 if (format != sc->format) {
5916 av_log(c->fc, AV_LOG_WARNING,
5917 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5918 (char*)&format, (char*)&sc->format);
5927 * Gets the current encryption info and associated current stream context. If
5928 * we are parsing a track fragment, this will return the specific encryption
5929 * info for this fragment; otherwise this will return the global encryption
5930 * info for the current stream.
5932 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5934 MOVFragmentStreamInfo *frag_stream_info;
5938 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5939 if (frag_stream_info) {
5940 for (i = 0; i < c->fc->nb_streams; i++) {
5941 if (c->fc->streams[i]->id == frag_stream_info->id) {
5942 st = c->fc->streams[i];
5946 if (i == c->fc->nb_streams)
5948 *sc = st->priv_data;
5950 if (!frag_stream_info->encryption_index) {
5951 // If this stream isn't encrypted, don't create the index.
5952 if (!(*sc)->cenc.default_encrypted_sample)
5954 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5955 if (!frag_stream_info->encryption_index)
5956 return AVERROR(ENOMEM);
5958 *encryption_index = frag_stream_info->encryption_index;
5961 // No current track fragment, using stream level encryption info.
5963 if (c->fc->nb_streams < 1)
5965 st = c->fc->streams[c->fc->nb_streams - 1];
5966 *sc = st->priv_data;
5968 if (!(*sc)->cenc.encryption_index) {
5969 // If this stream isn't encrypted, don't create the index.
5970 if (!(*sc)->cenc.default_encrypted_sample)
5972 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5973 if (!(*sc)->cenc.encryption_index)
5974 return AVERROR(ENOMEM);
5977 *encryption_index = (*sc)->cenc.encryption_index;
5982 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
5985 unsigned int subsample_count;
5986 AVSubsampleEncryptionInfo *subsamples;
5988 if (!sc->cenc.default_encrypted_sample) {
5989 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
5990 return AVERROR_INVALIDDATA;
5993 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
5995 return AVERROR(ENOMEM);
5997 if (sc->cenc.per_sample_iv_size != 0) {
5998 if (avio_read(pb, (*sample)->iv, sc->cenc.per_sample_iv_size) != sc->cenc.per_sample_iv_size) {
5999 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
6000 av_encryption_info_free(*sample);
6002 return AVERROR_INVALIDDATA;
6006 if (use_subsamples) {
6007 subsample_count = avio_rb16(pb);
6008 av_free((*sample)->subsamples);
6009 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
6010 if (!(*sample)->subsamples) {
6011 av_encryption_info_free(*sample);
6013 return AVERROR(ENOMEM);
6016 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
6017 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
6018 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
6021 if (pb->eof_reached) {
6022 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
6023 av_encryption_info_free(*sample);
6025 return AVERROR_INVALIDDATA;
6027 (*sample)->subsample_count = subsample_count;
6033 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6035 AVEncryptionInfo **encrypted_samples;
6036 MOVEncryptionIndex *encryption_index;
6037 MOVStreamContext *sc;
6038 int use_subsamples, ret;
6039 unsigned int sample_count, i, alloc_size = 0;
6041 ret = get_current_encryption_info(c, &encryption_index, &sc);
6045 if (encryption_index->nb_encrypted_samples) {
6046 // This can happen if we have both saio/saiz and senc atoms.
6047 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6051 avio_r8(pb); /* version */
6052 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6054 sample_count = avio_rb32(pb);
6055 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6056 return AVERROR(ENOMEM);
6058 for (i = 0; i < sample_count; i++) {
6059 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6060 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6061 min_samples * sizeof(*encrypted_samples));
6062 if (encrypted_samples) {
6063 encryption_index->encrypted_samples = encrypted_samples;
6065 ret = mov_read_sample_encryption_info(
6066 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6068 ret = AVERROR(ENOMEM);
6070 if (pb->eof_reached) {
6071 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6072 ret = AVERROR_INVALIDDATA;
6077 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6078 av_freep(&encryption_index->encrypted_samples);
6082 encryption_index->nb_encrypted_samples = sample_count;
6087 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6089 AVEncryptionInfo **sample, **encrypted_samples;
6091 size_t sample_count, sample_info_size, i;
6093 unsigned int alloc_size = 0;
6095 if (encryption_index->nb_encrypted_samples)
6097 sample_count = encryption_index->auxiliary_info_sample_count;
6098 if (encryption_index->auxiliary_offsets_count != 1) {
6099 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6100 return AVERROR_PATCHWELCOME;
6102 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6103 return AVERROR(ENOMEM);
6105 prev_pos = avio_tell(pb);
6106 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6107 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6108 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6112 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6113 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6114 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6115 min_samples * sizeof(*encrypted_samples));
6116 if (!encrypted_samples) {
6117 ret = AVERROR(ENOMEM);
6120 encryption_index->encrypted_samples = encrypted_samples;
6122 sample = &encryption_index->encrypted_samples[i];
6123 sample_info_size = encryption_index->auxiliary_info_default_size
6124 ? encryption_index->auxiliary_info_default_size
6125 : encryption_index->auxiliary_info_sizes[i];
6127 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6131 if (pb->eof_reached) {
6132 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6133 ret = AVERROR_INVALIDDATA;
6135 encryption_index->nb_encrypted_samples = sample_count;
6139 avio_seek(pb, prev_pos, SEEK_SET);
6141 for (; i > 0; i--) {
6142 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6144 av_freep(&encryption_index->encrypted_samples);
6150 * Tries to read the given number of bytes from the stream and puts it in a
6151 * newly allocated buffer. This reads in small chunks to avoid allocating large
6152 * memory if the file contains an invalid/malicious size value.
6154 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6156 const unsigned int block_size = 1024 * 1024;
6157 uint8_t *buffer = NULL;
6158 unsigned int alloc_size = 0, offset = 0;
6159 while (offset < size) {
6160 unsigned int new_size =
6161 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6162 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6163 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6166 return AVERROR(ENOMEM);
6168 buffer = new_buffer;
6170 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6172 return AVERROR_INVALIDDATA;
6181 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6183 MOVEncryptionIndex *encryption_index;
6184 MOVStreamContext *sc;
6186 unsigned int sample_count, aux_info_type, aux_info_param;
6188 ret = get_current_encryption_info(c, &encryption_index, &sc);
6192 if (encryption_index->nb_encrypted_samples) {
6193 // This can happen if we have both saio/saiz and senc atoms.
6194 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6198 if (encryption_index->auxiliary_info_sample_count) {
6199 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6200 return AVERROR_INVALIDDATA;
6203 avio_r8(pb); /* version */
6204 if (avio_rb24(pb) & 0x01) { /* flags */
6205 aux_info_type = avio_rb32(pb);
6206 aux_info_param = avio_rb32(pb);
6207 if (sc->cenc.default_encrypted_sample) {
6208 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6209 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6212 if (aux_info_param != 0) {
6213 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6217 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6218 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6219 aux_info_type == MKBETAG('c','e','n','s') ||
6220 aux_info_type == MKBETAG('c','b','c','1') ||
6221 aux_info_type == MKBETAG('c','b','c','s')) &&
6222 aux_info_param == 0) {
6223 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6224 return AVERROR_INVALIDDATA;
6229 } else if (!sc->cenc.default_encrypted_sample) {
6230 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6234 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6235 sample_count = avio_rb32(pb);
6236 encryption_index->auxiliary_info_sample_count = sample_count;
6238 if (encryption_index->auxiliary_info_default_size == 0) {
6239 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6241 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6246 if (encryption_index->auxiliary_offsets_count) {
6247 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6253 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6255 uint64_t *auxiliary_offsets;
6256 MOVEncryptionIndex *encryption_index;
6257 MOVStreamContext *sc;
6259 unsigned int version, entry_count, aux_info_type, aux_info_param;
6260 unsigned int alloc_size = 0;
6262 ret = get_current_encryption_info(c, &encryption_index, &sc);
6266 if (encryption_index->nb_encrypted_samples) {
6267 // This can happen if we have both saio/saiz and senc atoms.
6268 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6272 if (encryption_index->auxiliary_offsets_count) {
6273 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6274 return AVERROR_INVALIDDATA;
6277 version = avio_r8(pb); /* version */
6278 if (avio_rb24(pb) & 0x01) { /* flags */
6279 aux_info_type = avio_rb32(pb);
6280 aux_info_param = avio_rb32(pb);
6281 if (sc->cenc.default_encrypted_sample) {
6282 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6283 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6286 if (aux_info_param != 0) {
6287 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6291 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6292 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6293 aux_info_type == MKBETAG('c','e','n','s') ||
6294 aux_info_type == MKBETAG('c','b','c','1') ||
6295 aux_info_type == MKBETAG('c','b','c','s')) &&
6296 aux_info_param == 0) {
6297 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6298 return AVERROR_INVALIDDATA;
6303 } else if (!sc->cenc.default_encrypted_sample) {
6304 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6308 entry_count = avio_rb32(pb);
6309 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6310 return AVERROR(ENOMEM);
6312 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6313 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6314 auxiliary_offsets = av_fast_realloc(
6315 encryption_index->auxiliary_offsets, &alloc_size,
6316 min_offsets * sizeof(*auxiliary_offsets));
6317 if (!auxiliary_offsets) {
6318 av_freep(&encryption_index->auxiliary_offsets);
6319 return AVERROR(ENOMEM);
6321 encryption_index->auxiliary_offsets = auxiliary_offsets;
6324 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6326 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6328 if (c->frag_index.current >= 0) {
6329 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6333 if (pb->eof_reached) {
6334 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6335 av_freep(&encryption_index->auxiliary_offsets);
6336 return AVERROR_INVALIDDATA;
6339 encryption_index->auxiliary_offsets_count = entry_count;
6341 if (encryption_index->auxiliary_info_sample_count) {
6342 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6348 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6350 AVEncryptionInitInfo *info, *old_init_info;
6353 uint8_t *side_data, *extra_data, *old_side_data;
6354 size_t side_data_size;
6355 int ret = 0, old_side_data_size;
6356 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6358 if (c->fc->nb_streams < 1)
6360 st = c->fc->streams[c->fc->nb_streams-1];
6362 version = avio_r8(pb); /* version */
6363 avio_rb24(pb); /* flags */
6365 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6366 /* key_id_size */ 16, /* data_size */ 0);
6368 return AVERROR(ENOMEM);
6370 if (avio_read(pb, info->system_id, 16) != 16) {
6371 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6372 ret = AVERROR_INVALIDDATA;
6377 kid_count = avio_rb32(pb);
6378 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
6379 ret = AVERROR(ENOMEM);
6383 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6384 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6385 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6386 min_kid_count * sizeof(*key_ids));
6388 ret = AVERROR(ENOMEM);
6391 info->key_ids = key_ids;
6393 info->key_ids[i] = av_mallocz(16);
6394 if (!info->key_ids[i]) {
6395 ret = AVERROR(ENOMEM);
6398 info->num_key_ids = i + 1;
6400 if (avio_read(pb, info->key_ids[i], 16) != 16) {
6401 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6402 ret = AVERROR_INVALIDDATA;
6407 if (pb->eof_reached) {
6408 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6409 ret = AVERROR_INVALIDDATA;
6414 extra_data_size = avio_rb32(pb);
6415 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6419 av_freep(&info->data); // malloc(0) may still allocate something.
6420 info->data = extra_data;
6421 info->data_size = extra_data_size;
6423 // If there is existing initialization data, append to the list.
6424 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6425 if (old_side_data) {
6426 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6427 if (old_init_info) {
6428 // Append to the end of the list.
6429 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6435 info = old_init_info;
6437 // Assume existing side-data will be valid, so the only error we could get is OOM.
6438 ret = AVERROR(ENOMEM);
6443 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6445 ret = AVERROR(ENOMEM);
6448 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6449 side_data, side_data_size);
6454 av_encryption_init_info_free(info);
6458 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6461 MOVStreamContext *sc;
6463 if (c->fc->nb_streams < 1)
6465 st = c->fc->streams[c->fc->nb_streams-1];
6468 if (sc->pseudo_stream_id != 0) {
6469 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6470 return AVERROR_PATCHWELCOME;
6474 return AVERROR_INVALIDDATA;
6476 avio_rb32(pb); /* version and flags */
6478 if (!sc->cenc.default_encrypted_sample) {
6479 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6480 if (!sc->cenc.default_encrypted_sample) {
6481 return AVERROR(ENOMEM);
6485 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6489 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6492 MOVStreamContext *sc;
6493 unsigned int version, pattern, is_protected, iv_size;
6495 if (c->fc->nb_streams < 1)
6497 st = c->fc->streams[c->fc->nb_streams-1];
6500 if (sc->pseudo_stream_id != 0) {
6501 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6502 return AVERROR_PATCHWELCOME;
6505 if (!sc->cenc.default_encrypted_sample) {
6506 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6507 if (!sc->cenc.default_encrypted_sample) {
6508 return AVERROR(ENOMEM);
6513 return AVERROR_INVALIDDATA;
6515 version = avio_r8(pb); /* version */
6516 avio_rb24(pb); /* flags */
6518 avio_r8(pb); /* reserved */
6519 pattern = avio_r8(pb);
6522 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6523 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6526 is_protected = avio_r8(pb);
6527 if (is_protected && !sc->cenc.encryption_index) {
6528 // The whole stream should be by-default encrypted.
6529 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6530 if (!sc->cenc.encryption_index)
6531 return AVERROR(ENOMEM);
6533 sc->cenc.per_sample_iv_size = avio_r8(pb);
6534 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6535 sc->cenc.per_sample_iv_size != 16) {
6536 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6537 return AVERROR_INVALIDDATA;
6539 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6540 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6541 return AVERROR_INVALIDDATA;
6544 if (is_protected && !sc->cenc.per_sample_iv_size) {
6545 iv_size = avio_r8(pb);
6546 if (iv_size != 8 && iv_size != 16) {
6547 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6548 return AVERROR_INVALIDDATA;
6551 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6552 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6553 return AVERROR_INVALIDDATA;
6560 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6563 int last, type, size, ret;
6566 if (c->fc->nb_streams < 1)
6568 st = c->fc->streams[c->fc->nb_streams-1];
6570 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6571 return AVERROR_INVALIDDATA;
6573 /* Check FlacSpecificBox version. */
6574 if (avio_r8(pb) != 0)
6575 return AVERROR_INVALIDDATA;
6577 avio_rb24(pb); /* Flags */
6579 avio_read(pb, buf, sizeof(buf));
6580 flac_parse_block_header(buf, &last, &type, &size);
6582 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6583 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6584 return AVERROR_INVALIDDATA;
6587 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6592 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6597 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6601 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6602 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6603 return AVERROR_PATCHWELCOME;
6606 if (!sc->cenc.aes_ctr) {
6607 /* initialize the cipher */
6608 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6609 if (!sc->cenc.aes_ctr) {
6610 return AVERROR(ENOMEM);
6613 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6619 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6621 if (!sample->subsample_count)
6623 /* decrypt the whole packet */
6624 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6628 for (i = 0; i < sample->subsample_count; i++)
6630 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6631 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6632 return AVERROR_INVALIDDATA;
6635 /* skip the clear bytes */
6636 input += sample->subsamples[i].bytes_of_clear_data;
6637 size -= sample->subsamples[i].bytes_of_clear_data;
6639 /* decrypt the encrypted bytes */
6640 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6641 input += sample->subsamples[i].bytes_of_protected_data;
6642 size -= sample->subsamples[i].bytes_of_protected_data;
6646 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6647 return AVERROR_INVALIDDATA;
6653 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6655 MOVFragmentStreamInfo *frag_stream_info;
6656 MOVEncryptionIndex *encryption_index;
6657 AVEncryptionInfo *encrypted_sample;
6658 int encrypted_index, ret;
6660 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6661 encrypted_index = current_index;
6662 encryption_index = NULL;
6663 if (frag_stream_info) {
6664 // Note this only supports encryption info in the first sample descriptor.
6665 if (mov->fragment.stsd_id == 1) {
6666 if (frag_stream_info->encryption_index) {
6667 encrypted_index = current_index - frag_stream_info->index_entry;
6668 encryption_index = frag_stream_info->encryption_index;
6670 encryption_index = sc->cenc.encryption_index;
6674 encryption_index = sc->cenc.encryption_index;
6677 if (encryption_index) {
6678 if (encryption_index->auxiliary_info_sample_count &&
6679 !encryption_index->nb_encrypted_samples) {
6680 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6681 return AVERROR_INVALIDDATA;
6683 if (encryption_index->auxiliary_offsets_count &&
6684 !encryption_index->nb_encrypted_samples) {
6685 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6686 return AVERROR_INVALIDDATA;
6689 if (!encryption_index->nb_encrypted_samples) {
6690 // Full-sample encryption with default settings.
6691 encrypted_sample = sc->cenc.default_encrypted_sample;
6692 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6693 // Per-sample setting override.
6694 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6696 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6697 return AVERROR_INVALIDDATA;
6700 if (mov->decryption_key) {
6701 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6704 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6706 return AVERROR(ENOMEM);
6707 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6717 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6719 const int OPUS_SEEK_PREROLL_MS = 80;
6725 if (c->fc->nb_streams < 1)
6727 st = c->fc->streams[c->fc->nb_streams-1];
6729 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6730 return AVERROR_INVALIDDATA;
6732 /* Check OpusSpecificBox version. */
6733 if (avio_r8(pb) != 0) {
6734 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6735 return AVERROR_INVALIDDATA;
6738 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6739 size = atom.size + 8;
6741 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
6744 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6745 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6746 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6747 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6749 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6750 little-endian; aside from the preceeding magic and version they're
6751 otherwise currently identical. Data after output gain at offset 16
6752 doesn't need to be bytewapped. */
6753 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6754 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6755 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6756 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6758 st->codecpar->initial_padding = pre_skip;
6759 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6760 (AVRational){1, 1000},
6761 (AVRational){1, 48000});
6766 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6769 unsigned format_info;
6770 int channel_assignment, channel_assignment1, channel_assignment2;
6773 if (c->fc->nb_streams < 1)
6775 st = c->fc->streams[c->fc->nb_streams-1];
6778 return AVERROR_INVALIDDATA;
6780 format_info = avio_rb32(pb);
6782 ratebits = (format_info >> 28) & 0xF;
6783 channel_assignment1 = (format_info >> 15) & 0x1F;
6784 channel_assignment2 = format_info & 0x1FFF;
6785 if (channel_assignment2)
6786 channel_assignment = channel_assignment2;
6788 channel_assignment = channel_assignment1;
6790 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6791 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6792 st->codecpar->channels = truehd_channels(channel_assignment);
6793 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6798 static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6802 AVDOVIDecoderConfigurationRecord *dovi;
6806 if (c->fc->nb_streams < 1)
6808 st = c->fc->streams[c->fc->nb_streams-1];
6810 if ((uint64_t)atom.size > (1<<30) || atom.size < 4)
6811 return AVERROR_INVALIDDATA;
6813 dovi = av_dovi_alloc(&dovi_size);
6815 return AVERROR(ENOMEM);
6817 dovi->dv_version_major = avio_r8(pb);
6818 dovi->dv_version_minor = avio_r8(pb);
6820 buf = avio_rb16(pb);
6821 dovi->dv_profile = (buf >> 9) & 0x7f; // 7 bits
6822 dovi->dv_level = (buf >> 3) & 0x3f; // 6 bits
6823 dovi->rpu_present_flag = (buf >> 2) & 0x01; // 1 bit
6824 dovi->el_present_flag = (buf >> 1) & 0x01; // 1 bit
6825 dovi->bl_present_flag = buf & 0x01; // 1 bit
6826 if (atom.size >= 24) { // 4 + 4 + 4 * 4
6828 dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits
6830 // 0 stands for None
6831 // Dolby Vision V1.2.93 profiles and levels
6832 dovi->dv_bl_signal_compatibility_id = 0;
6835 ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF,
6836 (uint8_t *)dovi, dovi_size);
6842 av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC box, version: %d.%d, profile: %d, level: %d, "
6843 "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n",
6844 dovi->dv_version_major, dovi->dv_version_minor,
6845 dovi->dv_profile, dovi->dv_level,
6846 dovi->rpu_present_flag,
6847 dovi->el_present_flag,
6848 dovi->bl_present_flag,
6849 dovi->dv_bl_signal_compatibility_id
6855 static const MOVParseTableEntry mov_default_parse_table[] = {
6856 { MKTAG('A','C','L','R'), mov_read_aclr },
6857 { MKTAG('A','P','R','G'), mov_read_avid },
6858 { MKTAG('A','A','L','P'), mov_read_avid },
6859 { MKTAG('A','R','E','S'), mov_read_ares },
6860 { MKTAG('a','v','s','s'), mov_read_avss },
6861 { MKTAG('a','v','1','C'), mov_read_av1c },
6862 { MKTAG('c','h','p','l'), mov_read_chpl },
6863 { MKTAG('c','o','6','4'), mov_read_stco },
6864 { MKTAG('c','o','l','r'), mov_read_colr },
6865 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6866 { MKTAG('d','i','n','f'), mov_read_default },
6867 { MKTAG('D','p','x','E'), mov_read_dpxe },
6868 { MKTAG('d','r','e','f'), mov_read_dref },
6869 { MKTAG('e','d','t','s'), mov_read_default },
6870 { MKTAG('e','l','s','t'), mov_read_elst },
6871 { MKTAG('e','n','d','a'), mov_read_enda },
6872 { MKTAG('f','i','e','l'), mov_read_fiel },
6873 { MKTAG('a','d','r','m'), mov_read_adrm },
6874 { MKTAG('f','t','y','p'), mov_read_ftyp },
6875 { MKTAG('g','l','b','l'), mov_read_glbl },
6876 { MKTAG('h','d','l','r'), mov_read_hdlr },
6877 { MKTAG('i','l','s','t'), mov_read_ilst },
6878 { MKTAG('j','p','2','h'), mov_read_jp2h },
6879 { MKTAG('m','d','a','t'), mov_read_mdat },
6880 { MKTAG('m','d','h','d'), mov_read_mdhd },
6881 { MKTAG('m','d','i','a'), mov_read_default },
6882 { MKTAG('m','e','t','a'), mov_read_meta },
6883 { MKTAG('m','i','n','f'), mov_read_default },
6884 { MKTAG('m','o','o','f'), mov_read_moof },
6885 { MKTAG('m','o','o','v'), mov_read_moov },
6886 { MKTAG('m','v','e','x'), mov_read_default },
6887 { MKTAG('m','v','h','d'), mov_read_mvhd },
6888 { MKTAG('S','M','I',' '), mov_read_svq3 },
6889 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6890 { MKTAG('a','v','c','C'), mov_read_glbl },
6891 { MKTAG('p','a','s','p'), mov_read_pasp },
6892 { MKTAG('s','i','d','x'), mov_read_sidx },
6893 { MKTAG('s','t','b','l'), mov_read_default },
6894 { MKTAG('s','t','c','o'), mov_read_stco },
6895 { MKTAG('s','t','p','s'), mov_read_stps },
6896 { MKTAG('s','t','r','f'), mov_read_strf },
6897 { MKTAG('s','t','s','c'), mov_read_stsc },
6898 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6899 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6900 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6901 { MKTAG('s','t','t','s'), mov_read_stts },
6902 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6903 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
6904 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6905 { MKTAG('t','f','d','t'), mov_read_tfdt },
6906 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6907 { MKTAG('t','r','a','k'), mov_read_trak },
6908 { MKTAG('t','r','a','f'), mov_read_default },
6909 { MKTAG('t','r','e','f'), mov_read_default },
6910 { MKTAG('t','m','c','d'), mov_read_tmcd },
6911 { MKTAG('c','h','a','p'), mov_read_chap },
6912 { MKTAG('t','r','e','x'), mov_read_trex },
6913 { MKTAG('t','r','u','n'), mov_read_trun },
6914 { MKTAG('u','d','t','a'), mov_read_default },
6915 { MKTAG('w','a','v','e'), mov_read_wave },
6916 { MKTAG('e','s','d','s'), mov_read_esds },
6917 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6918 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6919 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6920 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6921 { MKTAG('w','f','e','x'), mov_read_wfex },
6922 { MKTAG('c','m','o','v'), mov_read_cmov },
6923 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6924 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6925 { MKTAG('s','b','g','p'), mov_read_sbgp },
6926 { MKTAG('h','v','c','C'), mov_read_glbl },
6927 { MKTAG('u','u','i','d'), mov_read_uuid },
6928 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6929 { MKTAG('f','r','e','e'), mov_read_free },
6930 { MKTAG('-','-','-','-'), mov_read_custom },
6931 { MKTAG('s','i','n','f'), mov_read_default },
6932 { MKTAG('f','r','m','a'), mov_read_frma },
6933 { MKTAG('s','e','n','c'), mov_read_senc },
6934 { MKTAG('s','a','i','z'), mov_read_saiz },
6935 { MKTAG('s','a','i','o'), mov_read_saio },
6936 { MKTAG('p','s','s','h'), mov_read_pssh },
6937 { MKTAG('s','c','h','m'), mov_read_schm },
6938 { MKTAG('s','c','h','i'), mov_read_default },
6939 { MKTAG('t','e','n','c'), mov_read_tenc },
6940 { MKTAG('d','f','L','a'), mov_read_dfla },
6941 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6942 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6943 { MKTAG('d','O','p','s'), mov_read_dops },
6944 { MKTAG('d','m','l','p'), mov_read_dmlp },
6945 { MKTAG('S','m','D','m'), mov_read_smdm },
6946 { MKTAG('C','o','L','L'), mov_read_coll },
6947 { MKTAG('v','p','c','C'), mov_read_vpcc },
6948 { MKTAG('m','d','c','v'), mov_read_mdcv },
6949 { MKTAG('c','l','l','i'), mov_read_clli },
6950 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
6951 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
6955 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6957 int64_t total_size = 0;
6961 if (c->atom_depth > 10) {
6962 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6963 return AVERROR_INVALIDDATA;
6968 atom.size = INT64_MAX;
6969 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6970 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
6973 if (atom.size >= 8) {
6974 a.size = avio_rb32(pb);
6975 a.type = avio_rl32(pb);
6976 if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
6977 a.type == MKTAG('h','o','o','v')) &&
6979 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
6981 uint32_t *type = (uint32_t *)buf + 1;
6982 if (avio_read(pb, buf, 8) != 8)
6983 return AVERROR_INVALIDDATA;
6984 avio_seek(pb, -8, SEEK_CUR);
6985 if (*type == MKTAG('m','v','h','d') ||
6986 *type == MKTAG('c','m','o','v')) {
6987 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
6988 a.type = MKTAG('m','o','o','v');
6991 if (atom.type != MKTAG('r','o','o','t') &&
6992 atom.type != MKTAG('m','o','o','v'))
6994 if (a.type == MKTAG('t','r','a','k') || a.type == MKTAG('m','d','a','t'))
6996 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
7003 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
7004 a.size = avio_rb64(pb) - 8;
7008 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
7009 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
7011 a.size = atom.size - total_size + 8;
7016 a.size = FFMIN(a.size, atom.size - total_size);
7018 for (i = 0; mov_default_parse_table[i].type; i++)
7019 if (mov_default_parse_table[i].type == a.type) {
7020 parse = mov_default_parse_table[i].parse;
7024 // container is user data
7025 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
7026 atom.type == MKTAG('i','l','s','t')))
7027 parse = mov_read_udta_string;
7029 // Supports parsing the QuickTime Metadata Keys.
7030 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
7031 if (!parse && c->found_hdlr_mdta &&
7032 atom.type == MKTAG('m','e','t','a') &&
7033 a.type == MKTAG('k','e','y','s') &&
7034 c->meta_keys_count == 0) {
7035 parse = mov_read_keys;
7038 if (!parse) { /* skip leaf atoms data */
7039 avio_skip(pb, a.size);
7041 int64_t start_pos = avio_tell(pb);
7043 int err = parse(c, pb, a);
7048 if (c->found_moov && c->found_mdat &&
7049 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
7050 start_pos + a.size == avio_size(pb))) {
7051 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
7052 c->next_root_atom = start_pos + a.size;
7056 left = a.size - avio_tell(pb) + start_pos;
7057 if (left > 0) /* skip garbage at atom end */
7058 avio_skip(pb, left);
7059 else if (left < 0) {
7060 av_log(c->fc, AV_LOG_WARNING,
7061 "overread end of atom '%.4s' by %"PRId64" bytes\n",
7062 (char*)&a.type, -left);
7063 avio_seek(pb, left, SEEK_CUR);
7067 total_size += a.size;
7070 if (total_size < atom.size && atom.size < 0x7ffff)
7071 avio_skip(pb, atom.size - total_size);
7077 static int mov_probe(const AVProbeData *p)
7082 int moov_offset = -1;
7084 /* check file header */
7087 /* ignore invalid offset */
7088 if ((offset + 8) > (unsigned int)p->buf_size)
7090 tag = AV_RL32(p->buf + offset + 4);
7092 /* check for obvious tags */
7093 case MKTAG('m','o','o','v'):
7094 moov_offset = offset + 4;
7095 case MKTAG('m','d','a','t'):
7096 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
7097 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
7098 case MKTAG('f','t','y','p'):
7099 if (AV_RB32(p->buf+offset) < 8 &&
7100 (AV_RB32(p->buf+offset) != 1 ||
7101 offset + 12 > (unsigned int)p->buf_size ||
7102 AV_RB64(p->buf+offset + 8) == 0)) {
7103 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7104 } else if (tag == MKTAG('f','t','y','p') &&
7105 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
7106 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
7108 score = FFMAX(score, 5);
7110 score = AVPROBE_SCORE_MAX;
7112 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7114 /* those are more common words, so rate then a bit less */
7115 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
7116 case MKTAG('w','i','d','e'):
7117 case MKTAG('f','r','e','e'):
7118 case MKTAG('j','u','n','k'):
7119 case MKTAG('p','i','c','t'):
7120 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
7121 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7123 case MKTAG(0x82,0x82,0x7f,0x7d):
7124 case MKTAG('s','k','i','p'):
7125 case MKTAG('u','u','i','d'):
7126 case MKTAG('p','r','f','l'):
7127 /* if we only find those cause probedata is too small at least rate them */
7128 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7129 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7132 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7135 if(score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
7136 /* moov atom in the header - we should make sure that this is not a
7137 * MOV-packed MPEG-PS */
7138 offset = moov_offset;
7140 while(offset < (p->buf_size - 16)){ /* Sufficient space */
7141 /* We found an actual hdlr atom */
7142 if(AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7143 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7144 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')){
7145 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7146 /* We found a media handler reference atom describing an
7147 * MPEG-PS-in-MOV, return a
7148 * low score to force expanding the probe window until
7149 * mpegps_probe finds what it needs */
7160 // must be done after parsing all trak because there's no order requirement
7161 static void mov_read_chapters(AVFormatContext *s)
7163 MOVContext *mov = s->priv_data;
7165 MOVStreamContext *sc;
7170 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7171 chapter_track = mov->chapter_tracks[j];
7173 for (i = 0; i < s->nb_streams; i++)
7174 if (s->streams[i]->id == chapter_track) {
7179 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7184 cur_pos = avio_tell(sc->pb);
7186 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7187 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7188 if (st->nb_index_entries) {
7189 // Retrieve the first frame, if possible
7191 AVIndexEntry *sample = &st->index_entries[0];
7192 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7193 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7197 if (av_get_packet(sc->pb, &pkt, sample->size) < 0)
7200 st->attached_pic = pkt;
7201 st->attached_pic.stream_index = st->index;
7202 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
7205 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7206 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7207 st->discard = AVDISCARD_ALL;
7208 for (i = 0; i < st->nb_index_entries; i++) {
7209 AVIndexEntry *sample = &st->index_entries[i];
7210 int64_t end = i+1 < st->nb_index_entries ? st->index_entries[i+1].timestamp : st->duration;
7215 if (end < sample->timestamp) {
7216 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7217 end = AV_NOPTS_VALUE;
7220 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7221 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7225 // the first two bytes are the length of the title
7226 len = avio_rb16(sc->pb);
7227 if (len > sample->size-2)
7229 title_len = 2*len + 1;
7230 if (!(title = av_mallocz(title_len)))
7233 // The samples could theoretically be in any encoding if there's an encd
7234 // atom following, but in practice are only utf-8 or utf-16, distinguished
7235 // instead by the presence of a BOM
7239 ch = avio_rb16(sc->pb);
7241 avio_get_str16be(sc->pb, len, title, title_len);
7242 else if (ch == 0xfffe)
7243 avio_get_str16le(sc->pb, len, title, title_len);
7246 if (len == 1 || len == 2)
7249 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7253 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7258 avio_seek(sc->pb, cur_pos, SEEK_SET);
7262 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7263 uint32_t value, int flags)
7266 char buf[AV_TIMECODE_STR_SIZE];
7267 AVRational rate = st->avg_frame_rate;
7268 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7271 av_dict_set(&st->metadata, "timecode",
7272 av_timecode_make_string(&tc, buf, value), 0);
7276 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7278 MOVStreamContext *sc = st->priv_data;
7279 char buf[AV_TIMECODE_STR_SIZE];
7280 int64_t cur_pos = avio_tell(sc->pb);
7281 int hh, mm, ss, ff, drop;
7283 if (!st->nb_index_entries)
7286 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7287 avio_skip(s->pb, 13);
7288 hh = avio_r8(s->pb);
7289 mm = avio_r8(s->pb);
7290 ss = avio_r8(s->pb);
7291 drop = avio_r8(s->pb);
7292 ff = avio_r8(s->pb);
7293 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7294 hh, mm, ss, drop ? ';' : ':', ff);
7295 av_dict_set(&st->metadata, "timecode", buf, 0);
7297 avio_seek(sc->pb, cur_pos, SEEK_SET);
7301 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7303 MOVStreamContext *sc = st->priv_data;
7305 int64_t cur_pos = avio_tell(sc->pb);
7308 if (!st->nb_index_entries)
7311 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7312 value = avio_rb32(s->pb);
7314 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7315 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7316 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7318 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7319 * not the case) and thus assume "frame number format" instead of QT one.
7320 * No sample with tmcd track can be found with a QT timecode at the moment,
7321 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7323 parse_timecode_in_framenum_format(s, st, value, flags);
7325 avio_seek(sc->pb, cur_pos, SEEK_SET);
7329 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7331 if (!index || !*index) return;
7332 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7333 av_encryption_info_free((*index)->encrypted_samples[i]);
7335 av_freep(&(*index)->encrypted_samples);
7336 av_freep(&(*index)->auxiliary_info_sizes);
7337 av_freep(&(*index)->auxiliary_offsets);
7341 static int mov_read_close(AVFormatContext *s)
7343 MOVContext *mov = s->priv_data;
7346 for (i = 0; i < s->nb_streams; i++) {
7347 AVStream *st = s->streams[i];
7348 MOVStreamContext *sc = st->priv_data;
7353 av_freep(&sc->ctts_data);
7354 for (j = 0; j < sc->drefs_count; j++) {
7355 av_freep(&sc->drefs[j].path);
7356 av_freep(&sc->drefs[j].dir);
7358 av_freep(&sc->drefs);
7360 sc->drefs_count = 0;
7362 if (!sc->pb_is_copied)
7363 ff_format_io_close(s, &sc->pb);
7366 av_freep(&sc->chunk_offsets);
7367 av_freep(&sc->stsc_data);
7368 av_freep(&sc->sample_sizes);
7369 av_freep(&sc->keyframes);
7370 av_freep(&sc->stts_data);
7371 av_freep(&sc->sdtp_data);
7372 av_freep(&sc->stps_data);
7373 av_freep(&sc->elst_data);
7374 av_freep(&sc->rap_group);
7375 av_freep(&sc->display_matrix);
7376 av_freep(&sc->index_ranges);
7379 for (j = 0; j < sc->stsd_count; j++)
7380 av_free(sc->extradata[j]);
7381 av_freep(&sc->extradata);
7382 av_freep(&sc->extradata_size);
7384 mov_free_encryption_index(&sc->cenc.encryption_index);
7385 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7386 av_aes_ctr_free(sc->cenc.aes_ctr);
7388 av_freep(&sc->stereo3d);
7389 av_freep(&sc->spherical);
7390 av_freep(&sc->mastering);
7391 av_freep(&sc->coll);
7394 if (mov->dv_demux) {
7395 avformat_free_context(mov->dv_fctx);
7396 mov->dv_fctx = NULL;
7399 if (mov->meta_keys) {
7400 for (i = 1; i < mov->meta_keys_count; i++) {
7401 av_freep(&mov->meta_keys[i]);
7403 av_freep(&mov->meta_keys);
7406 av_freep(&mov->trex_data);
7407 av_freep(&mov->bitrates);
7409 for (i = 0; i < mov->frag_index.nb_items; i++) {
7410 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7411 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7412 mov_free_encryption_index(&frag[j].encryption_index);
7414 av_freep(&mov->frag_index.item[i].stream_info);
7416 av_freep(&mov->frag_index.item);
7418 av_freep(&mov->aes_decrypt);
7419 av_freep(&mov->chapter_tracks);
7424 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7428 for (i = 0; i < s->nb_streams; i++) {
7429 AVStream *st = s->streams[i];
7430 MOVStreamContext *sc = st->priv_data;
7432 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7433 sc->timecode_track == tmcd_id)
7439 /* look for a tmcd track not referenced by any video track, and export it globally */
7440 static void export_orphan_timecode(AVFormatContext *s)
7444 for (i = 0; i < s->nb_streams; i++) {
7445 AVStream *st = s->streams[i];
7447 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7448 !tmcd_is_referenced(s, i + 1)) {
7449 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7451 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7458 static int read_tfra(MOVContext *mov, AVIOContext *f)
7460 int version, fieldlength, i, j;
7461 int64_t pos = avio_tell(f);
7462 uint32_t size = avio_rb32(f);
7463 unsigned track_id, item_count;
7465 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7468 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7470 version = avio_r8(f);
7472 track_id = avio_rb32(f);
7473 fieldlength = avio_rb32(f);
7474 item_count = avio_rb32(f);
7475 for (i = 0; i < item_count; i++) {
7476 int64_t time, offset;
7478 MOVFragmentStreamInfo * frag_stream_info;
7481 return AVERROR_INVALIDDATA;
7485 time = avio_rb64(f);
7486 offset = avio_rb64(f);
7488 time = avio_rb32(f);
7489 offset = avio_rb32(f);
7492 // The first sample of each stream in a fragment is always a random
7493 // access sample. So it's entry in the tfra can be used as the
7494 // initial PTS of the fragment.
7495 index = update_frag_index(mov, offset);
7496 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7497 if (frag_stream_info &&
7498 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7499 frag_stream_info->first_tfra_pts = time;
7501 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7503 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7505 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7509 avio_seek(f, pos + size, SEEK_SET);
7513 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7515 int64_t stream_size = avio_size(f);
7516 int64_t original_pos = avio_tell(f);
7520 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7524 mfra_size = avio_rb32(f);
7525 if (mfra_size < 0 || mfra_size > stream_size) {
7526 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7529 if ((seek_ret = avio_seek(f, -mfra_size, SEEK_CUR)) < 0) {
7533 if (avio_rb32(f) != mfra_size) {
7534 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7537 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7538 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7541 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7543 ret = read_tfra(c, f);
7549 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7551 av_log(c->fc, AV_LOG_ERROR,
7552 "failed to seek back after looking for mfra\n");
7558 static int mov_read_header(AVFormatContext *s)
7560 MOVContext *mov = s->priv_data;
7561 AVIOContext *pb = s->pb;
7563 MOVAtom atom = { AV_RL32("root") };
7566 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7567 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7568 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7569 return AVERROR(EINVAL);
7573 mov->trak_index = -1;
7574 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7575 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7576 atom.size = avio_size(pb);
7578 atom.size = INT64_MAX;
7580 /* check MOV header */
7582 if (mov->moov_retry)
7583 avio_seek(pb, 0, SEEK_SET);
7584 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7585 av_log(s, AV_LOG_ERROR, "error reading header\n");
7588 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7589 if (!mov->found_moov) {
7590 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7591 err = AVERROR_INVALIDDATA;
7594 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7596 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7597 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7598 mov_read_chapters(s);
7599 for (i = 0; i < s->nb_streams; i++)
7600 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7601 mov_read_timecode_track(s, s->streams[i]);
7602 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7603 mov_read_rtmd_track(s, s->streams[i]);
7607 /* copy timecode metadata from tmcd tracks to the related video streams */
7608 for (i = 0; i < s->nb_streams; i++) {
7609 AVStream *st = s->streams[i];
7610 MOVStreamContext *sc = st->priv_data;
7611 if (sc->timecode_track > 0) {
7612 AVDictionaryEntry *tcr;
7613 int tmcd_st_id = -1;
7615 for (j = 0; j < s->nb_streams; j++)
7616 if (s->streams[j]->id == sc->timecode_track)
7619 if (tmcd_st_id < 0 || tmcd_st_id == i)
7621 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7623 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7626 export_orphan_timecode(s);
7628 for (i = 0; i < s->nb_streams; i++) {
7629 AVStream *st = s->streams[i];
7630 MOVStreamContext *sc = st->priv_data;
7631 fix_timescale(mov, sc);
7632 if(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7633 st->skip_samples = sc->start_pad;
7635 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7636 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7637 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7638 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7639 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7640 st->codecpar->width = sc->width;
7641 st->codecpar->height = sc->height;
7643 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7644 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7648 if (mov->handbrake_version &&
7649 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7650 st->codecpar->codec_id == AV_CODEC_ID_MP3
7652 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7653 st->need_parsing = AVSTREAM_PARSE_FULL;
7657 if (mov->trex_data) {
7658 for (i = 0; i < s->nb_streams; i++) {
7659 AVStream *st = s->streams[i];
7660 MOVStreamContext *sc = st->priv_data;
7661 if (st->duration > 0) {
7662 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7663 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7664 sc->data_size, sc->time_scale);
7665 err = AVERROR_INVALIDDATA;
7668 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7673 if (mov->use_mfra_for > 0) {
7674 for (i = 0; i < s->nb_streams; i++) {
7675 AVStream *st = s->streams[i];
7676 MOVStreamContext *sc = st->priv_data;
7677 if (sc->duration_for_fps > 0) {
7678 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7679 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7680 sc->data_size, sc->time_scale);
7681 err = AVERROR_INVALIDDATA;
7684 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7685 sc->duration_for_fps;
7690 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7691 if (mov->bitrates[i]) {
7692 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7696 ff_rfps_calculate(s);
7698 for (i = 0; i < s->nb_streams; i++) {
7699 AVStream *st = s->streams[i];
7700 MOVStreamContext *sc = st->priv_data;
7702 switch (st->codecpar->codec_type) {
7703 case AVMEDIA_TYPE_AUDIO:
7704 err = ff_replaygain_export(st, s->metadata);
7709 case AVMEDIA_TYPE_VIDEO:
7710 if (sc->display_matrix) {
7711 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7712 sizeof(int32_t) * 9);
7716 sc->display_matrix = NULL;
7719 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7720 (uint8_t *)sc->stereo3d,
7721 sizeof(*sc->stereo3d));
7725 sc->stereo3d = NULL;
7727 if (sc->spherical) {
7728 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7729 (uint8_t *)sc->spherical,
7730 sc->spherical_size);
7734 sc->spherical = NULL;
7736 if (sc->mastering) {
7737 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7738 (uint8_t *)sc->mastering,
7739 sizeof(*sc->mastering));
7743 sc->mastering = NULL;
7746 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7747 (uint8_t *)sc->coll,
7757 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7759 for (i = 0; i < mov->frag_index.nb_items; i++)
7760 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7761 mov->frag_index.item[i].headers_read = 1;
7769 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7771 AVIndexEntry *sample = NULL;
7772 int64_t best_dts = INT64_MAX;
7774 for (i = 0; i < s->nb_streams; i++) {
7775 AVStream *avst = s->streams[i];
7776 MOVStreamContext *msc = avst->priv_data;
7777 if (msc->pb && msc->current_sample < avst->nb_index_entries) {
7778 AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample];
7779 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7780 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7781 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7782 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7783 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
7784 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7785 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7786 sample = current_sample;
7795 static int should_retry(AVIOContext *pb, int error_code) {
7796 if (error_code == AVERROR_EOF || avio_feof(pb))
7802 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7805 MOVContext *mov = s->priv_data;
7807 if (index >= 0 && index < mov->frag_index.nb_items)
7808 target = mov->frag_index.item[index].moof_offset;
7809 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7810 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7811 return AVERROR_INVALIDDATA;
7814 mov->next_root_atom = 0;
7815 if (index < 0 || index >= mov->frag_index.nb_items)
7816 index = search_frag_moof_offset(&mov->frag_index, target);
7817 if (index < mov->frag_index.nb_items &&
7818 mov->frag_index.item[index].moof_offset == target) {
7819 if (index + 1 < mov->frag_index.nb_items)
7820 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7821 if (mov->frag_index.item[index].headers_read)
7823 mov->frag_index.item[index].headers_read = 1;
7826 mov->found_mdat = 0;
7828 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7831 if (avio_feof(s->pb))
7833 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7838 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7840 uint8_t *side, *extradata;
7843 /* Save the current index. */
7844 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7846 /* Notify the decoder that extradata changed. */
7847 extradata_size = sc->extradata_size[sc->last_stsd_index];
7848 extradata = sc->extradata[sc->last_stsd_index];
7849 if (extradata_size > 0 && extradata) {
7850 side = av_packet_new_side_data(pkt,
7851 AV_PKT_DATA_NEW_EXTRADATA,
7854 return AVERROR(ENOMEM);
7855 memcpy(side, extradata, extradata_size);
7861 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7863 MOVContext *mov = s->priv_data;
7864 MOVStreamContext *sc;
7865 AVIndexEntry *sample;
7866 AVStream *st = NULL;
7867 int64_t current_index;
7871 sample = mov_find_next_sample(s, &st);
7872 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7873 if (!mov->next_root_atom)
7875 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7880 /* must be done just before reading, to avoid infinite loop on sample */
7881 current_index = sc->current_index;
7882 mov_current_sample_inc(sc);
7884 if (mov->next_root_atom) {
7885 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7886 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7889 if (st->discard != AVDISCARD_ALL) {
7890 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7891 if (ret64 != sample->pos) {
7892 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7893 sc->ffindex, sample->pos);
7894 if (should_retry(sc->pb, ret64)) {
7895 mov_current_sample_dec(sc);
7897 return AVERROR_INVALIDDATA;
7900 if( st->discard == AVDISCARD_NONKEY && 0==(sample->flags & AVINDEX_KEYFRAME) ) {
7901 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7905 ret = av_get_packet(sc->pb, pkt, sample->size);
7907 if (should_retry(sc->pb, ret)) {
7908 mov_current_sample_dec(sc);
7912 if (sc->has_palette) {
7915 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7917 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7919 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7920 sc->has_palette = 0;
7923 #if CONFIG_DV_DEMUXER
7924 if (mov->dv_demux && sc->dv_audio_container) {
7925 avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7926 av_freep(&pkt->data);
7928 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7933 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7934 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7935 st->need_parsing = AVSTREAM_PARSE_FULL;
7939 pkt->stream_index = sc->ffindex;
7940 pkt->dts = sample->timestamp;
7941 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7942 pkt->flags |= AV_PKT_FLAG_DISCARD;
7944 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7945 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
7946 /* update ctts context */
7948 if (sc->ctts_index < sc->ctts_count &&
7949 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
7951 sc->ctts_sample = 0;
7954 int64_t next_dts = (sc->current_sample < st->nb_index_entries) ?
7955 st->index_entries[sc->current_sample].timestamp : st->duration;
7957 if (next_dts >= pkt->dts)
7958 pkt->duration = next_dts - pkt->dts;
7959 pkt->pts = pkt->dts;
7961 if (st->discard == AVDISCARD_ALL)
7963 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
7964 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
7965 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
7966 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
7968 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
7969 pkt->pos = sample->pos;
7971 /* Multiple stsd handling. */
7972 if (sc->stsc_data) {
7973 /* Keep track of the stsc index for the given sample, then check
7974 * if the stsd index is different from the last used one. */
7976 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
7977 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
7979 sc->stsc_sample = 0;
7980 /* Do not check indexes after a switch. */
7981 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
7982 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
7983 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
7984 ret = mov_change_extradata(sc, pkt);
7991 aax_filter(pkt->data, pkt->size, mov);
7993 ret = cenc_filter(mov, st, sc, pkt, current_index);
8001 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
8003 MOVContext *mov = s->priv_data;
8006 if (!mov->frag_index.complete)
8009 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
8012 if (!mov->frag_index.item[index].headers_read)
8013 return mov_switch_root(s, -1, index);
8014 if (index + 1 < mov->frag_index.nb_items)
8015 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
8020 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
8022 MOVStreamContext *sc = st->priv_data;
8023 int sample, time_sample, ret;
8026 // Here we consider timestamp to be PTS, hence try to offset it so that we
8027 // can search over the DTS timeline.
8028 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
8030 ret = mov_seek_fragment(s, st, timestamp);
8034 sample = av_index_search_timestamp(st, timestamp, flags);
8035 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
8036 if (sample < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp)
8038 if (sample < 0) /* not sure what to do */
8039 return AVERROR_INVALIDDATA;
8040 mov_current_sample_set(sc, sample);
8041 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
8042 /* adjust ctts index */
8043 if (sc->ctts_data) {
8045 for (i = 0; i < sc->ctts_count; i++) {
8046 int next = time_sample + sc->ctts_data[i].count;
8047 if (next > sc->current_sample) {
8049 sc->ctts_sample = sc->current_sample - time_sample;
8056 /* adjust stsd index */
8057 if (sc->chunk_count) {
8059 for (i = 0; i < sc->stsc_count; i++) {
8060 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
8061 if (next > sc->current_sample) {
8063 sc->stsc_sample = sc->current_sample - time_sample;
8066 av_assert0(next == (int)next);
8074 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
8076 MOVContext *mc = s->priv_data;
8081 if (stream_index >= s->nb_streams)
8082 return AVERROR_INVALIDDATA;
8084 st = s->streams[stream_index];
8085 sample = mov_seek_stream(s, st, sample_time, flags);
8089 if (mc->seek_individually) {
8090 /* adjust seek timestamp to found sample timestamp */
8091 int64_t seek_timestamp = st->index_entries[sample].timestamp;
8093 for (i = 0; i < s->nb_streams; i++) {
8095 MOVStreamContext *sc = s->streams[i]->priv_data;
8097 st->skip_samples = (sample_time <= 0) ? sc->start_pad : 0;
8099 if (stream_index == i)
8102 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
8103 mov_seek_stream(s, st, timestamp, flags);
8106 for (i = 0; i < s->nb_streams; i++) {
8107 MOVStreamContext *sc;
8110 mov_current_sample_set(sc, 0);
8113 MOVStreamContext *sc;
8114 AVIndexEntry *entry = mov_find_next_sample(s, &st);
8116 return AVERROR_INVALIDDATA;
8118 if (sc->ffindex == stream_index && sc->current_sample == sample)
8120 mov_current_sample_inc(sc);
8126 #define OFFSET(x) offsetof(MOVContext, x)
8127 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
8128 static const AVOption mov_options[] = {
8129 {"use_absolute_path",
8130 "allow using absolute path when opening alias, this is a possible security issue",
8131 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
8133 {"seek_streams_individually",
8134 "Seek each stream individually to the closest point",
8135 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
8137 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
8139 {"advanced_editlist",
8140 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
8141 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
8143 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8146 "use mfra for fragment timestamps",
8147 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8148 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8150 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8151 FLAGS, "use_mfra_for" },
8152 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8153 FLAGS, "use_mfra_for" },
8154 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8155 FLAGS, "use_mfra_for" },
8156 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8157 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8158 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8159 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8160 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8161 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8162 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8163 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8164 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8165 .flags = AV_OPT_FLAG_DECODING_PARAM },
8166 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8167 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8168 {.i64 = 0}, 0, 1, FLAGS },
8173 static const AVClass mov_class = {
8174 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8175 .item_name = av_default_item_name,
8176 .option = mov_options,
8177 .version = LIBAVUTIL_VERSION_INT,
8180 AVInputFormat ff_mov_demuxer = {
8181 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8182 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8183 .priv_class = &mov_class,
8184 .priv_data_size = sizeof(MOVContext),
8185 .extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
8186 .read_probe = mov_probe,
8187 .read_header = mov_read_header,
8188 .read_packet = mov_read_packet,
8189 .read_close = mov_read_close,
8190 .read_seek = mov_read_seek,
8191 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,