3 * Copyright (c) 2001 Fabrice Bellard
4 * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
6 * first version by Francois Revol <revol@free.fr>
7 * seek function by Gael Chardon <gael.dev@4now.net>
9 * This file is part of FFmpeg.
11 * FFmpeg is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * FFmpeg is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with FFmpeg; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30 #include "libavutil/attributes.h"
31 #include "libavutil/channel_layout.h"
32 #include "libavutil/internal.h"
33 #include "libavutil/intreadwrite.h"
34 #include "libavutil/intfloat.h"
35 #include "libavutil/mathematics.h"
36 #include "libavutil/time_internal.h"
37 #include "libavutil/avassert.h"
38 #include "libavutil/avstring.h"
39 #include "libavutil/dict.h"
40 #include "libavutil/display.h"
41 #include "libavutil/opt.h"
42 #include "libavutil/aes.h"
43 #include "libavutil/aes_ctr.h"
44 #include "libavutil/pixdesc.h"
45 #include "libavutil/sha.h"
46 #include "libavutil/spherical.h"
47 #include "libavutil/stereo3d.h"
48 #include "libavutil/timecode.h"
49 #include "libavutil/dovi_meta.h"
50 #include "libavcodec/ac3tab.h"
51 #include "libavcodec/flac.h"
52 #include "libavcodec/mpegaudiodecheader.h"
53 #include "libavcodec/mlp_parse.h"
56 #include "avio_internal.h"
59 #include "libavcodec/get_bits.h"
62 #include "replaygain.h"
68 #include "qtpalette.h"
70 /* those functions parse an atom */
71 /* links atom IDs to parse functions */
72 typedef struct MOVParseTableEntry {
74 int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
77 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
78 static int mov_read_mfra(MOVContext *c, AVIOContext *f);
79 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
80 int count, int duration);
82 static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb,
83 unsigned len, const char *key)
87 short current, total = 0;
88 avio_rb16(pb); // unknown
89 current = avio_rb16(pb);
91 total = avio_rb16(pb);
93 snprintf(buf, sizeof(buf), "%d", current);
95 snprintf(buf, sizeof(buf), "%d/%d", current, total);
96 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
97 av_dict_set(&c->fc->metadata, key, buf, 0);
102 static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb,
103 unsigned len, const char *key)
105 /* bypass padding bytes */
110 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
111 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
116 static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb,
117 unsigned len, const char *key)
119 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
120 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
125 static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb,
126 unsigned len, const char *key)
130 avio_r8(pb); // unknown
133 if (genre < 1 || genre > ID3v1_GENRE_MAX)
135 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
136 av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
141 static const uint32_t mac_to_unicode[128] = {
142 0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
143 0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
144 0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
145 0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
146 0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
147 0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
148 0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
149 0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
150 0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
151 0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
152 0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
153 0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
154 0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
155 0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
156 0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
157 0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
160 static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len,
161 char *dst, int dstlen)
164 char *end = dst+dstlen-1;
167 for (i = 0; i < len; i++) {
168 uint8_t t, c = avio_r8(pb);
176 PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
182 static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
186 MOVStreamContext *sc;
191 case 0xd: id = AV_CODEC_ID_MJPEG; break;
192 case 0xe: id = AV_CODEC_ID_PNG; break;
193 case 0x1b: id = AV_CODEC_ID_BMP; break;
195 av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
200 st = avformat_new_stream(c->fc, NULL);
202 return AVERROR(ENOMEM);
203 sc = av_mallocz(sizeof(*sc));
205 return AVERROR(ENOMEM);
208 ret = av_get_packet(pb, &pkt, len);
212 if (pkt.size >= 8 && id != AV_CODEC_ID_BMP) {
213 if (AV_RB64(pkt.data) == 0x89504e470d0a1a0a) {
214 id = AV_CODEC_ID_PNG;
216 id = AV_CODEC_ID_MJPEG;
220 st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
222 st->attached_pic = pkt;
223 st->attached_pic.stream_index = st->index;
224 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
226 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
227 st->codecpar->codec_id = id;
233 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
235 char language[4] = { 0 };
236 char buf[200], place[100];
237 uint16_t langcode = 0;
238 double longitude, latitude, altitude;
239 const char *key = "location";
241 if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
242 av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
243 return AVERROR_INVALIDDATA;
246 avio_skip(pb, 4); // version+flags
247 langcode = avio_rb16(pb);
248 ff_mov_lang_to_iso639(langcode, language);
251 len -= avio_get_str(pb, len, place, sizeof(place));
253 av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
254 return AVERROR_INVALIDDATA;
256 avio_skip(pb, 1); // role
260 av_log(c->fc, AV_LOG_ERROR,
261 "loci too short (%u bytes left, need at least %d)\n", len, 12);
262 return AVERROR_INVALIDDATA;
264 longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
265 latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
266 altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
268 // Try to output in the same format as the ?xyz field
269 snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
271 av_strlcatf(buf, sizeof(buf), "%+f", altitude);
272 av_strlcatf(buf, sizeof(buf), "/%s", place);
274 if (*language && strcmp(language, "und")) {
276 snprintf(key2, sizeof(key2), "%s-%s", key, language);
277 av_dict_set(&c->fc->metadata, key2, buf, 0);
279 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
280 return av_dict_set(&c->fc->metadata, key, buf, 0);
283 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
289 if (c->ignore_chapters)
292 n_hmmt = avio_rb32(pb);
293 for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
294 int moment_time = avio_rb32(pb);
295 avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
300 static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
303 char key2[32], language[4] = {0};
305 const char *key = NULL;
306 uint16_t langcode = 0;
307 uint32_t data_type = 0, str_size, str_size_alloc;
308 int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
313 case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
314 case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
315 case MKTAG( 'X','M','P','_'):
316 if (c->export_xmp) { key = "xmp"; raw = 1; } break;
317 case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
318 case MKTAG( 'a','k','I','D'): key = "account_type";
319 parse = mov_metadata_int8_no_padding; break;
320 case MKTAG( 'a','p','I','D'): key = "account_id"; break;
321 case MKTAG( 'c','a','t','g'): key = "category"; break;
322 case MKTAG( 'c','p','i','l'): key = "compilation";
323 parse = mov_metadata_int8_no_padding; break;
324 case MKTAG( 'c','p','r','t'): key = "copyright"; break;
325 case MKTAG( 'd','e','s','c'): key = "description"; break;
326 case MKTAG( 'd','i','s','k'): key = "disc";
327 parse = mov_metadata_track_or_disc_number; break;
328 case MKTAG( 'e','g','i','d'): key = "episode_uid";
329 parse = mov_metadata_int8_no_padding; break;
330 case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
331 case MKTAG( 'g','n','r','e'): key = "genre";
332 parse = mov_metadata_gnre; break;
333 case MKTAG( 'h','d','v','d'): key = "hd_video";
334 parse = mov_metadata_int8_no_padding; break;
335 case MKTAG( 'H','M','M','T'):
336 return mov_metadata_hmmt(c, pb, atom.size);
337 case MKTAG( 'k','e','y','w'): key = "keywords"; break;
338 case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
339 case MKTAG( 'l','o','c','i'):
340 return mov_metadata_loci(c, pb, atom.size);
341 case MKTAG( 'm','a','n','u'): key = "make"; break;
342 case MKTAG( 'm','o','d','l'): key = "model"; break;
343 case MKTAG( 'p','c','s','t'): key = "podcast";
344 parse = mov_metadata_int8_no_padding; break;
345 case MKTAG( 'p','g','a','p'): key = "gapless_playback";
346 parse = mov_metadata_int8_no_padding; break;
347 case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
348 case MKTAG( 'r','t','n','g'): key = "rating";
349 parse = mov_metadata_int8_no_padding; break;
350 case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
351 case MKTAG( 's','o','a','l'): key = "sort_album"; break;
352 case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
353 case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
354 case MKTAG( 's','o','n','m'): key = "sort_name"; break;
355 case MKTAG( 's','o','s','n'): key = "sort_show"; break;
356 case MKTAG( 's','t','i','k'): key = "media_type";
357 parse = mov_metadata_int8_no_padding; break;
358 case MKTAG( 't','r','k','n'): key = "track";
359 parse = mov_metadata_track_or_disc_number; break;
360 case MKTAG( 't','v','e','n'): key = "episode_id"; break;
361 case MKTAG( 't','v','e','s'): key = "episode_sort";
362 parse = mov_metadata_int8_bypass_padding; break;
363 case MKTAG( 't','v','n','n'): key = "network"; break;
364 case MKTAG( 't','v','s','h'): key = "show"; break;
365 case MKTAG( 't','v','s','n'): key = "season_number";
366 parse = mov_metadata_int8_bypass_padding; break;
367 case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
368 case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
369 case MKTAG(0xa9,'a','l','b'): key = "album"; break;
370 case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
371 case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
372 case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
373 case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
374 case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
375 case MKTAG(0xa9,'d','a','y'): key = "date"; break;
376 case MKTAG(0xa9,'d','i','r'): key = "director"; break;
377 case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
378 case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
379 case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
380 case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
381 case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
382 case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
383 case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
384 case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
385 case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
386 case MKTAG(0xa9,'m','a','k'): key = "make"; break;
387 case MKTAG(0xa9,'m','o','d'): key = "model"; break;
388 case MKTAG(0xa9,'n','a','m'): key = "title"; break;
389 case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
390 case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
391 case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
392 case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
393 case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
394 case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
395 case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
396 case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
397 case MKTAG(0xa9,'t','r','k'): key = "track"; break;
398 case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
399 case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
400 case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
401 case MKTAG(0xa9,'x','y','z'): key = "location"; break;
404 if (c->itunes_metadata && atom.size > 8) {
405 int data_size = avio_rb32(pb);
406 int tag = avio_rl32(pb);
407 if (tag == MKTAG('d','a','t','a') && data_size <= atom.size) {
408 data_type = avio_rb32(pb); // type
409 avio_rb32(pb); // unknown
410 str_size = data_size - 16;
413 if (atom.type == MKTAG('c', 'o', 'v', 'r')) {
414 int ret = mov_read_covr(c, pb, data_type, str_size);
416 av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
419 atom.size -= str_size;
423 } else if (!key && c->found_hdlr_mdta && c->meta_keys) {
424 uint32_t index = AV_RB32(&atom.type);
425 if (index < c->meta_keys_count && index > 0) {
426 key = c->meta_keys[index];
428 av_log(c->fc, AV_LOG_WARNING,
429 "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
430 index, c->meta_keys_count);
434 } else if (atom.size > 4 && key && !c->itunes_metadata && !raw) {
435 str_size = avio_rb16(pb); // string length
436 if (str_size > atom.size) {
438 avio_seek(pb, -2, SEEK_CUR);
439 av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
442 langcode = avio_rb16(pb);
443 ff_mov_lang_to_iso639(langcode, language);
446 str_size = atom.size;
448 if (c->export_all && !key) {
449 snprintf(tmp_key, 5, "%.4s", (char*)&atom.type);
455 if (atom.size < 0 || str_size >= INT_MAX/2)
456 return AVERROR_INVALIDDATA;
458 // Allocates enough space if data_type is a int32 or float32 number, otherwise
459 // worst-case requirement for output string in case of utf8 coded input
460 num = (data_type >= 21 && data_type <= 23);
461 str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
462 str = av_mallocz(str_size_alloc);
464 return AVERROR(ENOMEM);
467 parse(c, pb, str_size, key);
469 if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
470 mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
471 } else if (data_type == 21) { // BE signed integer, variable size
474 val = (int8_t)avio_r8(pb);
475 else if (str_size == 2)
476 val = (int16_t)avio_rb16(pb);
477 else if (str_size == 3)
478 val = ((int32_t)(avio_rb24(pb)<<8))>>8;
479 else if (str_size == 4)
480 val = (int32_t)avio_rb32(pb);
481 if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
482 av_log(c->fc, AV_LOG_ERROR,
483 "Failed to store the number (%d) in string.\n", val);
485 return AVERROR_INVALIDDATA;
487 } else if (data_type == 22) { // BE unsigned integer, variable size
488 unsigned int val = 0;
491 else if (str_size == 2)
493 else if (str_size == 3)
495 else if (str_size == 4)
497 if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
498 av_log(c->fc, AV_LOG_ERROR,
499 "Failed to store the number (%u) in string.\n", val);
501 return AVERROR_INVALIDDATA;
503 } else if (data_type == 23 && str_size >= 4) { // BE float32
504 float val = av_int2float(avio_rb32(pb));
505 if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
506 av_log(c->fc, AV_LOG_ERROR,
507 "Failed to store the float32 number (%f) in string.\n", val);
509 return AVERROR_INVALIDDATA;
512 int ret = ffio_read_size(pb, str, str_size);
519 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
520 av_dict_set(&c->fc->metadata, key, str, 0);
521 if (*language && strcmp(language, "und")) {
522 snprintf(key2, sizeof(key2), "%s-%s", key, language);
523 av_dict_set(&c->fc->metadata, key2, str, 0);
525 if (!strcmp(key, "encoder")) {
526 int major, minor, micro;
527 if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, µ) == 3) {
528 c->handbrake_version = 1000000*major + 1000*minor + micro;
537 static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
540 int i, nb_chapters, str_len, version;
544 if (c->ignore_chapters)
547 if ((atom.size -= 5) < 0)
550 version = avio_r8(pb);
553 avio_rb32(pb); // ???
554 nb_chapters = avio_r8(pb);
556 for (i = 0; i < nb_chapters; i++) {
560 start = avio_rb64(pb);
561 str_len = avio_r8(pb);
563 if ((atom.size -= 9+str_len) < 0)
566 ret = ffio_read_size(pb, str, str_len);
570 avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
575 #define MIN_DATA_ENTRY_BOX_SIZE 12
576 static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
579 MOVStreamContext *sc;
582 if (c->fc->nb_streams < 1)
584 st = c->fc->streams[c->fc->nb_streams-1];
587 avio_rb32(pb); // version + flags
588 entries = avio_rb32(pb);
590 entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
591 entries >= UINT_MAX / sizeof(*sc->drefs))
592 return AVERROR_INVALIDDATA;
596 sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
598 return AVERROR(ENOMEM);
599 sc->drefs_count = entries;
601 for (i = 0; i < entries; i++) {
602 MOVDref *dref = &sc->drefs[i];
603 uint32_t size = avio_rb32(pb);
604 int64_t next = avio_tell(pb) + size - 4;
607 return AVERROR_INVALIDDATA;
609 dref->type = avio_rl32(pb);
610 avio_rb32(pb); // version + flags
612 if (dref->type == MKTAG('a','l','i','s') && size > 150) {
613 /* macintosh alias record */
614 uint16_t volume_len, len;
620 volume_len = avio_r8(pb);
621 volume_len = FFMIN(volume_len, 27);
622 ret = ffio_read_size(pb, dref->volume, 27);
625 dref->volume[volume_len] = 0;
626 av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
631 len = FFMIN(len, 63);
632 ret = ffio_read_size(pb, dref->filename, 63);
635 dref->filename[len] = 0;
636 av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
640 /* read next level up_from_alias/down_to_target */
641 dref->nlvl_from = avio_rb16(pb);
642 dref->nlvl_to = avio_rb16(pb);
643 av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
644 dref->nlvl_from, dref->nlvl_to);
648 for (type = 0; type != -1 && avio_tell(pb) < next; ) {
651 type = avio_rb16(pb);
653 av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
656 if (type == 2) { // absolute path
658 dref->path = av_mallocz(len+1);
660 return AVERROR(ENOMEM);
662 ret = ffio_read_size(pb, dref->path, len);
664 av_freep(&dref->path);
667 if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
669 memmove(dref->path, dref->path+volume_len, len);
672 // trim string of any ending zeros
673 for (j = len - 1; j >= 0; j--) {
674 if (dref->path[j] == 0)
679 for (j = 0; j < len; j++)
680 if (dref->path[j] == ':' || dref->path[j] == 0)
682 av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
683 } else if (type == 0) { // directory name
685 dref->dir = av_malloc(len+1);
687 return AVERROR(ENOMEM);
689 ret = ffio_read_size(pb, dref->dir, len);
691 av_freep(&dref->dir);
695 for (j = 0; j < len; j++)
696 if (dref->dir[j] == ':')
698 av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
703 av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
708 avio_seek(pb, next, SEEK_SET);
713 static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
722 avio_r8(pb); /* version */
723 avio_rb24(pb); /* flags */
726 ctype = avio_rl32(pb);
727 type = avio_rl32(pb); /* component subtype */
729 av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
730 av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
732 if (c->trak_index < 0) { // meta not inside a trak
733 if (type == MKTAG('m','d','t','a')) {
734 c->found_hdlr_mdta = 1;
739 st = c->fc->streams[c->fc->nb_streams-1];
741 if (type == MKTAG('v','i','d','e'))
742 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
743 else if (type == MKTAG('s','o','u','n'))
744 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
745 else if (type == MKTAG('m','1','a',' '))
746 st->codecpar->codec_id = AV_CODEC_ID_MP2;
747 else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
748 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
750 avio_rb32(pb); /* component manufacture */
751 avio_rb32(pb); /* component flags */
752 avio_rb32(pb); /* component flags mask */
754 title_size = atom.size - 24;
755 if (title_size > 0) {
756 if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
757 return AVERROR_INVALIDDATA;
758 title_str = av_malloc(title_size + 1); /* Add null terminator */
760 return AVERROR(ENOMEM);
762 ret = ffio_read_size(pb, title_str, title_size);
764 av_freep(&title_str);
767 title_str[title_size] = 0;
769 int off = (!c->isom && title_str[0] == title_size - 1);
770 // flag added so as to not set stream handler name if already set from mdia->hdlr
771 av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
773 av_freep(&title_str);
779 static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
781 return ff_mov_read_esds(c->fc, pb);
784 static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
787 enum AVAudioServiceType *ast;
788 int ac3info, acmod, lfeon, bsmod;
790 if (c->fc->nb_streams < 1)
792 st = c->fc->streams[c->fc->nb_streams-1];
794 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
797 return AVERROR(ENOMEM);
799 ac3info = avio_rb24(pb);
800 bsmod = (ac3info >> 14) & 0x7;
801 acmod = (ac3info >> 11) & 0x7;
802 lfeon = (ac3info >> 10) & 0x1;
803 st->codecpar->channels = ((int[]){2,1,2,3,3,4,4,5})[acmod] + lfeon;
804 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
806 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
808 if (st->codecpar->channels > 1 && bsmod == 0x7)
809 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
811 #if FF_API_LAVF_AVCTX
812 FF_DISABLE_DEPRECATION_WARNINGS
813 st->codec->audio_service_type = *ast;
814 FF_ENABLE_DEPRECATION_WARNINGS
820 static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
823 enum AVAudioServiceType *ast;
824 int eac3info, acmod, lfeon, bsmod;
826 if (c->fc->nb_streams < 1)
828 st = c->fc->streams[c->fc->nb_streams-1];
830 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
833 return AVERROR(ENOMEM);
835 /* No need to parse fields for additional independent substreams and its
836 * associated dependent substreams since libavcodec's E-AC-3 decoder
837 * does not support them yet. */
838 avio_rb16(pb); /* data_rate and num_ind_sub */
839 eac3info = avio_rb24(pb);
840 bsmod = (eac3info >> 12) & 0x1f;
841 acmod = (eac3info >> 9) & 0x7;
842 lfeon = (eac3info >> 8) & 0x1;
843 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
845 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
846 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
848 if (st->codecpar->channels > 1 && bsmod == 0x7)
849 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
851 #if FF_API_LAVF_AVCTX
852 FF_DISABLE_DEPRECATION_WARNINGS
853 st->codec->audio_service_type = *ast;
854 FF_ENABLE_DEPRECATION_WARNINGS
860 static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
862 const uint32_t ddts_size = 20;
865 uint32_t frame_duration_code = 0;
866 uint32_t channel_layout_code = 0;
869 buf = av_malloc(ddts_size + AV_INPUT_BUFFER_PADDING_SIZE);
871 return AVERROR(ENOMEM);
873 if (avio_read(pb, buf, ddts_size) < ddts_size) {
875 return AVERROR_INVALIDDATA;
878 init_get_bits(&gb, buf, 8*ddts_size);
880 if (c->fc->nb_streams < 1) {
884 st = c->fc->streams[c->fc->nb_streams-1];
886 st->codecpar->sample_rate = get_bits_long(&gb, 32);
887 if (st->codecpar->sample_rate <= 0) {
888 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
890 return AVERROR_INVALIDDATA;
892 skip_bits_long(&gb, 32); /* max bitrate */
893 st->codecpar->bit_rate = get_bits_long(&gb, 32);
894 st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
895 frame_duration_code = get_bits(&gb, 2);
896 skip_bits(&gb, 30); /* various fields */
897 channel_layout_code = get_bits(&gb, 16);
899 st->codecpar->frame_size =
900 (frame_duration_code == 0) ? 512 :
901 (frame_duration_code == 1) ? 1024 :
902 (frame_duration_code == 2) ? 2048 :
903 (frame_duration_code == 3) ? 4096 : 0;
905 if (channel_layout_code > 0xff) {
906 av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout");
908 st->codecpar->channel_layout =
909 ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
910 ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
911 ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
912 ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
913 ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
914 ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0);
916 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
922 static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
926 if (c->fc->nb_streams < 1)
928 st = c->fc->streams[c->fc->nb_streams-1];
933 /* skip version and flags */
936 ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
941 static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
946 if (c->fc->nb_streams < 1)
948 st = c->fc->streams[c->fc->nb_streams-1];
950 if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
951 av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
956 static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
958 const int num = avio_rb32(pb);
959 const int den = avio_rb32(pb);
962 if (c->fc->nb_streams < 1)
964 st = c->fc->streams[c->fc->nb_streams-1];
966 if ((st->sample_aspect_ratio.den != 1 || st->sample_aspect_ratio.num) && // default
967 (den != st->sample_aspect_ratio.den || num != st->sample_aspect_ratio.num)) {
968 av_log(c->fc, AV_LOG_WARNING,
969 "sample aspect ratio already set to %d:%d, ignoring 'pasp' atom (%d:%d)\n",
970 st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
972 } else if (den != 0) {
973 av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den,
979 /* this atom contains actual media data */
980 static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
982 if (atom.size == 0) /* wrong one (MP4) */
985 return 0; /* now go for moov */
988 #define DRM_BLOB_SIZE 56
990 static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
992 uint8_t intermediate_key[20];
993 uint8_t intermediate_iv[20];
996 uint8_t file_checksum[20];
997 uint8_t calculated_checksum[20];
1001 uint8_t *activation_bytes = c->activation_bytes;
1002 uint8_t *fixed_key = c->audible_fixed_key;
1006 sha = av_sha_alloc();
1008 return AVERROR(ENOMEM);
1009 av_free(c->aes_decrypt);
1010 c->aes_decrypt = av_aes_alloc();
1011 if (!c->aes_decrypt) {
1012 ret = AVERROR(ENOMEM);
1016 /* drm blob processing */
1017 avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1018 avio_read(pb, input, DRM_BLOB_SIZE);
1019 avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1020 avio_read(pb, file_checksum, 20);
1022 av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == "); // required by external tools
1023 for (i = 0; i < 20; i++)
1024 av_log(c->fc, AV_LOG_INFO, "%02x", file_checksum[i]);
1025 av_log(c->fc, AV_LOG_INFO, "\n");
1027 /* verify activation data */
1028 if (!activation_bytes) {
1029 av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1030 ret = 0; /* allow ffprobe to continue working on .aax files */
1033 if (c->activation_bytes_size != 4) {
1034 av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1035 ret = AVERROR(EINVAL);
1039 /* verify fixed key */
1040 if (c->audible_fixed_key_size != 16) {
1041 av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1042 ret = AVERROR(EINVAL);
1046 /* AAX (and AAX+) key derivation */
1047 av_sha_init(sha, 160);
1048 av_sha_update(sha, fixed_key, 16);
1049 av_sha_update(sha, activation_bytes, 4);
1050 av_sha_final(sha, intermediate_key);
1051 av_sha_init(sha, 160);
1052 av_sha_update(sha, fixed_key, 16);
1053 av_sha_update(sha, intermediate_key, 20);
1054 av_sha_update(sha, activation_bytes, 4);
1055 av_sha_final(sha, intermediate_iv);
1056 av_sha_init(sha, 160);
1057 av_sha_update(sha, intermediate_key, 16);
1058 av_sha_update(sha, intermediate_iv, 16);
1059 av_sha_final(sha, calculated_checksum);
1060 if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1061 av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1062 ret = AVERROR_INVALIDDATA;
1065 av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1066 av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1067 for (i = 0; i < 4; i++) {
1068 // file data (in output) is stored in big-endian mode
1069 if (activation_bytes[i] != output[3 - i]) { // critical error
1070 av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1071 ret = AVERROR_INVALIDDATA;
1075 memcpy(c->file_key, output + 8, 16);
1076 memcpy(input, output + 26, 16);
1077 av_sha_init(sha, 160);
1078 av_sha_update(sha, input, 16);
1079 av_sha_update(sha, c->file_key, 16);
1080 av_sha_update(sha, fixed_key, 16);
1081 av_sha_final(sha, c->file_iv);
1089 // Audible AAX (and AAX+) bytestream decryption
1090 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1093 unsigned char iv[16];
1095 memcpy(iv, c->file_iv, 16); // iv is overwritten
1096 blocks = size >> 4; // trailing bytes are not encrypted!
1097 av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1098 av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1103 /* read major brand, minor version and compatible brands and store them as metadata */
1104 static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1107 int comp_brand_size;
1108 char* comp_brands_str;
1109 uint8_t type[5] = {0};
1110 int ret = ffio_read_size(pb, type, 4);
1114 if (strcmp(type, "qt "))
1116 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1117 av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1118 minor_ver = avio_rb32(pb); /* minor version */
1119 av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1121 comp_brand_size = atom.size - 8;
1122 if (comp_brand_size < 0)
1123 return AVERROR_INVALIDDATA;
1124 comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1125 if (!comp_brands_str)
1126 return AVERROR(ENOMEM);
1128 ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1130 av_freep(&comp_brands_str);
1133 comp_brands_str[comp_brand_size] = 0;
1134 av_dict_set(&c->fc->metadata, "compatible_brands",
1135 comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1140 /* this atom should contain all header atoms */
1141 static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1145 if (c->found_moov) {
1146 av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1147 avio_skip(pb, atom.size);
1151 if ((ret = mov_read_default(c, pb, atom)) < 0)
1153 /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1154 /* so we don't parse the whole file if over a network */
1156 return 0; /* now go for mdat */
1159 static MOVFragmentStreamInfo * get_frag_stream_info(
1160 MOVFragmentIndex *frag_index,
1165 MOVFragmentIndexItem * item;
1167 if (index < 0 || index >= frag_index->nb_items)
1169 item = &frag_index->item[index];
1170 for (i = 0; i < item->nb_stream_info; i++)
1171 if (item->stream_info[i].id == id)
1172 return &item->stream_info[i];
1174 // This shouldn't happen
1178 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1181 MOVFragmentIndexItem * item;
1183 if (frag_index->current < 0 ||
1184 frag_index->current >= frag_index->nb_items)
1187 item = &frag_index->item[frag_index->current];
1188 for (i = 0; i < item->nb_stream_info; i++)
1189 if (item->stream_info[i].id == id) {
1194 // id not found. This shouldn't happen.
1198 static MOVFragmentStreamInfo * get_current_frag_stream_info(
1199 MOVFragmentIndex *frag_index)
1201 MOVFragmentIndexItem *item;
1202 if (frag_index->current < 0 ||
1203 frag_index->current >= frag_index->nb_items)
1206 item = &frag_index->item[frag_index->current];
1207 if (item->current >= 0 && item->current < item->nb_stream_info)
1208 return &item->stream_info[item->current];
1210 // This shouldn't happen
1214 static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
1217 int64_t moof_offset;
1219 // Optimize for appending new entries
1220 if (!frag_index->nb_items ||
1221 frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1222 return frag_index->nb_items;
1225 b = frag_index->nb_items;
1229 moof_offset = frag_index->item[m].moof_offset;
1230 if (moof_offset >= offset)
1232 if (moof_offset <= offset)
1238 static int64_t get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
1240 av_assert0(frag_stream_info);
1241 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1242 return frag_stream_info->sidx_pts;
1243 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1244 return frag_stream_info->first_tfra_pts;
1245 return frag_stream_info->tfdt_dts;
1248 static int64_t get_frag_time(MOVFragmentIndex *frag_index,
1249 int index, int track_id)
1251 MOVFragmentStreamInfo * frag_stream_info;
1255 if (track_id >= 0) {
1256 frag_stream_info = get_frag_stream_info(frag_index, index, track_id);
1257 return frag_stream_info->sidx_pts;
1260 for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1261 frag_stream_info = &frag_index->item[index].stream_info[i];
1262 timestamp = get_stream_info_time(frag_stream_info);
1263 if (timestamp != AV_NOPTS_VALUE)
1266 return AV_NOPTS_VALUE;
1269 static int search_frag_timestamp(MOVFragmentIndex *frag_index,
1270 AVStream *st, int64_t timestamp)
1277 // If the stream is referenced by any sidx, limit the search
1278 // to fragments that referenced this stream in the sidx
1279 MOVStreamContext *sc = st->priv_data;
1285 b = frag_index->nb_items;
1288 m0 = m = (a + b) >> 1;
1291 (frag_time = get_frag_time(frag_index, m, id)) == AV_NOPTS_VALUE)
1294 if (m < b && frag_time <= timestamp)
1303 static int update_frag_index(MOVContext *c, int64_t offset)
1306 MOVFragmentIndexItem * item;
1307 MOVFragmentStreamInfo * frag_stream_info;
1309 // If moof_offset already exists in frag_index, return index to it
1310 index = search_frag_moof_offset(&c->frag_index, offset);
1311 if (index < c->frag_index.nb_items &&
1312 c->frag_index.item[index].moof_offset == offset)
1315 // offset is not yet in frag index.
1316 // Insert new item at index (sorted by moof offset)
1317 item = av_fast_realloc(c->frag_index.item,
1318 &c->frag_index.allocated_size,
1319 (c->frag_index.nb_items + 1) *
1320 sizeof(*c->frag_index.item));
1323 c->frag_index.item = item;
1325 frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1326 sizeof(*item->stream_info));
1327 if (!frag_stream_info)
1330 for (i = 0; i < c->fc->nb_streams; i++) {
1331 // Avoid building frag index if streams lack track id.
1332 if (c->fc->streams[i]->id < 0) {
1333 av_free(frag_stream_info);
1334 return AVERROR_INVALIDDATA;
1337 frag_stream_info[i].id = c->fc->streams[i]->id;
1338 frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1339 frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1340 frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1341 frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1342 frag_stream_info[i].index_entry = -1;
1343 frag_stream_info[i].encryption_index = NULL;
1346 if (index < c->frag_index.nb_items)
1347 memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1348 (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1350 item = &c->frag_index.item[index];
1351 item->headers_read = 0;
1353 item->nb_stream_info = c->fc->nb_streams;
1354 item->moof_offset = offset;
1355 item->stream_info = frag_stream_info;
1356 c->frag_index.nb_items++;
1361 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1362 int id, int entries)
1365 MOVFragmentStreamInfo * frag_stream_info;
1369 for (i = index; i < frag_index->nb_items; i++) {
1370 frag_stream_info = get_frag_stream_info(frag_index, i, id);
1371 if (frag_stream_info && frag_stream_info->index_entry >= 0)
1372 frag_stream_info->index_entry += entries;
1376 static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1378 // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1379 c->fragment.found_tfhd = 0;
1381 if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1382 c->has_looked_for_mfra = 1;
1383 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1385 av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1387 if ((ret = mov_read_mfra(c, pb)) < 0) {
1388 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1389 "read the mfra (may be a live ismv)\n");
1392 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1393 "seekable, can not look for mfra\n");
1396 c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1397 av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1398 c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1399 return mov_read_default(c, pb, atom);
1402 static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time, void *logctx)
1405 if(time >= 2082844800)
1406 time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1408 if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1409 av_log(logctx, AV_LOG_DEBUG, "creation_time is not representable\n");
1413 avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1417 static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1420 MOVStreamContext *sc;
1422 char language[4] = {0};
1424 int64_t creation_time;
1426 if (c->fc->nb_streams < 1)
1428 st = c->fc->streams[c->fc->nb_streams-1];
1431 if (sc->time_scale) {
1432 av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1433 return AVERROR_INVALIDDATA;
1436 version = avio_r8(pb);
1438 avpriv_request_sample(c->fc, "Version %d", version);
1439 return AVERROR_PATCHWELCOME;
1441 avio_rb24(pb); /* flags */
1443 creation_time = avio_rb64(pb);
1446 creation_time = avio_rb32(pb);
1447 avio_rb32(pb); /* modification time */
1449 mov_metadata_creation_time(&st->metadata, creation_time, c->fc);
1451 sc->time_scale = avio_rb32(pb);
1452 if (sc->time_scale <= 0) {
1453 av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1456 st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1458 lang = avio_rb16(pb); /* language */
1459 if (ff_mov_lang_to_iso639(lang, language))
1460 av_dict_set(&st->metadata, "language", language, 0);
1461 avio_rb16(pb); /* quality */
1466 static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1469 int64_t creation_time;
1470 int version = avio_r8(pb); /* version */
1471 avio_rb24(pb); /* flags */
1474 creation_time = avio_rb64(pb);
1477 creation_time = avio_rb32(pb);
1478 avio_rb32(pb); /* modification time */
1480 mov_metadata_creation_time(&c->fc->metadata, creation_time, c->fc);
1481 c->time_scale = avio_rb32(pb); /* time scale */
1482 if (c->time_scale <= 0) {
1483 av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1486 av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1488 c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1489 // set the AVCodecContext duration because the duration of individual tracks
1490 // may be inaccurate
1491 if (c->time_scale > 0 && !c->trex_data)
1492 c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale);
1493 avio_rb32(pb); /* preferred scale */
1495 avio_rb16(pb); /* preferred volume */
1497 avio_skip(pb, 10); /* reserved */
1499 /* movie display matrix, store it in main context and use it later on */
1500 for (i = 0; i < 3; i++) {
1501 c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1502 c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1503 c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1506 avio_rb32(pb); /* preview time */
1507 avio_rb32(pb); /* preview duration */
1508 avio_rb32(pb); /* poster time */
1509 avio_rb32(pb); /* selection time */
1510 avio_rb32(pb); /* selection duration */
1511 avio_rb32(pb); /* current time */
1512 avio_rb32(pb); /* next track ID */
1517 static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1522 if (c->fc->nb_streams < 1)
1524 st = c->fc->streams[c->fc->nb_streams-1];
1526 little_endian = avio_rb16(pb) & 0xFF;
1527 av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1528 if (little_endian == 1) {
1529 switch (st->codecpar->codec_id) {
1530 case AV_CODEC_ID_PCM_S24BE:
1531 st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE;
1533 case AV_CODEC_ID_PCM_S32BE:
1534 st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE;
1536 case AV_CODEC_ID_PCM_F32BE:
1537 st->codecpar->codec_id = AV_CODEC_ID_PCM_F32LE;
1539 case AV_CODEC_ID_PCM_F64BE:
1540 st->codecpar->codec_id = AV_CODEC_ID_PCM_F64LE;
1549 static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1552 uint8_t *icc_profile;
1553 char color_parameter_type[5] = { 0 };
1554 uint16_t color_primaries, color_trc, color_matrix;
1557 if (c->fc->nb_streams < 1)
1559 st = c->fc->streams[c->fc->nb_streams - 1];
1561 ret = ffio_read_size(pb, color_parameter_type, 4);
1564 if (strncmp(color_parameter_type, "nclx", 4) &&
1565 strncmp(color_parameter_type, "nclc", 4) &&
1566 strncmp(color_parameter_type, "prof", 4)) {
1567 av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
1568 color_parameter_type);
1572 if (!strncmp(color_parameter_type, "prof", 4)) {
1573 icc_profile = av_stream_new_side_data(st, AV_PKT_DATA_ICC_PROFILE, atom.size - 4);
1575 return AVERROR(ENOMEM);
1576 ret = ffio_read_size(pb, icc_profile, atom.size - 4);
1581 color_primaries = avio_rb16(pb);
1582 color_trc = avio_rb16(pb);
1583 color_matrix = avio_rb16(pb);
1585 av_log(c->fc, AV_LOG_TRACE,
1586 "%s: pri %d trc %d matrix %d",
1587 color_parameter_type, color_primaries, color_trc, color_matrix);
1589 if (!strncmp(color_parameter_type, "nclx", 4)) {
1590 uint8_t color_range = avio_r8(pb) >> 7;
1591 av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
1593 st->codecpar->color_range = AVCOL_RANGE_JPEG;
1595 st->codecpar->color_range = AVCOL_RANGE_MPEG;
1598 if (!av_color_primaries_name(color_primaries))
1599 color_primaries = AVCOL_PRI_UNSPECIFIED;
1600 if (!av_color_transfer_name(color_trc))
1601 color_trc = AVCOL_TRC_UNSPECIFIED;
1602 if (!av_color_space_name(color_matrix))
1603 color_matrix = AVCOL_SPC_UNSPECIFIED;
1605 st->codecpar->color_primaries = color_primaries;
1606 st->codecpar->color_trc = color_trc;
1607 st->codecpar->color_space = color_matrix;
1608 av_log(c->fc, AV_LOG_TRACE, "\n");
1613 static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1616 unsigned mov_field_order;
1617 enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
1619 if (c->fc->nb_streams < 1) // will happen with jp2 files
1621 st = c->fc->streams[c->fc->nb_streams-1];
1623 return AVERROR_INVALIDDATA;
1624 mov_field_order = avio_rb16(pb);
1625 if ((mov_field_order & 0xFF00) == 0x0100)
1626 decoded_field_order = AV_FIELD_PROGRESSIVE;
1627 else if ((mov_field_order & 0xFF00) == 0x0200) {
1628 switch (mov_field_order & 0xFF) {
1629 case 0x01: decoded_field_order = AV_FIELD_TT;
1631 case 0x06: decoded_field_order = AV_FIELD_BB;
1633 case 0x09: decoded_field_order = AV_FIELD_TB;
1635 case 0x0E: decoded_field_order = AV_FIELD_BT;
1639 if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
1640 av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
1642 st->codecpar->field_order = decoded_field_order;
1647 static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
1650 uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
1651 if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
1652 return AVERROR_INVALIDDATA;
1653 if ((err = av_reallocp(&par->extradata, size)) < 0) {
1654 par->extradata_size = 0;
1657 par->extradata_size = size - AV_INPUT_BUFFER_PADDING_SIZE;
1661 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
1662 static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1663 AVCodecParameters *par, uint8_t *buf)
1665 int64_t result = atom.size;
1668 AV_WB32(buf , atom.size + 8);
1669 AV_WL32(buf + 4, atom.type);
1670 err = ffio_read_size(pb, buf + 8, atom.size);
1672 par->extradata_size -= atom.size;
1674 } else if (err < atom.size) {
1675 av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
1676 par->extradata_size -= atom.size - err;
1679 memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1683 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
1684 static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1685 enum AVCodecID codec_id)
1688 uint64_t original_size;
1691 if (c->fc->nb_streams < 1) // will happen with jp2 files
1693 st = c->fc->streams[c->fc->nb_streams-1];
1695 if (st->codecpar->codec_id != codec_id)
1696 return 0; /* unexpected codec_id - don't mess with extradata */
1698 original_size = st->codecpar->extradata_size;
1699 err = mov_realloc_extradata(st->codecpar, atom);
1703 err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
1706 return 0; // Note: this is the original behavior to ignore truncation.
1709 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
1710 static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1712 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
1715 static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1717 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS);
1720 static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1722 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
1725 static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1727 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
1730 static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1732 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
1734 ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
1738 static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1740 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
1742 if (!ret && c->fc->nb_streams >= 1) {
1743 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1744 if (par->extradata_size >= 40) {
1745 par->height = AV_RB16(&par->extradata[36]);
1746 par->width = AV_RB16(&par->extradata[38]);
1752 static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1754 if (c->fc->nb_streams >= 1) {
1755 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1756 if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
1757 par->codec_id == AV_CODEC_ID_H264 &&
1761 cid = avio_rb16(pb);
1762 /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
1763 if (cid == 0xd4d || cid == 0xd4e)
1766 } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
1767 par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
1768 par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
1772 num = avio_rb32(pb);
1773 den = avio_rb32(pb);
1774 if (num <= 0 || den <= 0)
1776 switch (avio_rb32(pb)) {
1778 if (den >= INT_MAX / 2)
1782 c->fc->streams[c->fc->nb_streams-1]->display_aspect_ratio.num = num;
1783 c->fc->streams[c->fc->nb_streams-1]->display_aspect_ratio.den = den;
1790 return mov_read_avid(c, pb, atom);
1793 static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1797 uint64_t original_size;
1798 if (c->fc->nb_streams >= 1) {
1799 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1800 if (par->codec_id == AV_CODEC_ID_H264)
1802 if (atom.size == 16) {
1803 original_size = par->extradata_size;
1804 ret = mov_realloc_extradata(par, atom);
1806 length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
1807 if (length == atom.size) {
1808 const uint8_t range_value = par->extradata[original_size + 19];
1809 switch (range_value) {
1811 par->color_range = AVCOL_RANGE_MPEG;
1814 par->color_range = AVCOL_RANGE_JPEG;
1817 av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
1820 ff_dlog(c->fc, "color_range: %d\n", par->color_range);
1822 /* For some reason the whole atom was not added to the extradata */
1823 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
1826 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
1829 av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
1836 static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1838 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
1841 static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1846 if (c->fc->nb_streams < 1)
1848 st = c->fc->streams[c->fc->nb_streams-1];
1850 if ((uint64_t)atom.size > (1<<30))
1851 return AVERROR_INVALIDDATA;
1853 if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
1854 st->codecpar->codec_id == AV_CODEC_ID_QDMC ||
1855 st->codecpar->codec_id == AV_CODEC_ID_SPEEX) {
1856 // pass all frma atom to codec, needed at least for QDMC and QDM2
1857 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1860 } else if (atom.size > 8) { /* to read frma, esds atoms */
1861 if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
1863 ret = ffio_ensure_seekback(pb, 8);
1866 buffer = avio_rb64(pb);
1868 if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
1869 && buffer >> 32 <= atom.size
1870 && buffer >> 32 >= 8) {
1873 } else if (!st->codecpar->extradata_size) {
1874 #define ALAC_EXTRADATA_SIZE 36
1875 st->codecpar->extradata = av_mallocz(ALAC_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
1876 if (!st->codecpar->extradata)
1877 return AVERROR(ENOMEM);
1878 st->codecpar->extradata_size = ALAC_EXTRADATA_SIZE;
1879 AV_WB32(st->codecpar->extradata , ALAC_EXTRADATA_SIZE);
1880 AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
1881 AV_WB64(st->codecpar->extradata + 12, buffer);
1882 avio_read(pb, st->codecpar->extradata + 20, 16);
1883 avio_skip(pb, atom.size - 24);
1887 if ((ret = mov_read_default(c, pb, atom)) < 0)
1890 avio_skip(pb, atom.size);
1895 * This function reads atom content and puts data in extradata without tag
1896 * nor size unlike mov_read_extradata.
1898 static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1903 if (c->fc->nb_streams < 1)
1905 st = c->fc->streams[c->fc->nb_streams-1];
1907 if ((uint64_t)atom.size > (1<<30))
1908 return AVERROR_INVALIDDATA;
1910 if (atom.size >= 10) {
1911 // Broken files created by legacy versions of libavformat will
1912 // wrap a whole fiel atom inside of a glbl atom.
1913 unsigned size = avio_rb32(pb);
1914 unsigned type = avio_rl32(pb);
1915 avio_seek(pb, -8, SEEK_CUR);
1916 if (type == MKTAG('f','i','e','l') && size == atom.size)
1917 return mov_read_default(c, pb, atom);
1919 if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
1920 av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
1923 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1926 if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
1927 /* HEVC-based Dolby Vision derived from hvc1.
1928 Happens to match with an identifier
1929 previously utilized for DV. Thus, if we have
1930 the hvcC extradata box available as specified,
1931 set codec to HEVC */
1932 st->codecpar->codec_id = AV_CODEC_ID_HEVC;
1937 static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1940 uint8_t profile_level;
1943 if (c->fc->nb_streams < 1)
1945 st = c->fc->streams[c->fc->nb_streams-1];
1947 if (atom.size >= (1<<28) || atom.size < 7)
1948 return AVERROR_INVALIDDATA;
1950 profile_level = avio_r8(pb);
1951 if ((profile_level & 0xf0) != 0xc0)
1954 avio_seek(pb, 6, SEEK_CUR);
1955 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
1963 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
1964 * but can have extradata appended at the end after the 40 bytes belonging
1967 static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1972 if (c->fc->nb_streams < 1)
1974 if (atom.size <= 40)
1976 st = c->fc->streams[c->fc->nb_streams-1];
1978 if ((uint64_t)atom.size > (1<<30))
1979 return AVERROR_INVALIDDATA;
1982 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
1989 static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1992 MOVStreamContext *sc;
1993 unsigned int i, entries;
1995 if (c->trak_index < 0) {
1996 av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
1999 if (c->fc->nb_streams < 1)
2001 st = c->fc->streams[c->fc->nb_streams-1];
2004 avio_r8(pb); /* version */
2005 avio_rb24(pb); /* flags */
2007 entries = avio_rb32(pb);
2012 if (sc->chunk_offsets)
2013 av_log(c->fc, AV_LOG_WARNING, "Duplicated STCO atom\n");
2014 av_free(sc->chunk_offsets);
2015 sc->chunk_count = 0;
2016 sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2017 if (!sc->chunk_offsets)
2018 return AVERROR(ENOMEM);
2019 sc->chunk_count = entries;
2021 if (atom.type == MKTAG('s','t','c','o'))
2022 for (i = 0; i < entries && !pb->eof_reached; i++)
2023 sc->chunk_offsets[i] = avio_rb32(pb);
2024 else if (atom.type == MKTAG('c','o','6','4'))
2025 for (i = 0; i < entries && !pb->eof_reached; i++)
2026 sc->chunk_offsets[i] = avio_rb64(pb);
2028 return AVERROR_INVALIDDATA;
2030 sc->chunk_count = i;
2032 if (pb->eof_reached) {
2033 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2040 static int mov_codec_id(AVStream *st, uint32_t format)
2042 int id = ff_codec_get_id(ff_codec_movaudio_tags, format);
2045 ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2046 (format & 0xFFFF) == 'T' + ('S' << 8)))
2047 id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format) & 0xFFFF);
2049 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2050 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2051 } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2052 /* skip old ASF MPEG-4 tag */
2053 format && format != MKTAG('m','p','4','s')) {
2054 id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2056 id = ff_codec_get_id(ff_codec_bmp_tags, format);
2058 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
2059 else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2060 (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE &&
2061 st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2062 id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
2064 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
2066 id = ff_codec_get_id(ff_codec_movdata_tags, format);
2070 st->codecpar->codec_tag = format;
2075 static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
2076 AVStream *st, MOVStreamContext *sc)
2078 uint8_t codec_name[32] = { 0 };
2082 /* The first 16 bytes of the video sample description are already
2083 * read in ff_mov_read_stsd_entries() */
2084 stsd_start = avio_tell(pb) - 16;
2086 avio_rb16(pb); /* version */
2087 avio_rb16(pb); /* revision level */
2088 avio_rb32(pb); /* vendor */
2089 avio_rb32(pb); /* temporal quality */
2090 avio_rb32(pb); /* spatial quality */
2092 st->codecpar->width = avio_rb16(pb); /* width */
2093 st->codecpar->height = avio_rb16(pb); /* height */
2095 avio_rb32(pb); /* horiz resolution */
2096 avio_rb32(pb); /* vert resolution */
2097 avio_rb32(pb); /* data size, always 0 */
2098 avio_rb16(pb); /* frames per samples */
2100 len = avio_r8(pb); /* codec name, pascal string */
2103 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2105 avio_skip(pb, 31 - len);
2108 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2110 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2111 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2112 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2113 st->codecpar->width &= ~1;
2114 st->codecpar->height &= ~1;
2116 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2117 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2118 !strncmp(codec_name, "Sorenson H263", 13))
2119 st->codecpar->codec_id = AV_CODEC_ID_FLV1;
2121 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2123 avio_seek(pb, stsd_start, SEEK_SET);
2125 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2126 st->codecpar->bits_per_coded_sample &= 0x1F;
2127 sc->has_palette = 1;
2131 static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
2132 AVStream *st, MOVStreamContext *sc)
2134 int bits_per_sample, flags;
2135 uint16_t version = avio_rb16(pb);
2136 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2138 avio_rb16(pb); /* revision level */
2139 avio_rb32(pb); /* vendor */
2141 st->codecpar->channels = avio_rb16(pb); /* channel count */
2142 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2143 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", st->codecpar->channels);
2145 sc->audio_cid = avio_rb16(pb);
2146 avio_rb16(pb); /* packet size = 0 */
2148 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2150 // Read QT version 1 fields. In version 0 these do not exist.
2151 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2153 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2154 (sc->stsd_version == 0 && version > 0)) {
2156 sc->samples_per_frame = avio_rb32(pb);
2157 avio_rb32(pb); /* bytes per packet */
2158 sc->bytes_per_frame = avio_rb32(pb);
2159 avio_rb32(pb); /* bytes per sample */
2160 } else if (version == 2) {
2161 avio_rb32(pb); /* sizeof struct only */
2162 st->codecpar->sample_rate = av_int2double(avio_rb64(pb));
2163 st->codecpar->channels = avio_rb32(pb);
2164 avio_rb32(pb); /* always 0x7F000000 */
2165 st->codecpar->bits_per_coded_sample = avio_rb32(pb);
2167 flags = avio_rb32(pb); /* lpcm format specific flag */
2168 sc->bytes_per_frame = avio_rb32(pb);
2169 sc->samples_per_frame = avio_rb32(pb);
2170 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2171 st->codecpar->codec_id =
2172 ff_mov_get_lpcm_codec_id(st->codecpar->bits_per_coded_sample,
2175 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2176 /* can't correctly handle variable sized packet as audio unit */
2177 switch (st->codecpar->codec_id) {
2178 case AV_CODEC_ID_MP2:
2179 case AV_CODEC_ID_MP3:
2180 st->need_parsing = AVSTREAM_PARSE_FULL;
2186 if (sc->format == 0) {
2187 if (st->codecpar->bits_per_coded_sample == 8)
2188 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2189 else if (st->codecpar->bits_per_coded_sample == 16)
2190 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2193 switch (st->codecpar->codec_id) {
2194 case AV_CODEC_ID_PCM_S8:
2195 case AV_CODEC_ID_PCM_U8:
2196 if (st->codecpar->bits_per_coded_sample == 16)
2197 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16BE;
2199 case AV_CODEC_ID_PCM_S16LE:
2200 case AV_CODEC_ID_PCM_S16BE:
2201 if (st->codecpar->bits_per_coded_sample == 8)
2202 st->codecpar->codec_id = AV_CODEC_ID_PCM_S8;
2203 else if (st->codecpar->bits_per_coded_sample == 24)
2204 st->codecpar->codec_id =
2205 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2206 AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
2207 else if (st->codecpar->bits_per_coded_sample == 32)
2208 st->codecpar->codec_id =
2209 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2210 AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
2212 /* set values for old format before stsd version 1 appeared */
2213 case AV_CODEC_ID_MACE3:
2214 sc->samples_per_frame = 6;
2215 sc->bytes_per_frame = 2 * st->codecpar->channels;
2217 case AV_CODEC_ID_MACE6:
2218 sc->samples_per_frame = 6;
2219 sc->bytes_per_frame = 1 * st->codecpar->channels;
2221 case AV_CODEC_ID_ADPCM_IMA_QT:
2222 sc->samples_per_frame = 64;
2223 sc->bytes_per_frame = 34 * st->codecpar->channels;
2225 case AV_CODEC_ID_GSM:
2226 sc->samples_per_frame = 160;
2227 sc->bytes_per_frame = 33;
2233 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2234 if (bits_per_sample) {
2235 st->codecpar->bits_per_coded_sample = bits_per_sample;
2236 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->channels;
2240 static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
2241 AVStream *st, MOVStreamContext *sc,
2244 // ttxt stsd contains display flags, justification, background
2245 // color, fonts, and default styles, so fake an atom to read it
2246 MOVAtom fake_atom = { .size = size };
2247 // mp4s contains a regular esds atom
2248 if (st->codecpar->codec_tag != AV_RL32("mp4s"))
2249 mov_read_glbl(c, pb, fake_atom);
2250 st->codecpar->width = sc->width;
2251 st->codecpar->height = sc->height;
2254 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2259 y = (ycbcr >> 16) & 0xFF;
2260 cr = (ycbcr >> 8) & 0xFF;
2263 b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
2264 g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
2265 r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
2267 return (r << 16) | (g << 8) | b;
2270 static int mov_rewrite_dvd_sub_extradata(AVStream *st)
2272 char buf[256] = {0};
2273 uint8_t *src = st->codecpar->extradata;
2276 if (st->codecpar->extradata_size != 64)
2279 if (st->codecpar->width > 0 && st->codecpar->height > 0)
2280 snprintf(buf, sizeof(buf), "size: %dx%d\n",
2281 st->codecpar->width, st->codecpar->height);
2282 av_strlcat(buf, "palette: ", sizeof(buf));
2284 for (i = 0; i < 16; i++) {
2285 uint32_t yuv = AV_RB32(src + i * 4);
2286 uint32_t rgba = yuv_to_rgba(yuv);
2288 av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2291 if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2294 ret = ff_alloc_extradata(st->codecpar, strlen(buf));
2297 memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2302 static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
2303 AVStream *st, MOVStreamContext *sc,
2308 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2309 if ((int)size != size)
2310 return AVERROR(ENOMEM);
2312 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2316 MOVStreamContext *tmcd_ctx = st->priv_data;
2318 val = AV_RB32(st->codecpar->extradata + 4);
2319 tmcd_ctx->tmcd_flags = val;
2320 st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2321 st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2322 #if FF_API_LAVF_AVCTX
2323 FF_DISABLE_DEPRECATION_WARNINGS
2324 st->codec->time_base = av_inv_q(st->avg_frame_rate);
2325 FF_ENABLE_DEPRECATION_WARNINGS
2327 /* adjust for per frame dur in counter mode */
2328 if (tmcd_ctx->tmcd_flags & 0x0008) {
2329 int timescale = AV_RB32(st->codecpar->extradata + 8);
2330 int framedur = AV_RB32(st->codecpar->extradata + 12);
2331 st->avg_frame_rate.num *= timescale;
2332 st->avg_frame_rate.den *= framedur;
2333 #if FF_API_LAVF_AVCTX
2334 FF_DISABLE_DEPRECATION_WARNINGS
2335 st->codec->time_base.den *= timescale;
2336 st->codec->time_base.num *= framedur;
2337 FF_ENABLE_DEPRECATION_WARNINGS
2341 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2342 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2343 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2344 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2345 if (str_size > 0 && size >= (int)str_size + 26) {
2346 char *reel_name = av_malloc(str_size + 1);
2348 return AVERROR(ENOMEM);
2349 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2350 reel_name[str_size] = 0; /* Add null terminator */
2351 /* don't add reel_name if emtpy string */
2352 if (*reel_name == 0) {
2355 av_dict_set(&st->metadata, "reel_name", reel_name, AV_DICT_DONT_STRDUP_VAL);
2362 /* other codec type, just skip (rtp, mp4s ...) */
2363 avio_skip(pb, size);
2368 static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
2369 AVStream *st, MOVStreamContext *sc)
2371 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2372 !st->codecpar->sample_rate && sc->time_scale > 1)
2373 st->codecpar->sample_rate = sc->time_scale;
2375 /* special codec parameters handling */
2376 switch (st->codecpar->codec_id) {
2377 #if CONFIG_DV_DEMUXER
2378 case AV_CODEC_ID_DVAUDIO:
2379 c->dv_fctx = avformat_alloc_context();
2381 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2382 return AVERROR(ENOMEM);
2384 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2386 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2387 return AVERROR(ENOMEM);
2389 sc->dv_audio_container = 1;
2390 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
2393 /* no ifdef since parameters are always those */
2394 case AV_CODEC_ID_QCELP:
2395 st->codecpar->channels = 1;
2396 // force sample rate for qcelp when not stored in mov
2397 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2398 st->codecpar->sample_rate = 8000;
2399 // FIXME: Why is the following needed for some files?
2400 sc->samples_per_frame = 160;
2401 if (!sc->bytes_per_frame)
2402 sc->bytes_per_frame = 35;
2404 case AV_CODEC_ID_AMR_NB:
2405 st->codecpar->channels = 1;
2406 /* force sample rate for amr, stsd in 3gp does not store sample rate */
2407 st->codecpar->sample_rate = 8000;
2409 case AV_CODEC_ID_AMR_WB:
2410 st->codecpar->channels = 1;
2411 st->codecpar->sample_rate = 16000;
2413 case AV_CODEC_ID_MP2:
2414 case AV_CODEC_ID_MP3:
2415 /* force type after stsd for m1a hdlr */
2416 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2418 case AV_CODEC_ID_GSM:
2419 case AV_CODEC_ID_ADPCM_MS:
2420 case AV_CODEC_ID_ADPCM_IMA_WAV:
2421 case AV_CODEC_ID_ILBC:
2422 case AV_CODEC_ID_MACE3:
2423 case AV_CODEC_ID_MACE6:
2424 case AV_CODEC_ID_QDM2:
2425 st->codecpar->block_align = sc->bytes_per_frame;
2427 case AV_CODEC_ID_ALAC:
2428 if (st->codecpar->extradata_size == 36) {
2429 st->codecpar->channels = AV_RB8 (st->codecpar->extradata + 21);
2430 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2433 case AV_CODEC_ID_AC3:
2434 case AV_CODEC_ID_EAC3:
2435 case AV_CODEC_ID_MPEG1VIDEO:
2436 case AV_CODEC_ID_VC1:
2437 case AV_CODEC_ID_VP8:
2438 case AV_CODEC_ID_VP9:
2439 st->need_parsing = AVSTREAM_PARSE_FULL;
2447 static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
2448 int codec_tag, int format,
2451 int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2454 (codec_tag != format &&
2455 // AVID 1:1 samples with differing data format and codec tag exist
2456 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
2457 // prores is allowed to have differing data format and codec tag
2458 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
2460 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
2461 (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id
2462 : codec_tag != MKTAG('j','p','e','g')))) {
2463 /* Multiple fourcc, we skip JPEG. This is not correct, we should
2464 * export it as a separate AVStream but this needs a few changes
2465 * in the MOV demuxer, patch welcome. */
2467 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
2468 avio_skip(pb, size);
2475 int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
2478 MOVStreamContext *sc;
2479 int pseudo_stream_id;
2481 av_assert0 (c->fc->nb_streams >= 1);
2482 st = c->fc->streams[c->fc->nb_streams-1];
2485 for (pseudo_stream_id = 0;
2486 pseudo_stream_id < entries && !pb->eof_reached;
2487 pseudo_stream_id++) {
2488 //Parsing Sample description table
2490 int ret, dref_id = 1;
2491 MOVAtom a = { AV_RL32("stsd") };
2492 int64_t start_pos = avio_tell(pb);
2493 int64_t size = avio_rb32(pb); /* size */
2494 uint32_t format = avio_rl32(pb); /* data format */
2497 avio_rb32(pb); /* reserved */
2498 avio_rb16(pb); /* reserved */
2499 dref_id = avio_rb16(pb);
2500 } else if (size <= 7) {
2501 av_log(c->fc, AV_LOG_ERROR,
2502 "invalid size %"PRId64" in stsd\n", size);
2503 return AVERROR_INVALIDDATA;
2506 if (mov_skip_multiple_stsd(c, pb, st->codecpar->codec_tag, format,
2507 size - (avio_tell(pb) - start_pos))) {
2512 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
2513 sc->dref_id= dref_id;
2514 sc->format = format;
2516 id = mov_codec_id(st, format);
2518 av_log(c->fc, AV_LOG_TRACE,
2519 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
2520 av_fourcc2str(format), st->codecpar->codec_type);
2522 st->codecpar->codec_id = id;
2523 if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) {
2524 mov_parse_stsd_video(c, pb, st, sc);
2525 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
2526 mov_parse_stsd_audio(c, pb, st, sc);
2527 if (st->codecpar->sample_rate < 0) {
2528 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
2529 return AVERROR_INVALIDDATA;
2531 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
2532 mov_parse_stsd_subtitle(c, pb, st, sc,
2533 size - (avio_tell(pb) - start_pos));
2535 ret = mov_parse_stsd_data(c, pb, st, sc,
2536 size - (avio_tell(pb) - start_pos));
2540 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
2541 a.size = size - (avio_tell(pb) - start_pos);
2543 if ((ret = mov_read_default(c, pb, a)) < 0)
2545 } else if (a.size > 0)
2546 avio_skip(pb, a.size);
2548 if (sc->extradata && st->codecpar->extradata) {
2549 int extra_size = st->codecpar->extradata_size;
2551 /* Move the current stream extradata to the stream context one. */
2552 sc->extradata_size[pseudo_stream_id] = extra_size;
2553 sc->extradata[pseudo_stream_id] = av_malloc(extra_size + AV_INPUT_BUFFER_PADDING_SIZE);
2554 if (!sc->extradata[pseudo_stream_id])
2555 return AVERROR(ENOMEM);
2556 memcpy(sc->extradata[pseudo_stream_id], st->codecpar->extradata, extra_size);
2557 av_freep(&st->codecpar->extradata);
2558 st->codecpar->extradata_size = 0;
2563 if (pb->eof_reached) {
2564 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
2571 static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2574 MOVStreamContext *sc;
2577 if (c->fc->nb_streams < 1)
2579 st = c->fc->streams[c->fc->nb_streams - 1];
2582 sc->stsd_version = avio_r8(pb);
2583 avio_rb24(pb); /* flags */
2584 entries = avio_rb32(pb);
2586 /* Each entry contains a size (4 bytes) and format (4 bytes). */
2587 if (entries <= 0 || entries > atom.size / 8) {
2588 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
2589 return AVERROR_INVALIDDATA;
2592 if (sc->extradata) {
2593 av_log(c->fc, AV_LOG_ERROR,
2594 "Duplicate stsd found in this track.\n");
2595 return AVERROR_INVALIDDATA;
2598 /* Prepare space for hosting multiple extradata. */
2599 sc->extradata = av_mallocz_array(entries, sizeof(*sc->extradata));
2601 return AVERROR(ENOMEM);
2603 sc->extradata_size = av_mallocz_array(entries, sizeof(*sc->extradata_size));
2604 if (!sc->extradata_size) {
2605 ret = AVERROR(ENOMEM);
2609 ret = ff_mov_read_stsd_entries(c, pb, entries);
2613 /* Restore back the primary extradata. */
2614 av_freep(&st->codecpar->extradata);
2615 st->codecpar->extradata_size = sc->extradata_size[0];
2616 if (sc->extradata_size[0]) {
2617 st->codecpar->extradata = av_mallocz(sc->extradata_size[0] + AV_INPUT_BUFFER_PADDING_SIZE);
2618 if (!st->codecpar->extradata)
2619 return AVERROR(ENOMEM);
2620 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
2623 return mov_finalize_stsd_codec(c, pb, st, sc);
2625 if (sc->extradata) {
2627 for (j = 0; j < sc->stsd_count; j++)
2628 av_freep(&sc->extradata[j]);
2631 av_freep(&sc->extradata);
2632 av_freep(&sc->extradata_size);
2636 static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2639 MOVStreamContext *sc;
2640 unsigned int i, entries;
2642 if (c->fc->nb_streams < 1)
2644 st = c->fc->streams[c->fc->nb_streams-1];
2647 avio_r8(pb); /* version */
2648 avio_rb24(pb); /* flags */
2650 entries = avio_rb32(pb);
2651 if ((uint64_t)entries * 12 + 4 > atom.size)
2652 return AVERROR_INVALIDDATA;
2654 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
2659 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSC atom\n");
2660 av_free(sc->stsc_data);
2662 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
2664 return AVERROR(ENOMEM);
2666 for (i = 0; i < entries && !pb->eof_reached; i++) {
2667 sc->stsc_data[i].first = avio_rb32(pb);
2668 sc->stsc_data[i].count = avio_rb32(pb);
2669 sc->stsc_data[i].id = avio_rb32(pb);
2673 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
2674 int64_t first_min = i + 1;
2675 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
2676 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
2677 sc->stsc_data[i].first < first_min ||
2678 sc->stsc_data[i].count < 1 ||
2679 sc->stsc_data[i].id < 1) {
2680 av_log(c->fc, AV_LOG_WARNING, "STSC entry %d is invalid (first=%d count=%d id=%d)\n", i, sc->stsc_data[i].first, sc->stsc_data[i].count, sc->stsc_data[i].id);
2681 if (i+1 >= sc->stsc_count) {
2682 if (sc->stsc_data[i].count == 0 && i > 0) {
2686 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
2687 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
2688 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
2689 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
2690 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
2693 av_assert0(sc->stsc_data[i+1].first >= 2);
2694 // We replace this entry by the next valid
2695 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
2696 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
2697 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
2701 if (pb->eof_reached) {
2702 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
2709 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
2711 return index < count - 1;
2714 /* Compute the samples value for the stsc entry at the given index. */
2715 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
2719 if (mov_stsc_index_valid(index, sc->stsc_count))
2720 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
2722 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
2723 av_assert0(sc->stsc_data[index].first <= sc->chunk_count);
2724 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
2727 return sc->stsc_data[index].count * (int64_t)chunk_count;
2730 static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2733 MOVStreamContext *sc;
2734 unsigned i, entries;
2736 if (c->fc->nb_streams < 1)
2738 st = c->fc->streams[c->fc->nb_streams-1];
2741 avio_rb32(pb); // version + flags
2743 entries = avio_rb32(pb);
2745 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
2746 av_free(sc->stps_data);
2748 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
2750 return AVERROR(ENOMEM);
2752 for (i = 0; i < entries && !pb->eof_reached; i++) {
2753 sc->stps_data[i] = avio_rb32(pb);
2758 if (pb->eof_reached) {
2759 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
2766 static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2769 MOVStreamContext *sc;
2770 unsigned int i, entries;
2772 if (c->fc->nb_streams < 1)
2774 st = c->fc->streams[c->fc->nb_streams-1];
2777 avio_r8(pb); /* version */
2778 avio_rb24(pb); /* flags */
2780 entries = avio_rb32(pb);
2782 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
2786 sc->keyframe_absent = 1;
2787 if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
2788 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2792 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
2793 if (entries >= UINT_MAX / sizeof(int))
2794 return AVERROR_INVALIDDATA;
2795 av_freep(&sc->keyframes);
2796 sc->keyframe_count = 0;
2797 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
2799 return AVERROR(ENOMEM);
2801 for (i = 0; i < entries && !pb->eof_reached; i++) {
2802 sc->keyframes[i] = avio_rb32(pb);
2805 sc->keyframe_count = i;
2807 if (pb->eof_reached) {
2808 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
2815 static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2818 MOVStreamContext *sc;
2819 unsigned int i, entries, sample_size, field_size, num_bytes;
2824 if (c->fc->nb_streams < 1)
2826 st = c->fc->streams[c->fc->nb_streams-1];
2829 avio_r8(pb); /* version */
2830 avio_rb24(pb); /* flags */
2832 if (atom.type == MKTAG('s','t','s','z')) {
2833 sample_size = avio_rb32(pb);
2834 if (!sc->sample_size) /* do not overwrite value computed in stsd */
2835 sc->sample_size = sample_size;
2836 sc->stsz_sample_size = sample_size;
2840 avio_rb24(pb); /* reserved */
2841 field_size = avio_r8(pb);
2843 entries = avio_rb32(pb);
2845 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
2847 sc->sample_count = entries;
2851 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
2852 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
2853 return AVERROR_INVALIDDATA;
2858 if (entries >= (UINT_MAX - 4) / field_size)
2859 return AVERROR_INVALIDDATA;
2860 if (sc->sample_sizes)
2861 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
2862 av_free(sc->sample_sizes);
2863 sc->sample_count = 0;
2864 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
2865 if (!sc->sample_sizes)
2866 return AVERROR(ENOMEM);
2868 num_bytes = (entries*field_size+4)>>3;
2870 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
2872 av_freep(&sc->sample_sizes);
2873 return AVERROR(ENOMEM);
2876 ret = ffio_read_size(pb, buf, num_bytes);
2878 av_freep(&sc->sample_sizes);
2880 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
2884 init_get_bits(&gb, buf, 8*num_bytes);
2886 for (i = 0; i < entries && !pb->eof_reached; i++) {
2887 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
2888 if (sc->sample_sizes[i] < 0) {
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) {
4437 *p = av_malloc(len + 1);
4439 ret = AVERROR(ENOMEM);
4442 ret = ffio_read_size(pb, *p, len);
4450 if (mean && key && val) {
4451 if (strcmp(key, "iTunSMPB") == 0) {
4452 int priming, remainder, samples;
4453 if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
4454 if(priming>0 && priming<16384)
4455 sc->start_pad = priming;
4458 if (strcmp(key, "cdec") != 0) {
4459 av_dict_set(&c->fc->metadata, key, val,
4460 AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
4464 av_log(c->fc, AV_LOG_VERBOSE,
4465 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
4468 avio_seek(pb, end, SEEK_SET);
4475 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4477 while (atom.size > 8) {
4481 tag = avio_rl32(pb);
4483 if (tag == MKTAG('h','d','l','r')) {
4484 avio_seek(pb, -8, SEEK_CUR);
4486 return mov_read_default(c, pb, atom);
4492 // return 1 when matrix is identity, 0 otherwise
4493 #define IS_MATRIX_IDENT(matrix) \
4494 ( (matrix)[0][0] == (1 << 16) && \
4495 (matrix)[1][1] == (1 << 16) && \
4496 (matrix)[2][2] == (1 << 30) && \
4497 !(matrix)[0][1] && !(matrix)[0][2] && \
4498 !(matrix)[1][0] && !(matrix)[1][2] && \
4499 !(matrix)[2][0] && !(matrix)[2][1])
4501 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4506 int display_matrix[3][3];
4507 int res_display_matrix[3][3] = { { 0 } };
4509 MOVStreamContext *sc;
4513 if (c->fc->nb_streams < 1)
4515 st = c->fc->streams[c->fc->nb_streams-1];
4518 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4519 // avoids corrupting AVStreams mapped to an earlier tkhd.
4521 return AVERROR_INVALIDDATA;
4523 version = avio_r8(pb);
4524 flags = avio_rb24(pb);
4525 st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
4531 avio_rb32(pb); /* creation time */
4532 avio_rb32(pb); /* modification time */
4534 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4535 avio_rb32(pb); /* reserved */
4537 /* highlevel (considering edits) duration in movie timebase */
4538 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4539 avio_rb32(pb); /* reserved */
4540 avio_rb32(pb); /* reserved */
4542 avio_rb16(pb); /* layer */
4543 avio_rb16(pb); /* alternate group */
4544 avio_rb16(pb); /* volume */
4545 avio_rb16(pb); /* reserved */
4547 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4548 // they're kept in fixed point format through all calculations
4549 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4550 // side data, but the scale factor is not needed to calculate aspect ratio
4551 for (i = 0; i < 3; i++) {
4552 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
4553 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
4554 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
4557 width = avio_rb32(pb); // 16.16 fixed point track width
4558 height = avio_rb32(pb); // 16.16 fixed point track height
4559 sc->width = width >> 16;
4560 sc->height = height >> 16;
4562 // apply the moov display matrix (after the tkhd one)
4563 for (i = 0; i < 3; i++) {
4564 const int sh[3] = { 16, 16, 30 };
4565 for (j = 0; j < 3; j++) {
4566 for (e = 0; e < 3; e++) {
4567 res_display_matrix[i][j] +=
4568 ((int64_t) display_matrix[i][e] *
4569 c->movie_display_matrix[e][j]) >> sh[e];
4574 // save the matrix when it is not the default identity
4575 if (!IS_MATRIX_IDENT(res_display_matrix)) {
4578 av_freep(&sc->display_matrix);
4579 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4580 if (!sc->display_matrix)
4581 return AVERROR(ENOMEM);
4583 for (i = 0; i < 3; i++)
4584 for (j = 0; j < 3; j++)
4585 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4587 #if FF_API_OLD_ROTATE_API
4588 rotate = av_display_rotation_get(sc->display_matrix);
4589 if (!isnan(rotate)) {
4590 char rotate_buf[64];
4592 if (rotate < 0) // for backward compatibility
4594 snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate);
4595 av_dict_set(&st->metadata, "rotate", rotate_buf, 0);
4600 // transform the display width/height according to the matrix
4601 // to keep the same scale, use [width height 1<<16]
4602 if (width && height && sc->display_matrix) {
4603 double disp_transform[2];
4605 for (i = 0; i < 2; i++)
4606 disp_transform[i] = hypot(sc->display_matrix[0 + i],
4607 sc->display_matrix[3 + i]);
4609 if (disp_transform[0] > 0 && disp_transform[1] > 0 &&
4610 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4611 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4612 st->sample_aspect_ratio = av_d2q(
4613 disp_transform[0] / disp_transform[1],
4619 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4621 MOVFragment *frag = &c->fragment;
4622 MOVTrackExt *trex = NULL;
4623 int flags, track_id, i;
4624 MOVFragmentStreamInfo * frag_stream_info;
4626 avio_r8(pb); /* version */
4627 flags = avio_rb24(pb);
4629 track_id = avio_rb32(pb);
4631 return AVERROR_INVALIDDATA;
4632 for (i = 0; i < c->trex_count; i++)
4633 if (c->trex_data[i].track_id == track_id) {
4634 trex = &c->trex_data[i];
4638 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4641 c->fragment.found_tfhd = 1;
4642 frag->track_id = track_id;
4643 set_frag_stream(&c->frag_index, track_id);
4645 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4646 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4647 frag->moof_offset : frag->implicit_offset;
4648 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4650 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4651 avio_rb32(pb) : trex->duration;
4652 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4653 avio_rb32(pb) : trex->size;
4654 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4655 avio_rb32(pb) : trex->flags;
4656 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4658 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4659 if (frag_stream_info)
4660 frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
4665 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4670 num = atom.size / 4;
4671 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4672 return AVERROR(ENOMEM);
4674 av_free(c->chapter_tracks);
4675 c->chapter_tracks = new_tracks;
4676 c->nb_chapter_tracks = num;
4678 for (i = 0; i < num && !pb->eof_reached; i++)
4679 c->chapter_tracks[i] = avio_rb32(pb);
4684 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4689 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4690 return AVERROR_INVALIDDATA;
4691 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4692 sizeof(*c->trex_data))) < 0) {
4697 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4699 trex = &c->trex_data[c->trex_count++];
4700 avio_r8(pb); /* version */
4701 avio_rb24(pb); /* flags */
4702 trex->track_id = avio_rb32(pb);
4703 trex->stsd_id = avio_rb32(pb);
4704 trex->duration = avio_rb32(pb);
4705 trex->size = avio_rb32(pb);
4706 trex->flags = avio_rb32(pb);
4710 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4712 MOVFragment *frag = &c->fragment;
4713 AVStream *st = NULL;
4714 MOVStreamContext *sc;
4716 MOVFragmentStreamInfo * frag_stream_info;
4717 int64_t base_media_decode_time;
4719 for (i = 0; i < c->fc->nb_streams; i++) {
4720 if (c->fc->streams[i]->id == frag->track_id) {
4721 st = c->fc->streams[i];
4726 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4730 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4732 version = avio_r8(pb);
4733 avio_rb24(pb); /* flags */
4735 base_media_decode_time = avio_rb64(pb);
4737 base_media_decode_time = avio_rb32(pb);
4740 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4741 if (frag_stream_info)
4742 frag_stream_info->tfdt_dts = base_media_decode_time;
4743 sc->track_end = base_media_decode_time;
4748 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4750 MOVFragment *frag = &c->fragment;
4751 AVStream *st = NULL;
4752 MOVStreamContext *sc;
4755 int64_t dts, pts = AV_NOPTS_VALUE;
4756 int data_offset = 0;
4757 unsigned entries, first_sample_flags = frag->flags;
4758 int flags, distance, i;
4759 int64_t prev_dts = AV_NOPTS_VALUE;
4760 int next_frag_index = -1, index_entry_pos;
4761 size_t requested_size;
4762 size_t old_ctts_allocated_size;
4763 AVIndexEntry *new_entries;
4764 MOVFragmentStreamInfo * frag_stream_info;
4766 if (!frag->found_tfhd) {
4767 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4768 return AVERROR_INVALIDDATA;
4771 for (i = 0; i < c->fc->nb_streams; i++) {
4772 if (c->fc->streams[i]->id == frag->track_id) {
4773 st = c->fc->streams[i];
4778 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4782 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4785 // Find the next frag_index index that has a valid index_entry for
4786 // the current track_id.
4788 // A valid index_entry means the trun for the fragment was read
4789 // and it's samples are in index_entries at the given position.
4790 // New index entries will be inserted before the index_entry found.
4791 index_entry_pos = st->nb_index_entries;
4792 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4793 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4794 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4795 next_frag_index = i;
4796 index_entry_pos = frag_stream_info->index_entry;
4800 av_assert0(index_entry_pos <= st->nb_index_entries);
4802 avio_r8(pb); /* version */
4803 flags = avio_rb24(pb);
4804 entries = avio_rb32(pb);
4805 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4807 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4808 return AVERROR_INVALIDDATA;
4809 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4810 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4812 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4813 if (frag_stream_info)
4815 if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
4816 dts = frag_stream_info->next_trun_dts - sc->time_offset;
4817 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4818 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4819 pts = frag_stream_info->first_tfra_pts;
4820 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4821 ", using it for pts\n", pts);
4822 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4823 c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
4824 dts = frag_stream_info->first_tfra_pts;
4825 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4826 ", using it for dts\n", pts);
4827 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4828 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4829 // pts = frag_stream_info->sidx_pts;
4830 dts = frag_stream_info->sidx_pts - sc->time_offset;
4831 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4832 ", using it for pts\n", pts);
4833 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4834 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4835 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4836 ", using it for dts\n", dts);
4838 dts = sc->track_end - sc->time_offset;
4839 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4840 ", using it for dts\n", dts);
4843 dts = sc->track_end - sc->time_offset;
4844 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4845 ", using it for dts\n", dts);
4847 offset = frag->base_data_offset + data_offset;
4849 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4851 // realloc space for new index entries
4852 if((uint64_t)st->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4853 entries = UINT_MAX / sizeof(AVIndexEntry) - st->nb_index_entries;
4854 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4859 requested_size = (st->nb_index_entries + entries) * sizeof(AVIndexEntry);
4860 new_entries = av_fast_realloc(st->index_entries,
4861 &st->index_entries_allocated_size,
4864 return AVERROR(ENOMEM);
4865 st->index_entries= new_entries;
4867 requested_size = (st->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4868 old_ctts_allocated_size = sc->ctts_allocated_size;
4869 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4872 return AVERROR(ENOMEM);
4873 sc->ctts_data = ctts_data;
4875 // In case there were samples without ctts entries, ensure they get
4876 // zero valued entries. This ensures clips which mix boxes with and
4877 // without ctts entries don't pickup uninitialized data.
4878 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4879 sc->ctts_allocated_size - old_ctts_allocated_size);
4881 if (index_entry_pos < st->nb_index_entries) {
4882 // Make hole in index_entries and ctts_data for new samples
4883 memmove(st->index_entries + index_entry_pos + entries,
4884 st->index_entries + index_entry_pos,
4885 sizeof(*st->index_entries) *
4886 (st->nb_index_entries - index_entry_pos));
4887 memmove(sc->ctts_data + index_entry_pos + entries,
4888 sc->ctts_data + index_entry_pos,
4889 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4890 if (index_entry_pos < sc->current_sample) {
4891 sc->current_sample += entries;
4895 st->nb_index_entries += entries;
4896 sc->ctts_count = st->nb_index_entries;
4898 // Record the index_entry position in frag_index of this fragment
4899 if (frag_stream_info)
4900 frag_stream_info->index_entry = index_entry_pos;
4902 if (index_entry_pos > 0)
4903 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4905 for (i = 0; i < entries && !pb->eof_reached; i++) {
4906 unsigned sample_size = frag->size;
4907 int sample_flags = i ? frag->flags : first_sample_flags;
4908 unsigned sample_duration = frag->duration;
4909 unsigned ctts_duration = 0;
4911 int index_entry_flags = 0;
4913 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4914 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4915 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4916 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4918 mov_update_dts_shift(sc, ctts_duration, c->fc);
4919 if (pts != AV_NOPTS_VALUE) {
4920 dts = pts - sc->dts_shift;
4921 if (flags & MOV_TRUN_SAMPLE_CTS) {
4922 dts -= ctts_duration;
4924 dts -= sc->time_offset;
4926 av_log(c->fc, AV_LOG_DEBUG,
4927 "pts %"PRId64" calculated dts %"PRId64
4928 " sc->dts_shift %d ctts.duration %d"
4929 " sc->time_offset %"PRId64
4930 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4932 sc->dts_shift, ctts_duration,
4933 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4934 pts = AV_NOPTS_VALUE;
4937 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4941 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4942 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4945 index_entry_flags |= AVINDEX_KEYFRAME;
4947 // Fragments can overlap in time. Discard overlapping frames after
4949 if (prev_dts >= dts)
4950 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4952 st->index_entries[index_entry_pos].pos = offset;
4953 st->index_entries[index_entry_pos].timestamp = dts;
4954 st->index_entries[index_entry_pos].size= sample_size;
4955 st->index_entries[index_entry_pos].min_distance= distance;
4956 st->index_entries[index_entry_pos].flags = index_entry_flags;
4958 sc->ctts_data[index_entry_pos].count = 1;
4959 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4962 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4963 "size %u, distance %d, keyframe %d\n", st->index,
4964 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4966 dts += sample_duration;
4967 offset += sample_size;
4968 sc->data_size += sample_size;
4970 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4971 1 <= INT_MAX - sc->nb_frames_for_fps
4973 sc->duration_for_fps += sample_duration;
4974 sc->nb_frames_for_fps ++;
4977 if (frag_stream_info)
4978 frag_stream_info->next_trun_dts = dts + sc->time_offset;
4980 // EOF found before reading all entries. Fix the hole this would
4981 // leave in index_entries and ctts_data
4982 int gap = entries - i;
4983 memmove(st->index_entries + index_entry_pos,
4984 st->index_entries + index_entry_pos + gap,
4985 sizeof(*st->index_entries) *
4986 (st->nb_index_entries - (index_entry_pos + gap)));
4987 memmove(sc->ctts_data + index_entry_pos,
4988 sc->ctts_data + index_entry_pos + gap,
4989 sizeof(*sc->ctts_data) *
4990 (sc->ctts_count - (index_entry_pos + gap)));
4992 st->nb_index_entries -= gap;
4993 sc->ctts_count -= gap;
4994 if (index_entry_pos < sc->current_sample) {
4995 sc->current_sample -= gap;
5000 // The end of this new fragment may overlap in time with the start
5001 // of the next fragment in index_entries. Mark the samples in the next
5002 // fragment that overlap with AVINDEX_DISCARD_FRAME
5003 prev_dts = AV_NOPTS_VALUE;
5004 if (index_entry_pos > 0)
5005 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
5006 for (i = index_entry_pos; i < st->nb_index_entries; i++) {
5007 if (prev_dts < st->index_entries[i].timestamp)
5009 st->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
5012 // If a hole was created to insert the new index_entries into,
5013 // the index_entry recorded for all subsequent moof must
5014 // be incremented by the number of entries inserted.
5015 fix_frag_index_entries(&c->frag_index, next_frag_index,
5016 frag->track_id, entries);
5018 if (pb->eof_reached) {
5019 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
5023 frag->implicit_offset = offset;
5025 sc->track_end = dts + sc->time_offset;
5026 if (st->duration < sc->track_end)
5027 st->duration = sc->track_end;
5032 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5034 int64_t offset = avio_tell(pb) + atom.size, pts, timestamp;
5036 unsigned i, j, track_id, item_count;
5037 AVStream *st = NULL;
5038 AVStream *ref_st = NULL;
5039 MOVStreamContext *sc, *ref_sc = NULL;
5040 AVRational timescale;
5042 version = avio_r8(pb);
5044 avpriv_request_sample(c->fc, "sidx version %u", version);
5048 avio_rb24(pb); // flags
5050 track_id = avio_rb32(pb); // Reference ID
5051 for (i = 0; i < c->fc->nb_streams; i++) {
5052 if (c->fc->streams[i]->id == track_id) {
5053 st = c->fc->streams[i];
5058 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5064 timescale = av_make_q(1, avio_rb32(pb));
5066 if (timescale.den <= 0) {
5067 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5068 return AVERROR_INVALIDDATA;
5072 pts = avio_rb32(pb);
5073 offset += avio_rb32(pb);
5075 pts = avio_rb64(pb);
5076 offset += avio_rb64(pb);
5079 avio_rb16(pb); // reserved
5081 item_count = avio_rb16(pb);
5083 for (i = 0; i < item_count; i++) {
5085 MOVFragmentStreamInfo * frag_stream_info;
5086 uint32_t size = avio_rb32(pb);
5087 uint32_t duration = avio_rb32(pb);
5088 if (size & 0x80000000) {
5089 avpriv_request_sample(c->fc, "sidx reference_type 1");
5090 return AVERROR_PATCHWELCOME;
5092 avio_rb32(pb); // sap_flags
5093 timestamp = av_rescale_q(pts, timescale, st->time_base);
5095 index = update_frag_index(c, offset);
5096 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5097 if (frag_stream_info)
5098 frag_stream_info->sidx_pts = timestamp;
5104 st->duration = sc->track_end = pts;
5108 if (offset == avio_size(pb)) {
5109 // Find first entry in fragment index that came from an sidx.
5110 // This will pretty much always be the first entry.
5111 for (i = 0; i < c->frag_index.nb_items; i++) {
5112 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5113 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5114 MOVFragmentStreamInfo * si;
5115 si = &item->stream_info[j];
5116 if (si->sidx_pts != AV_NOPTS_VALUE) {
5117 ref_st = c->fc->streams[j];
5118 ref_sc = ref_st->priv_data;
5123 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5124 st = c->fc->streams[i];
5126 if (!sc->has_sidx) {
5127 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5131 c->frag_index.complete = 1;
5137 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5138 /* like the files created with Adobe Premiere 5.0, for samples see */
5139 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5140 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5145 return 0; /* continue */
5146 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5147 avio_skip(pb, atom.size - 4);
5150 atom.type = avio_rl32(pb);
5152 if (atom.type != MKTAG('m','d','a','t')) {
5153 avio_skip(pb, atom.size);
5156 err = mov_read_mdat(c, pb, atom);
5160 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5165 uint8_t *moov_data; /* uncompressed data */
5166 long cmov_len, moov_len;
5169 avio_rb32(pb); /* dcom atom */
5170 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5171 return AVERROR_INVALIDDATA;
5172 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5173 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5174 return AVERROR_INVALIDDATA;
5176 avio_rb32(pb); /* cmvd atom */
5177 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5178 return AVERROR_INVALIDDATA;
5179 moov_len = avio_rb32(pb); /* uncompressed size */
5180 cmov_len = atom.size - 6 * 4;
5182 cmov_data = av_malloc(cmov_len);
5184 return AVERROR(ENOMEM);
5185 moov_data = av_malloc(moov_len);
5188 return AVERROR(ENOMEM);
5190 ret = ffio_read_size(pb, cmov_data, cmov_len);
5192 goto free_and_return;
5194 ret = AVERROR_INVALIDDATA;
5195 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5196 goto free_and_return;
5197 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5198 goto free_and_return;
5199 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5200 atom.type = MKTAG('m','o','o','v');
5201 atom.size = moov_len;
5202 ret = mov_read_default(c, &ctx, atom);
5208 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5209 return AVERROR(ENOSYS);
5213 /* edit list atom */
5214 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5216 MOVStreamContext *sc;
5217 int i, edit_count, version;
5218 int64_t elst_entry_size;
5220 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5222 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5224 version = avio_r8(pb); /* version */
5225 avio_rb24(pb); /* flags */
5226 edit_count = avio_rb32(pb); /* entries */
5229 elst_entry_size = version == 1 ? 20 : 12;
5230 if (atom.size != edit_count * elst_entry_size) {
5231 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5232 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5233 edit_count, atom.size + 8);
5234 return AVERROR_INVALIDDATA;
5236 edit_count = atom.size / elst_entry_size;
5237 if (edit_count * elst_entry_size != atom.size) {
5238 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.", atom.size, edit_count);
5246 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5247 av_free(sc->elst_data);
5249 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5251 return AVERROR(ENOMEM);
5253 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5254 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5255 MOVElst *e = &sc->elst_data[i];
5258 e->duration = avio_rb64(pb);
5259 e->time = avio_rb64(pb);
5262 e->duration = avio_rb32(pb); /* segment duration */
5263 e->time = (int32_t)avio_rb32(pb); /* media time */
5266 e->rate = avio_rb32(pb) / 65536.0;
5268 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5269 e->duration, e->time, e->rate);
5271 if (e->time < 0 && e->time != -1 &&
5272 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5273 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5274 c->fc->nb_streams-1, i, e->time);
5275 return AVERROR_INVALIDDATA;
5283 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5285 MOVStreamContext *sc;
5287 if (c->fc->nb_streams < 1)
5288 return AVERROR_INVALIDDATA;
5289 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5290 sc->timecode_track = avio_rb32(pb);
5294 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5299 if (c->fc->nb_streams < 1)
5301 st = c->fc->streams[c->fc->nb_streams - 1];
5303 if (atom.size < 4) {
5304 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5305 return AVERROR_INVALIDDATA;
5308 /* For now, propagate only the OBUs, if any. Once libavcodec is
5309 updated to handle isobmff style extradata this can be removed. */
5315 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5322 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5325 int version, color_range, color_primaries, color_trc, color_space;
5327 if (c->fc->nb_streams < 1)
5329 st = c->fc->streams[c->fc->nb_streams - 1];
5331 if (atom.size < 5) {
5332 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5333 return AVERROR_INVALIDDATA;
5336 version = avio_r8(pb);
5338 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5341 avio_skip(pb, 3); /* flags */
5343 avio_skip(pb, 2); /* profile + level */
5344 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5345 color_primaries = avio_r8(pb);
5346 color_trc = avio_r8(pb);
5347 color_space = avio_r8(pb);
5348 if (avio_rb16(pb)) /* codecIntializationDataSize */
5349 return AVERROR_INVALIDDATA;
5351 if (!av_color_primaries_name(color_primaries))
5352 color_primaries = AVCOL_PRI_UNSPECIFIED;
5353 if (!av_color_transfer_name(color_trc))
5354 color_trc = AVCOL_TRC_UNSPECIFIED;
5355 if (!av_color_space_name(color_space))
5356 color_space = AVCOL_SPC_UNSPECIFIED;
5358 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5359 st->codecpar->color_primaries = color_primaries;
5360 st->codecpar->color_trc = color_trc;
5361 st->codecpar->color_space = color_space;
5366 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5368 MOVStreamContext *sc;
5371 if (c->fc->nb_streams < 1)
5372 return AVERROR_INVALIDDATA;
5374 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5376 if (atom.size < 5) {
5377 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5378 return AVERROR_INVALIDDATA;
5381 version = avio_r8(pb);
5383 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5386 avio_skip(pb, 3); /* flags */
5388 sc->mastering = av_mastering_display_metadata_alloc();
5390 return AVERROR(ENOMEM);
5392 for (i = 0; i < 3; i++) {
5393 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5394 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5396 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5397 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5399 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5400 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5402 sc->mastering->has_primaries = 1;
5403 sc->mastering->has_luminance = 1;
5408 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5410 MOVStreamContext *sc;
5411 const int mapping[3] = {1, 2, 0};
5412 const int chroma_den = 50000;
5413 const int luma_den = 10000;
5416 if (c->fc->nb_streams < 1)
5417 return AVERROR_INVALIDDATA;
5419 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5421 if (atom.size < 24) {
5422 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5423 return AVERROR_INVALIDDATA;
5426 sc->mastering = av_mastering_display_metadata_alloc();
5428 return AVERROR(ENOMEM);
5430 for (i = 0; i < 3; i++) {
5431 const int j = mapping[i];
5432 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5433 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5435 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5436 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5438 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5439 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5441 sc->mastering->has_luminance = 1;
5442 sc->mastering->has_primaries = 1;
5447 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5449 MOVStreamContext *sc;
5452 if (c->fc->nb_streams < 1)
5453 return AVERROR_INVALIDDATA;
5455 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5457 if (atom.size < 5) {
5458 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5459 return AVERROR_INVALIDDATA;
5462 version = avio_r8(pb);
5464 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5467 avio_skip(pb, 3); /* flags */
5469 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5471 return AVERROR(ENOMEM);
5473 sc->coll->MaxCLL = avio_rb16(pb);
5474 sc->coll->MaxFALL = avio_rb16(pb);
5479 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5481 MOVStreamContext *sc;
5483 if (c->fc->nb_streams < 1)
5484 return AVERROR_INVALIDDATA;
5486 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5488 if (atom.size < 4) {
5489 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5490 return AVERROR_INVALIDDATA;
5493 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5495 return AVERROR(ENOMEM);
5497 sc->coll->MaxCLL = avio_rb16(pb);
5498 sc->coll->MaxFALL = avio_rb16(pb);
5503 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5506 MOVStreamContext *sc;
5507 enum AVStereo3DType type;
5510 if (c->fc->nb_streams < 1)
5513 st = c->fc->streams[c->fc->nb_streams - 1];
5516 if (atom.size < 5) {
5517 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5518 return AVERROR_INVALIDDATA;
5520 avio_skip(pb, 4); /* version + flags */
5525 type = AV_STEREO3D_2D;
5528 type = AV_STEREO3D_TOPBOTTOM;
5531 type = AV_STEREO3D_SIDEBYSIDE;
5534 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5538 sc->stereo3d = av_stereo3d_alloc();
5540 return AVERROR(ENOMEM);
5542 sc->stereo3d->type = type;
5546 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5549 MOVStreamContext *sc;
5550 int size, version, layout;
5551 int32_t yaw, pitch, roll;
5552 uint32_t l = 0, t = 0, r = 0, b = 0;
5553 uint32_t tag, padding = 0;
5554 enum AVSphericalProjection projection;
5556 if (c->fc->nb_streams < 1)
5559 st = c->fc->streams[c->fc->nb_streams - 1];
5562 if (atom.size < 8) {
5563 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5564 return AVERROR_INVALIDDATA;
5567 size = avio_rb32(pb);
5568 if (size <= 12 || size > atom.size)
5569 return AVERROR_INVALIDDATA;
5571 tag = avio_rl32(pb);
5572 if (tag != MKTAG('s','v','h','d')) {
5573 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5576 version = avio_r8(pb);
5578 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5582 avio_skip(pb, 3); /* flags */
5583 avio_skip(pb, size - 12); /* metadata_source */
5585 size = avio_rb32(pb);
5586 if (size > atom.size)
5587 return AVERROR_INVALIDDATA;
5589 tag = avio_rl32(pb);
5590 if (tag != MKTAG('p','r','o','j')) {
5591 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5595 size = avio_rb32(pb);
5596 if (size > atom.size)
5597 return AVERROR_INVALIDDATA;
5599 tag = avio_rl32(pb);
5600 if (tag != MKTAG('p','r','h','d')) {
5601 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5604 version = avio_r8(pb);
5606 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5610 avio_skip(pb, 3); /* flags */
5612 /* 16.16 fixed point */
5613 yaw = avio_rb32(pb);
5614 pitch = avio_rb32(pb);
5615 roll = avio_rb32(pb);
5617 size = avio_rb32(pb);
5618 if (size > atom.size)
5619 return AVERROR_INVALIDDATA;
5621 tag = avio_rl32(pb);
5622 version = avio_r8(pb);
5624 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5628 avio_skip(pb, 3); /* flags */
5630 case MKTAG('c','b','m','p'):
5631 layout = avio_rb32(pb);
5633 av_log(c->fc, AV_LOG_WARNING,
5634 "Unsupported cubemap layout %d\n", layout);
5637 projection = AV_SPHERICAL_CUBEMAP;
5638 padding = avio_rb32(pb);
5640 case MKTAG('e','q','u','i'):
5646 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5647 av_log(c->fc, AV_LOG_ERROR,
5648 "Invalid bounding rectangle coordinates "
5649 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5650 return AVERROR_INVALIDDATA;
5653 if (l || t || r || b)
5654 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5656 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5659 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5663 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5665 return AVERROR(ENOMEM);
5667 sc->spherical->projection = projection;
5669 sc->spherical->yaw = yaw;
5670 sc->spherical->pitch = pitch;
5671 sc->spherical->roll = roll;
5673 sc->spherical->padding = padding;
5675 sc->spherical->bound_left = l;
5676 sc->spherical->bound_top = t;
5677 sc->spherical->bound_right = r;
5678 sc->spherical->bound_bottom = b;
5683 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5686 uint8_t *buffer = av_malloc(len + 1);
5690 return AVERROR(ENOMEM);
5693 ret = ffio_read_size(pb, buffer, len);
5697 /* Check for mandatory keys and values, try to support XML as best-effort */
5698 if (!sc->spherical &&
5699 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5700 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5701 av_stristr(val, "true") &&
5702 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5703 av_stristr(val, "true") &&
5704 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5705 av_stristr(val, "equirectangular")) {
5706 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5710 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5712 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5713 enum AVStereo3DType mode;
5715 if (av_stristr(buffer, "left-right"))
5716 mode = AV_STEREO3D_SIDEBYSIDE;
5717 else if (av_stristr(buffer, "top-bottom"))
5718 mode = AV_STEREO3D_TOPBOTTOM;
5720 mode = AV_STEREO3D_2D;
5722 sc->stereo3d = av_stereo3d_alloc();
5726 sc->stereo3d->type = mode;
5730 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5732 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5733 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5735 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5736 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5738 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5746 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5749 MOVStreamContext *sc;
5752 static const uint8_t uuid_isml_manifest[] = {
5753 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5754 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5756 static const uint8_t uuid_xmp[] = {
5757 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5758 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5760 static const uint8_t uuid_spherical[] = {
5761 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5762 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5765 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5766 return AVERROR_INVALIDDATA;
5768 if (c->fc->nb_streams < 1)
5770 st = c->fc->streams[c->fc->nb_streams - 1];
5773 ret = avio_read(pb, uuid, sizeof(uuid));
5776 } else if (ret != sizeof(uuid)) {
5777 return AVERROR_INVALIDDATA;
5779 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5780 uint8_t *buffer, *ptr;
5782 size_t len = atom.size - sizeof(uuid);
5785 return AVERROR_INVALIDDATA;
5787 ret = avio_skip(pb, 4); // zeroes
5790 buffer = av_mallocz(len + 1);
5792 return AVERROR(ENOMEM);
5794 ret = avio_read(pb, buffer, len);
5798 } else if (ret != len) {
5800 return AVERROR_INVALIDDATA;
5804 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5805 ptr += sizeof("systemBitrate=\"") - 1;
5806 c->bitrates_count++;
5807 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5809 c->bitrates_count = 0;
5811 return AVERROR(ENOMEM);
5814 ret = strtol(ptr, &endptr, 10);
5815 if (ret < 0 || errno || *endptr != '"') {
5816 c->bitrates[c->bitrates_count - 1] = 0;
5818 c->bitrates[c->bitrates_count - 1] = ret;
5823 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5825 size_t len = atom.size - sizeof(uuid);
5826 if (c->export_xmp) {
5827 buffer = av_mallocz(len + 1);
5829 return AVERROR(ENOMEM);
5831 ret = avio_read(pb, buffer, len);
5835 } else if (ret != len) {
5837 return AVERROR_INVALIDDATA;
5840 av_dict_set(&c->fc->metadata, "xmp",
5841 buffer, AV_DICT_DONT_STRDUP_VAL);
5843 // skip all uuid atom, which makes it fast for long uuid-xmp file
5844 ret = avio_skip(pb, len);
5848 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5849 size_t len = atom.size - sizeof(uuid);
5850 ret = mov_parse_uuid_spherical(sc, pb, len);
5854 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5860 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5863 uint8_t content[16];
5868 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5874 && !memcmp(content, "Anevia\x1A\x1A", 8)
5875 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5876 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5882 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5884 uint32_t format = avio_rl32(pb);
5885 MOVStreamContext *sc;
5889 if (c->fc->nb_streams < 1)
5891 st = c->fc->streams[c->fc->nb_streams - 1];
5896 case MKTAG('e','n','c','v'): // encrypted video
5897 case MKTAG('e','n','c','a'): // encrypted audio
5898 id = mov_codec_id(st, format);
5899 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5900 st->codecpar->codec_id != id) {
5901 av_log(c->fc, AV_LOG_WARNING,
5902 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5903 (char*)&format, st->codecpar->codec_id);
5907 st->codecpar->codec_id = id;
5908 sc->format = format;
5912 if (format != sc->format) {
5913 av_log(c->fc, AV_LOG_WARNING,
5914 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5915 (char*)&format, (char*)&sc->format);
5924 * Gets the current encryption info and associated current stream context. If
5925 * we are parsing a track fragment, this will return the specific encryption
5926 * info for this fragment; otherwise this will return the global encryption
5927 * info for the current stream.
5929 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5931 MOVFragmentStreamInfo *frag_stream_info;
5935 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5936 if (frag_stream_info) {
5937 for (i = 0; i < c->fc->nb_streams; i++) {
5938 if (c->fc->streams[i]->id == frag_stream_info->id) {
5939 st = c->fc->streams[i];
5943 if (i == c->fc->nb_streams)
5945 *sc = st->priv_data;
5947 if (!frag_stream_info->encryption_index) {
5948 // If this stream isn't encrypted, don't create the index.
5949 if (!(*sc)->cenc.default_encrypted_sample)
5951 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5952 if (!frag_stream_info->encryption_index)
5953 return AVERROR(ENOMEM);
5955 *encryption_index = frag_stream_info->encryption_index;
5958 // No current track fragment, using stream level encryption info.
5960 if (c->fc->nb_streams < 1)
5962 st = c->fc->streams[c->fc->nb_streams - 1];
5963 *sc = st->priv_data;
5965 if (!(*sc)->cenc.encryption_index) {
5966 // If this stream isn't encrypted, don't create the index.
5967 if (!(*sc)->cenc.default_encrypted_sample)
5969 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5970 if (!(*sc)->cenc.encryption_index)
5971 return AVERROR(ENOMEM);
5974 *encryption_index = (*sc)->cenc.encryption_index;
5979 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
5982 unsigned int subsample_count;
5983 AVSubsampleEncryptionInfo *subsamples;
5985 if (!sc->cenc.default_encrypted_sample) {
5986 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
5987 return AVERROR_INVALIDDATA;
5990 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
5992 return AVERROR(ENOMEM);
5994 if (sc->cenc.per_sample_iv_size != 0) {
5995 if (avio_read(pb, (*sample)->iv, sc->cenc.per_sample_iv_size) != sc->cenc.per_sample_iv_size) {
5996 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
5997 av_encryption_info_free(*sample);
5999 return AVERROR_INVALIDDATA;
6003 if (use_subsamples) {
6004 subsample_count = avio_rb16(pb);
6005 av_free((*sample)->subsamples);
6006 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
6007 if (!(*sample)->subsamples) {
6008 av_encryption_info_free(*sample);
6010 return AVERROR(ENOMEM);
6013 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
6014 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
6015 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
6018 if (pb->eof_reached) {
6019 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
6020 av_encryption_info_free(*sample);
6022 return AVERROR_INVALIDDATA;
6024 (*sample)->subsample_count = subsample_count;
6030 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6032 AVEncryptionInfo **encrypted_samples;
6033 MOVEncryptionIndex *encryption_index;
6034 MOVStreamContext *sc;
6035 int use_subsamples, ret;
6036 unsigned int sample_count, i, alloc_size = 0;
6038 ret = get_current_encryption_info(c, &encryption_index, &sc);
6042 if (encryption_index->nb_encrypted_samples) {
6043 // This can happen if we have both saio/saiz and senc atoms.
6044 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6048 avio_r8(pb); /* version */
6049 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6051 sample_count = avio_rb32(pb);
6052 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6053 return AVERROR(ENOMEM);
6055 for (i = 0; i < sample_count; i++) {
6056 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6057 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6058 min_samples * sizeof(*encrypted_samples));
6059 if (encrypted_samples) {
6060 encryption_index->encrypted_samples = encrypted_samples;
6062 ret = mov_read_sample_encryption_info(
6063 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6065 ret = AVERROR(ENOMEM);
6067 if (pb->eof_reached) {
6068 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6069 ret = AVERROR_INVALIDDATA;
6074 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6075 av_freep(&encryption_index->encrypted_samples);
6079 encryption_index->nb_encrypted_samples = sample_count;
6084 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6086 AVEncryptionInfo **sample, **encrypted_samples;
6088 size_t sample_count, sample_info_size, i;
6090 unsigned int alloc_size = 0;
6092 if (encryption_index->nb_encrypted_samples)
6094 sample_count = encryption_index->auxiliary_info_sample_count;
6095 if (encryption_index->auxiliary_offsets_count != 1) {
6096 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6097 return AVERROR_PATCHWELCOME;
6099 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6100 return AVERROR(ENOMEM);
6102 prev_pos = avio_tell(pb);
6103 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6104 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6105 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6109 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6110 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6111 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6112 min_samples * sizeof(*encrypted_samples));
6113 if (!encrypted_samples) {
6114 ret = AVERROR(ENOMEM);
6117 encryption_index->encrypted_samples = encrypted_samples;
6119 sample = &encryption_index->encrypted_samples[i];
6120 sample_info_size = encryption_index->auxiliary_info_default_size
6121 ? encryption_index->auxiliary_info_default_size
6122 : encryption_index->auxiliary_info_sizes[i];
6124 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6128 if (pb->eof_reached) {
6129 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6130 ret = AVERROR_INVALIDDATA;
6132 encryption_index->nb_encrypted_samples = sample_count;
6136 avio_seek(pb, prev_pos, SEEK_SET);
6138 for (; i > 0; i--) {
6139 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6141 av_freep(&encryption_index->encrypted_samples);
6147 * Tries to read the given number of bytes from the stream and puts it in a
6148 * newly allocated buffer. This reads in small chunks to avoid allocating large
6149 * memory if the file contains an invalid/malicious size value.
6151 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6153 const unsigned int block_size = 1024 * 1024;
6154 uint8_t *buffer = NULL;
6155 unsigned int alloc_size = 0, offset = 0;
6156 while (offset < size) {
6157 unsigned int new_size =
6158 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6159 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6160 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6163 return AVERROR(ENOMEM);
6165 buffer = new_buffer;
6167 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6169 return AVERROR_INVALIDDATA;
6178 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6180 MOVEncryptionIndex *encryption_index;
6181 MOVStreamContext *sc;
6183 unsigned int sample_count, aux_info_type, aux_info_param;
6185 ret = get_current_encryption_info(c, &encryption_index, &sc);
6189 if (encryption_index->nb_encrypted_samples) {
6190 // This can happen if we have both saio/saiz and senc atoms.
6191 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6195 if (encryption_index->auxiliary_info_sample_count) {
6196 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6197 return AVERROR_INVALIDDATA;
6200 avio_r8(pb); /* version */
6201 if (avio_rb24(pb) & 0x01) { /* flags */
6202 aux_info_type = avio_rb32(pb);
6203 aux_info_param = avio_rb32(pb);
6204 if (sc->cenc.default_encrypted_sample) {
6205 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6206 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6209 if (aux_info_param != 0) {
6210 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6214 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6215 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6216 aux_info_type == MKBETAG('c','e','n','s') ||
6217 aux_info_type == MKBETAG('c','b','c','1') ||
6218 aux_info_type == MKBETAG('c','b','c','s')) &&
6219 aux_info_param == 0) {
6220 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6221 return AVERROR_INVALIDDATA;
6226 } else if (!sc->cenc.default_encrypted_sample) {
6227 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6231 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6232 sample_count = avio_rb32(pb);
6233 encryption_index->auxiliary_info_sample_count = sample_count;
6235 if (encryption_index->auxiliary_info_default_size == 0) {
6236 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6238 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6243 if (encryption_index->auxiliary_offsets_count) {
6244 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6250 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6252 uint64_t *auxiliary_offsets;
6253 MOVEncryptionIndex *encryption_index;
6254 MOVStreamContext *sc;
6256 unsigned int version, entry_count, aux_info_type, aux_info_param;
6257 unsigned int alloc_size = 0;
6259 ret = get_current_encryption_info(c, &encryption_index, &sc);
6263 if (encryption_index->nb_encrypted_samples) {
6264 // This can happen if we have both saio/saiz and senc atoms.
6265 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6269 if (encryption_index->auxiliary_offsets_count) {
6270 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6271 return AVERROR_INVALIDDATA;
6274 version = avio_r8(pb); /* version */
6275 if (avio_rb24(pb) & 0x01) { /* flags */
6276 aux_info_type = avio_rb32(pb);
6277 aux_info_param = avio_rb32(pb);
6278 if (sc->cenc.default_encrypted_sample) {
6279 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6280 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6283 if (aux_info_param != 0) {
6284 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6288 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6289 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6290 aux_info_type == MKBETAG('c','e','n','s') ||
6291 aux_info_type == MKBETAG('c','b','c','1') ||
6292 aux_info_type == MKBETAG('c','b','c','s')) &&
6293 aux_info_param == 0) {
6294 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6295 return AVERROR_INVALIDDATA;
6300 } else if (!sc->cenc.default_encrypted_sample) {
6301 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6305 entry_count = avio_rb32(pb);
6306 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6307 return AVERROR(ENOMEM);
6309 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6310 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6311 auxiliary_offsets = av_fast_realloc(
6312 encryption_index->auxiliary_offsets, &alloc_size,
6313 min_offsets * sizeof(*auxiliary_offsets));
6314 if (!auxiliary_offsets) {
6315 av_freep(&encryption_index->auxiliary_offsets);
6316 return AVERROR(ENOMEM);
6318 encryption_index->auxiliary_offsets = auxiliary_offsets;
6321 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6323 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6325 if (c->frag_index.current >= 0) {
6326 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6330 if (pb->eof_reached) {
6331 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6332 av_freep(&encryption_index->auxiliary_offsets);
6333 return AVERROR_INVALIDDATA;
6336 encryption_index->auxiliary_offsets_count = entry_count;
6338 if (encryption_index->auxiliary_info_sample_count) {
6339 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6345 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6347 AVEncryptionInitInfo *info, *old_init_info;
6350 uint8_t *side_data, *extra_data, *old_side_data;
6351 size_t side_data_size;
6352 int ret = 0, old_side_data_size;
6353 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6355 if (c->fc->nb_streams < 1)
6357 st = c->fc->streams[c->fc->nb_streams-1];
6359 version = avio_r8(pb); /* version */
6360 avio_rb24(pb); /* flags */
6362 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6363 /* key_id_size */ 16, /* data_size */ 0);
6365 return AVERROR(ENOMEM);
6367 if (avio_read(pb, info->system_id, 16) != 16) {
6368 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6369 ret = AVERROR_INVALIDDATA;
6374 kid_count = avio_rb32(pb);
6375 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
6376 ret = AVERROR(ENOMEM);
6380 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6381 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6382 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6383 min_kid_count * sizeof(*key_ids));
6385 ret = AVERROR(ENOMEM);
6388 info->key_ids = key_ids;
6390 info->key_ids[i] = av_mallocz(16);
6391 if (!info->key_ids[i]) {
6392 ret = AVERROR(ENOMEM);
6395 info->num_key_ids = i + 1;
6397 if (avio_read(pb, info->key_ids[i], 16) != 16) {
6398 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6399 ret = AVERROR_INVALIDDATA;
6404 if (pb->eof_reached) {
6405 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6406 ret = AVERROR_INVALIDDATA;
6411 extra_data_size = avio_rb32(pb);
6412 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6416 av_freep(&info->data); // malloc(0) may still allocate something.
6417 info->data = extra_data;
6418 info->data_size = extra_data_size;
6420 // If there is existing initialization data, append to the list.
6421 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6422 if (old_side_data) {
6423 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6424 if (old_init_info) {
6425 // Append to the end of the list.
6426 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6432 info = old_init_info;
6434 // Assume existing side-data will be valid, so the only error we could get is OOM.
6435 ret = AVERROR(ENOMEM);
6440 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6442 ret = AVERROR(ENOMEM);
6445 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6446 side_data, side_data_size);
6451 av_encryption_init_info_free(info);
6455 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6458 MOVStreamContext *sc;
6460 if (c->fc->nb_streams < 1)
6462 st = c->fc->streams[c->fc->nb_streams-1];
6465 if (sc->pseudo_stream_id != 0) {
6466 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6467 return AVERROR_PATCHWELCOME;
6471 return AVERROR_INVALIDDATA;
6473 avio_rb32(pb); /* version and flags */
6475 if (!sc->cenc.default_encrypted_sample) {
6476 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6477 if (!sc->cenc.default_encrypted_sample) {
6478 return AVERROR(ENOMEM);
6482 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6486 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6489 MOVStreamContext *sc;
6490 unsigned int version, pattern, is_protected, iv_size;
6492 if (c->fc->nb_streams < 1)
6494 st = c->fc->streams[c->fc->nb_streams-1];
6497 if (sc->pseudo_stream_id != 0) {
6498 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6499 return AVERROR_PATCHWELCOME;
6502 if (!sc->cenc.default_encrypted_sample) {
6503 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6504 if (!sc->cenc.default_encrypted_sample) {
6505 return AVERROR(ENOMEM);
6510 return AVERROR_INVALIDDATA;
6512 version = avio_r8(pb); /* version */
6513 avio_rb24(pb); /* flags */
6515 avio_r8(pb); /* reserved */
6516 pattern = avio_r8(pb);
6519 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6520 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6523 is_protected = avio_r8(pb);
6524 if (is_protected && !sc->cenc.encryption_index) {
6525 // The whole stream should be by-default encrypted.
6526 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6527 if (!sc->cenc.encryption_index)
6528 return AVERROR(ENOMEM);
6530 sc->cenc.per_sample_iv_size = avio_r8(pb);
6531 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6532 sc->cenc.per_sample_iv_size != 16) {
6533 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6534 return AVERROR_INVALIDDATA;
6536 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6537 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6538 return AVERROR_INVALIDDATA;
6541 if (is_protected && !sc->cenc.per_sample_iv_size) {
6542 iv_size = avio_r8(pb);
6543 if (iv_size != 8 && iv_size != 16) {
6544 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6545 return AVERROR_INVALIDDATA;
6548 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6549 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6550 return AVERROR_INVALIDDATA;
6557 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6560 int last, type, size, ret;
6563 if (c->fc->nb_streams < 1)
6565 st = c->fc->streams[c->fc->nb_streams-1];
6567 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6568 return AVERROR_INVALIDDATA;
6570 /* Check FlacSpecificBox version. */
6571 if (avio_r8(pb) != 0)
6572 return AVERROR_INVALIDDATA;
6574 avio_rb24(pb); /* Flags */
6576 avio_read(pb, buf, sizeof(buf));
6577 flac_parse_block_header(buf, &last, &type, &size);
6579 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6580 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6581 return AVERROR_INVALIDDATA;
6584 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6589 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6594 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6598 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6599 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6600 return AVERROR_PATCHWELCOME;
6603 if (!sc->cenc.aes_ctr) {
6604 /* initialize the cipher */
6605 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6606 if (!sc->cenc.aes_ctr) {
6607 return AVERROR(ENOMEM);
6610 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6616 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6618 if (!sample->subsample_count)
6620 /* decrypt the whole packet */
6621 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6625 for (i = 0; i < sample->subsample_count; i++)
6627 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6628 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6629 return AVERROR_INVALIDDATA;
6632 /* skip the clear bytes */
6633 input += sample->subsamples[i].bytes_of_clear_data;
6634 size -= sample->subsamples[i].bytes_of_clear_data;
6636 /* decrypt the encrypted bytes */
6637 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6638 input += sample->subsamples[i].bytes_of_protected_data;
6639 size -= sample->subsamples[i].bytes_of_protected_data;
6643 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6644 return AVERROR_INVALIDDATA;
6650 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6652 MOVFragmentStreamInfo *frag_stream_info;
6653 MOVEncryptionIndex *encryption_index;
6654 AVEncryptionInfo *encrypted_sample;
6655 int encrypted_index, ret;
6657 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6658 encrypted_index = current_index;
6659 encryption_index = NULL;
6660 if (frag_stream_info) {
6661 // Note this only supports encryption info in the first sample descriptor.
6662 if (mov->fragment.stsd_id == 1) {
6663 if (frag_stream_info->encryption_index) {
6664 encrypted_index = current_index - frag_stream_info->index_entry;
6665 encryption_index = frag_stream_info->encryption_index;
6667 encryption_index = sc->cenc.encryption_index;
6671 encryption_index = sc->cenc.encryption_index;
6674 if (encryption_index) {
6675 if (encryption_index->auxiliary_info_sample_count &&
6676 !encryption_index->nb_encrypted_samples) {
6677 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6678 return AVERROR_INVALIDDATA;
6680 if (encryption_index->auxiliary_offsets_count &&
6681 !encryption_index->nb_encrypted_samples) {
6682 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6683 return AVERROR_INVALIDDATA;
6686 if (!encryption_index->nb_encrypted_samples) {
6687 // Full-sample encryption with default settings.
6688 encrypted_sample = sc->cenc.default_encrypted_sample;
6689 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6690 // Per-sample setting override.
6691 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6693 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6694 return AVERROR_INVALIDDATA;
6697 if (mov->decryption_key) {
6698 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6701 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6703 return AVERROR(ENOMEM);
6704 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6714 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6716 const int OPUS_SEEK_PREROLL_MS = 80;
6722 if (c->fc->nb_streams < 1)
6724 st = c->fc->streams[c->fc->nb_streams-1];
6726 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6727 return AVERROR_INVALIDDATA;
6729 /* Check OpusSpecificBox version. */
6730 if (avio_r8(pb) != 0) {
6731 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6732 return AVERROR_INVALIDDATA;
6735 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6736 size = atom.size + 8;
6738 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
6741 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6742 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6743 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6744 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6746 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6747 little-endian; aside from the preceeding magic and version they're
6748 otherwise currently identical. Data after output gain at offset 16
6749 doesn't need to be bytewapped. */
6750 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6751 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6752 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6753 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6755 st->codecpar->initial_padding = pre_skip;
6756 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6757 (AVRational){1, 1000},
6758 (AVRational){1, 48000});
6763 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6766 unsigned format_info;
6767 int channel_assignment, channel_assignment1, channel_assignment2;
6770 if (c->fc->nb_streams < 1)
6772 st = c->fc->streams[c->fc->nb_streams-1];
6775 return AVERROR_INVALIDDATA;
6777 format_info = avio_rb32(pb);
6779 ratebits = (format_info >> 28) & 0xF;
6780 channel_assignment1 = (format_info >> 15) & 0x1F;
6781 channel_assignment2 = format_info & 0x1FFF;
6782 if (channel_assignment2)
6783 channel_assignment = channel_assignment2;
6785 channel_assignment = channel_assignment1;
6787 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6788 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6789 st->codecpar->channels = truehd_channels(channel_assignment);
6790 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6795 static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6799 AVDOVIDecoderConfigurationRecord *dovi;
6803 if (c->fc->nb_streams < 1)
6805 st = c->fc->streams[c->fc->nb_streams-1];
6807 if ((uint64_t)atom.size > (1<<30) || atom.size < 4)
6808 return AVERROR_INVALIDDATA;
6810 dovi = av_dovi_alloc(&dovi_size);
6812 return AVERROR(ENOMEM);
6814 dovi->dv_version_major = avio_r8(pb);
6815 dovi->dv_version_minor = avio_r8(pb);
6817 buf = avio_rb16(pb);
6818 dovi->dv_profile = (buf >> 9) & 0x7f; // 7 bits
6819 dovi->dv_level = (buf >> 3) & 0x3f; // 6 bits
6820 dovi->rpu_present_flag = (buf >> 2) & 0x01; // 1 bit
6821 dovi->el_present_flag = (buf >> 1) & 0x01; // 1 bit
6822 dovi->bl_present_flag = buf & 0x01; // 1 bit
6823 if (atom.size >= 24) { // 4 + 4 + 4 * 4
6825 dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits
6827 // 0 stands for None
6828 // Dolby Vision V1.2.93 profiles and levels
6829 dovi->dv_bl_signal_compatibility_id = 0;
6832 ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF,
6833 (uint8_t *)dovi, dovi_size);
6839 av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC box, version: %d.%d, profile: %d, level: %d, "
6840 "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n",
6841 dovi->dv_version_major, dovi->dv_version_minor,
6842 dovi->dv_profile, dovi->dv_level,
6843 dovi->rpu_present_flag,
6844 dovi->el_present_flag,
6845 dovi->bl_present_flag,
6846 dovi->dv_bl_signal_compatibility_id
6852 static const MOVParseTableEntry mov_default_parse_table[] = {
6853 { MKTAG('A','C','L','R'), mov_read_aclr },
6854 { MKTAG('A','P','R','G'), mov_read_avid },
6855 { MKTAG('A','A','L','P'), mov_read_avid },
6856 { MKTAG('A','R','E','S'), mov_read_ares },
6857 { MKTAG('a','v','s','s'), mov_read_avss },
6858 { MKTAG('a','v','1','C'), mov_read_av1c },
6859 { MKTAG('c','h','p','l'), mov_read_chpl },
6860 { MKTAG('c','o','6','4'), mov_read_stco },
6861 { MKTAG('c','o','l','r'), mov_read_colr },
6862 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6863 { MKTAG('d','i','n','f'), mov_read_default },
6864 { MKTAG('D','p','x','E'), mov_read_dpxe },
6865 { MKTAG('d','r','e','f'), mov_read_dref },
6866 { MKTAG('e','d','t','s'), mov_read_default },
6867 { MKTAG('e','l','s','t'), mov_read_elst },
6868 { MKTAG('e','n','d','a'), mov_read_enda },
6869 { MKTAG('f','i','e','l'), mov_read_fiel },
6870 { MKTAG('a','d','r','m'), mov_read_adrm },
6871 { MKTAG('f','t','y','p'), mov_read_ftyp },
6872 { MKTAG('g','l','b','l'), mov_read_glbl },
6873 { MKTAG('h','d','l','r'), mov_read_hdlr },
6874 { MKTAG('i','l','s','t'), mov_read_ilst },
6875 { MKTAG('j','p','2','h'), mov_read_jp2h },
6876 { MKTAG('m','d','a','t'), mov_read_mdat },
6877 { MKTAG('m','d','h','d'), mov_read_mdhd },
6878 { MKTAG('m','d','i','a'), mov_read_default },
6879 { MKTAG('m','e','t','a'), mov_read_meta },
6880 { MKTAG('m','i','n','f'), mov_read_default },
6881 { MKTAG('m','o','o','f'), mov_read_moof },
6882 { MKTAG('m','o','o','v'), mov_read_moov },
6883 { MKTAG('m','v','e','x'), mov_read_default },
6884 { MKTAG('m','v','h','d'), mov_read_mvhd },
6885 { MKTAG('S','M','I',' '), mov_read_svq3 },
6886 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6887 { MKTAG('a','v','c','C'), mov_read_glbl },
6888 { MKTAG('p','a','s','p'), mov_read_pasp },
6889 { MKTAG('s','i','d','x'), mov_read_sidx },
6890 { MKTAG('s','t','b','l'), mov_read_default },
6891 { MKTAG('s','t','c','o'), mov_read_stco },
6892 { MKTAG('s','t','p','s'), mov_read_stps },
6893 { MKTAG('s','t','r','f'), mov_read_strf },
6894 { MKTAG('s','t','s','c'), mov_read_stsc },
6895 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6896 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6897 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6898 { MKTAG('s','t','t','s'), mov_read_stts },
6899 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6900 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
6901 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6902 { MKTAG('t','f','d','t'), mov_read_tfdt },
6903 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6904 { MKTAG('t','r','a','k'), mov_read_trak },
6905 { MKTAG('t','r','a','f'), mov_read_default },
6906 { MKTAG('t','r','e','f'), mov_read_default },
6907 { MKTAG('t','m','c','d'), mov_read_tmcd },
6908 { MKTAG('c','h','a','p'), mov_read_chap },
6909 { MKTAG('t','r','e','x'), mov_read_trex },
6910 { MKTAG('t','r','u','n'), mov_read_trun },
6911 { MKTAG('u','d','t','a'), mov_read_default },
6912 { MKTAG('w','a','v','e'), mov_read_wave },
6913 { MKTAG('e','s','d','s'), mov_read_esds },
6914 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6915 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6916 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6917 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6918 { MKTAG('w','f','e','x'), mov_read_wfex },
6919 { MKTAG('c','m','o','v'), mov_read_cmov },
6920 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6921 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6922 { MKTAG('s','b','g','p'), mov_read_sbgp },
6923 { MKTAG('h','v','c','C'), mov_read_glbl },
6924 { MKTAG('u','u','i','d'), mov_read_uuid },
6925 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6926 { MKTAG('f','r','e','e'), mov_read_free },
6927 { MKTAG('-','-','-','-'), mov_read_custom },
6928 { MKTAG('s','i','n','f'), mov_read_default },
6929 { MKTAG('f','r','m','a'), mov_read_frma },
6930 { MKTAG('s','e','n','c'), mov_read_senc },
6931 { MKTAG('s','a','i','z'), mov_read_saiz },
6932 { MKTAG('s','a','i','o'), mov_read_saio },
6933 { MKTAG('p','s','s','h'), mov_read_pssh },
6934 { MKTAG('s','c','h','m'), mov_read_schm },
6935 { MKTAG('s','c','h','i'), mov_read_default },
6936 { MKTAG('t','e','n','c'), mov_read_tenc },
6937 { MKTAG('d','f','L','a'), mov_read_dfla },
6938 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6939 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6940 { MKTAG('d','O','p','s'), mov_read_dops },
6941 { MKTAG('d','m','l','p'), mov_read_dmlp },
6942 { MKTAG('S','m','D','m'), mov_read_smdm },
6943 { MKTAG('C','o','L','L'), mov_read_coll },
6944 { MKTAG('v','p','c','C'), mov_read_vpcc },
6945 { MKTAG('m','d','c','v'), mov_read_mdcv },
6946 { MKTAG('c','l','l','i'), mov_read_clli },
6947 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
6948 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
6952 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6954 int64_t total_size = 0;
6958 if (c->atom_depth > 10) {
6959 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6960 return AVERROR_INVALIDDATA;
6965 atom.size = INT64_MAX;
6966 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6967 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
6970 if (atom.size >= 8) {
6971 a.size = avio_rb32(pb);
6972 a.type = avio_rl32(pb);
6973 if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
6974 a.type == MKTAG('h','o','o','v')) &&
6976 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
6978 uint32_t *type = (uint32_t *)buf + 1;
6979 if (avio_read(pb, buf, 8) != 8)
6980 return AVERROR_INVALIDDATA;
6981 avio_seek(pb, -8, SEEK_CUR);
6982 if (*type == MKTAG('m','v','h','d') ||
6983 *type == MKTAG('c','m','o','v')) {
6984 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
6985 a.type = MKTAG('m','o','o','v');
6988 if (atom.type != MKTAG('r','o','o','t') &&
6989 atom.type != MKTAG('m','o','o','v'))
6991 if (a.type == MKTAG('t','r','a','k') || a.type == MKTAG('m','d','a','t'))
6993 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
7000 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
7001 a.size = avio_rb64(pb) - 8;
7005 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
7006 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
7008 a.size = atom.size - total_size + 8;
7013 a.size = FFMIN(a.size, atom.size - total_size);
7015 for (i = 0; mov_default_parse_table[i].type; i++)
7016 if (mov_default_parse_table[i].type == a.type) {
7017 parse = mov_default_parse_table[i].parse;
7021 // container is user data
7022 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
7023 atom.type == MKTAG('i','l','s','t')))
7024 parse = mov_read_udta_string;
7026 // Supports parsing the QuickTime Metadata Keys.
7027 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
7028 if (!parse && c->found_hdlr_mdta &&
7029 atom.type == MKTAG('m','e','t','a') &&
7030 a.type == MKTAG('k','e','y','s') &&
7031 c->meta_keys_count == 0) {
7032 parse = mov_read_keys;
7035 if (!parse) { /* skip leaf atoms data */
7036 avio_skip(pb, a.size);
7038 int64_t start_pos = avio_tell(pb);
7040 int err = parse(c, pb, a);
7045 if (c->found_moov && c->found_mdat &&
7046 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
7047 start_pos + a.size == avio_size(pb))) {
7048 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
7049 c->next_root_atom = start_pos + a.size;
7053 left = a.size - avio_tell(pb) + start_pos;
7054 if (left > 0) /* skip garbage at atom end */
7055 avio_skip(pb, left);
7056 else if (left < 0) {
7057 av_log(c->fc, AV_LOG_WARNING,
7058 "overread end of atom '%.4s' by %"PRId64" bytes\n",
7059 (char*)&a.type, -left);
7060 avio_seek(pb, left, SEEK_CUR);
7064 total_size += a.size;
7067 if (total_size < atom.size && atom.size < 0x7ffff)
7068 avio_skip(pb, atom.size - total_size);
7074 static int mov_probe(const AVProbeData *p)
7079 int moov_offset = -1;
7081 /* check file header */
7084 /* ignore invalid offset */
7085 if ((offset + 8) > (unsigned int)p->buf_size)
7087 tag = AV_RL32(p->buf + offset + 4);
7089 /* check for obvious tags */
7090 case MKTAG('m','o','o','v'):
7091 moov_offset = offset + 4;
7092 case MKTAG('m','d','a','t'):
7093 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
7094 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
7095 case MKTAG('f','t','y','p'):
7096 if (AV_RB32(p->buf+offset) < 8 &&
7097 (AV_RB32(p->buf+offset) != 1 ||
7098 offset + 12 > (unsigned int)p->buf_size ||
7099 AV_RB64(p->buf+offset + 8) == 0)) {
7100 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7101 } else if (tag == MKTAG('f','t','y','p') &&
7102 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
7103 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
7105 score = FFMAX(score, 5);
7107 score = AVPROBE_SCORE_MAX;
7109 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7111 /* those are more common words, so rate then a bit less */
7112 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
7113 case MKTAG('w','i','d','e'):
7114 case MKTAG('f','r','e','e'):
7115 case MKTAG('j','u','n','k'):
7116 case MKTAG('p','i','c','t'):
7117 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
7118 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7120 case MKTAG(0x82,0x82,0x7f,0x7d):
7121 case MKTAG('s','k','i','p'):
7122 case MKTAG('u','u','i','d'):
7123 case MKTAG('p','r','f','l'):
7124 /* if we only find those cause probedata is too small at least rate them */
7125 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7126 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7129 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7132 if(score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
7133 /* moov atom in the header - we should make sure that this is not a
7134 * MOV-packed MPEG-PS */
7135 offset = moov_offset;
7137 while(offset < (p->buf_size - 16)){ /* Sufficient space */
7138 /* We found an actual hdlr atom */
7139 if(AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7140 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7141 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')){
7142 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7143 /* We found a media handler reference atom describing an
7144 * MPEG-PS-in-MOV, return a
7145 * low score to force expanding the probe window until
7146 * mpegps_probe finds what it needs */
7157 // must be done after parsing all trak because there's no order requirement
7158 static void mov_read_chapters(AVFormatContext *s)
7160 MOVContext *mov = s->priv_data;
7162 MOVStreamContext *sc;
7167 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7168 chapter_track = mov->chapter_tracks[j];
7170 for (i = 0; i < s->nb_streams; i++)
7171 if (s->streams[i]->id == chapter_track) {
7176 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7181 cur_pos = avio_tell(sc->pb);
7183 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7184 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7185 if (st->nb_index_entries) {
7186 // Retrieve the first frame, if possible
7188 AVIndexEntry *sample = &st->index_entries[0];
7189 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7190 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7194 if (av_get_packet(sc->pb, &pkt, sample->size) < 0)
7197 st->attached_pic = pkt;
7198 st->attached_pic.stream_index = st->index;
7199 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
7202 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7203 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7204 st->discard = AVDISCARD_ALL;
7205 for (i = 0; i < st->nb_index_entries; i++) {
7206 AVIndexEntry *sample = &st->index_entries[i];
7207 int64_t end = i+1 < st->nb_index_entries ? st->index_entries[i+1].timestamp : st->duration;
7212 if (end < sample->timestamp) {
7213 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7214 end = AV_NOPTS_VALUE;
7217 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7218 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7222 // the first two bytes are the length of the title
7223 len = avio_rb16(sc->pb);
7224 if (len > sample->size-2)
7226 title_len = 2*len + 1;
7227 if (!(title = av_mallocz(title_len)))
7230 // The samples could theoretically be in any encoding if there's an encd
7231 // atom following, but in practice are only utf-8 or utf-16, distinguished
7232 // instead by the presence of a BOM
7236 ch = avio_rb16(sc->pb);
7238 avio_get_str16be(sc->pb, len, title, title_len);
7239 else if (ch == 0xfffe)
7240 avio_get_str16le(sc->pb, len, title, title_len);
7243 if (len == 1 || len == 2)
7246 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7250 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7255 avio_seek(sc->pb, cur_pos, SEEK_SET);
7259 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7260 uint32_t value, int flags)
7263 char buf[AV_TIMECODE_STR_SIZE];
7264 AVRational rate = st->avg_frame_rate;
7265 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7268 av_dict_set(&st->metadata, "timecode",
7269 av_timecode_make_string(&tc, buf, value), 0);
7273 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7275 MOVStreamContext *sc = st->priv_data;
7276 char buf[AV_TIMECODE_STR_SIZE];
7277 int64_t cur_pos = avio_tell(sc->pb);
7278 int hh, mm, ss, ff, drop;
7280 if (!st->nb_index_entries)
7283 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7284 avio_skip(s->pb, 13);
7285 hh = avio_r8(s->pb);
7286 mm = avio_r8(s->pb);
7287 ss = avio_r8(s->pb);
7288 drop = avio_r8(s->pb);
7289 ff = avio_r8(s->pb);
7290 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7291 hh, mm, ss, drop ? ';' : ':', ff);
7292 av_dict_set(&st->metadata, "timecode", buf, 0);
7294 avio_seek(sc->pb, cur_pos, SEEK_SET);
7298 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7300 MOVStreamContext *sc = st->priv_data;
7302 int64_t cur_pos = avio_tell(sc->pb);
7305 if (!st->nb_index_entries)
7308 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7309 value = avio_rb32(s->pb);
7311 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7312 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7313 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7315 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7316 * not the case) and thus assume "frame number format" instead of QT one.
7317 * No sample with tmcd track can be found with a QT timecode at the moment,
7318 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7320 parse_timecode_in_framenum_format(s, st, value, flags);
7322 avio_seek(sc->pb, cur_pos, SEEK_SET);
7326 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7328 if (!index || !*index) return;
7329 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7330 av_encryption_info_free((*index)->encrypted_samples[i]);
7332 av_freep(&(*index)->encrypted_samples);
7333 av_freep(&(*index)->auxiliary_info_sizes);
7334 av_freep(&(*index)->auxiliary_offsets);
7338 static int mov_read_close(AVFormatContext *s)
7340 MOVContext *mov = s->priv_data;
7343 for (i = 0; i < s->nb_streams; i++) {
7344 AVStream *st = s->streams[i];
7345 MOVStreamContext *sc = st->priv_data;
7350 av_freep(&sc->ctts_data);
7351 for (j = 0; j < sc->drefs_count; j++) {
7352 av_freep(&sc->drefs[j].path);
7353 av_freep(&sc->drefs[j].dir);
7355 av_freep(&sc->drefs);
7357 sc->drefs_count = 0;
7359 if (!sc->pb_is_copied)
7360 ff_format_io_close(s, &sc->pb);
7363 av_freep(&sc->chunk_offsets);
7364 av_freep(&sc->stsc_data);
7365 av_freep(&sc->sample_sizes);
7366 av_freep(&sc->keyframes);
7367 av_freep(&sc->stts_data);
7368 av_freep(&sc->sdtp_data);
7369 av_freep(&sc->stps_data);
7370 av_freep(&sc->elst_data);
7371 av_freep(&sc->rap_group);
7372 av_freep(&sc->display_matrix);
7373 av_freep(&sc->index_ranges);
7376 for (j = 0; j < sc->stsd_count; j++)
7377 av_free(sc->extradata[j]);
7378 av_freep(&sc->extradata);
7379 av_freep(&sc->extradata_size);
7381 mov_free_encryption_index(&sc->cenc.encryption_index);
7382 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7383 av_aes_ctr_free(sc->cenc.aes_ctr);
7385 av_freep(&sc->stereo3d);
7386 av_freep(&sc->spherical);
7387 av_freep(&sc->mastering);
7388 av_freep(&sc->coll);
7391 if (mov->dv_demux) {
7392 avformat_free_context(mov->dv_fctx);
7393 mov->dv_fctx = NULL;
7396 if (mov->meta_keys) {
7397 for (i = 1; i < mov->meta_keys_count; i++) {
7398 av_freep(&mov->meta_keys[i]);
7400 av_freep(&mov->meta_keys);
7403 av_freep(&mov->trex_data);
7404 av_freep(&mov->bitrates);
7406 for (i = 0; i < mov->frag_index.nb_items; i++) {
7407 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7408 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7409 mov_free_encryption_index(&frag[j].encryption_index);
7411 av_freep(&mov->frag_index.item[i].stream_info);
7413 av_freep(&mov->frag_index.item);
7415 av_freep(&mov->aes_decrypt);
7416 av_freep(&mov->chapter_tracks);
7421 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7425 for (i = 0; i < s->nb_streams; i++) {
7426 AVStream *st = s->streams[i];
7427 MOVStreamContext *sc = st->priv_data;
7429 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7430 sc->timecode_track == tmcd_id)
7436 /* look for a tmcd track not referenced by any video track, and export it globally */
7437 static void export_orphan_timecode(AVFormatContext *s)
7441 for (i = 0; i < s->nb_streams; i++) {
7442 AVStream *st = s->streams[i];
7444 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7445 !tmcd_is_referenced(s, i + 1)) {
7446 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7448 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7455 static int read_tfra(MOVContext *mov, AVIOContext *f)
7457 int version, fieldlength, i, j;
7458 int64_t pos = avio_tell(f);
7459 uint32_t size = avio_rb32(f);
7460 unsigned track_id, item_count;
7462 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7465 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7467 version = avio_r8(f);
7469 track_id = avio_rb32(f);
7470 fieldlength = avio_rb32(f);
7471 item_count = avio_rb32(f);
7472 for (i = 0; i < item_count; i++) {
7473 int64_t time, offset;
7475 MOVFragmentStreamInfo * frag_stream_info;
7478 return AVERROR_INVALIDDATA;
7482 time = avio_rb64(f);
7483 offset = avio_rb64(f);
7485 time = avio_rb32(f);
7486 offset = avio_rb32(f);
7489 // The first sample of each stream in a fragment is always a random
7490 // access sample. So it's entry in the tfra can be used as the
7491 // initial PTS of the fragment.
7492 index = update_frag_index(mov, offset);
7493 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7494 if (frag_stream_info &&
7495 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7496 frag_stream_info->first_tfra_pts = time;
7498 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7500 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7502 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7506 avio_seek(f, pos + size, SEEK_SET);
7510 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7512 int64_t stream_size = avio_size(f);
7513 int64_t original_pos = avio_tell(f);
7517 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7521 mfra_size = avio_rb32(f);
7522 if (mfra_size < 0 || mfra_size > stream_size) {
7523 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7526 if ((seek_ret = avio_seek(f, -mfra_size, SEEK_CUR)) < 0) {
7530 if (avio_rb32(f) != mfra_size) {
7531 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7534 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7535 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7538 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7540 ret = read_tfra(c, f);
7546 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7548 av_log(c->fc, AV_LOG_ERROR,
7549 "failed to seek back after looking for mfra\n");
7555 static int mov_read_header(AVFormatContext *s)
7557 MOVContext *mov = s->priv_data;
7558 AVIOContext *pb = s->pb;
7560 MOVAtom atom = { AV_RL32("root") };
7563 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7564 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7565 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7566 return AVERROR(EINVAL);
7570 mov->trak_index = -1;
7571 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7572 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7573 atom.size = avio_size(pb);
7575 atom.size = INT64_MAX;
7577 /* check MOV header */
7579 if (mov->moov_retry)
7580 avio_seek(pb, 0, SEEK_SET);
7581 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7582 av_log(s, AV_LOG_ERROR, "error reading header\n");
7585 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7586 if (!mov->found_moov) {
7587 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7588 err = AVERROR_INVALIDDATA;
7591 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7593 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7594 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7595 mov_read_chapters(s);
7596 for (i = 0; i < s->nb_streams; i++)
7597 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7598 mov_read_timecode_track(s, s->streams[i]);
7599 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7600 mov_read_rtmd_track(s, s->streams[i]);
7604 /* copy timecode metadata from tmcd tracks to the related video streams */
7605 for (i = 0; i < s->nb_streams; i++) {
7606 AVStream *st = s->streams[i];
7607 MOVStreamContext *sc = st->priv_data;
7608 if (sc->timecode_track > 0) {
7609 AVDictionaryEntry *tcr;
7610 int tmcd_st_id = -1;
7612 for (j = 0; j < s->nb_streams; j++)
7613 if (s->streams[j]->id == sc->timecode_track)
7616 if (tmcd_st_id < 0 || tmcd_st_id == i)
7618 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7620 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7623 export_orphan_timecode(s);
7625 for (i = 0; i < s->nb_streams; i++) {
7626 AVStream *st = s->streams[i];
7627 MOVStreamContext *sc = st->priv_data;
7628 fix_timescale(mov, sc);
7629 if(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7630 st->skip_samples = sc->start_pad;
7632 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7633 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7634 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7635 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7636 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7637 st->codecpar->width = sc->width;
7638 st->codecpar->height = sc->height;
7640 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7641 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7645 if (mov->handbrake_version &&
7646 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7647 st->codecpar->codec_id == AV_CODEC_ID_MP3
7649 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7650 st->need_parsing = AVSTREAM_PARSE_FULL;
7654 if (mov->trex_data) {
7655 for (i = 0; i < s->nb_streams; i++) {
7656 AVStream *st = s->streams[i];
7657 MOVStreamContext *sc = st->priv_data;
7658 if (st->duration > 0) {
7659 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7660 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7661 sc->data_size, sc->time_scale);
7662 err = AVERROR_INVALIDDATA;
7665 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7670 if (mov->use_mfra_for > 0) {
7671 for (i = 0; i < s->nb_streams; i++) {
7672 AVStream *st = s->streams[i];
7673 MOVStreamContext *sc = st->priv_data;
7674 if (sc->duration_for_fps > 0) {
7675 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7676 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7677 sc->data_size, sc->time_scale);
7678 err = AVERROR_INVALIDDATA;
7681 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7682 sc->duration_for_fps;
7687 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7688 if (mov->bitrates[i]) {
7689 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7693 ff_rfps_calculate(s);
7695 for (i = 0; i < s->nb_streams; i++) {
7696 AVStream *st = s->streams[i];
7697 MOVStreamContext *sc = st->priv_data;
7699 switch (st->codecpar->codec_type) {
7700 case AVMEDIA_TYPE_AUDIO:
7701 err = ff_replaygain_export(st, s->metadata);
7706 case AVMEDIA_TYPE_VIDEO:
7707 if (sc->display_matrix) {
7708 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7709 sizeof(int32_t) * 9);
7713 sc->display_matrix = NULL;
7716 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7717 (uint8_t *)sc->stereo3d,
7718 sizeof(*sc->stereo3d));
7722 sc->stereo3d = NULL;
7724 if (sc->spherical) {
7725 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7726 (uint8_t *)sc->spherical,
7727 sc->spherical_size);
7731 sc->spherical = NULL;
7733 if (sc->mastering) {
7734 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7735 (uint8_t *)sc->mastering,
7736 sizeof(*sc->mastering));
7740 sc->mastering = NULL;
7743 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7744 (uint8_t *)sc->coll,
7754 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7756 for (i = 0; i < mov->frag_index.nb_items; i++)
7757 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7758 mov->frag_index.item[i].headers_read = 1;
7766 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7768 AVIndexEntry *sample = NULL;
7769 int64_t best_dts = INT64_MAX;
7771 for (i = 0; i < s->nb_streams; i++) {
7772 AVStream *avst = s->streams[i];
7773 MOVStreamContext *msc = avst->priv_data;
7774 if (msc->pb && msc->current_sample < avst->nb_index_entries) {
7775 AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample];
7776 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7777 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7778 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7779 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7780 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
7781 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7782 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7783 sample = current_sample;
7792 static int should_retry(AVIOContext *pb, int error_code) {
7793 if (error_code == AVERROR_EOF || avio_feof(pb))
7799 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7802 MOVContext *mov = s->priv_data;
7804 if (index >= 0 && index < mov->frag_index.nb_items)
7805 target = mov->frag_index.item[index].moof_offset;
7806 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7807 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7808 return AVERROR_INVALIDDATA;
7811 mov->next_root_atom = 0;
7812 if (index < 0 || index >= mov->frag_index.nb_items)
7813 index = search_frag_moof_offset(&mov->frag_index, target);
7814 if (index < mov->frag_index.nb_items &&
7815 mov->frag_index.item[index].moof_offset == target) {
7816 if (index + 1 < mov->frag_index.nb_items)
7817 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7818 if (mov->frag_index.item[index].headers_read)
7820 mov->frag_index.item[index].headers_read = 1;
7823 mov->found_mdat = 0;
7825 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7828 if (avio_feof(s->pb))
7830 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7835 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7837 uint8_t *side, *extradata;
7840 /* Save the current index. */
7841 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7843 /* Notify the decoder that extradata changed. */
7844 extradata_size = sc->extradata_size[sc->last_stsd_index];
7845 extradata = sc->extradata[sc->last_stsd_index];
7846 if (extradata_size > 0 && extradata) {
7847 side = av_packet_new_side_data(pkt,
7848 AV_PKT_DATA_NEW_EXTRADATA,
7851 return AVERROR(ENOMEM);
7852 memcpy(side, extradata, extradata_size);
7858 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7860 MOVContext *mov = s->priv_data;
7861 MOVStreamContext *sc;
7862 AVIndexEntry *sample;
7863 AVStream *st = NULL;
7864 int64_t current_index;
7868 sample = mov_find_next_sample(s, &st);
7869 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7870 if (!mov->next_root_atom)
7872 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7877 /* must be done just before reading, to avoid infinite loop on sample */
7878 current_index = sc->current_index;
7879 mov_current_sample_inc(sc);
7881 if (mov->next_root_atom) {
7882 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7883 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7886 if (st->discard != AVDISCARD_ALL) {
7887 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7888 if (ret64 != sample->pos) {
7889 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7890 sc->ffindex, sample->pos);
7891 if (should_retry(sc->pb, ret64)) {
7892 mov_current_sample_dec(sc);
7894 return AVERROR_INVALIDDATA;
7897 if( st->discard == AVDISCARD_NONKEY && 0==(sample->flags & AVINDEX_KEYFRAME) ) {
7898 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7902 ret = av_get_packet(sc->pb, pkt, sample->size);
7904 if (should_retry(sc->pb, ret)) {
7905 mov_current_sample_dec(sc);
7909 if (sc->has_palette) {
7912 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7914 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7916 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7917 sc->has_palette = 0;
7920 #if CONFIG_DV_DEMUXER
7921 if (mov->dv_demux && sc->dv_audio_container) {
7922 avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7923 av_freep(&pkt->data);
7925 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7930 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7931 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7932 st->need_parsing = AVSTREAM_PARSE_FULL;
7936 pkt->stream_index = sc->ffindex;
7937 pkt->dts = sample->timestamp;
7938 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7939 pkt->flags |= AV_PKT_FLAG_DISCARD;
7941 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7942 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
7943 /* update ctts context */
7945 if (sc->ctts_index < sc->ctts_count &&
7946 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
7948 sc->ctts_sample = 0;
7951 int64_t next_dts = (sc->current_sample < st->nb_index_entries) ?
7952 st->index_entries[sc->current_sample].timestamp : st->duration;
7954 if (next_dts >= pkt->dts)
7955 pkt->duration = next_dts - pkt->dts;
7956 pkt->pts = pkt->dts;
7958 if (st->discard == AVDISCARD_ALL)
7960 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
7961 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
7962 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
7963 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
7965 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
7966 pkt->pos = sample->pos;
7968 /* Multiple stsd handling. */
7969 if (sc->stsc_data) {
7970 /* Keep track of the stsc index for the given sample, then check
7971 * if the stsd index is different from the last used one. */
7973 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
7974 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
7976 sc->stsc_sample = 0;
7977 /* Do not check indexes after a switch. */
7978 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
7979 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
7980 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
7981 ret = mov_change_extradata(sc, pkt);
7988 aax_filter(pkt->data, pkt->size, mov);
7990 ret = cenc_filter(mov, st, sc, pkt, current_index);
7998 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
8000 MOVContext *mov = s->priv_data;
8003 if (!mov->frag_index.complete)
8006 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
8009 if (!mov->frag_index.item[index].headers_read)
8010 return mov_switch_root(s, -1, index);
8011 if (index + 1 < mov->frag_index.nb_items)
8012 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
8017 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
8019 MOVStreamContext *sc = st->priv_data;
8020 int sample, time_sample, ret;
8023 // Here we consider timestamp to be PTS, hence try to offset it so that we
8024 // can search over the DTS timeline.
8025 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
8027 ret = mov_seek_fragment(s, st, timestamp);
8031 sample = av_index_search_timestamp(st, timestamp, flags);
8032 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
8033 if (sample < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp)
8035 if (sample < 0) /* not sure what to do */
8036 return AVERROR_INVALIDDATA;
8037 mov_current_sample_set(sc, sample);
8038 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
8039 /* adjust ctts index */
8040 if (sc->ctts_data) {
8042 for (i = 0; i < sc->ctts_count; i++) {
8043 int next = time_sample + sc->ctts_data[i].count;
8044 if (next > sc->current_sample) {
8046 sc->ctts_sample = sc->current_sample - time_sample;
8053 /* adjust stsd index */
8054 if (sc->chunk_count) {
8056 for (i = 0; i < sc->stsc_count; i++) {
8057 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
8058 if (next > sc->current_sample) {
8060 sc->stsc_sample = sc->current_sample - time_sample;
8063 av_assert0(next == (int)next);
8071 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
8073 MOVContext *mc = s->priv_data;
8078 if (stream_index >= s->nb_streams)
8079 return AVERROR_INVALIDDATA;
8081 st = s->streams[stream_index];
8082 sample = mov_seek_stream(s, st, sample_time, flags);
8086 if (mc->seek_individually) {
8087 /* adjust seek timestamp to found sample timestamp */
8088 int64_t seek_timestamp = st->index_entries[sample].timestamp;
8090 for (i = 0; i < s->nb_streams; i++) {
8092 MOVStreamContext *sc = s->streams[i]->priv_data;
8094 st->skip_samples = (sample_time <= 0) ? sc->start_pad : 0;
8096 if (stream_index == i)
8099 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
8100 mov_seek_stream(s, st, timestamp, flags);
8103 for (i = 0; i < s->nb_streams; i++) {
8104 MOVStreamContext *sc;
8107 mov_current_sample_set(sc, 0);
8110 MOVStreamContext *sc;
8111 AVIndexEntry *entry = mov_find_next_sample(s, &st);
8113 return AVERROR_INVALIDDATA;
8115 if (sc->ffindex == stream_index && sc->current_sample == sample)
8117 mov_current_sample_inc(sc);
8123 #define OFFSET(x) offsetof(MOVContext, x)
8124 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
8125 static const AVOption mov_options[] = {
8126 {"use_absolute_path",
8127 "allow using absolute path when opening alias, this is a possible security issue",
8128 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
8130 {"seek_streams_individually",
8131 "Seek each stream individually to the closest point",
8132 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
8134 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
8136 {"advanced_editlist",
8137 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
8138 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
8140 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8143 "use mfra for fragment timestamps",
8144 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8145 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8147 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8148 FLAGS, "use_mfra_for" },
8149 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8150 FLAGS, "use_mfra_for" },
8151 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8152 FLAGS, "use_mfra_for" },
8153 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8154 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8155 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8156 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8157 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8158 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8159 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8160 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8161 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8162 .flags = AV_OPT_FLAG_DECODING_PARAM },
8163 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8164 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8165 {.i64 = 0}, 0, 1, FLAGS },
8170 static const AVClass mov_class = {
8171 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8172 .item_name = av_default_item_name,
8173 .option = mov_options,
8174 .version = LIBAVUTIL_VERSION_INT,
8177 AVInputFormat ff_mov_demuxer = {
8178 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8179 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8180 .priv_class = &mov_class,
8181 .priv_data_size = sizeof(MOVContext),
8182 .extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
8183 .read_probe = mov_probe,
8184 .read_header = mov_read_header,
8185 .read_packet = mov_read_packet,
8186 .read_close = mov_read_close,
8187 .read_seek = mov_read_seek,
8188 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,