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 "libavcodec/ac3tab.h"
50 #include "libavcodec/flac.h"
51 #include "libavcodec/mpegaudiodecheader.h"
52 #include "libavcodec/mlp_parse.h"
55 #include "avio_internal.h"
58 #include "libavcodec/get_bits.h"
61 #include "replaygain.h"
67 #include "qtpalette.h"
69 /* those functions parse an atom */
70 /* links atom IDs to parse functions */
71 typedef struct MOVParseTableEntry {
73 int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
76 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
77 static int mov_read_mfra(MOVContext *c, AVIOContext *f);
78 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
79 int count, int duration);
81 static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb,
82 unsigned len, const char *key)
86 short current, total = 0;
87 avio_rb16(pb); // unknown
88 current = avio_rb16(pb);
90 total = avio_rb16(pb);
92 snprintf(buf, sizeof(buf), "%d", current);
94 snprintf(buf, sizeof(buf), "%d/%d", current, total);
95 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
96 av_dict_set(&c->fc->metadata, key, buf, 0);
101 static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb,
102 unsigned len, const char *key)
104 /* bypass padding bytes */
109 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
110 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
115 static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb,
116 unsigned len, const char *key)
118 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
119 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
124 static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb,
125 unsigned len, const char *key)
129 avio_r8(pb); // unknown
132 if (genre < 1 || genre > ID3v1_GENRE_MAX)
134 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
135 av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
140 static const uint32_t mac_to_unicode[128] = {
141 0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
142 0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
143 0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
144 0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
145 0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
146 0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
147 0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
148 0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
149 0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
150 0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
151 0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
152 0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
153 0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
154 0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
155 0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
156 0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
159 static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len,
160 char *dst, int dstlen)
163 char *end = dst+dstlen-1;
166 for (i = 0; i < len; i++) {
167 uint8_t t, c = avio_r8(pb);
175 PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
181 static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
185 MOVStreamContext *sc;
190 case 0xd: id = AV_CODEC_ID_MJPEG; break;
191 case 0xe: id = AV_CODEC_ID_PNG; break;
192 case 0x1b: id = AV_CODEC_ID_BMP; break;
194 av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
199 st = avformat_new_stream(c->fc, NULL);
201 return AVERROR(ENOMEM);
202 sc = av_mallocz(sizeof(*sc));
204 return AVERROR(ENOMEM);
207 ret = av_get_packet(pb, &pkt, len);
211 if (pkt.size >= 8 && id != AV_CODEC_ID_BMP) {
212 if (AV_RB64(pkt.data) == 0x89504e470d0a1a0a) {
213 id = AV_CODEC_ID_PNG;
215 id = AV_CODEC_ID_MJPEG;
219 st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
221 st->attached_pic = pkt;
222 st->attached_pic.stream_index = st->index;
223 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
225 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
226 st->codecpar->codec_id = id;
232 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
234 char language[4] = { 0 };
235 char buf[200], place[100];
236 uint16_t langcode = 0;
237 double longitude, latitude, altitude;
238 const char *key = "location";
240 if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
241 av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
242 return AVERROR_INVALIDDATA;
245 avio_skip(pb, 4); // version+flags
246 langcode = avio_rb16(pb);
247 ff_mov_lang_to_iso639(langcode, language);
250 len -= avio_get_str(pb, len, place, sizeof(place));
252 av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
253 return AVERROR_INVALIDDATA;
255 avio_skip(pb, 1); // role
259 av_log(c->fc, AV_LOG_ERROR,
260 "loci too short (%u bytes left, need at least %d)\n", len, 12);
261 return AVERROR_INVALIDDATA;
263 longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
264 latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
265 altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
267 // Try to output in the same format as the ?xyz field
268 snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
270 av_strlcatf(buf, sizeof(buf), "%+f", altitude);
271 av_strlcatf(buf, sizeof(buf), "/%s", place);
273 if (*language && strcmp(language, "und")) {
275 snprintf(key2, sizeof(key2), "%s-%s", key, language);
276 av_dict_set(&c->fc->metadata, key2, buf, 0);
278 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
279 return av_dict_set(&c->fc->metadata, key, buf, 0);
282 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
288 if (c->ignore_chapters)
291 n_hmmt = avio_rb32(pb);
292 for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
293 int moment_time = avio_rb32(pb);
294 avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
299 static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
302 char key2[32], language[4] = {0};
304 const char *key = NULL;
305 uint16_t langcode = 0;
306 uint32_t data_type = 0, str_size, str_size_alloc;
307 int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
312 case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
313 case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
314 case MKTAG( 'X','M','P','_'):
315 if (c->export_xmp) { key = "xmp"; raw = 1; } break;
316 case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
317 case MKTAG( 'a','k','I','D'): key = "account_type";
318 parse = mov_metadata_int8_no_padding; break;
319 case MKTAG( 'a','p','I','D'): key = "account_id"; break;
320 case MKTAG( 'c','a','t','g'): key = "category"; break;
321 case MKTAG( 'c','p','i','l'): key = "compilation";
322 parse = mov_metadata_int8_no_padding; break;
323 case MKTAG( 'c','p','r','t'): key = "copyright"; break;
324 case MKTAG( 'd','e','s','c'): key = "description"; break;
325 case MKTAG( 'd','i','s','k'): key = "disc";
326 parse = mov_metadata_track_or_disc_number; break;
327 case MKTAG( 'e','g','i','d'): key = "episode_uid";
328 parse = mov_metadata_int8_no_padding; break;
329 case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
330 case MKTAG( 'g','n','r','e'): key = "genre";
331 parse = mov_metadata_gnre; break;
332 case MKTAG( 'h','d','v','d'): key = "hd_video";
333 parse = mov_metadata_int8_no_padding; break;
334 case MKTAG( 'H','M','M','T'):
335 return mov_metadata_hmmt(c, pb, atom.size);
336 case MKTAG( 'k','e','y','w'): key = "keywords"; break;
337 case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
338 case MKTAG( 'l','o','c','i'):
339 return mov_metadata_loci(c, pb, atom.size);
340 case MKTAG( 'm','a','n','u'): key = "make"; break;
341 case MKTAG( 'm','o','d','l'): key = "model"; break;
342 case MKTAG( 'p','c','s','t'): key = "podcast";
343 parse = mov_metadata_int8_no_padding; break;
344 case MKTAG( 'p','g','a','p'): key = "gapless_playback";
345 parse = mov_metadata_int8_no_padding; break;
346 case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
347 case MKTAG( 'r','t','n','g'): key = "rating";
348 parse = mov_metadata_int8_no_padding; break;
349 case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
350 case MKTAG( 's','o','a','l'): key = "sort_album"; break;
351 case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
352 case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
353 case MKTAG( 's','o','n','m'): key = "sort_name"; break;
354 case MKTAG( 's','o','s','n'): key = "sort_show"; break;
355 case MKTAG( 's','t','i','k'): key = "media_type";
356 parse = mov_metadata_int8_no_padding; break;
357 case MKTAG( 't','r','k','n'): key = "track";
358 parse = mov_metadata_track_or_disc_number; break;
359 case MKTAG( 't','v','e','n'): key = "episode_id"; break;
360 case MKTAG( 't','v','e','s'): key = "episode_sort";
361 parse = mov_metadata_int8_bypass_padding; break;
362 case MKTAG( 't','v','n','n'): key = "network"; break;
363 case MKTAG( 't','v','s','h'): key = "show"; break;
364 case MKTAG( 't','v','s','n'): key = "season_number";
365 parse = mov_metadata_int8_bypass_padding; break;
366 case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
367 case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
368 case MKTAG(0xa9,'a','l','b'): key = "album"; break;
369 case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
370 case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
371 case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
372 case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
373 case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
374 case MKTAG(0xa9,'d','a','y'): key = "date"; break;
375 case MKTAG(0xa9,'d','i','r'): key = "director"; break;
376 case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
377 case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
378 case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
379 case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
380 case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
381 case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
382 case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
383 case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
384 case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
385 case MKTAG(0xa9,'m','a','k'): key = "make"; break;
386 case MKTAG(0xa9,'m','o','d'): key = "model"; break;
387 case MKTAG(0xa9,'n','a','m'): key = "title"; break;
388 case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
389 case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
390 case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
391 case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
392 case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
393 case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
394 case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
395 case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
396 case MKTAG(0xa9,'t','r','k'): key = "track"; break;
397 case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
398 case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
399 case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
400 case MKTAG(0xa9,'x','y','z'): key = "location"; break;
403 if (c->itunes_metadata && atom.size > 8) {
404 int data_size = avio_rb32(pb);
405 int tag = avio_rl32(pb);
406 if (tag == MKTAG('d','a','t','a') && data_size <= atom.size) {
407 data_type = avio_rb32(pb); // type
408 avio_rb32(pb); // unknown
409 str_size = data_size - 16;
412 if (atom.type == MKTAG('c', 'o', 'v', 'r')) {
413 int ret = mov_read_covr(c, pb, data_type, str_size);
415 av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
418 atom.size -= str_size;
422 } else if (!key && c->found_hdlr_mdta && c->meta_keys) {
423 uint32_t index = AV_RB32(&atom.type);
424 if (index < c->meta_keys_count && index > 0) {
425 key = c->meta_keys[index];
427 av_log(c->fc, AV_LOG_WARNING,
428 "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
429 index, c->meta_keys_count);
433 } else if (atom.size > 4 && key && !c->itunes_metadata && !raw) {
434 str_size = avio_rb16(pb); // string length
435 if (str_size > atom.size) {
437 avio_seek(pb, -2, SEEK_CUR);
438 av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
441 langcode = avio_rb16(pb);
442 ff_mov_lang_to_iso639(langcode, language);
445 str_size = atom.size;
447 if (c->export_all && !key) {
448 snprintf(tmp_key, 5, "%.4s", (char*)&atom.type);
454 if (atom.size < 0 || str_size >= INT_MAX/2)
455 return AVERROR_INVALIDDATA;
457 // Allocates enough space if data_type is a int32 or float32 number, otherwise
458 // worst-case requirement for output string in case of utf8 coded input
459 num = (data_type >= 21 && data_type <= 23);
460 str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
461 str = av_mallocz(str_size_alloc);
463 return AVERROR(ENOMEM);
466 parse(c, pb, str_size, key);
468 if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
469 mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
470 } else if (data_type == 21) { // BE signed integer, variable size
473 val = (int8_t)avio_r8(pb);
474 else if (str_size == 2)
475 val = (int16_t)avio_rb16(pb);
476 else if (str_size == 3)
477 val = ((int32_t)(avio_rb24(pb)<<8))>>8;
478 else if (str_size == 4)
479 val = (int32_t)avio_rb32(pb);
480 if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
481 av_log(c->fc, AV_LOG_ERROR,
482 "Failed to store the number (%d) in string.\n", val);
484 return AVERROR_INVALIDDATA;
486 } else if (data_type == 22) { // BE unsigned integer, variable size
487 unsigned int val = 0;
490 else if (str_size == 2)
492 else if (str_size == 3)
494 else if (str_size == 4)
496 if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
497 av_log(c->fc, AV_LOG_ERROR,
498 "Failed to store the number (%u) in string.\n", val);
500 return AVERROR_INVALIDDATA;
502 } else if (data_type == 23 && str_size >= 4) { // BE float32
503 float val = av_int2float(avio_rb32(pb));
504 if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
505 av_log(c->fc, AV_LOG_ERROR,
506 "Failed to store the float32 number (%f) in string.\n", val);
508 return AVERROR_INVALIDDATA;
511 int ret = ffio_read_size(pb, str, str_size);
518 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
519 av_dict_set(&c->fc->metadata, key, str, 0);
520 if (*language && strcmp(language, "und")) {
521 snprintf(key2, sizeof(key2), "%s-%s", key, language);
522 av_dict_set(&c->fc->metadata, key2, str, 0);
524 if (!strcmp(key, "encoder")) {
525 int major, minor, micro;
526 if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, µ) == 3) {
527 c->handbrake_version = 1000000*major + 1000*minor + micro;
536 static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
539 int i, nb_chapters, str_len, version;
543 if (c->ignore_chapters)
546 if ((atom.size -= 5) < 0)
549 version = avio_r8(pb);
552 avio_rb32(pb); // ???
553 nb_chapters = avio_r8(pb);
555 for (i = 0; i < nb_chapters; i++) {
559 start = avio_rb64(pb);
560 str_len = avio_r8(pb);
562 if ((atom.size -= 9+str_len) < 0)
565 ret = ffio_read_size(pb, str, str_len);
569 avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
574 #define MIN_DATA_ENTRY_BOX_SIZE 12
575 static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
578 MOVStreamContext *sc;
581 if (c->fc->nb_streams < 1)
583 st = c->fc->streams[c->fc->nb_streams-1];
586 avio_rb32(pb); // version + flags
587 entries = avio_rb32(pb);
589 entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
590 entries >= UINT_MAX / sizeof(*sc->drefs))
591 return AVERROR_INVALIDDATA;
595 sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
597 return AVERROR(ENOMEM);
598 sc->drefs_count = entries;
600 for (i = 0; i < entries; i++) {
601 MOVDref *dref = &sc->drefs[i];
602 uint32_t size = avio_rb32(pb);
603 int64_t next = avio_tell(pb) + size - 4;
606 return AVERROR_INVALIDDATA;
608 dref->type = avio_rl32(pb);
609 avio_rb32(pb); // version + flags
611 if (dref->type == MKTAG('a','l','i','s') && size > 150) {
612 /* macintosh alias record */
613 uint16_t volume_len, len;
619 volume_len = avio_r8(pb);
620 volume_len = FFMIN(volume_len, 27);
621 ret = ffio_read_size(pb, dref->volume, 27);
624 dref->volume[volume_len] = 0;
625 av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
630 len = FFMIN(len, 63);
631 ret = ffio_read_size(pb, dref->filename, 63);
634 dref->filename[len] = 0;
635 av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
639 /* read next level up_from_alias/down_to_target */
640 dref->nlvl_from = avio_rb16(pb);
641 dref->nlvl_to = avio_rb16(pb);
642 av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
643 dref->nlvl_from, dref->nlvl_to);
647 for (type = 0; type != -1 && avio_tell(pb) < next; ) {
650 type = avio_rb16(pb);
652 av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
655 if (type == 2) { // absolute path
657 dref->path = av_mallocz(len+1);
659 return AVERROR(ENOMEM);
661 ret = ffio_read_size(pb, dref->path, len);
663 av_freep(&dref->path);
666 if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
668 memmove(dref->path, dref->path+volume_len, len);
671 // trim string of any ending zeros
672 for (j = len - 1; j >= 0; j--) {
673 if (dref->path[j] == 0)
678 for (j = 0; j < len; j++)
679 if (dref->path[j] == ':' || dref->path[j] == 0)
681 av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
682 } else if (type == 0) { // directory name
684 dref->dir = av_malloc(len+1);
686 return AVERROR(ENOMEM);
688 ret = ffio_read_size(pb, dref->dir, len);
690 av_freep(&dref->dir);
694 for (j = 0; j < len; j++)
695 if (dref->dir[j] == ':')
697 av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
702 av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
707 avio_seek(pb, next, SEEK_SET);
712 static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
721 avio_r8(pb); /* version */
722 avio_rb24(pb); /* flags */
725 ctype = avio_rl32(pb);
726 type = avio_rl32(pb); /* component subtype */
728 av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
729 av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
731 if (c->trak_index < 0) { // meta not inside a trak
732 if (type == MKTAG('m','d','t','a')) {
733 c->found_hdlr_mdta = 1;
738 st = c->fc->streams[c->fc->nb_streams-1];
740 if (type == MKTAG('v','i','d','e'))
741 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
742 else if (type == MKTAG('s','o','u','n'))
743 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
744 else if (type == MKTAG('m','1','a',' '))
745 st->codecpar->codec_id = AV_CODEC_ID_MP2;
746 else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
747 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
749 avio_rb32(pb); /* component manufacture */
750 avio_rb32(pb); /* component flags */
751 avio_rb32(pb); /* component flags mask */
753 title_size = atom.size - 24;
754 if (title_size > 0) {
755 if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
756 return AVERROR_INVALIDDATA;
757 title_str = av_malloc(title_size + 1); /* Add null terminator */
759 return AVERROR(ENOMEM);
761 ret = ffio_read_size(pb, title_str, title_size);
763 av_freep(&title_str);
766 title_str[title_size] = 0;
768 int off = (!c->isom && title_str[0] == title_size - 1);
769 // flag added so as to not set stream handler name if already set from mdia->hdlr
770 av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
772 av_freep(&title_str);
778 static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
780 return ff_mov_read_esds(c->fc, pb);
783 static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
786 enum AVAudioServiceType *ast;
787 int ac3info, acmod, lfeon, bsmod;
789 if (c->fc->nb_streams < 1)
791 st = c->fc->streams[c->fc->nb_streams-1];
793 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
796 return AVERROR(ENOMEM);
798 ac3info = avio_rb24(pb);
799 bsmod = (ac3info >> 14) & 0x7;
800 acmod = (ac3info >> 11) & 0x7;
801 lfeon = (ac3info >> 10) & 0x1;
802 st->codecpar->channels = ((int[]){2,1,2,3,3,4,4,5})[acmod] + lfeon;
803 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
805 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
807 if (st->codecpar->channels > 1 && bsmod == 0x7)
808 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
810 #if FF_API_LAVF_AVCTX
811 FF_DISABLE_DEPRECATION_WARNINGS
812 st->codec->audio_service_type = *ast;
813 FF_ENABLE_DEPRECATION_WARNINGS
819 static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
822 enum AVAudioServiceType *ast;
823 int eac3info, acmod, lfeon, bsmod;
825 if (c->fc->nb_streams < 1)
827 st = c->fc->streams[c->fc->nb_streams-1];
829 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
832 return AVERROR(ENOMEM);
834 /* No need to parse fields for additional independent substreams and its
835 * associated dependent substreams since libavcodec's E-AC-3 decoder
836 * does not support them yet. */
837 avio_rb16(pb); /* data_rate and num_ind_sub */
838 eac3info = avio_rb24(pb);
839 bsmod = (eac3info >> 12) & 0x1f;
840 acmod = (eac3info >> 9) & 0x7;
841 lfeon = (eac3info >> 8) & 0x1;
842 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
844 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
845 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
847 if (st->codecpar->channels > 1 && bsmod == 0x7)
848 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
850 #if FF_API_LAVF_AVCTX
851 FF_DISABLE_DEPRECATION_WARNINGS
852 st->codec->audio_service_type = *ast;
853 FF_ENABLE_DEPRECATION_WARNINGS
859 static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
861 const uint32_t ddts_size = 20;
864 uint32_t frame_duration_code = 0;
865 uint32_t channel_layout_code = 0;
868 buf = av_malloc(ddts_size + AV_INPUT_BUFFER_PADDING_SIZE);
870 return AVERROR(ENOMEM);
872 if (avio_read(pb, buf, ddts_size) < ddts_size) {
874 return AVERROR_INVALIDDATA;
877 init_get_bits(&gb, buf, 8*ddts_size);
879 if (c->fc->nb_streams < 1) {
883 st = c->fc->streams[c->fc->nb_streams-1];
885 st->codecpar->sample_rate = get_bits_long(&gb, 32);
886 if (st->codecpar->sample_rate <= 0) {
887 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
889 return AVERROR_INVALIDDATA;
891 skip_bits_long(&gb, 32); /* max bitrate */
892 st->codecpar->bit_rate = get_bits_long(&gb, 32);
893 st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
894 frame_duration_code = get_bits(&gb, 2);
895 skip_bits(&gb, 30); /* various fields */
896 channel_layout_code = get_bits(&gb, 16);
898 st->codecpar->frame_size =
899 (frame_duration_code == 0) ? 512 :
900 (frame_duration_code == 1) ? 1024 :
901 (frame_duration_code == 2) ? 2048 :
902 (frame_duration_code == 3) ? 4096 : 0;
904 if (channel_layout_code > 0xff) {
905 av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout");
907 st->codecpar->channel_layout =
908 ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
909 ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
910 ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
911 ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
912 ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
913 ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0);
915 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
921 static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
925 if (c->fc->nb_streams < 1)
927 st = c->fc->streams[c->fc->nb_streams-1];
932 /* skip version and flags */
935 ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
940 static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
945 if (c->fc->nb_streams < 1)
947 st = c->fc->streams[c->fc->nb_streams-1];
949 if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
950 av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
955 static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
957 const int num = avio_rb32(pb);
958 const int den = avio_rb32(pb);
961 if (c->fc->nb_streams < 1)
963 st = c->fc->streams[c->fc->nb_streams-1];
965 if ((st->sample_aspect_ratio.den != 1 || st->sample_aspect_ratio.num) && // default
966 (den != st->sample_aspect_ratio.den || num != st->sample_aspect_ratio.num)) {
967 av_log(c->fc, AV_LOG_WARNING,
968 "sample aspect ratio already set to %d:%d, ignoring 'pasp' atom (%d:%d)\n",
969 st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
971 } else if (den != 0) {
972 av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den,
978 /* this atom contains actual media data */
979 static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
981 if (atom.size == 0) /* wrong one (MP4) */
984 return 0; /* now go for moov */
987 #define DRM_BLOB_SIZE 56
989 static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
991 uint8_t intermediate_key[20];
992 uint8_t intermediate_iv[20];
995 uint8_t file_checksum[20];
996 uint8_t calculated_checksum[20];
1000 uint8_t *activation_bytes = c->activation_bytes;
1001 uint8_t *fixed_key = c->audible_fixed_key;
1005 sha = av_sha_alloc();
1007 return AVERROR(ENOMEM);
1008 av_free(c->aes_decrypt);
1009 c->aes_decrypt = av_aes_alloc();
1010 if (!c->aes_decrypt) {
1011 ret = AVERROR(ENOMEM);
1015 /* drm blob processing */
1016 avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1017 avio_read(pb, input, DRM_BLOB_SIZE);
1018 avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1019 avio_read(pb, file_checksum, 20);
1021 av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == "); // required by external tools
1022 for (i = 0; i < 20; i++)
1023 av_log(c->fc, AV_LOG_INFO, "%02x", file_checksum[i]);
1024 av_log(c->fc, AV_LOG_INFO, "\n");
1026 /* verify activation data */
1027 if (!activation_bytes) {
1028 av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1029 ret = 0; /* allow ffprobe to continue working on .aax files */
1032 if (c->activation_bytes_size != 4) {
1033 av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1034 ret = AVERROR(EINVAL);
1038 /* verify fixed key */
1039 if (c->audible_fixed_key_size != 16) {
1040 av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1041 ret = AVERROR(EINVAL);
1045 /* AAX (and AAX+) key derivation */
1046 av_sha_init(sha, 160);
1047 av_sha_update(sha, fixed_key, 16);
1048 av_sha_update(sha, activation_bytes, 4);
1049 av_sha_final(sha, intermediate_key);
1050 av_sha_init(sha, 160);
1051 av_sha_update(sha, fixed_key, 16);
1052 av_sha_update(sha, intermediate_key, 20);
1053 av_sha_update(sha, activation_bytes, 4);
1054 av_sha_final(sha, intermediate_iv);
1055 av_sha_init(sha, 160);
1056 av_sha_update(sha, intermediate_key, 16);
1057 av_sha_update(sha, intermediate_iv, 16);
1058 av_sha_final(sha, calculated_checksum);
1059 if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1060 av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1061 ret = AVERROR_INVALIDDATA;
1064 av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1065 av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1066 for (i = 0; i < 4; i++) {
1067 // file data (in output) is stored in big-endian mode
1068 if (activation_bytes[i] != output[3 - i]) { // critical error
1069 av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1070 ret = AVERROR_INVALIDDATA;
1074 memcpy(c->file_key, output + 8, 16);
1075 memcpy(input, output + 26, 16);
1076 av_sha_init(sha, 160);
1077 av_sha_update(sha, input, 16);
1078 av_sha_update(sha, c->file_key, 16);
1079 av_sha_update(sha, fixed_key, 16);
1080 av_sha_final(sha, c->file_iv);
1088 // Audible AAX (and AAX+) bytestream decryption
1089 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1092 unsigned char iv[16];
1094 memcpy(iv, c->file_iv, 16); // iv is overwritten
1095 blocks = size >> 4; // trailing bytes are not encrypted!
1096 av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1097 av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1102 /* read major brand, minor version and compatible brands and store them as metadata */
1103 static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1106 int comp_brand_size;
1107 char* comp_brands_str;
1108 uint8_t type[5] = {0};
1109 int ret = ffio_read_size(pb, type, 4);
1113 if (strcmp(type, "qt "))
1115 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1116 av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1117 minor_ver = avio_rb32(pb); /* minor version */
1118 av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1120 comp_brand_size = atom.size - 8;
1121 if (comp_brand_size < 0)
1122 return AVERROR_INVALIDDATA;
1123 comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1124 if (!comp_brands_str)
1125 return AVERROR(ENOMEM);
1127 ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1129 av_freep(&comp_brands_str);
1132 comp_brands_str[comp_brand_size] = 0;
1133 av_dict_set(&c->fc->metadata, "compatible_brands",
1134 comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1139 /* this atom should contain all header atoms */
1140 static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1144 if (c->found_moov) {
1145 av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1146 avio_skip(pb, atom.size);
1150 if ((ret = mov_read_default(c, pb, atom)) < 0)
1152 /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1153 /* so we don't parse the whole file if over a network */
1155 return 0; /* now go for mdat */
1158 static MOVFragmentStreamInfo * get_frag_stream_info(
1159 MOVFragmentIndex *frag_index,
1164 MOVFragmentIndexItem * item;
1166 if (index < 0 || index >= frag_index->nb_items)
1168 item = &frag_index->item[index];
1169 for (i = 0; i < item->nb_stream_info; i++)
1170 if (item->stream_info[i].id == id)
1171 return &item->stream_info[i];
1173 // This shouldn't happen
1177 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1180 MOVFragmentIndexItem * item;
1182 if (frag_index->current < 0 ||
1183 frag_index->current >= frag_index->nb_items)
1186 item = &frag_index->item[frag_index->current];
1187 for (i = 0; i < item->nb_stream_info; i++)
1188 if (item->stream_info[i].id == id) {
1193 // id not found. This shouldn't happen.
1197 static MOVFragmentStreamInfo * get_current_frag_stream_info(
1198 MOVFragmentIndex *frag_index)
1200 MOVFragmentIndexItem *item;
1201 if (frag_index->current < 0 ||
1202 frag_index->current >= frag_index->nb_items)
1205 item = &frag_index->item[frag_index->current];
1206 if (item->current >= 0 && item->current < item->nb_stream_info)
1207 return &item->stream_info[item->current];
1209 // This shouldn't happen
1213 static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
1216 int64_t moof_offset;
1218 // Optimize for appending new entries
1219 if (!frag_index->nb_items ||
1220 frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1221 return frag_index->nb_items;
1224 b = frag_index->nb_items;
1228 moof_offset = frag_index->item[m].moof_offset;
1229 if (moof_offset >= offset)
1231 if (moof_offset <= offset)
1237 static int64_t get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
1239 av_assert0(frag_stream_info);
1240 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1241 return frag_stream_info->sidx_pts;
1242 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1243 return frag_stream_info->first_tfra_pts;
1244 return frag_stream_info->tfdt_dts;
1247 static int64_t get_frag_time(MOVFragmentIndex *frag_index,
1248 int index, int track_id)
1250 MOVFragmentStreamInfo * frag_stream_info;
1254 if (track_id >= 0) {
1255 frag_stream_info = get_frag_stream_info(frag_index, index, track_id);
1256 return frag_stream_info->sidx_pts;
1259 for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1260 frag_stream_info = &frag_index->item[index].stream_info[i];
1261 timestamp = get_stream_info_time(frag_stream_info);
1262 if (timestamp != AV_NOPTS_VALUE)
1265 return AV_NOPTS_VALUE;
1268 static int search_frag_timestamp(MOVFragmentIndex *frag_index,
1269 AVStream *st, int64_t timestamp)
1276 // If the stream is referenced by any sidx, limit the search
1277 // to fragments that referenced this stream in the sidx
1278 MOVStreamContext *sc = st->priv_data;
1284 b = frag_index->nb_items;
1287 m0 = m = (a + b) >> 1;
1290 (frag_time = get_frag_time(frag_index, m, id)) == AV_NOPTS_VALUE)
1293 if (m < b && frag_time <= timestamp)
1302 static int update_frag_index(MOVContext *c, int64_t offset)
1305 MOVFragmentIndexItem * item;
1306 MOVFragmentStreamInfo * frag_stream_info;
1308 // If moof_offset already exists in frag_index, return index to it
1309 index = search_frag_moof_offset(&c->frag_index, offset);
1310 if (index < c->frag_index.nb_items &&
1311 c->frag_index.item[index].moof_offset == offset)
1314 // offset is not yet in frag index.
1315 // Insert new item at index (sorted by moof offset)
1316 item = av_fast_realloc(c->frag_index.item,
1317 &c->frag_index.allocated_size,
1318 (c->frag_index.nb_items + 1) *
1319 sizeof(*c->frag_index.item));
1322 c->frag_index.item = item;
1324 frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1325 sizeof(*item->stream_info));
1326 if (!frag_stream_info)
1329 for (i = 0; i < c->fc->nb_streams; i++) {
1330 // Avoid building frag index if streams lack track id.
1331 if (c->fc->streams[i]->id < 0) {
1332 av_free(frag_stream_info);
1333 return AVERROR_INVALIDDATA;
1336 frag_stream_info[i].id = c->fc->streams[i]->id;
1337 frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1338 frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1339 frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1340 frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1341 frag_stream_info[i].index_entry = -1;
1342 frag_stream_info[i].encryption_index = NULL;
1345 if (index < c->frag_index.nb_items)
1346 memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1347 (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1349 item = &c->frag_index.item[index];
1350 item->headers_read = 0;
1352 item->nb_stream_info = c->fc->nb_streams;
1353 item->moof_offset = offset;
1354 item->stream_info = frag_stream_info;
1355 c->frag_index.nb_items++;
1360 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1361 int id, int entries)
1364 MOVFragmentStreamInfo * frag_stream_info;
1368 for (i = index; i < frag_index->nb_items; i++) {
1369 frag_stream_info = get_frag_stream_info(frag_index, i, id);
1370 if (frag_stream_info && frag_stream_info->index_entry >= 0)
1371 frag_stream_info->index_entry += entries;
1375 static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1377 // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1378 c->fragment.found_tfhd = 0;
1380 if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1381 c->has_looked_for_mfra = 1;
1382 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1384 av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1386 if ((ret = mov_read_mfra(c, pb)) < 0) {
1387 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1388 "read the mfra (may be a live ismv)\n");
1391 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1392 "seekable, can not look for mfra\n");
1395 c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1396 av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1397 c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1398 return mov_read_default(c, pb, atom);
1401 static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time, void *logctx)
1404 if(time >= 2082844800)
1405 time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1407 if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1408 av_log(logctx, AV_LOG_DEBUG, "creation_time is not representable\n");
1412 avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1416 static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1419 MOVStreamContext *sc;
1421 char language[4] = {0};
1423 int64_t creation_time;
1425 if (c->fc->nb_streams < 1)
1427 st = c->fc->streams[c->fc->nb_streams-1];
1430 if (sc->time_scale) {
1431 av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1432 return AVERROR_INVALIDDATA;
1435 version = avio_r8(pb);
1437 avpriv_request_sample(c->fc, "Version %d", version);
1438 return AVERROR_PATCHWELCOME;
1440 avio_rb24(pb); /* flags */
1442 creation_time = avio_rb64(pb);
1445 creation_time = avio_rb32(pb);
1446 avio_rb32(pb); /* modification time */
1448 mov_metadata_creation_time(&st->metadata, creation_time, c->fc);
1450 sc->time_scale = avio_rb32(pb);
1451 if (sc->time_scale <= 0) {
1452 av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1455 st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1457 lang = avio_rb16(pb); /* language */
1458 if (ff_mov_lang_to_iso639(lang, language))
1459 av_dict_set(&st->metadata, "language", language, 0);
1460 avio_rb16(pb); /* quality */
1465 static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1468 int64_t creation_time;
1469 int version = avio_r8(pb); /* version */
1470 avio_rb24(pb); /* flags */
1473 creation_time = avio_rb64(pb);
1476 creation_time = avio_rb32(pb);
1477 avio_rb32(pb); /* modification time */
1479 mov_metadata_creation_time(&c->fc->metadata, creation_time, c->fc);
1480 c->time_scale = avio_rb32(pb); /* time scale */
1481 if (c->time_scale <= 0) {
1482 av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1485 av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1487 c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1488 // set the AVCodecContext duration because the duration of individual tracks
1489 // may be inaccurate
1490 if (c->time_scale > 0 && !c->trex_data)
1491 c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale);
1492 avio_rb32(pb); /* preferred scale */
1494 avio_rb16(pb); /* preferred volume */
1496 avio_skip(pb, 10); /* reserved */
1498 /* movie display matrix, store it in main context and use it later on */
1499 for (i = 0; i < 3; i++) {
1500 c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1501 c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1502 c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1505 avio_rb32(pb); /* preview time */
1506 avio_rb32(pb); /* preview duration */
1507 avio_rb32(pb); /* poster time */
1508 avio_rb32(pb); /* selection time */
1509 avio_rb32(pb); /* selection duration */
1510 avio_rb32(pb); /* current time */
1511 avio_rb32(pb); /* next track ID */
1516 static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1521 if (c->fc->nb_streams < 1)
1523 st = c->fc->streams[c->fc->nb_streams-1];
1525 little_endian = avio_rb16(pb) & 0xFF;
1526 av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1527 if (little_endian == 1) {
1528 switch (st->codecpar->codec_id) {
1529 case AV_CODEC_ID_PCM_S24BE:
1530 st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE;
1532 case AV_CODEC_ID_PCM_S32BE:
1533 st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE;
1535 case AV_CODEC_ID_PCM_F32BE:
1536 st->codecpar->codec_id = AV_CODEC_ID_PCM_F32LE;
1538 case AV_CODEC_ID_PCM_F64BE:
1539 st->codecpar->codec_id = AV_CODEC_ID_PCM_F64LE;
1548 static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1551 uint8_t *icc_profile;
1552 char color_parameter_type[5] = { 0 };
1553 uint16_t color_primaries, color_trc, color_matrix;
1556 if (c->fc->nb_streams < 1)
1558 st = c->fc->streams[c->fc->nb_streams - 1];
1560 ret = ffio_read_size(pb, color_parameter_type, 4);
1563 if (strncmp(color_parameter_type, "nclx", 4) &&
1564 strncmp(color_parameter_type, "nclc", 4) &&
1565 strncmp(color_parameter_type, "prof", 4)) {
1566 av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
1567 color_parameter_type);
1571 if (!strncmp(color_parameter_type, "prof", 4)) {
1572 icc_profile = av_stream_new_side_data(st, AV_PKT_DATA_ICC_PROFILE, atom.size - 4);
1574 return AVERROR(ENOMEM);
1575 ret = ffio_read_size(pb, icc_profile, atom.size - 4);
1580 color_primaries = avio_rb16(pb);
1581 color_trc = avio_rb16(pb);
1582 color_matrix = avio_rb16(pb);
1584 av_log(c->fc, AV_LOG_TRACE,
1585 "%s: pri %d trc %d matrix %d",
1586 color_parameter_type, color_primaries, color_trc, color_matrix);
1588 if (!strncmp(color_parameter_type, "nclx", 4)) {
1589 uint8_t color_range = avio_r8(pb) >> 7;
1590 av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
1592 st->codecpar->color_range = AVCOL_RANGE_JPEG;
1594 st->codecpar->color_range = AVCOL_RANGE_MPEG;
1597 if (!av_color_primaries_name(color_primaries))
1598 color_primaries = AVCOL_PRI_UNSPECIFIED;
1599 if (!av_color_transfer_name(color_trc))
1600 color_trc = AVCOL_TRC_UNSPECIFIED;
1601 if (!av_color_space_name(color_matrix))
1602 color_matrix = AVCOL_SPC_UNSPECIFIED;
1604 st->codecpar->color_primaries = color_primaries;
1605 st->codecpar->color_trc = color_trc;
1606 st->codecpar->color_space = color_matrix;
1607 av_log(c->fc, AV_LOG_TRACE, "\n");
1612 static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1615 unsigned mov_field_order;
1616 enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
1618 if (c->fc->nb_streams < 1) // will happen with jp2 files
1620 st = c->fc->streams[c->fc->nb_streams-1];
1622 return AVERROR_INVALIDDATA;
1623 mov_field_order = avio_rb16(pb);
1624 if ((mov_field_order & 0xFF00) == 0x0100)
1625 decoded_field_order = AV_FIELD_PROGRESSIVE;
1626 else if ((mov_field_order & 0xFF00) == 0x0200) {
1627 switch (mov_field_order & 0xFF) {
1628 case 0x01: decoded_field_order = AV_FIELD_TT;
1630 case 0x06: decoded_field_order = AV_FIELD_BB;
1632 case 0x09: decoded_field_order = AV_FIELD_TB;
1634 case 0x0E: decoded_field_order = AV_FIELD_BT;
1638 if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
1639 av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
1641 st->codecpar->field_order = decoded_field_order;
1646 static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
1649 uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
1650 if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
1651 return AVERROR_INVALIDDATA;
1652 if ((err = av_reallocp(&par->extradata, size)) < 0) {
1653 par->extradata_size = 0;
1656 par->extradata_size = size - AV_INPUT_BUFFER_PADDING_SIZE;
1660 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
1661 static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1662 AVCodecParameters *par, uint8_t *buf)
1664 int64_t result = atom.size;
1667 AV_WB32(buf , atom.size + 8);
1668 AV_WL32(buf + 4, atom.type);
1669 err = ffio_read_size(pb, buf + 8, atom.size);
1671 par->extradata_size -= atom.size;
1673 } else if (err < atom.size) {
1674 av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
1675 par->extradata_size -= atom.size - err;
1678 memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1682 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
1683 static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1684 enum AVCodecID codec_id)
1687 uint64_t original_size;
1690 if (c->fc->nb_streams < 1) // will happen with jp2 files
1692 st = c->fc->streams[c->fc->nb_streams-1];
1694 if (st->codecpar->codec_id != codec_id)
1695 return 0; /* unexpected codec_id - don't mess with extradata */
1697 original_size = st->codecpar->extradata_size;
1698 err = mov_realloc_extradata(st->codecpar, atom);
1702 err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
1705 return 0; // Note: this is the original behavior to ignore truncation.
1708 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
1709 static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1711 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
1714 static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1716 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS);
1719 static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1721 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
1724 static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1726 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
1729 static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1731 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
1733 ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
1737 static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1739 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
1741 if (!ret && c->fc->nb_streams >= 1) {
1742 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1743 if (par->extradata_size >= 40) {
1744 par->height = AV_RB16(&par->extradata[36]);
1745 par->width = AV_RB16(&par->extradata[38]);
1751 static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1753 if (c->fc->nb_streams >= 1) {
1754 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1755 if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
1756 par->codec_id == AV_CODEC_ID_H264 &&
1760 cid = avio_rb16(pb);
1761 /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
1762 if (cid == 0xd4d || cid == 0xd4e)
1765 } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
1766 par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
1767 par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
1771 num = avio_rb32(pb);
1772 den = avio_rb32(pb);
1773 if (num <= 0 || den <= 0)
1775 switch (avio_rb32(pb)) {
1777 if (den >= INT_MAX / 2)
1781 c->fc->streams[c->fc->nb_streams-1]->display_aspect_ratio.num = num;
1782 c->fc->streams[c->fc->nb_streams-1]->display_aspect_ratio.den = den;
1789 return mov_read_avid(c, pb, atom);
1792 static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1796 uint64_t original_size;
1797 if (c->fc->nb_streams >= 1) {
1798 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1799 if (par->codec_id == AV_CODEC_ID_H264)
1801 if (atom.size == 16) {
1802 original_size = par->extradata_size;
1803 ret = mov_realloc_extradata(par, atom);
1805 length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
1806 if (length == atom.size) {
1807 const uint8_t range_value = par->extradata[original_size + 19];
1808 switch (range_value) {
1810 par->color_range = AVCOL_RANGE_MPEG;
1813 par->color_range = AVCOL_RANGE_JPEG;
1816 av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
1819 ff_dlog(c->fc, "color_range: %d\n", par->color_range);
1821 /* For some reason the whole atom was not added to the extradata */
1822 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
1825 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
1828 av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
1835 static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1837 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
1840 static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1845 if (c->fc->nb_streams < 1)
1847 st = c->fc->streams[c->fc->nb_streams-1];
1849 if ((uint64_t)atom.size > (1<<30))
1850 return AVERROR_INVALIDDATA;
1852 if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
1853 st->codecpar->codec_id == AV_CODEC_ID_QDMC ||
1854 st->codecpar->codec_id == AV_CODEC_ID_SPEEX) {
1855 // pass all frma atom to codec, needed at least for QDMC and QDM2
1856 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1859 } else if (atom.size > 8) { /* to read frma, esds atoms */
1860 if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
1862 ret = ffio_ensure_seekback(pb, 8);
1865 buffer = avio_rb64(pb);
1867 if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
1868 && buffer >> 32 <= atom.size
1869 && buffer >> 32 >= 8) {
1872 } else if (!st->codecpar->extradata_size) {
1873 #define ALAC_EXTRADATA_SIZE 36
1874 st->codecpar->extradata = av_mallocz(ALAC_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
1875 if (!st->codecpar->extradata)
1876 return AVERROR(ENOMEM);
1877 st->codecpar->extradata_size = ALAC_EXTRADATA_SIZE;
1878 AV_WB32(st->codecpar->extradata , ALAC_EXTRADATA_SIZE);
1879 AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
1880 AV_WB64(st->codecpar->extradata + 12, buffer);
1881 avio_read(pb, st->codecpar->extradata + 20, 16);
1882 avio_skip(pb, atom.size - 24);
1886 if ((ret = mov_read_default(c, pb, atom)) < 0)
1889 avio_skip(pb, atom.size);
1894 * This function reads atom content and puts data in extradata without tag
1895 * nor size unlike mov_read_extradata.
1897 static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1902 if (c->fc->nb_streams < 1)
1904 st = c->fc->streams[c->fc->nb_streams-1];
1906 if ((uint64_t)atom.size > (1<<30))
1907 return AVERROR_INVALIDDATA;
1909 if (atom.size >= 10) {
1910 // Broken files created by legacy versions of libavformat will
1911 // wrap a whole fiel atom inside of a glbl atom.
1912 unsigned size = avio_rb32(pb);
1913 unsigned type = avio_rl32(pb);
1914 avio_seek(pb, -8, SEEK_CUR);
1915 if (type == MKTAG('f','i','e','l') && size == atom.size)
1916 return mov_read_default(c, pb, atom);
1918 if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
1919 av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
1922 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1925 if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
1926 /* HEVC-based Dolby Vision derived from hvc1.
1927 Happens to match with an identifier
1928 previously utilized for DV. Thus, if we have
1929 the hvcC extradata box available as specified,
1930 set codec to HEVC */
1931 st->codecpar->codec_id = AV_CODEC_ID_HEVC;
1936 static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1939 uint8_t profile_level;
1942 if (c->fc->nb_streams < 1)
1944 st = c->fc->streams[c->fc->nb_streams-1];
1946 if (atom.size >= (1<<28) || atom.size < 7)
1947 return AVERROR_INVALIDDATA;
1949 profile_level = avio_r8(pb);
1950 if ((profile_level & 0xf0) != 0xc0)
1953 avio_seek(pb, 6, SEEK_CUR);
1954 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
1962 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
1963 * but can have extradata appended at the end after the 40 bytes belonging
1966 static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1971 if (c->fc->nb_streams < 1)
1973 if (atom.size <= 40)
1975 st = c->fc->streams[c->fc->nb_streams-1];
1977 if ((uint64_t)atom.size > (1<<30))
1978 return AVERROR_INVALIDDATA;
1981 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
1988 static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1991 MOVStreamContext *sc;
1992 unsigned int i, entries;
1994 if (c->trak_index < 0) {
1995 av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
1998 if (c->fc->nb_streams < 1)
2000 st = c->fc->streams[c->fc->nb_streams-1];
2003 avio_r8(pb); /* version */
2004 avio_rb24(pb); /* flags */
2006 entries = avio_rb32(pb);
2011 if (sc->chunk_offsets)
2012 av_log(c->fc, AV_LOG_WARNING, "Duplicated STCO atom\n");
2013 av_free(sc->chunk_offsets);
2014 sc->chunk_count = 0;
2015 sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2016 if (!sc->chunk_offsets)
2017 return AVERROR(ENOMEM);
2018 sc->chunk_count = entries;
2020 if (atom.type == MKTAG('s','t','c','o'))
2021 for (i = 0; i < entries && !pb->eof_reached; i++)
2022 sc->chunk_offsets[i] = avio_rb32(pb);
2023 else if (atom.type == MKTAG('c','o','6','4'))
2024 for (i = 0; i < entries && !pb->eof_reached; i++)
2025 sc->chunk_offsets[i] = avio_rb64(pb);
2027 return AVERROR_INVALIDDATA;
2029 sc->chunk_count = i;
2031 if (pb->eof_reached) {
2032 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2039 static int mov_codec_id(AVStream *st, uint32_t format)
2041 int id = ff_codec_get_id(ff_codec_movaudio_tags, format);
2044 ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2045 (format & 0xFFFF) == 'T' + ('S' << 8)))
2046 id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format) & 0xFFFF);
2048 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2049 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2050 } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2051 /* skip old ASF MPEG-4 tag */
2052 format && format != MKTAG('m','p','4','s')) {
2053 id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2055 id = ff_codec_get_id(ff_codec_bmp_tags, format);
2057 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
2058 else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2059 (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE &&
2060 st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2061 id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
2063 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
2065 id = ff_codec_get_id(ff_codec_movdata_tags, format);
2069 st->codecpar->codec_tag = format;
2074 static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
2075 AVStream *st, MOVStreamContext *sc)
2077 uint8_t codec_name[32] = { 0 };
2081 /* The first 16 bytes of the video sample description are already
2082 * read in ff_mov_read_stsd_entries() */
2083 stsd_start = avio_tell(pb) - 16;
2085 avio_rb16(pb); /* version */
2086 avio_rb16(pb); /* revision level */
2087 avio_rb32(pb); /* vendor */
2088 avio_rb32(pb); /* temporal quality */
2089 avio_rb32(pb); /* spatial quality */
2091 st->codecpar->width = avio_rb16(pb); /* width */
2092 st->codecpar->height = avio_rb16(pb); /* height */
2094 avio_rb32(pb); /* horiz resolution */
2095 avio_rb32(pb); /* vert resolution */
2096 avio_rb32(pb); /* data size, always 0 */
2097 avio_rb16(pb); /* frames per samples */
2099 len = avio_r8(pb); /* codec name, pascal string */
2102 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2104 avio_skip(pb, 31 - len);
2107 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2109 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2110 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2111 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2112 st->codecpar->width &= ~1;
2113 st->codecpar->height &= ~1;
2115 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2116 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2117 !strncmp(codec_name, "Sorenson H263", 13))
2118 st->codecpar->codec_id = AV_CODEC_ID_FLV1;
2120 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2122 avio_seek(pb, stsd_start, SEEK_SET);
2124 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2125 st->codecpar->bits_per_coded_sample &= 0x1F;
2126 sc->has_palette = 1;
2130 static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
2131 AVStream *st, MOVStreamContext *sc)
2133 int bits_per_sample, flags;
2134 uint16_t version = avio_rb16(pb);
2135 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2137 avio_rb16(pb); /* revision level */
2138 avio_rb32(pb); /* vendor */
2140 st->codecpar->channels = avio_rb16(pb); /* channel count */
2141 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2142 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", st->codecpar->channels);
2144 sc->audio_cid = avio_rb16(pb);
2145 avio_rb16(pb); /* packet size = 0 */
2147 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2149 // Read QT version 1 fields. In version 0 these do not exist.
2150 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2152 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2153 (sc->stsd_version == 0 && version > 0)) {
2155 sc->samples_per_frame = avio_rb32(pb);
2156 avio_rb32(pb); /* bytes per packet */
2157 sc->bytes_per_frame = avio_rb32(pb);
2158 avio_rb32(pb); /* bytes per sample */
2159 } else if (version == 2) {
2160 avio_rb32(pb); /* sizeof struct only */
2161 st->codecpar->sample_rate = av_int2double(avio_rb64(pb));
2162 st->codecpar->channels = avio_rb32(pb);
2163 avio_rb32(pb); /* always 0x7F000000 */
2164 st->codecpar->bits_per_coded_sample = avio_rb32(pb);
2166 flags = avio_rb32(pb); /* lpcm format specific flag */
2167 sc->bytes_per_frame = avio_rb32(pb);
2168 sc->samples_per_frame = avio_rb32(pb);
2169 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2170 st->codecpar->codec_id =
2171 ff_mov_get_lpcm_codec_id(st->codecpar->bits_per_coded_sample,
2174 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2175 /* can't correctly handle variable sized packet as audio unit */
2176 switch (st->codecpar->codec_id) {
2177 case AV_CODEC_ID_MP2:
2178 case AV_CODEC_ID_MP3:
2179 st->need_parsing = AVSTREAM_PARSE_FULL;
2185 if (sc->format == 0) {
2186 if (st->codecpar->bits_per_coded_sample == 8)
2187 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2188 else if (st->codecpar->bits_per_coded_sample == 16)
2189 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2192 switch (st->codecpar->codec_id) {
2193 case AV_CODEC_ID_PCM_S8:
2194 case AV_CODEC_ID_PCM_U8:
2195 if (st->codecpar->bits_per_coded_sample == 16)
2196 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16BE;
2198 case AV_CODEC_ID_PCM_S16LE:
2199 case AV_CODEC_ID_PCM_S16BE:
2200 if (st->codecpar->bits_per_coded_sample == 8)
2201 st->codecpar->codec_id = AV_CODEC_ID_PCM_S8;
2202 else if (st->codecpar->bits_per_coded_sample == 24)
2203 st->codecpar->codec_id =
2204 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2205 AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
2206 else if (st->codecpar->bits_per_coded_sample == 32)
2207 st->codecpar->codec_id =
2208 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2209 AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
2211 /* set values for old format before stsd version 1 appeared */
2212 case AV_CODEC_ID_MACE3:
2213 sc->samples_per_frame = 6;
2214 sc->bytes_per_frame = 2 * st->codecpar->channels;
2216 case AV_CODEC_ID_MACE6:
2217 sc->samples_per_frame = 6;
2218 sc->bytes_per_frame = 1 * st->codecpar->channels;
2220 case AV_CODEC_ID_ADPCM_IMA_QT:
2221 sc->samples_per_frame = 64;
2222 sc->bytes_per_frame = 34 * st->codecpar->channels;
2224 case AV_CODEC_ID_GSM:
2225 sc->samples_per_frame = 160;
2226 sc->bytes_per_frame = 33;
2232 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2233 if (bits_per_sample) {
2234 st->codecpar->bits_per_coded_sample = bits_per_sample;
2235 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->channels;
2239 static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
2240 AVStream *st, MOVStreamContext *sc,
2243 // ttxt stsd contains display flags, justification, background
2244 // color, fonts, and default styles, so fake an atom to read it
2245 MOVAtom fake_atom = { .size = size };
2246 // mp4s contains a regular esds atom
2247 if (st->codecpar->codec_tag != AV_RL32("mp4s"))
2248 mov_read_glbl(c, pb, fake_atom);
2249 st->codecpar->width = sc->width;
2250 st->codecpar->height = sc->height;
2253 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2258 y = (ycbcr >> 16) & 0xFF;
2259 cr = (ycbcr >> 8) & 0xFF;
2262 b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
2263 g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
2264 r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
2266 return (r << 16) | (g << 8) | b;
2269 static int mov_rewrite_dvd_sub_extradata(AVStream *st)
2271 char buf[256] = {0};
2272 uint8_t *src = st->codecpar->extradata;
2275 if (st->codecpar->extradata_size != 64)
2278 if (st->codecpar->width > 0 && st->codecpar->height > 0)
2279 snprintf(buf, sizeof(buf), "size: %dx%d\n",
2280 st->codecpar->width, st->codecpar->height);
2281 av_strlcat(buf, "palette: ", sizeof(buf));
2283 for (i = 0; i < 16; i++) {
2284 uint32_t yuv = AV_RB32(src + i * 4);
2285 uint32_t rgba = yuv_to_rgba(yuv);
2287 av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2290 if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2293 ret = ff_alloc_extradata(st->codecpar, strlen(buf));
2296 memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2301 static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
2302 AVStream *st, MOVStreamContext *sc,
2307 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2308 if ((int)size != size)
2309 return AVERROR(ENOMEM);
2311 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2315 MOVStreamContext *tmcd_ctx = st->priv_data;
2317 val = AV_RB32(st->codecpar->extradata + 4);
2318 tmcd_ctx->tmcd_flags = val;
2319 st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2320 st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2321 #if FF_API_LAVF_AVCTX
2322 FF_DISABLE_DEPRECATION_WARNINGS
2323 st->codec->time_base = av_inv_q(st->avg_frame_rate);
2324 FF_ENABLE_DEPRECATION_WARNINGS
2326 /* adjust for per frame dur in counter mode */
2327 if (tmcd_ctx->tmcd_flags & 0x0008) {
2328 int timescale = AV_RB32(st->codecpar->extradata + 8);
2329 int framedur = AV_RB32(st->codecpar->extradata + 12);
2330 st->avg_frame_rate.num *= timescale;
2331 st->avg_frame_rate.den *= framedur;
2332 #if FF_API_LAVF_AVCTX
2333 FF_DISABLE_DEPRECATION_WARNINGS
2334 st->codec->time_base.den *= timescale;
2335 st->codec->time_base.num *= framedur;
2336 FF_ENABLE_DEPRECATION_WARNINGS
2340 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2341 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2342 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2343 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2344 if (str_size > 0 && size >= (int)str_size + 26) {
2345 char *reel_name = av_malloc(str_size + 1);
2347 return AVERROR(ENOMEM);
2348 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2349 reel_name[str_size] = 0; /* Add null terminator */
2350 /* don't add reel_name if emtpy string */
2351 if (*reel_name == 0) {
2354 av_dict_set(&st->metadata, "reel_name", reel_name, AV_DICT_DONT_STRDUP_VAL);
2361 /* other codec type, just skip (rtp, mp4s ...) */
2362 avio_skip(pb, size);
2367 static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
2368 AVStream *st, MOVStreamContext *sc)
2370 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2371 !st->codecpar->sample_rate && sc->time_scale > 1)
2372 st->codecpar->sample_rate = sc->time_scale;
2374 /* special codec parameters handling */
2375 switch (st->codecpar->codec_id) {
2376 #if CONFIG_DV_DEMUXER
2377 case AV_CODEC_ID_DVAUDIO:
2378 c->dv_fctx = avformat_alloc_context();
2380 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2381 return AVERROR(ENOMEM);
2383 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2385 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2386 return AVERROR(ENOMEM);
2388 sc->dv_audio_container = 1;
2389 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
2392 /* no ifdef since parameters are always those */
2393 case AV_CODEC_ID_QCELP:
2394 st->codecpar->channels = 1;
2395 // force sample rate for qcelp when not stored in mov
2396 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2397 st->codecpar->sample_rate = 8000;
2398 // FIXME: Why is the following needed for some files?
2399 sc->samples_per_frame = 160;
2400 if (!sc->bytes_per_frame)
2401 sc->bytes_per_frame = 35;
2403 case AV_CODEC_ID_AMR_NB:
2404 st->codecpar->channels = 1;
2405 /* force sample rate for amr, stsd in 3gp does not store sample rate */
2406 st->codecpar->sample_rate = 8000;
2408 case AV_CODEC_ID_AMR_WB:
2409 st->codecpar->channels = 1;
2410 st->codecpar->sample_rate = 16000;
2412 case AV_CODEC_ID_MP2:
2413 case AV_CODEC_ID_MP3:
2414 /* force type after stsd for m1a hdlr */
2415 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2417 case AV_CODEC_ID_GSM:
2418 case AV_CODEC_ID_ADPCM_MS:
2419 case AV_CODEC_ID_ADPCM_IMA_WAV:
2420 case AV_CODEC_ID_ILBC:
2421 case AV_CODEC_ID_MACE3:
2422 case AV_CODEC_ID_MACE6:
2423 case AV_CODEC_ID_QDM2:
2424 st->codecpar->block_align = sc->bytes_per_frame;
2426 case AV_CODEC_ID_ALAC:
2427 if (st->codecpar->extradata_size == 36) {
2428 st->codecpar->channels = AV_RB8 (st->codecpar->extradata + 21);
2429 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2432 case AV_CODEC_ID_AC3:
2433 case AV_CODEC_ID_EAC3:
2434 case AV_CODEC_ID_MPEG1VIDEO:
2435 case AV_CODEC_ID_VC1:
2436 case AV_CODEC_ID_VP8:
2437 case AV_CODEC_ID_VP9:
2438 st->need_parsing = AVSTREAM_PARSE_FULL;
2446 static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
2447 int codec_tag, int format,
2450 int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2453 (codec_tag != format &&
2454 // AVID 1:1 samples with differing data format and codec tag exist
2455 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
2456 // prores is allowed to have differing data format and codec tag
2457 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
2459 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
2460 (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id
2461 : codec_tag != MKTAG('j','p','e','g')))) {
2462 /* Multiple fourcc, we skip JPEG. This is not correct, we should
2463 * export it as a separate AVStream but this needs a few changes
2464 * in the MOV demuxer, patch welcome. */
2466 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
2467 avio_skip(pb, size);
2474 int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
2477 MOVStreamContext *sc;
2478 int pseudo_stream_id;
2480 av_assert0 (c->fc->nb_streams >= 1);
2481 st = c->fc->streams[c->fc->nb_streams-1];
2484 for (pseudo_stream_id = 0;
2485 pseudo_stream_id < entries && !pb->eof_reached;
2486 pseudo_stream_id++) {
2487 //Parsing Sample description table
2489 int ret, dref_id = 1;
2490 MOVAtom a = { AV_RL32("stsd") };
2491 int64_t start_pos = avio_tell(pb);
2492 int64_t size = avio_rb32(pb); /* size */
2493 uint32_t format = avio_rl32(pb); /* data format */
2496 avio_rb32(pb); /* reserved */
2497 avio_rb16(pb); /* reserved */
2498 dref_id = avio_rb16(pb);
2499 } else if (size <= 7) {
2500 av_log(c->fc, AV_LOG_ERROR,
2501 "invalid size %"PRId64" in stsd\n", size);
2502 return AVERROR_INVALIDDATA;
2505 if (mov_skip_multiple_stsd(c, pb, st->codecpar->codec_tag, format,
2506 size - (avio_tell(pb) - start_pos))) {
2511 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
2512 sc->dref_id= dref_id;
2513 sc->format = format;
2515 id = mov_codec_id(st, format);
2517 av_log(c->fc, AV_LOG_TRACE,
2518 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
2519 av_fourcc2str(format), st->codecpar->codec_type);
2521 st->codecpar->codec_id = id;
2522 if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) {
2523 mov_parse_stsd_video(c, pb, st, sc);
2524 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
2525 mov_parse_stsd_audio(c, pb, st, sc);
2526 if (st->codecpar->sample_rate < 0) {
2527 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
2528 return AVERROR_INVALIDDATA;
2530 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
2531 mov_parse_stsd_subtitle(c, pb, st, sc,
2532 size - (avio_tell(pb) - start_pos));
2534 ret = mov_parse_stsd_data(c, pb, st, sc,
2535 size - (avio_tell(pb) - start_pos));
2539 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
2540 a.size = size - (avio_tell(pb) - start_pos);
2542 if ((ret = mov_read_default(c, pb, a)) < 0)
2544 } else if (a.size > 0)
2545 avio_skip(pb, a.size);
2547 if (sc->extradata && st->codecpar->extradata) {
2548 int extra_size = st->codecpar->extradata_size;
2550 /* Move the current stream extradata to the stream context one. */
2551 sc->extradata_size[pseudo_stream_id] = extra_size;
2552 sc->extradata[pseudo_stream_id] = av_malloc(extra_size + AV_INPUT_BUFFER_PADDING_SIZE);
2553 if (!sc->extradata[pseudo_stream_id])
2554 return AVERROR(ENOMEM);
2555 memcpy(sc->extradata[pseudo_stream_id], st->codecpar->extradata, extra_size);
2556 av_freep(&st->codecpar->extradata);
2557 st->codecpar->extradata_size = 0;
2562 if (pb->eof_reached) {
2563 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
2570 static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2573 MOVStreamContext *sc;
2576 if (c->fc->nb_streams < 1)
2578 st = c->fc->streams[c->fc->nb_streams - 1];
2581 sc->stsd_version = avio_r8(pb);
2582 avio_rb24(pb); /* flags */
2583 entries = avio_rb32(pb);
2585 /* Each entry contains a size (4 bytes) and format (4 bytes). */
2586 if (entries <= 0 || entries > atom.size / 8) {
2587 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
2588 return AVERROR_INVALIDDATA;
2591 if (sc->extradata) {
2592 av_log(c->fc, AV_LOG_ERROR,
2593 "Duplicate stsd found in this track.\n");
2594 return AVERROR_INVALIDDATA;
2597 /* Prepare space for hosting multiple extradata. */
2598 sc->extradata = av_mallocz_array(entries, sizeof(*sc->extradata));
2600 return AVERROR(ENOMEM);
2602 sc->extradata_size = av_mallocz_array(entries, sizeof(*sc->extradata_size));
2603 if (!sc->extradata_size) {
2604 ret = AVERROR(ENOMEM);
2608 ret = ff_mov_read_stsd_entries(c, pb, entries);
2612 /* Restore back the primary extradata. */
2613 av_freep(&st->codecpar->extradata);
2614 st->codecpar->extradata_size = sc->extradata_size[0];
2615 if (sc->extradata_size[0]) {
2616 st->codecpar->extradata = av_mallocz(sc->extradata_size[0] + AV_INPUT_BUFFER_PADDING_SIZE);
2617 if (!st->codecpar->extradata)
2618 return AVERROR(ENOMEM);
2619 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
2622 return mov_finalize_stsd_codec(c, pb, st, sc);
2624 if (sc->extradata) {
2626 for (j = 0; j < sc->stsd_count; j++)
2627 av_freep(&sc->extradata[j]);
2630 av_freep(&sc->extradata);
2631 av_freep(&sc->extradata_size);
2635 static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2638 MOVStreamContext *sc;
2639 unsigned int i, entries;
2641 if (c->fc->nb_streams < 1)
2643 st = c->fc->streams[c->fc->nb_streams-1];
2646 avio_r8(pb); /* version */
2647 avio_rb24(pb); /* flags */
2649 entries = avio_rb32(pb);
2650 if ((uint64_t)entries * 12 + 4 > atom.size)
2651 return AVERROR_INVALIDDATA;
2653 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
2658 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSC atom\n");
2659 av_free(sc->stsc_data);
2661 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
2663 return AVERROR(ENOMEM);
2665 for (i = 0; i < entries && !pb->eof_reached; i++) {
2666 sc->stsc_data[i].first = avio_rb32(pb);
2667 sc->stsc_data[i].count = avio_rb32(pb);
2668 sc->stsc_data[i].id = avio_rb32(pb);
2672 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
2673 int64_t first_min = i + 1;
2674 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
2675 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
2676 sc->stsc_data[i].first < first_min ||
2677 sc->stsc_data[i].count < 1 ||
2678 sc->stsc_data[i].id < 1) {
2679 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);
2680 if (i+1 >= sc->stsc_count) {
2681 if (sc->stsc_data[i].count == 0 && i > 0) {
2685 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
2686 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
2687 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
2688 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
2689 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
2692 av_assert0(sc->stsc_data[i+1].first >= 2);
2693 // We replace this entry by the next valid
2694 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
2695 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
2696 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
2700 if (pb->eof_reached) {
2701 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
2708 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
2710 return index < count - 1;
2713 /* Compute the samples value for the stsc entry at the given index. */
2714 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
2718 if (mov_stsc_index_valid(index, sc->stsc_count))
2719 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
2721 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
2722 av_assert0(sc->stsc_data[index].first <= sc->chunk_count);
2723 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
2726 return sc->stsc_data[index].count * (int64_t)chunk_count;
2729 static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2732 MOVStreamContext *sc;
2733 unsigned i, entries;
2735 if (c->fc->nb_streams < 1)
2737 st = c->fc->streams[c->fc->nb_streams-1];
2740 avio_rb32(pb); // version + flags
2742 entries = avio_rb32(pb);
2744 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
2745 av_free(sc->stps_data);
2747 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
2749 return AVERROR(ENOMEM);
2751 for (i = 0; i < entries && !pb->eof_reached; i++) {
2752 sc->stps_data[i] = avio_rb32(pb);
2757 if (pb->eof_reached) {
2758 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
2765 static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2768 MOVStreamContext *sc;
2769 unsigned int i, entries;
2771 if (c->fc->nb_streams < 1)
2773 st = c->fc->streams[c->fc->nb_streams-1];
2776 avio_r8(pb); /* version */
2777 avio_rb24(pb); /* flags */
2779 entries = avio_rb32(pb);
2781 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
2785 sc->keyframe_absent = 1;
2786 if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
2787 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2791 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
2792 if (entries >= UINT_MAX / sizeof(int))
2793 return AVERROR_INVALIDDATA;
2794 av_freep(&sc->keyframes);
2795 sc->keyframe_count = 0;
2796 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
2798 return AVERROR(ENOMEM);
2800 for (i = 0; i < entries && !pb->eof_reached; i++) {
2801 sc->keyframes[i] = avio_rb32(pb);
2804 sc->keyframe_count = i;
2806 if (pb->eof_reached) {
2807 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
2814 static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2817 MOVStreamContext *sc;
2818 unsigned int i, entries, sample_size, field_size, num_bytes;
2823 if (c->fc->nb_streams < 1)
2825 st = c->fc->streams[c->fc->nb_streams-1];
2828 avio_r8(pb); /* version */
2829 avio_rb24(pb); /* flags */
2831 if (atom.type == MKTAG('s','t','s','z')) {
2832 sample_size = avio_rb32(pb);
2833 if (!sc->sample_size) /* do not overwrite value computed in stsd */
2834 sc->sample_size = sample_size;
2835 sc->stsz_sample_size = sample_size;
2839 avio_rb24(pb); /* reserved */
2840 field_size = avio_r8(pb);
2842 entries = avio_rb32(pb);
2844 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
2846 sc->sample_count = entries;
2850 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
2851 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
2852 return AVERROR_INVALIDDATA;
2857 if (entries >= (UINT_MAX - 4) / field_size)
2858 return AVERROR_INVALIDDATA;
2859 if (sc->sample_sizes)
2860 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
2861 av_free(sc->sample_sizes);
2862 sc->sample_count = 0;
2863 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
2864 if (!sc->sample_sizes)
2865 return AVERROR(ENOMEM);
2867 num_bytes = (entries*field_size+4)>>3;
2869 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
2871 av_freep(&sc->sample_sizes);
2872 return AVERROR(ENOMEM);
2875 ret = ffio_read_size(pb, buf, num_bytes);
2877 av_freep(&sc->sample_sizes);
2879 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
2883 init_get_bits(&gb, buf, 8*num_bytes);
2885 for (i = 0; i < entries && !pb->eof_reached; i++) {
2886 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
2887 sc->data_size += sc->sample_sizes[i];
2890 sc->sample_count = i;
2894 if (pb->eof_reached) {
2895 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSZ atom\n");
2902 static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2905 MOVStreamContext *sc;
2906 unsigned int i, entries, alloc_size = 0;
2908 int64_t total_sample_count=0;
2910 if (c->fc->nb_streams < 1)
2912 st = c->fc->streams[c->fc->nb_streams-1];
2915 avio_r8(pb); /* version */
2916 avio_rb24(pb); /* flags */
2917 entries = avio_rb32(pb);
2919 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
2920 c->fc->nb_streams-1, entries);
2923 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
2924 av_freep(&sc->stts_data);
2926 if (entries >= INT_MAX / sizeof(*sc->stts_data))
2927 return AVERROR(ENOMEM);
2929 for (i = 0; i < entries && !pb->eof_reached; i++) {
2930 int sample_duration;
2931 unsigned int sample_count;
2932 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
2933 MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
2934 min_entries * sizeof(*sc->stts_data));
2936 av_freep(&sc->stts_data);
2938 return AVERROR(ENOMEM);
2940 sc->stts_count = min_entries;
2941 sc->stts_data = stts_data;
2943 sample_count=avio_rb32(pb);
2944 sample_duration = avio_rb32(pb);
2946 sc->stts_data[i].count= sample_count;
2947 sc->stts_data[i].duration= sample_duration;
2949 av_log(c->fc, AV_LOG_TRACE, "sample_count=%d, sample_duration=%d\n",
2950 sample_count, sample_duration);
2952 duration+=(int64_t)sample_duration*(uint64_t)sample_count;
2953 total_sample_count+=sample_count;
2959 duration <= INT64_MAX - sc->duration_for_fps &&
2960 total_sample_count <= INT_MAX - sc->nb_frames_for_fps
2962 sc->duration_for_fps += duration;
2963 sc->nb_frames_for_fps += total_sample_count;
2966 if (pb->eof_reached) {
2967 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
2971 st->nb_frames= total_sample_count;
2973 st->duration= FFMIN(st->duration, duration);
2974 sc->track_end = duration;
2978 static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2981 MOVStreamContext *sc;
2984 if (c->fc->nb_streams < 1)
2986 st = c->fc->streams[c->fc->nb_streams - 1];
2989 avio_r8(pb); /* version */
2990 avio_rb24(pb); /* flags */
2991 entries = atom.size - 4;
2993 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
2994 c->fc->nb_streams - 1, entries);
2997 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
2998 av_freep(&sc->sdtp_data);
3001 sc->sdtp_data = av_mallocz(entries);
3003 return AVERROR(ENOMEM);
3005 for (i = 0; i < entries && !pb->eof_reached; i++)
3006 sc->sdtp_data[i] = avio_r8(pb);
3012 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3015 if (duration == INT_MIN) {
3016 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3019 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3023 static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3026 MOVStreamContext *sc;
3027 unsigned int i, entries, ctts_count = 0;
3029 if (c->fc->nb_streams < 1)
3031 st = c->fc->streams[c->fc->nb_streams-1];
3034 avio_r8(pb); /* version */
3035 avio_rb24(pb); /* flags */
3036 entries = avio_rb32(pb);
3038 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3042 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3043 return AVERROR_INVALIDDATA;
3044 av_freep(&sc->ctts_data);
3045 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3047 return AVERROR(ENOMEM);
3049 for (i = 0; i < entries && !pb->eof_reached; i++) {
3050 int count =avio_rb32(pb);
3051 int duration =avio_rb32(pb);
3054 av_log(c->fc, AV_LOG_TRACE,
3055 "ignoring CTTS entry with count=%d duration=%d\n",
3060 add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3063 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3066 if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3067 av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3068 av_freep(&sc->ctts_data);
3074 mov_update_dts_shift(sc, duration, c->fc);
3077 sc->ctts_count = ctts_count;
3079 if (pb->eof_reached) {
3080 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3084 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3089 static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3092 MOVStreamContext *sc;
3093 unsigned int i, entries;
3095 uint32_t grouping_type;
3097 if (c->fc->nb_streams < 1)
3099 st = c->fc->streams[c->fc->nb_streams-1];
3102 version = avio_r8(pb); /* version */
3103 avio_rb24(pb); /* flags */
3104 grouping_type = avio_rl32(pb);
3105 if (grouping_type != MKTAG( 'r','a','p',' '))
3106 return 0; /* only support 'rap ' grouping */
3108 avio_rb32(pb); /* grouping_type_parameter */
3110 entries = avio_rb32(pb);
3114 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP atom\n");
3115 av_free(sc->rap_group);
3116 sc->rap_group_count = 0;
3117 sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group));
3119 return AVERROR(ENOMEM);
3121 for (i = 0; i < entries && !pb->eof_reached; i++) {
3122 sc->rap_group[i].count = avio_rb32(pb); /* sample_count */
3123 sc->rap_group[i].index = avio_rb32(pb); /* group_description_index */
3126 sc->rap_group_count = i;
3128 if (pb->eof_reached) {
3129 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3137 * Get ith edit list entry (media time, duration).
3139 static int get_edit_list_entry(MOVContext *mov,
3140 const MOVStreamContext *msc,
3141 unsigned int edit_list_index,
3142 int64_t *edit_list_media_time,
3143 int64_t *edit_list_duration,
3144 int64_t global_timescale)
3146 if (edit_list_index == msc->elst_count) {
3149 *edit_list_media_time = msc->elst_data[edit_list_index].time;
3150 *edit_list_duration = msc->elst_data[edit_list_index].duration;
3152 /* duration is in global timescale units;convert to msc timescale */
3153 if (global_timescale == 0) {
3154 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3157 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3163 * Find the closest previous frame to the timestamp_pts, in e_old index
3164 * entries. Searching for just any frame / just key frames can be controlled by
3165 * last argument 'flag'.
3166 * Note that if ctts_data is not NULL, we will always search for a key frame
3167 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3168 * return the first frame of the video.
3170 * Here the timestamp_pts is considered to be a presentation timestamp and
3171 * the timestamp of index entries are considered to be decoding timestamps.
3173 * Returns 0 if successful in finding a frame, else returns -1.
3174 * Places the found index corresponding output arg.
3176 * If ctts_old is not NULL, then refines the searched entry by searching
3177 * backwards from the found timestamp, to find the frame with correct PTS.
3179 * Places the found ctts_index and ctts_sample in corresponding output args.
3181 static int find_prev_closest_index(AVStream *st,
3182 AVIndexEntry *e_old,
3186 int64_t timestamp_pts,
3189 int64_t* ctts_index,
3190 int64_t* ctts_sample)
3192 MOVStreamContext *msc = st->priv_data;
3193 AVIndexEntry *e_keep = st->index_entries;
3194 int nb_keep = st->nb_index_entries;
3196 int64_t index_ctts_count;
3200 // If dts_shift > 0, then all the index timestamps will have to be offset by
3201 // at least dts_shift amount to obtain PTS.
3202 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3203 if (msc->dts_shift > 0) {
3204 timestamp_pts -= msc->dts_shift;
3207 st->index_entries = e_old;
3208 st->nb_index_entries = nb_old;
3209 *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3211 // Keep going backwards in the index entries until the timestamp is the same.
3213 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3215 if ((flag & AVSEEK_FLAG_ANY) ||
3216 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3222 // If we have CTTS then refine the search, by searching backwards over PTS
3223 // computed by adding corresponding CTTS durations to index timestamps.
3224 if (ctts_data && *index >= 0) {
3225 av_assert0(ctts_index);
3226 av_assert0(ctts_sample);
3227 // Find out the ctts_index for the found frame.
3230 for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3231 if (*ctts_index < ctts_count) {
3233 if (ctts_data[*ctts_index].count == *ctts_sample) {
3240 while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3241 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3242 // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3243 // compensated by dts_shift above.
3244 if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3245 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3250 if (*ctts_sample == 0) {
3252 if (*ctts_index >= 0)
3253 *ctts_sample = ctts_data[*ctts_index].count - 1;
3260 /* restore AVStream state*/
3261 st->index_entries = e_keep;
3262 st->nb_index_entries = nb_keep;
3263 return *index >= 0 ? 0 : -1;
3267 * Add index entry with the given values, to the end of st->index_entries.
3268 * Returns the new size st->index_entries if successful, else returns -1.
3270 * This function is similar to ff_add_index_entry in libavformat/utils.c
3271 * except that here we are always unconditionally adding an index entry to
3272 * the end, instead of searching the entries list and skipping the add if
3273 * there is an existing entry with the same timestamp.
3274 * This is needed because the mov_fix_index calls this func with the same
3275 * unincremented timestamp for successive discarded frames.
3277 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3278 int size, int distance, int flags)
3280 AVIndexEntry *entries, *ie;
3282 const size_t min_size_needed = (st->nb_index_entries + 1) * sizeof(AVIndexEntry);
3284 // Double the allocation each time, to lower memory fragmentation.
3285 // Another difference from ff_add_index_entry function.
3286 const size_t requested_size =
3287 min_size_needed > st->index_entries_allocated_size ?
3288 FFMAX(min_size_needed, 2 * st->index_entries_allocated_size) :
3291 if((unsigned)st->nb_index_entries + 1 >= UINT_MAX / sizeof(AVIndexEntry))
3294 entries = av_fast_realloc(st->index_entries,
3295 &st->index_entries_allocated_size,
3300 st->index_entries= entries;
3302 index= st->nb_index_entries++;
3303 ie= &entries[index];
3306 ie->timestamp = timestamp;
3307 ie->min_distance= distance;
3314 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3315 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3317 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3318 int64_t* frame_duration_buffer,
3319 int frame_duration_buffer_size) {
3321 av_assert0(end_index >= 0 && end_index <= st->nb_index_entries);
3322 for (i = 0; i < frame_duration_buffer_size; i++) {
3323 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3324 st->index_entries[end_index - 1 - i].timestamp = end_ts;
3329 * Append a new ctts entry to ctts_data.
3330 * Returns the new ctts_count if successful, else returns -1.
3332 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3333 int count, int duration)
3335 MOVStts *ctts_buf_new;
3336 const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVStts);
3337 const size_t requested_size =
3338 min_size_needed > *allocated_size ?
3339 FFMAX(min_size_needed, 2 * (*allocated_size)) :
3342 if((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
3345 ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3350 *ctts_data = ctts_buf_new;
3352 ctts_buf_new[*ctts_count].count = count;
3353 ctts_buf_new[*ctts_count].duration = duration;
3355 *ctts_count = (*ctts_count) + 1;
3359 #define MAX_REORDER_DELAY 16
3360 static void mov_estimate_video_delay(MOVContext *c, AVStream* st) {
3361 MOVStreamContext *msc = st->priv_data;
3364 int ctts_sample = 0;
3365 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3367 int j, r, num_swaps;
3369 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3370 pts_buf[j] = INT64_MIN;
3372 if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3373 st->codecpar->codec_id == AV_CODEC_ID_H264) {
3374 st->codecpar->video_delay = 0;
3375 for(ind = 0; ind < st->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3376 // Point j to the last elem of the buffer and insert the current pts there.
3378 buf_start = (buf_start + 1);
3379 if (buf_start == MAX_REORDER_DELAY + 1)
3382 pts_buf[j] = st->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3384 // The timestamps that are already in the sorted buffer, and are greater than the
3385 // current pts, are exactly the timestamps that need to be buffered to output PTS
3386 // in correct sorted order.
3387 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3388 // can be computed as the maximum no. of swaps any particular timestamp needs to
3389 // go through, to keep this buffer in sorted order.
3391 while (j != buf_start) {
3393 if (r < 0) r = MAX_REORDER_DELAY;
3394 if (pts_buf[j] < pts_buf[r]) {
3395 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3402 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3405 if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3410 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3411 st->codecpar->video_delay, st->index);
3415 static void mov_current_sample_inc(MOVStreamContext *sc)
3417 sc->current_sample++;
3418 sc->current_index++;
3419 if (sc->index_ranges &&
3420 sc->current_index >= sc->current_index_range->end &&
3421 sc->current_index_range->end) {
3422 sc->current_index_range++;
3423 sc->current_index = sc->current_index_range->start;
3427 static void mov_current_sample_dec(MOVStreamContext *sc)
3429 sc->current_sample--;
3430 sc->current_index--;
3431 if (sc->index_ranges &&
3432 sc->current_index < sc->current_index_range->start &&
3433 sc->current_index_range > sc->index_ranges) {
3434 sc->current_index_range--;
3435 sc->current_index = sc->current_index_range->end - 1;
3439 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3443 sc->current_sample = current_sample;
3444 sc->current_index = current_sample;
3445 if (!sc->index_ranges) {
3449 for (sc->current_index_range = sc->index_ranges;
3450 sc->current_index_range->end;
3451 sc->current_index_range++) {
3452 range_size = sc->current_index_range->end - sc->current_index_range->start;
3453 if (range_size > current_sample) {
3454 sc->current_index = sc->current_index_range->start + current_sample;
3457 current_sample -= range_size;
3462 * Fix st->index_entries, so that it contains only the entries (and the entries
3463 * which are needed to decode them) that fall in the edit list time ranges.
3464 * Also fixes the timestamps of the index entries to match the timeline
3465 * specified the edit lists.
3467 static void mov_fix_index(MOVContext *mov, AVStream *st)
3469 MOVStreamContext *msc = st->priv_data;
3470 AVIndexEntry *e_old = st->index_entries;
3471 int nb_old = st->nb_index_entries;
3472 const AVIndexEntry *e_old_end = e_old + nb_old;
3473 const AVIndexEntry *current = NULL;
3474 MOVStts *ctts_data_old = msc->ctts_data;
3475 int64_t ctts_index_old = 0;
3476 int64_t ctts_sample_old = 0;
3477 int64_t ctts_count_old = msc->ctts_count;
3478 int64_t edit_list_media_time = 0;
3479 int64_t edit_list_duration = 0;
3480 int64_t frame_duration = 0;
3481 int64_t edit_list_dts_counter = 0;
3482 int64_t edit_list_dts_entry_end = 0;
3483 int64_t edit_list_start_ctts_sample = 0;
3485 int64_t curr_ctts = 0;
3486 int64_t empty_edits_sum_duration = 0;
3487 int64_t edit_list_index = 0;
3490 int64_t start_dts = 0;
3491 int64_t edit_list_start_encountered = 0;
3492 int64_t search_timestamp = 0;
3493 int64_t* frame_duration_buffer = NULL;
3494 int num_discarded_begin = 0;
3495 int first_non_zero_audio_edit = -1;
3496 int packet_skip_samples = 0;
3497 MOVIndexRange *current_index_range;
3499 int found_keyframe_after_edit = 0;
3500 int found_non_empty_edit = 0;
3502 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
3506 // allocate the index ranges array
3507 msc->index_ranges = av_malloc((msc->elst_count + 1) * sizeof(msc->index_ranges[0]));
3508 if (!msc->index_ranges) {
3509 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
3512 msc->current_index_range = msc->index_ranges;
3513 current_index_range = msc->index_ranges - 1;
3515 // Clean AVStream from traces of old index
3516 st->index_entries = NULL;
3517 st->index_entries_allocated_size = 0;
3518 st->nb_index_entries = 0;
3520 // Clean ctts fields of MOVStreamContext
3521 msc->ctts_data = NULL;
3522 msc->ctts_count = 0;
3523 msc->ctts_index = 0;
3524 msc->ctts_sample = 0;
3525 msc->ctts_allocated_size = 0;
3527 // Reinitialize min_corrected_pts so that it can be computed again.
3528 msc->min_corrected_pts = -1;
3530 // If the dts_shift is positive (in case of negative ctts values in mov),
3531 // then negate the DTS by dts_shift
3532 if (msc->dts_shift > 0) {
3533 edit_list_dts_entry_end -= msc->dts_shift;
3534 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
3537 start_dts = edit_list_dts_entry_end;
3539 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
3540 &edit_list_duration, mov->time_scale)) {
3541 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
3542 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
3544 edit_list_dts_counter = edit_list_dts_entry_end;
3545 edit_list_dts_entry_end += edit_list_duration;
3546 num_discarded_begin = 0;
3547 if (!found_non_empty_edit && edit_list_media_time == -1) {
3548 empty_edits_sum_duration += edit_list_duration;
3551 found_non_empty_edit = 1;
3553 // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
3554 // according to the edit list below.
3555 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3556 if (first_non_zero_audio_edit < 0) {
3557 first_non_zero_audio_edit = 1;
3559 first_non_zero_audio_edit = 0;
3562 if (first_non_zero_audio_edit > 0)
3563 st->skip_samples = msc->start_pad = 0;
3566 // While reordering frame index according to edit list we must handle properly
3567 // the scenario when edit list entry starts from none key frame.
3568 // We find closest previous key frame and preserve it and consequent frames in index.
3569 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
3570 search_timestamp = edit_list_media_time;
3571 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3572 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
3573 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
3574 // edit_list_media_time to cover the decoder delay.
3575 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
3578 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
3579 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3580 av_log(mov->fc, AV_LOG_WARNING,
3581 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
3582 st->index, edit_list_index, search_timestamp);
3583 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
3584 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3585 av_log(mov->fc, AV_LOG_WARNING,
3586 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
3587 st->index, edit_list_index, search_timestamp);
3590 ctts_sample_old = 0;
3593 current = e_old + index;
3594 edit_list_start_ctts_sample = ctts_sample_old;
3596 // Iterate over index and arrange it according to edit list
3597 edit_list_start_encountered = 0;
3598 found_keyframe_after_edit = 0;
3599 for (; current < e_old_end; current++, index++) {
3600 // check if frame outside edit list mark it for discard
3601 frame_duration = (current + 1 < e_old_end) ?
3602 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
3604 flags = current->flags;
3606 // frames (pts) before or after edit list
3607 curr_cts = current->timestamp + msc->dts_shift;
3610 if (ctts_data_old && ctts_index_old < ctts_count_old) {
3611 curr_ctts = ctts_data_old[ctts_index_old].duration;
3612 av_log(mov->fc, AV_LOG_DEBUG, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
3613 curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
3614 curr_cts += curr_ctts;
3616 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
3617 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3618 &msc->ctts_allocated_size,
3619 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3620 ctts_data_old[ctts_index_old].duration) == -1) {
3621 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3623 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3624 ctts_data_old[ctts_index_old].duration);
3628 ctts_sample_old = 0;
3629 edit_list_start_ctts_sample = 0;
3633 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
3634 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
3635 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
3636 first_non_zero_audio_edit > 0) {
3637 packet_skip_samples = edit_list_media_time - curr_cts;
3638 st->skip_samples += packet_skip_samples;
3640 // Shift the index entry timestamp by packet_skip_samples to be correct.
3641 edit_list_dts_counter -= packet_skip_samples;
3642 if (edit_list_start_encountered == 0) {
3643 edit_list_start_encountered = 1;
3644 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
3645 // discarded packets.
3646 if (frame_duration_buffer) {
3647 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3648 frame_duration_buffer, num_discarded_begin);
3649 av_freep(&frame_duration_buffer);
3653 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
3655 flags |= AVINDEX_DISCARD_FRAME;
3656 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
3658 if (edit_list_start_encountered == 0) {
3659 num_discarded_begin++;
3660 frame_duration_buffer = av_realloc(frame_duration_buffer,
3661 num_discarded_begin * sizeof(int64_t));
3662 if (!frame_duration_buffer) {
3663 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
3666 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
3668 // Increment skip_samples for the first non-zero audio edit list
3669 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3670 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
3671 st->skip_samples += frame_duration;
3676 if (msc->min_corrected_pts < 0) {
3677 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
3679 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
3681 if (edit_list_start_encountered == 0) {
3682 edit_list_start_encountered = 1;
3683 // Make timestamps strictly monotonically increasing by rewriting timestamps for
3684 // discarded packets.
3685 if (frame_duration_buffer) {
3686 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3687 frame_duration_buffer, num_discarded_begin);
3688 av_freep(&frame_duration_buffer);
3693 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
3694 current->min_distance, flags) == -1) {
3695 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
3699 // Update the index ranges array
3700 if (current_index_range < msc->index_ranges || index != current_index_range->end) {
3701 current_index_range++;
3702 current_index_range->start = index;
3704 current_index_range->end = index + 1;
3706 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
3707 if (edit_list_start_encountered > 0) {
3708 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
3711 // Break when found first key frame after edit entry completion
3712 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
3713 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
3714 if (ctts_data_old) {
3715 // If we have CTTS and this is the first keyframe after edit elist,
3716 // wait for one more, because there might be trailing B-frames after this I-frame
3717 // that do belong to the edit.
3718 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
3719 found_keyframe_after_edit = 1;
3722 if (ctts_sample_old != 0) {
3723 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3724 &msc->ctts_allocated_size,
3725 ctts_sample_old - edit_list_start_ctts_sample,
3726 ctts_data_old[ctts_index_old].duration) == -1) {
3727 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3728 ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
3729 ctts_data_old[ctts_index_old].duration);
3738 // If there are empty edits, then msc->min_corrected_pts might be positive
3739 // intentionally. So we subtract the sum duration of emtpy edits here.
3740 msc->min_corrected_pts -= empty_edits_sum_duration;
3742 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
3743 // dts by that amount to make the first pts zero.
3744 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
3745 if (msc->min_corrected_pts > 0) {
3746 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
3747 for (i = 0; i < st->nb_index_entries; ++i) {
3748 st->index_entries[i].timestamp -= msc->min_corrected_pts;
3752 // Start time should be equal to zero or the duration of any empty edits.
3753 st->start_time = empty_edits_sum_duration;
3755 // Update av stream length, if it ends up shorter than the track's media duration
3756 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
3757 msc->start_pad = st->skip_samples;
3759 // Free the old index and the old CTTS structures
3761 av_free(ctts_data_old);
3762 av_freep(&frame_duration_buffer);
3764 // Null terminate the index ranges array
3765 current_index_range++;
3766 current_index_range->start = 0;
3767 current_index_range->end = 0;
3768 msc->current_index = msc->index_ranges[0].start;
3771 static void mov_build_index(MOVContext *mov, AVStream *st)
3773 MOVStreamContext *sc = st->priv_data;
3774 int64_t current_offset;
3775 int64_t current_dts = 0;
3776 unsigned int stts_index = 0;
3777 unsigned int stsc_index = 0;
3778 unsigned int stss_index = 0;
3779 unsigned int stps_index = 0;
3781 uint64_t stream_size = 0;
3782 MOVStts *ctts_data_old = sc->ctts_data;
3783 unsigned int ctts_count_old = sc->ctts_count;
3785 if (sc->elst_count) {
3786 int i, edit_start_index = 0, multiple_edits = 0;
3787 int64_t empty_duration = 0; // empty duration of the first edit list entry
3788 int64_t start_time = 0; // start time of the media
3790 for (i = 0; i < sc->elst_count; i++) {
3791 const MOVElst *e = &sc->elst_data[i];
3792 if (i == 0 && e->time == -1) {
3793 /* if empty, the first entry is the start time of the stream
3794 * relative to the presentation itself */
3795 empty_duration = e->duration;
3796 edit_start_index = 1;
3797 } else if (i == edit_start_index && e->time >= 0) {
3798 start_time = e->time;
3804 if (multiple_edits && !mov->advanced_editlist)
3805 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
3806 "Use -advanced_editlist to correctly decode otherwise "
3807 "a/v desync might occur\n");
3809 /* adjust first dts according to edit list */
3810 if ((empty_duration || start_time) && mov->time_scale > 0) {
3812 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
3813 sc->time_offset = start_time - empty_duration;
3814 sc->min_corrected_pts = start_time;
3815 if (!mov->advanced_editlist)
3816 current_dts = -sc->time_offset;
3819 if (!multiple_edits && !mov->advanced_editlist &&
3820 st->codecpar->codec_id == AV_CODEC_ID_AAC && start_time > 0)
3821 sc->start_pad = start_time;
3824 /* only use old uncompressed audio chunk demuxing when stts specifies it */
3825 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3826 sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
3827 unsigned int current_sample = 0;
3828 unsigned int stts_sample = 0;
3829 unsigned int sample_size;
3830 unsigned int distance = 0;
3831 unsigned int rap_group_index = 0;
3832 unsigned int rap_group_sample = 0;
3833 int64_t last_dts = 0;
3834 int64_t dts_correction = 0;
3835 int rap_group_present = sc->rap_group_count && sc->rap_group;
3836 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
3838 current_dts -= sc->dts_shift;
3839 last_dts = current_dts;
3841 if (!sc->sample_count || st->nb_index_entries)
3843 if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
3845 if (av_reallocp_array(&st->index_entries,
3846 st->nb_index_entries + sc->sample_count,
3847 sizeof(*st->index_entries)) < 0) {
3848 st->nb_index_entries = 0;
3851 st->index_entries_allocated_size = (st->nb_index_entries + sc->sample_count) * sizeof(*st->index_entries);
3853 if (ctts_data_old) {
3854 // Expand ctts entries such that we have a 1-1 mapping with samples
3855 if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
3858 sc->ctts_allocated_size = 0;
3859 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size,
3860 sc->sample_count * sizeof(*sc->ctts_data));
3861 if (!sc->ctts_data) {
3862 av_free(ctts_data_old);
3866 memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
3868 for (i = 0; i < ctts_count_old &&
3869 sc->ctts_count < sc->sample_count; i++)
3870 for (j = 0; j < ctts_data_old[i].count &&
3871 sc->ctts_count < sc->sample_count; j++)
3872 add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
3873 &sc->ctts_allocated_size, 1,
3874 ctts_data_old[i].duration);
3875 av_free(ctts_data_old);
3878 for (i = 0; i < sc->chunk_count; i++) {
3879 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
3880 current_offset = sc->chunk_offsets[i];
3881 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3882 i + 1 == sc->stsc_data[stsc_index + 1].first)
3885 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
3886 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
3887 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
3888 sc->stsz_sample_size = sc->sample_size;
3890 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
3891 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
3892 sc->stsz_sample_size = sc->sample_size;
3895 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
3897 if (current_sample >= sc->sample_count) {
3898 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
3902 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
3904 if (stss_index + 1 < sc->keyframe_count)
3906 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
3908 if (stps_index + 1 < sc->stps_count)
3911 if (rap_group_present && rap_group_index < sc->rap_group_count) {
3912 if (sc->rap_group[rap_group_index].index > 0)
3914 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
3915 rap_group_sample = 0;
3919 if (sc->keyframe_absent
3921 && !rap_group_present
3922 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
3926 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
3927 if (sc->pseudo_stream_id == -1 ||
3928 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
3930 if (sample_size > 0x3FFFFFFF) {
3931 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
3934 e = &st->index_entries[st->nb_index_entries++];
3935 e->pos = current_offset;
3936 e->timestamp = current_dts;
3937 e->size = sample_size;
3938 e->min_distance = distance;
3939 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
3940 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
3941 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
3942 current_offset, current_dts, sample_size, distance, keyframe);
3943 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries < 100)
3944 ff_rfps_add_frame(mov->fc, st, current_dts);
3947 current_offset += sample_size;
3948 stream_size += sample_size;
3950 /* A negative sample duration is invalid based on the spec,
3951 * but some samples need it to correct the DTS. */
3952 if (sc->stts_data[stts_index].duration < 0) {
3953 av_log(mov->fc, AV_LOG_WARNING,
3954 "Invalid SampleDelta %d in STTS, at %d st:%d\n",
3955 sc->stts_data[stts_index].duration, stts_index,
3957 dts_correction += sc->stts_data[stts_index].duration - 1;
3958 sc->stts_data[stts_index].duration = 1;
3960 current_dts += sc->stts_data[stts_index].duration;
3961 if (!dts_correction || current_dts + dts_correction > last_dts) {
3962 current_dts += dts_correction;
3965 /* Avoid creating non-monotonous DTS */
3966 dts_correction += current_dts - last_dts - 1;
3967 current_dts = last_dts + 1;
3969 last_dts = current_dts;
3973 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
3979 if (st->duration > 0)
3980 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
3982 unsigned chunk_samples, total = 0;
3984 if (!sc->chunk_count)
3987 // compute total chunk count
3988 for (i = 0; i < sc->stsc_count; i++) {
3989 unsigned count, chunk_count;
3991 chunk_samples = sc->stsc_data[i].count;
3992 if (i != sc->stsc_count - 1 &&
3993 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
3994 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
3998 if (sc->samples_per_frame >= 160) { // gsm
3999 count = chunk_samples / sc->samples_per_frame;
4000 } else if (sc->samples_per_frame > 1) {
4001 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4002 count = (chunk_samples+samples-1) / samples;
4004 count = (chunk_samples+1023) / 1024;
4007 if (mov_stsc_index_valid(i, sc->stsc_count))
4008 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4010 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4011 total += chunk_count * count;
4014 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4015 if (total >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
4017 if (av_reallocp_array(&st->index_entries,
4018 st->nb_index_entries + total,
4019 sizeof(*st->index_entries)) < 0) {
4020 st->nb_index_entries = 0;
4023 st->index_entries_allocated_size = (st->nb_index_entries + total) * sizeof(*st->index_entries);
4026 for (i = 0; i < sc->chunk_count; i++) {
4027 current_offset = sc->chunk_offsets[i];
4028 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4029 i + 1 == sc->stsc_data[stsc_index + 1].first)
4031 chunk_samples = sc->stsc_data[stsc_index].count;
4033 while (chunk_samples > 0) {
4035 unsigned size, samples;
4037 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4038 avpriv_request_sample(mov->fc,
4039 "Zero bytes per frame, but %d samples per frame",
4040 sc->samples_per_frame);
4044 if (sc->samples_per_frame >= 160) { // gsm
4045 samples = sc->samples_per_frame;
4046 size = sc->bytes_per_frame;
4048 if (sc->samples_per_frame > 1) {
4049 samples = FFMIN((1024 / sc->samples_per_frame)*
4050 sc->samples_per_frame, chunk_samples);
4051 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
4053 samples = FFMIN(1024, chunk_samples);
4054 size = samples * sc->sample_size;
4058 if (st->nb_index_entries >= total) {
4059 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4062 if (size > 0x3FFFFFFF) {
4063 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4066 e = &st->index_entries[st->nb_index_entries++];
4067 e->pos = current_offset;
4068 e->timestamp = current_dts;
4070 e->min_distance = 0;
4071 e->flags = AVINDEX_KEYFRAME;
4072 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4073 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4076 current_offset += size;
4077 current_dts += samples;
4078 chunk_samples -= samples;
4083 if (!mov->ignore_editlist && mov->advanced_editlist) {
4084 // Fix index according to edit lists.
4085 mov_fix_index(mov, st);
4088 // Update start time of the stream.
4089 if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries > 0) {
4090 st->start_time = st->index_entries[0].timestamp + sc->dts_shift;
4091 if (sc->ctts_data) {
4092 st->start_time += sc->ctts_data[0].duration;
4096 mov_estimate_video_delay(mov, st);
4099 static int test_same_origin(const char *src, const char *ref) {
4109 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4110 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4112 if (strlen(src) == 0) {
4114 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4115 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4116 strlen(src_host) + 1 >= sizeof(src_host) ||
4117 strlen(ref_host) + 1 >= sizeof(ref_host)) {
4119 } else if (strcmp(src_proto, ref_proto) ||
4120 strcmp(src_auth, ref_auth) ||
4121 strcmp(src_host, ref_host) ||
4122 src_port != ref_port) {
4128 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4130 /* try relative path, we do not try the absolute because it can leak information about our
4131 system to an attacker */
4132 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4133 char filename[1025];
4134 const char *src_path;
4137 /* find a source dir */
4138 src_path = strrchr(src, '/');
4144 /* find a next level down to target */
4145 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4146 if (ref->path[l] == '/') {
4147 if (i == ref->nlvl_to - 1)
4153 /* compose filename if next level down to target was found */
4154 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4155 memcpy(filename, src, src_path - src);
4156 filename[src_path - src] = 0;
4158 for (i = 1; i < ref->nlvl_from; i++)
4159 av_strlcat(filename, "../", sizeof(filename));
4161 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4162 if (!c->use_absolute_path) {
4163 int same_origin = test_same_origin(src, filename);
4166 av_log(c->fc, AV_LOG_ERROR,
4167 "Reference with mismatching origin, %s not tried for security reasons, "
4168 "set demuxer option use_absolute_path to allow it anyway\n",
4170 return AVERROR(ENOENT);
4173 if(strstr(ref->path + l + 1, "..") ||
4174 strstr(ref->path + l + 1, ":") ||
4175 (ref->nlvl_from > 1 && same_origin < 0) ||
4176 (filename[0] == '/' && src_path == src))
4177 return AVERROR(ENOENT);
4180 if (strlen(filename) + 1 == sizeof(filename))
4181 return AVERROR(ENOENT);
4182 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4185 } else if (c->use_absolute_path) {
4186 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4187 "this is a possible security issue\n");
4188 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4191 av_log(c->fc, AV_LOG_ERROR,
4192 "Absolute path %s not tried for security reasons, "
4193 "set demuxer option use_absolute_path to allow absolute paths\n",
4197 return AVERROR(ENOENT);
4200 static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
4202 if (sc->time_scale <= 0) {
4203 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4204 sc->time_scale = c->time_scale;
4205 if (sc->time_scale <= 0)
4210 static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4213 MOVStreamContext *sc;
4216 st = avformat_new_stream(c->fc, NULL);
4217 if (!st) return AVERROR(ENOMEM);
4219 sc = av_mallocz(sizeof(MOVStreamContext));
4220 if (!sc) return AVERROR(ENOMEM);
4223 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
4224 sc->ffindex = st->index;
4225 c->trak_index = st->index;
4227 if ((ret = mov_read_default(c, pb, atom)) < 0)
4232 // Here stsc refers to a chunk not described in stco. This is technically invalid,
4233 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4234 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4236 av_freep(&sc->stsc_data);
4240 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4241 (!sc->sample_size && !sc->sample_count))) ||
4242 (!sc->chunk_count && sc->sample_count)) {
4243 av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4247 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4248 av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4250 return AVERROR_INVALIDDATA;
4253 fix_timescale(c, sc);
4255 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4257 mov_build_index(c, st);
4259 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4260 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4261 if (c->enable_drefs) {
4262 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4263 av_log(c->fc, AV_LOG_ERROR,
4264 "stream %d, error opening alias: path='%s', dir='%s', "
4265 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4266 st->index, dref->path, dref->dir, dref->filename,
4267 dref->volume, dref->nlvl_from, dref->nlvl_to);
4269 av_log(c->fc, AV_LOG_WARNING,
4270 "Skipped opening external track: "
4271 "stream %d, alias: path='%s', dir='%s', "
4272 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4273 "Set enable_drefs to allow this.\n",
4274 st->index, dref->path, dref->dir, dref->filename,
4275 dref->volume, dref->nlvl_from, dref->nlvl_to);
4279 sc->pb_is_copied = 1;
4282 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4283 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4284 sc->height && sc->width &&
4285 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4286 st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4287 ((double)st->codecpar->width * sc->height), INT_MAX);
4290 #if FF_API_R_FRAME_RATE
4291 if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4292 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
4293 sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4297 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4298 if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4299 TAG_IS_AVCI(st->codecpar->codec_tag)) {
4300 ret = ff_generate_avci_extradata(st);
4305 switch (st->codecpar->codec_id) {
4306 #if CONFIG_H261_DECODER
4307 case AV_CODEC_ID_H261:
4309 #if CONFIG_H263_DECODER
4310 case AV_CODEC_ID_H263:
4312 #if CONFIG_MPEG4_DECODER
4313 case AV_CODEC_ID_MPEG4:
4315 st->codecpar->width = 0; /* let decoder init width/height */
4316 st->codecpar->height= 0;
4320 // If the duration of the mp3 packets is not constant, then they could need a parser
4321 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4322 && sc->stts_count > 3
4323 && sc->stts_count*10 > st->nb_frames
4324 && sc->time_scale == st->codecpar->sample_rate) {
4325 st->need_parsing = AVSTREAM_PARSE_FULL;
4327 /* Do not need those anymore. */
4328 av_freep(&sc->chunk_offsets);
4329 av_freep(&sc->sample_sizes);
4330 av_freep(&sc->keyframes);
4331 av_freep(&sc->stts_data);
4332 av_freep(&sc->stps_data);
4333 av_freep(&sc->elst_data);
4334 av_freep(&sc->rap_group);
4339 static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4342 c->itunes_metadata = 1;
4343 ret = mov_read_default(c, pb, atom);
4344 c->itunes_metadata = 0;
4348 static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4357 count = avio_rb32(pb);
4358 if (count > UINT_MAX / sizeof(*c->meta_keys) - 1) {
4359 av_log(c->fc, AV_LOG_ERROR,
4360 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
4361 return AVERROR_INVALIDDATA;
4364 c->meta_keys_count = count + 1;
4365 c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
4367 return AVERROR(ENOMEM);
4369 for (i = 1; i <= count; ++i) {
4370 uint32_t key_size = avio_rb32(pb);
4371 uint32_t type = avio_rl32(pb);
4373 av_log(c->fc, AV_LOG_ERROR,
4374 "The key# %"PRIu32" in meta has invalid size:"
4375 "%"PRIu32"\n", i, key_size);
4376 return AVERROR_INVALIDDATA;
4379 if (type != MKTAG('m','d','t','a')) {
4380 avio_skip(pb, key_size);
4382 c->meta_keys[i] = av_mallocz(key_size + 1);
4383 if (!c->meta_keys[i])
4384 return AVERROR(ENOMEM);
4385 avio_read(pb, c->meta_keys[i], key_size);
4391 static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4393 int64_t end = avio_tell(pb) + atom.size;
4394 uint8_t *key = NULL, *val = NULL, *mean = NULL;
4398 MOVStreamContext *sc;
4400 if (c->fc->nb_streams < 1)
4402 st = c->fc->streams[c->fc->nb_streams-1];
4405 for (i = 0; i < 3; i++) {
4409 if (end - avio_tell(pb) <= 12)
4412 len = avio_rb32(pb);
4413 tag = avio_rl32(pb);
4414 avio_skip(pb, 4); // flags
4416 if (len < 12 || len - 12 > end - avio_tell(pb))
4420 if (tag == MKTAG('m', 'e', 'a', 'n'))
4422 else if (tag == MKTAG('n', 'a', 'm', 'e'))
4424 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
4431 *p = av_malloc(len + 1);
4433 ret = AVERROR(ENOMEM);
4436 ret = ffio_read_size(pb, *p, len);
4444 if (mean && key && val) {
4445 if (strcmp(key, "iTunSMPB") == 0) {
4446 int priming, remainder, samples;
4447 if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
4448 if(priming>0 && priming<16384)
4449 sc->start_pad = priming;
4452 if (strcmp(key, "cdec") != 0) {
4453 av_dict_set(&c->fc->metadata, key, val,
4454 AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
4458 av_log(c->fc, AV_LOG_VERBOSE,
4459 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
4462 avio_seek(pb, end, SEEK_SET);
4469 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4471 while (atom.size > 8) {
4475 tag = avio_rl32(pb);
4477 if (tag == MKTAG('h','d','l','r')) {
4478 avio_seek(pb, -8, SEEK_CUR);
4480 return mov_read_default(c, pb, atom);
4486 // return 1 when matrix is identity, 0 otherwise
4487 #define IS_MATRIX_IDENT(matrix) \
4488 ( (matrix)[0][0] == (1 << 16) && \
4489 (matrix)[1][1] == (1 << 16) && \
4490 (matrix)[2][2] == (1 << 30) && \
4491 !(matrix)[0][1] && !(matrix)[0][2] && \
4492 !(matrix)[1][0] && !(matrix)[1][2] && \
4493 !(matrix)[2][0] && !(matrix)[2][1])
4495 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4500 int display_matrix[3][3];
4501 int res_display_matrix[3][3] = { { 0 } };
4503 MOVStreamContext *sc;
4507 if (c->fc->nb_streams < 1)
4509 st = c->fc->streams[c->fc->nb_streams-1];
4512 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4513 // avoids corrupting AVStreams mapped to an earlier tkhd.
4515 return AVERROR_INVALIDDATA;
4517 version = avio_r8(pb);
4518 flags = avio_rb24(pb);
4519 st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
4525 avio_rb32(pb); /* creation time */
4526 avio_rb32(pb); /* modification time */
4528 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4529 avio_rb32(pb); /* reserved */
4531 /* highlevel (considering edits) duration in movie timebase */
4532 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4533 avio_rb32(pb); /* reserved */
4534 avio_rb32(pb); /* reserved */
4536 avio_rb16(pb); /* layer */
4537 avio_rb16(pb); /* alternate group */
4538 avio_rb16(pb); /* volume */
4539 avio_rb16(pb); /* reserved */
4541 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4542 // they're kept in fixed point format through all calculations
4543 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4544 // side data, but the scale factor is not needed to calculate aspect ratio
4545 for (i = 0; i < 3; i++) {
4546 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
4547 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
4548 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
4551 width = avio_rb32(pb); // 16.16 fixed point track width
4552 height = avio_rb32(pb); // 16.16 fixed point track height
4553 sc->width = width >> 16;
4554 sc->height = height >> 16;
4556 // apply the moov display matrix (after the tkhd one)
4557 for (i = 0; i < 3; i++) {
4558 const int sh[3] = { 16, 16, 30 };
4559 for (j = 0; j < 3; j++) {
4560 for (e = 0; e < 3; e++) {
4561 res_display_matrix[i][j] +=
4562 ((int64_t) display_matrix[i][e] *
4563 c->movie_display_matrix[e][j]) >> sh[e];
4568 // save the matrix when it is not the default identity
4569 if (!IS_MATRIX_IDENT(res_display_matrix)) {
4572 av_freep(&sc->display_matrix);
4573 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4574 if (!sc->display_matrix)
4575 return AVERROR(ENOMEM);
4577 for (i = 0; i < 3; i++)
4578 for (j = 0; j < 3; j++)
4579 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4581 #if FF_API_OLD_ROTATE_API
4582 rotate = av_display_rotation_get(sc->display_matrix);
4583 if (!isnan(rotate)) {
4584 char rotate_buf[64];
4586 if (rotate < 0) // for backward compatibility
4588 snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate);
4589 av_dict_set(&st->metadata, "rotate", rotate_buf, 0);
4594 // transform the display width/height according to the matrix
4595 // to keep the same scale, use [width height 1<<16]
4596 if (width && height && sc->display_matrix) {
4597 double disp_transform[2];
4599 for (i = 0; i < 2; i++)
4600 disp_transform[i] = hypot(sc->display_matrix[0 + i],
4601 sc->display_matrix[3 + i]);
4603 if (disp_transform[0] > 0 && disp_transform[1] > 0 &&
4604 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4605 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4606 st->sample_aspect_ratio = av_d2q(
4607 disp_transform[0] / disp_transform[1],
4613 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4615 MOVFragment *frag = &c->fragment;
4616 MOVTrackExt *trex = NULL;
4617 int flags, track_id, i;
4618 MOVFragmentStreamInfo * frag_stream_info;
4620 avio_r8(pb); /* version */
4621 flags = avio_rb24(pb);
4623 track_id = avio_rb32(pb);
4625 return AVERROR_INVALIDDATA;
4626 for (i = 0; i < c->trex_count; i++)
4627 if (c->trex_data[i].track_id == track_id) {
4628 trex = &c->trex_data[i];
4632 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4635 c->fragment.found_tfhd = 1;
4636 frag->track_id = track_id;
4637 set_frag_stream(&c->frag_index, track_id);
4639 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4640 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4641 frag->moof_offset : frag->implicit_offset;
4642 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4644 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4645 avio_rb32(pb) : trex->duration;
4646 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4647 avio_rb32(pb) : trex->size;
4648 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4649 avio_rb32(pb) : trex->flags;
4650 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4652 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4653 if (frag_stream_info)
4654 frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
4659 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4664 num = atom.size / 4;
4665 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4666 return AVERROR(ENOMEM);
4668 av_free(c->chapter_tracks);
4669 c->chapter_tracks = new_tracks;
4670 c->nb_chapter_tracks = num;
4672 for (i = 0; i < num && !pb->eof_reached; i++)
4673 c->chapter_tracks[i] = avio_rb32(pb);
4678 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4683 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4684 return AVERROR_INVALIDDATA;
4685 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4686 sizeof(*c->trex_data))) < 0) {
4691 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4693 trex = &c->trex_data[c->trex_count++];
4694 avio_r8(pb); /* version */
4695 avio_rb24(pb); /* flags */
4696 trex->track_id = avio_rb32(pb);
4697 trex->stsd_id = avio_rb32(pb);
4698 trex->duration = avio_rb32(pb);
4699 trex->size = avio_rb32(pb);
4700 trex->flags = avio_rb32(pb);
4704 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4706 MOVFragment *frag = &c->fragment;
4707 AVStream *st = NULL;
4708 MOVStreamContext *sc;
4710 MOVFragmentStreamInfo * frag_stream_info;
4711 int64_t base_media_decode_time;
4713 for (i = 0; i < c->fc->nb_streams; i++) {
4714 if (c->fc->streams[i]->id == frag->track_id) {
4715 st = c->fc->streams[i];
4720 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4724 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4726 version = avio_r8(pb);
4727 avio_rb24(pb); /* flags */
4729 base_media_decode_time = avio_rb64(pb);
4731 base_media_decode_time = avio_rb32(pb);
4734 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4735 if (frag_stream_info)
4736 frag_stream_info->tfdt_dts = base_media_decode_time;
4737 sc->track_end = base_media_decode_time;
4742 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4744 MOVFragment *frag = &c->fragment;
4745 AVStream *st = NULL;
4746 MOVStreamContext *sc;
4749 int64_t dts, pts = AV_NOPTS_VALUE;
4750 int data_offset = 0;
4751 unsigned entries, first_sample_flags = frag->flags;
4752 int flags, distance, i;
4753 int64_t prev_dts = AV_NOPTS_VALUE;
4754 int next_frag_index = -1, index_entry_pos;
4755 size_t requested_size;
4756 size_t old_ctts_allocated_size;
4757 AVIndexEntry *new_entries;
4758 MOVFragmentStreamInfo * frag_stream_info;
4760 if (!frag->found_tfhd) {
4761 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4762 return AVERROR_INVALIDDATA;
4765 for (i = 0; i < c->fc->nb_streams; i++) {
4766 if (c->fc->streams[i]->id == frag->track_id) {
4767 st = c->fc->streams[i];
4772 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4776 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4779 // Find the next frag_index index that has a valid index_entry for
4780 // the current track_id.
4782 // A valid index_entry means the trun for the fragment was read
4783 // and it's samples are in index_entries at the given position.
4784 // New index entries will be inserted before the index_entry found.
4785 index_entry_pos = st->nb_index_entries;
4786 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4787 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4788 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4789 next_frag_index = i;
4790 index_entry_pos = frag_stream_info->index_entry;
4794 av_assert0(index_entry_pos <= st->nb_index_entries);
4796 avio_r8(pb); /* version */
4797 flags = avio_rb24(pb);
4798 entries = avio_rb32(pb);
4799 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4801 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4802 return AVERROR_INVALIDDATA;
4803 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4804 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4806 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4807 if (frag_stream_info)
4809 if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
4810 dts = frag_stream_info->next_trun_dts - sc->time_offset;
4811 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4812 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4813 pts = frag_stream_info->first_tfra_pts;
4814 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4815 ", using it for pts\n", pts);
4816 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4817 c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
4818 dts = frag_stream_info->first_tfra_pts;
4819 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4820 ", using it for dts\n", pts);
4821 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4822 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4823 // pts = frag_stream_info->sidx_pts;
4824 dts = frag_stream_info->sidx_pts - sc->time_offset;
4825 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4826 ", using it for pts\n", pts);
4827 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4828 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4829 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4830 ", using it for dts\n", dts);
4832 dts = sc->track_end - sc->time_offset;
4833 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4834 ", using it for dts\n", dts);
4837 dts = sc->track_end - sc->time_offset;
4838 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4839 ", using it for dts\n", dts);
4841 offset = frag->base_data_offset + data_offset;
4843 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4845 // realloc space for new index entries
4846 if((uint64_t)st->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4847 entries = UINT_MAX / sizeof(AVIndexEntry) - st->nb_index_entries;
4848 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4853 requested_size = (st->nb_index_entries + entries) * sizeof(AVIndexEntry);
4854 new_entries = av_fast_realloc(st->index_entries,
4855 &st->index_entries_allocated_size,
4858 return AVERROR(ENOMEM);
4859 st->index_entries= new_entries;
4861 requested_size = (st->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4862 old_ctts_allocated_size = sc->ctts_allocated_size;
4863 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4866 return AVERROR(ENOMEM);
4867 sc->ctts_data = ctts_data;
4869 // In case there were samples without ctts entries, ensure they get
4870 // zero valued entries. This ensures clips which mix boxes with and
4871 // without ctts entries don't pickup uninitialized data.
4872 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4873 sc->ctts_allocated_size - old_ctts_allocated_size);
4875 if (index_entry_pos < st->nb_index_entries) {
4876 // Make hole in index_entries and ctts_data for new samples
4877 memmove(st->index_entries + index_entry_pos + entries,
4878 st->index_entries + index_entry_pos,
4879 sizeof(*st->index_entries) *
4880 (st->nb_index_entries - index_entry_pos));
4881 memmove(sc->ctts_data + index_entry_pos + entries,
4882 sc->ctts_data + index_entry_pos,
4883 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4884 if (index_entry_pos < sc->current_sample) {
4885 sc->current_sample += entries;
4889 st->nb_index_entries += entries;
4890 sc->ctts_count = st->nb_index_entries;
4892 // Record the index_entry position in frag_index of this fragment
4893 if (frag_stream_info)
4894 frag_stream_info->index_entry = index_entry_pos;
4896 if (index_entry_pos > 0)
4897 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4899 for (i = 0; i < entries && !pb->eof_reached; i++) {
4900 unsigned sample_size = frag->size;
4901 int sample_flags = i ? frag->flags : first_sample_flags;
4902 unsigned sample_duration = frag->duration;
4903 unsigned ctts_duration = 0;
4905 int index_entry_flags = 0;
4907 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4908 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4909 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4910 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4912 mov_update_dts_shift(sc, ctts_duration, c->fc);
4913 if (pts != AV_NOPTS_VALUE) {
4914 dts = pts - sc->dts_shift;
4915 if (flags & MOV_TRUN_SAMPLE_CTS) {
4916 dts -= ctts_duration;
4918 dts -= sc->time_offset;
4920 av_log(c->fc, AV_LOG_DEBUG,
4921 "pts %"PRId64" calculated dts %"PRId64
4922 " sc->dts_shift %d ctts.duration %d"
4923 " sc->time_offset %"PRId64
4924 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4926 sc->dts_shift, ctts_duration,
4927 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4928 pts = AV_NOPTS_VALUE;
4931 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4935 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4936 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4939 index_entry_flags |= AVINDEX_KEYFRAME;
4941 // Fragments can overlap in time. Discard overlapping frames after
4943 if (prev_dts >= dts)
4944 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4946 st->index_entries[index_entry_pos].pos = offset;
4947 st->index_entries[index_entry_pos].timestamp = dts;
4948 st->index_entries[index_entry_pos].size= sample_size;
4949 st->index_entries[index_entry_pos].min_distance= distance;
4950 st->index_entries[index_entry_pos].flags = index_entry_flags;
4952 sc->ctts_data[index_entry_pos].count = 1;
4953 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4956 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4957 "size %u, distance %d, keyframe %d\n", st->index,
4958 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4960 dts += sample_duration;
4961 offset += sample_size;
4962 sc->data_size += sample_size;
4964 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4965 1 <= INT_MAX - sc->nb_frames_for_fps
4967 sc->duration_for_fps += sample_duration;
4968 sc->nb_frames_for_fps ++;
4971 if (frag_stream_info)
4972 frag_stream_info->next_trun_dts = dts + sc->time_offset;
4974 // EOF found before reading all entries. Fix the hole this would
4975 // leave in index_entries and ctts_data
4976 int gap = entries - i;
4977 memmove(st->index_entries + index_entry_pos,
4978 st->index_entries + index_entry_pos + gap,
4979 sizeof(*st->index_entries) *
4980 (st->nb_index_entries - (index_entry_pos + gap)));
4981 memmove(sc->ctts_data + index_entry_pos,
4982 sc->ctts_data + index_entry_pos + gap,
4983 sizeof(*sc->ctts_data) *
4984 (sc->ctts_count - (index_entry_pos + gap)));
4986 st->nb_index_entries -= gap;
4987 sc->ctts_count -= gap;
4988 if (index_entry_pos < sc->current_sample) {
4989 sc->current_sample -= gap;
4994 // The end of this new fragment may overlap in time with the start
4995 // of the next fragment in index_entries. Mark the samples in the next
4996 // fragment that overlap with AVINDEX_DISCARD_FRAME
4997 prev_dts = AV_NOPTS_VALUE;
4998 if (index_entry_pos > 0)
4999 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
5000 for (i = index_entry_pos; i < st->nb_index_entries; i++) {
5001 if (prev_dts < st->index_entries[i].timestamp)
5003 st->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
5006 // If a hole was created to insert the new index_entries into,
5007 // the index_entry recorded for all subsequent moof must
5008 // be incremented by the number of entries inserted.
5009 fix_frag_index_entries(&c->frag_index, next_frag_index,
5010 frag->track_id, entries);
5012 if (pb->eof_reached) {
5013 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
5017 frag->implicit_offset = offset;
5019 sc->track_end = dts + sc->time_offset;
5020 if (st->duration < sc->track_end)
5021 st->duration = sc->track_end;
5026 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5028 int64_t offset = avio_tell(pb) + atom.size, pts, timestamp;
5030 unsigned i, j, track_id, item_count;
5031 AVStream *st = NULL;
5032 AVStream *ref_st = NULL;
5033 MOVStreamContext *sc, *ref_sc = NULL;
5034 AVRational timescale;
5036 version = avio_r8(pb);
5038 avpriv_request_sample(c->fc, "sidx version %u", version);
5042 avio_rb24(pb); // flags
5044 track_id = avio_rb32(pb); // Reference ID
5045 for (i = 0; i < c->fc->nb_streams; i++) {
5046 if (c->fc->streams[i]->id == track_id) {
5047 st = c->fc->streams[i];
5052 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5058 timescale = av_make_q(1, avio_rb32(pb));
5060 if (timescale.den <= 0) {
5061 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5062 return AVERROR_INVALIDDATA;
5066 pts = avio_rb32(pb);
5067 offset += avio_rb32(pb);
5069 pts = avio_rb64(pb);
5070 offset += avio_rb64(pb);
5073 avio_rb16(pb); // reserved
5075 item_count = avio_rb16(pb);
5077 for (i = 0; i < item_count; i++) {
5079 MOVFragmentStreamInfo * frag_stream_info;
5080 uint32_t size = avio_rb32(pb);
5081 uint32_t duration = avio_rb32(pb);
5082 if (size & 0x80000000) {
5083 avpriv_request_sample(c->fc, "sidx reference_type 1");
5084 return AVERROR_PATCHWELCOME;
5086 avio_rb32(pb); // sap_flags
5087 timestamp = av_rescale_q(pts, timescale, st->time_base);
5089 index = update_frag_index(c, offset);
5090 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5091 if (frag_stream_info)
5092 frag_stream_info->sidx_pts = timestamp;
5098 st->duration = sc->track_end = pts;
5102 if (offset == avio_size(pb)) {
5103 // Find first entry in fragment index that came from an sidx.
5104 // This will pretty much always be the first entry.
5105 for (i = 0; i < c->frag_index.nb_items; i++) {
5106 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5107 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5108 MOVFragmentStreamInfo * si;
5109 si = &item->stream_info[j];
5110 if (si->sidx_pts != AV_NOPTS_VALUE) {
5111 ref_st = c->fc->streams[j];
5112 ref_sc = ref_st->priv_data;
5117 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5118 st = c->fc->streams[i];
5120 if (!sc->has_sidx) {
5121 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5125 c->frag_index.complete = 1;
5131 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5132 /* like the files created with Adobe Premiere 5.0, for samples see */
5133 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5134 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5139 return 0; /* continue */
5140 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5141 avio_skip(pb, atom.size - 4);
5144 atom.type = avio_rl32(pb);
5146 if (atom.type != MKTAG('m','d','a','t')) {
5147 avio_skip(pb, atom.size);
5150 err = mov_read_mdat(c, pb, atom);
5154 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5159 uint8_t *moov_data; /* uncompressed data */
5160 long cmov_len, moov_len;
5163 avio_rb32(pb); /* dcom atom */
5164 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5165 return AVERROR_INVALIDDATA;
5166 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5167 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5168 return AVERROR_INVALIDDATA;
5170 avio_rb32(pb); /* cmvd atom */
5171 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5172 return AVERROR_INVALIDDATA;
5173 moov_len = avio_rb32(pb); /* uncompressed size */
5174 cmov_len = atom.size - 6 * 4;
5176 cmov_data = av_malloc(cmov_len);
5178 return AVERROR(ENOMEM);
5179 moov_data = av_malloc(moov_len);
5182 return AVERROR(ENOMEM);
5184 ret = ffio_read_size(pb, cmov_data, cmov_len);
5186 goto free_and_return;
5188 ret = AVERROR_INVALIDDATA;
5189 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5190 goto free_and_return;
5191 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5192 goto free_and_return;
5193 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5194 atom.type = MKTAG('m','o','o','v');
5195 atom.size = moov_len;
5196 ret = mov_read_default(c, &ctx, atom);
5202 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5203 return AVERROR(ENOSYS);
5207 /* edit list atom */
5208 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5210 MOVStreamContext *sc;
5211 int i, edit_count, version;
5212 int64_t elst_entry_size;
5214 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5216 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5218 version = avio_r8(pb); /* version */
5219 avio_rb24(pb); /* flags */
5220 edit_count = avio_rb32(pb); /* entries */
5223 elst_entry_size = version == 1 ? 20 : 12;
5224 if (atom.size != edit_count * elst_entry_size) {
5225 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5226 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5227 edit_count, atom.size + 8);
5228 return AVERROR_INVALIDDATA;
5230 edit_count = atom.size / elst_entry_size;
5231 if (edit_count * elst_entry_size != atom.size) {
5232 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.", atom.size, edit_count);
5240 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5241 av_free(sc->elst_data);
5243 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5245 return AVERROR(ENOMEM);
5247 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5248 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5249 MOVElst *e = &sc->elst_data[i];
5252 e->duration = avio_rb64(pb);
5253 e->time = avio_rb64(pb);
5256 e->duration = avio_rb32(pb); /* segment duration */
5257 e->time = (int32_t)avio_rb32(pb); /* media time */
5260 e->rate = avio_rb32(pb) / 65536.0;
5262 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5263 e->duration, e->time, e->rate);
5265 if (e->time < 0 && e->time != -1 &&
5266 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5267 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5268 c->fc->nb_streams-1, i, e->time);
5269 return AVERROR_INVALIDDATA;
5277 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5279 MOVStreamContext *sc;
5281 if (c->fc->nb_streams < 1)
5282 return AVERROR_INVALIDDATA;
5283 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5284 sc->timecode_track = avio_rb32(pb);
5288 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5293 if (c->fc->nb_streams < 1)
5295 st = c->fc->streams[c->fc->nb_streams - 1];
5297 if (atom.size < 4) {
5298 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5299 return AVERROR_INVALIDDATA;
5302 /* For now, propagate only the OBUs, if any. Once libavcodec is
5303 updated to handle isobmff style extradata this can be removed. */
5309 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5316 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5319 int version, color_range, color_primaries, color_trc, color_space;
5321 if (c->fc->nb_streams < 1)
5323 st = c->fc->streams[c->fc->nb_streams - 1];
5325 if (atom.size < 5) {
5326 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5327 return AVERROR_INVALIDDATA;
5330 version = avio_r8(pb);
5332 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5335 avio_skip(pb, 3); /* flags */
5337 avio_skip(pb, 2); /* profile + level */
5338 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5339 color_primaries = avio_r8(pb);
5340 color_trc = avio_r8(pb);
5341 color_space = avio_r8(pb);
5342 if (avio_rb16(pb)) /* codecIntializationDataSize */
5343 return AVERROR_INVALIDDATA;
5345 if (!av_color_primaries_name(color_primaries))
5346 color_primaries = AVCOL_PRI_UNSPECIFIED;
5347 if (!av_color_transfer_name(color_trc))
5348 color_trc = AVCOL_TRC_UNSPECIFIED;
5349 if (!av_color_space_name(color_space))
5350 color_space = AVCOL_SPC_UNSPECIFIED;
5352 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5353 st->codecpar->color_primaries = color_primaries;
5354 st->codecpar->color_trc = color_trc;
5355 st->codecpar->color_space = color_space;
5360 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5362 MOVStreamContext *sc;
5365 if (c->fc->nb_streams < 1)
5366 return AVERROR_INVALIDDATA;
5368 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5370 if (atom.size < 5) {
5371 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5372 return AVERROR_INVALIDDATA;
5375 version = avio_r8(pb);
5377 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5380 avio_skip(pb, 3); /* flags */
5382 sc->mastering = av_mastering_display_metadata_alloc();
5384 return AVERROR(ENOMEM);
5386 for (i = 0; i < 3; i++) {
5387 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5388 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5390 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5391 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5393 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5394 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5396 sc->mastering->has_primaries = 1;
5397 sc->mastering->has_luminance = 1;
5402 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5404 MOVStreamContext *sc;
5405 const int mapping[3] = {1, 2, 0};
5406 const int chroma_den = 50000;
5407 const int luma_den = 10000;
5410 if (c->fc->nb_streams < 1)
5411 return AVERROR_INVALIDDATA;
5413 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5415 if (atom.size < 24) {
5416 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5417 return AVERROR_INVALIDDATA;
5420 sc->mastering = av_mastering_display_metadata_alloc();
5422 return AVERROR(ENOMEM);
5424 for (i = 0; i < 3; i++) {
5425 const int j = mapping[i];
5426 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5427 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5429 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5430 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5432 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5433 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5435 sc->mastering->has_luminance = 1;
5436 sc->mastering->has_primaries = 1;
5441 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5443 MOVStreamContext *sc;
5446 if (c->fc->nb_streams < 1)
5447 return AVERROR_INVALIDDATA;
5449 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5451 if (atom.size < 5) {
5452 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5453 return AVERROR_INVALIDDATA;
5456 version = avio_r8(pb);
5458 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5461 avio_skip(pb, 3); /* flags */
5463 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5465 return AVERROR(ENOMEM);
5467 sc->coll->MaxCLL = avio_rb16(pb);
5468 sc->coll->MaxFALL = avio_rb16(pb);
5473 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5475 MOVStreamContext *sc;
5477 if (c->fc->nb_streams < 1)
5478 return AVERROR_INVALIDDATA;
5480 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5482 if (atom.size < 4) {
5483 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5484 return AVERROR_INVALIDDATA;
5487 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5489 return AVERROR(ENOMEM);
5491 sc->coll->MaxCLL = avio_rb16(pb);
5492 sc->coll->MaxFALL = avio_rb16(pb);
5497 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5500 MOVStreamContext *sc;
5501 enum AVStereo3DType type;
5504 if (c->fc->nb_streams < 1)
5507 st = c->fc->streams[c->fc->nb_streams - 1];
5510 if (atom.size < 5) {
5511 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5512 return AVERROR_INVALIDDATA;
5514 avio_skip(pb, 4); /* version + flags */
5519 type = AV_STEREO3D_2D;
5522 type = AV_STEREO3D_TOPBOTTOM;
5525 type = AV_STEREO3D_SIDEBYSIDE;
5528 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5532 sc->stereo3d = av_stereo3d_alloc();
5534 return AVERROR(ENOMEM);
5536 sc->stereo3d->type = type;
5540 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5543 MOVStreamContext *sc;
5544 int size, version, layout;
5545 int32_t yaw, pitch, roll;
5546 uint32_t l = 0, t = 0, r = 0, b = 0;
5547 uint32_t tag, padding = 0;
5548 enum AVSphericalProjection projection;
5550 if (c->fc->nb_streams < 1)
5553 st = c->fc->streams[c->fc->nb_streams - 1];
5556 if (atom.size < 8) {
5557 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5558 return AVERROR_INVALIDDATA;
5561 size = avio_rb32(pb);
5562 if (size <= 12 || size > atom.size)
5563 return AVERROR_INVALIDDATA;
5565 tag = avio_rl32(pb);
5566 if (tag != MKTAG('s','v','h','d')) {
5567 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5570 version = avio_r8(pb);
5572 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5576 avio_skip(pb, 3); /* flags */
5577 avio_skip(pb, size - 12); /* metadata_source */
5579 size = avio_rb32(pb);
5580 if (size > atom.size)
5581 return AVERROR_INVALIDDATA;
5583 tag = avio_rl32(pb);
5584 if (tag != MKTAG('p','r','o','j')) {
5585 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5589 size = avio_rb32(pb);
5590 if (size > atom.size)
5591 return AVERROR_INVALIDDATA;
5593 tag = avio_rl32(pb);
5594 if (tag != MKTAG('p','r','h','d')) {
5595 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5598 version = avio_r8(pb);
5600 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5604 avio_skip(pb, 3); /* flags */
5606 /* 16.16 fixed point */
5607 yaw = avio_rb32(pb);
5608 pitch = avio_rb32(pb);
5609 roll = avio_rb32(pb);
5611 size = avio_rb32(pb);
5612 if (size > atom.size)
5613 return AVERROR_INVALIDDATA;
5615 tag = avio_rl32(pb);
5616 version = avio_r8(pb);
5618 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5622 avio_skip(pb, 3); /* flags */
5624 case MKTAG('c','b','m','p'):
5625 layout = avio_rb32(pb);
5627 av_log(c->fc, AV_LOG_WARNING,
5628 "Unsupported cubemap layout %d\n", layout);
5631 projection = AV_SPHERICAL_CUBEMAP;
5632 padding = avio_rb32(pb);
5634 case MKTAG('e','q','u','i'):
5640 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5641 av_log(c->fc, AV_LOG_ERROR,
5642 "Invalid bounding rectangle coordinates "
5643 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5644 return AVERROR_INVALIDDATA;
5647 if (l || t || r || b)
5648 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5650 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5653 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5657 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5659 return AVERROR(ENOMEM);
5661 sc->spherical->projection = projection;
5663 sc->spherical->yaw = yaw;
5664 sc->spherical->pitch = pitch;
5665 sc->spherical->roll = roll;
5667 sc->spherical->padding = padding;
5669 sc->spherical->bound_left = l;
5670 sc->spherical->bound_top = t;
5671 sc->spherical->bound_right = r;
5672 sc->spherical->bound_bottom = b;
5677 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5680 uint8_t *buffer = av_malloc(len + 1);
5684 return AVERROR(ENOMEM);
5687 ret = ffio_read_size(pb, buffer, len);
5691 /* Check for mandatory keys and values, try to support XML as best-effort */
5692 if (!sc->spherical &&
5693 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5694 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5695 av_stristr(val, "true") &&
5696 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5697 av_stristr(val, "true") &&
5698 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5699 av_stristr(val, "equirectangular")) {
5700 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5704 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5706 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5707 enum AVStereo3DType mode;
5709 if (av_stristr(buffer, "left-right"))
5710 mode = AV_STEREO3D_SIDEBYSIDE;
5711 else if (av_stristr(buffer, "top-bottom"))
5712 mode = AV_STEREO3D_TOPBOTTOM;
5714 mode = AV_STEREO3D_2D;
5716 sc->stereo3d = av_stereo3d_alloc();
5720 sc->stereo3d->type = mode;
5724 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5726 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5727 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5729 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5730 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5732 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5740 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5743 MOVStreamContext *sc;
5746 static const uint8_t uuid_isml_manifest[] = {
5747 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5748 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5750 static const uint8_t uuid_xmp[] = {
5751 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5752 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5754 static const uint8_t uuid_spherical[] = {
5755 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5756 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5759 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5760 return AVERROR_INVALIDDATA;
5762 if (c->fc->nb_streams < 1)
5764 st = c->fc->streams[c->fc->nb_streams - 1];
5767 ret = avio_read(pb, uuid, sizeof(uuid));
5770 } else if (ret != sizeof(uuid)) {
5771 return AVERROR_INVALIDDATA;
5773 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5774 uint8_t *buffer, *ptr;
5776 size_t len = atom.size - sizeof(uuid);
5779 return AVERROR_INVALIDDATA;
5781 ret = avio_skip(pb, 4); // zeroes
5784 buffer = av_mallocz(len + 1);
5786 return AVERROR(ENOMEM);
5788 ret = avio_read(pb, buffer, len);
5792 } else if (ret != len) {
5794 return AVERROR_INVALIDDATA;
5798 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5799 ptr += sizeof("systemBitrate=\"") - 1;
5800 c->bitrates_count++;
5801 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5803 c->bitrates_count = 0;
5805 return AVERROR(ENOMEM);
5808 ret = strtol(ptr, &endptr, 10);
5809 if (ret < 0 || errno || *endptr != '"') {
5810 c->bitrates[c->bitrates_count - 1] = 0;
5812 c->bitrates[c->bitrates_count - 1] = ret;
5817 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5819 size_t len = atom.size - sizeof(uuid);
5820 if (c->export_xmp) {
5821 buffer = av_mallocz(len + 1);
5823 return AVERROR(ENOMEM);
5825 ret = avio_read(pb, buffer, len);
5829 } else if (ret != len) {
5831 return AVERROR_INVALIDDATA;
5834 av_dict_set(&c->fc->metadata, "xmp",
5835 buffer, AV_DICT_DONT_STRDUP_VAL);
5837 // skip all uuid atom, which makes it fast for long uuid-xmp file
5838 ret = avio_skip(pb, len);
5842 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5843 size_t len = atom.size - sizeof(uuid);
5844 ret = mov_parse_uuid_spherical(sc, pb, len);
5848 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5854 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5857 uint8_t content[16];
5862 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5868 && !memcmp(content, "Anevia\x1A\x1A", 8)
5869 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5870 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5876 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5878 uint32_t format = avio_rl32(pb);
5879 MOVStreamContext *sc;
5883 if (c->fc->nb_streams < 1)
5885 st = c->fc->streams[c->fc->nb_streams - 1];
5890 case MKTAG('e','n','c','v'): // encrypted video
5891 case MKTAG('e','n','c','a'): // encrypted audio
5892 id = mov_codec_id(st, format);
5893 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5894 st->codecpar->codec_id != id) {
5895 av_log(c->fc, AV_LOG_WARNING,
5896 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5897 (char*)&format, st->codecpar->codec_id);
5901 st->codecpar->codec_id = id;
5902 sc->format = format;
5906 if (format != sc->format) {
5907 av_log(c->fc, AV_LOG_WARNING,
5908 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5909 (char*)&format, (char*)&sc->format);
5918 * Gets the current encryption info and associated current stream context. If
5919 * we are parsing a track fragment, this will return the specific encryption
5920 * info for this fragment; otherwise this will return the global encryption
5921 * info for the current stream.
5923 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5925 MOVFragmentStreamInfo *frag_stream_info;
5929 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5930 if (frag_stream_info) {
5931 for (i = 0; i < c->fc->nb_streams; i++) {
5932 if (c->fc->streams[i]->id == frag_stream_info->id) {
5933 st = c->fc->streams[i];
5937 if (i == c->fc->nb_streams)
5939 *sc = st->priv_data;
5941 if (!frag_stream_info->encryption_index) {
5942 // If this stream isn't encrypted, don't create the index.
5943 if (!(*sc)->cenc.default_encrypted_sample)
5945 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5946 if (!frag_stream_info->encryption_index)
5947 return AVERROR(ENOMEM);
5949 *encryption_index = frag_stream_info->encryption_index;
5952 // No current track fragment, using stream level encryption info.
5954 if (c->fc->nb_streams < 1)
5956 st = c->fc->streams[c->fc->nb_streams - 1];
5957 *sc = st->priv_data;
5959 if (!(*sc)->cenc.encryption_index) {
5960 // If this stream isn't encrypted, don't create the index.
5961 if (!(*sc)->cenc.default_encrypted_sample)
5963 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5964 if (!(*sc)->cenc.encryption_index)
5965 return AVERROR(ENOMEM);
5968 *encryption_index = (*sc)->cenc.encryption_index;
5973 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
5976 unsigned int subsample_count;
5977 AVSubsampleEncryptionInfo *subsamples;
5979 if (!sc->cenc.default_encrypted_sample) {
5980 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
5981 return AVERROR_INVALIDDATA;
5984 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
5986 return AVERROR(ENOMEM);
5988 if (sc->cenc.per_sample_iv_size != 0) {
5989 if (avio_read(pb, (*sample)->iv, sc->cenc.per_sample_iv_size) != sc->cenc.per_sample_iv_size) {
5990 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
5991 av_encryption_info_free(*sample);
5993 return AVERROR_INVALIDDATA;
5997 if (use_subsamples) {
5998 subsample_count = avio_rb16(pb);
5999 av_free((*sample)->subsamples);
6000 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
6001 if (!(*sample)->subsamples) {
6002 av_encryption_info_free(*sample);
6004 return AVERROR(ENOMEM);
6007 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
6008 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
6009 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
6012 if (pb->eof_reached) {
6013 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
6014 av_encryption_info_free(*sample);
6016 return AVERROR_INVALIDDATA;
6018 (*sample)->subsample_count = subsample_count;
6024 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6026 AVEncryptionInfo **encrypted_samples;
6027 MOVEncryptionIndex *encryption_index;
6028 MOVStreamContext *sc;
6029 int use_subsamples, ret;
6030 unsigned int sample_count, i, alloc_size = 0;
6032 ret = get_current_encryption_info(c, &encryption_index, &sc);
6036 if (encryption_index->nb_encrypted_samples) {
6037 // This can happen if we have both saio/saiz and senc atoms.
6038 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6042 avio_r8(pb); /* version */
6043 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6045 sample_count = avio_rb32(pb);
6046 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6047 return AVERROR(ENOMEM);
6049 for (i = 0; i < sample_count; i++) {
6050 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6051 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6052 min_samples * sizeof(*encrypted_samples));
6053 if (encrypted_samples) {
6054 encryption_index->encrypted_samples = encrypted_samples;
6056 ret = mov_read_sample_encryption_info(
6057 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6059 ret = AVERROR(ENOMEM);
6061 if (pb->eof_reached) {
6062 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6063 ret = AVERROR_INVALIDDATA;
6068 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6069 av_freep(&encryption_index->encrypted_samples);
6073 encryption_index->nb_encrypted_samples = sample_count;
6078 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6080 AVEncryptionInfo **sample, **encrypted_samples;
6082 size_t sample_count, sample_info_size, i;
6084 unsigned int alloc_size = 0;
6086 if (encryption_index->nb_encrypted_samples)
6088 sample_count = encryption_index->auxiliary_info_sample_count;
6089 if (encryption_index->auxiliary_offsets_count != 1) {
6090 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6091 return AVERROR_PATCHWELCOME;
6093 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6094 return AVERROR(ENOMEM);
6096 prev_pos = avio_tell(pb);
6097 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6098 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6099 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6103 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6104 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6105 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6106 min_samples * sizeof(*encrypted_samples));
6107 if (!encrypted_samples) {
6108 ret = AVERROR(ENOMEM);
6111 encryption_index->encrypted_samples = encrypted_samples;
6113 sample = &encryption_index->encrypted_samples[i];
6114 sample_info_size = encryption_index->auxiliary_info_default_size
6115 ? encryption_index->auxiliary_info_default_size
6116 : encryption_index->auxiliary_info_sizes[i];
6118 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6122 if (pb->eof_reached) {
6123 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6124 ret = AVERROR_INVALIDDATA;
6126 encryption_index->nb_encrypted_samples = sample_count;
6130 avio_seek(pb, prev_pos, SEEK_SET);
6132 for (; i > 0; i--) {
6133 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6135 av_freep(&encryption_index->encrypted_samples);
6141 * Tries to read the given number of bytes from the stream and puts it in a
6142 * newly allocated buffer. This reads in small chunks to avoid allocating large
6143 * memory if the file contains an invalid/malicious size value.
6145 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6147 const unsigned int block_size = 1024 * 1024;
6148 uint8_t *buffer = NULL;
6149 unsigned int alloc_size = 0, offset = 0;
6150 while (offset < size) {
6151 unsigned int new_size =
6152 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6153 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6154 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6157 return AVERROR(ENOMEM);
6159 buffer = new_buffer;
6161 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6163 return AVERROR_INVALIDDATA;
6172 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6174 MOVEncryptionIndex *encryption_index;
6175 MOVStreamContext *sc;
6177 unsigned int sample_count, aux_info_type, aux_info_param;
6179 ret = get_current_encryption_info(c, &encryption_index, &sc);
6183 if (encryption_index->nb_encrypted_samples) {
6184 // This can happen if we have both saio/saiz and senc atoms.
6185 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6189 if (encryption_index->auxiliary_info_sample_count) {
6190 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6191 return AVERROR_INVALIDDATA;
6194 avio_r8(pb); /* version */
6195 if (avio_rb24(pb) & 0x01) { /* flags */
6196 aux_info_type = avio_rb32(pb);
6197 aux_info_param = avio_rb32(pb);
6198 if (sc->cenc.default_encrypted_sample) {
6199 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6200 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6203 if (aux_info_param != 0) {
6204 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6208 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6209 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6210 aux_info_type == MKBETAG('c','e','n','s') ||
6211 aux_info_type == MKBETAG('c','b','c','1') ||
6212 aux_info_type == MKBETAG('c','b','c','s')) &&
6213 aux_info_param == 0) {
6214 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6215 return AVERROR_INVALIDDATA;
6220 } else if (!sc->cenc.default_encrypted_sample) {
6221 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6225 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6226 sample_count = avio_rb32(pb);
6227 encryption_index->auxiliary_info_sample_count = sample_count;
6229 if (encryption_index->auxiliary_info_default_size == 0) {
6230 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6232 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6237 if (encryption_index->auxiliary_offsets_count) {
6238 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6244 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6246 uint64_t *auxiliary_offsets;
6247 MOVEncryptionIndex *encryption_index;
6248 MOVStreamContext *sc;
6250 unsigned int version, entry_count, aux_info_type, aux_info_param;
6251 unsigned int alloc_size = 0;
6253 ret = get_current_encryption_info(c, &encryption_index, &sc);
6257 if (encryption_index->nb_encrypted_samples) {
6258 // This can happen if we have both saio/saiz and senc atoms.
6259 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6263 if (encryption_index->auxiliary_offsets_count) {
6264 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6265 return AVERROR_INVALIDDATA;
6268 version = avio_r8(pb); /* version */
6269 if (avio_rb24(pb) & 0x01) { /* flags */
6270 aux_info_type = avio_rb32(pb);
6271 aux_info_param = avio_rb32(pb);
6272 if (sc->cenc.default_encrypted_sample) {
6273 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6274 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6277 if (aux_info_param != 0) {
6278 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6282 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6283 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6284 aux_info_type == MKBETAG('c','e','n','s') ||
6285 aux_info_type == MKBETAG('c','b','c','1') ||
6286 aux_info_type == MKBETAG('c','b','c','s')) &&
6287 aux_info_param == 0) {
6288 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6289 return AVERROR_INVALIDDATA;
6294 } else if (!sc->cenc.default_encrypted_sample) {
6295 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6299 entry_count = avio_rb32(pb);
6300 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6301 return AVERROR(ENOMEM);
6303 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6304 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6305 auxiliary_offsets = av_fast_realloc(
6306 encryption_index->auxiliary_offsets, &alloc_size,
6307 min_offsets * sizeof(*auxiliary_offsets));
6308 if (!auxiliary_offsets) {
6309 av_freep(&encryption_index->auxiliary_offsets);
6310 return AVERROR(ENOMEM);
6312 encryption_index->auxiliary_offsets = auxiliary_offsets;
6315 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6317 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6319 if (c->frag_index.current >= 0) {
6320 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6324 if (pb->eof_reached) {
6325 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6326 av_freep(&encryption_index->auxiliary_offsets);
6327 return AVERROR_INVALIDDATA;
6330 encryption_index->auxiliary_offsets_count = entry_count;
6332 if (encryption_index->auxiliary_info_sample_count) {
6333 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6339 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6341 AVEncryptionInitInfo *info, *old_init_info;
6344 uint8_t *side_data, *extra_data, *old_side_data;
6345 size_t side_data_size;
6346 int ret = 0, old_side_data_size;
6347 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6349 if (c->fc->nb_streams < 1)
6351 st = c->fc->streams[c->fc->nb_streams-1];
6353 version = avio_r8(pb); /* version */
6354 avio_rb24(pb); /* flags */
6356 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6357 /* key_id_size */ 16, /* data_size */ 0);
6359 return AVERROR(ENOMEM);
6361 if (avio_read(pb, info->system_id, 16) != 16) {
6362 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6363 ret = AVERROR_INVALIDDATA;
6368 kid_count = avio_rb32(pb);
6369 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
6370 ret = AVERROR(ENOMEM);
6374 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6375 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6376 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6377 min_kid_count * sizeof(*key_ids));
6379 ret = AVERROR(ENOMEM);
6382 info->key_ids = key_ids;
6384 info->key_ids[i] = av_mallocz(16);
6385 if (!info->key_ids[i]) {
6386 ret = AVERROR(ENOMEM);
6389 info->num_key_ids = i + 1;
6391 if (avio_read(pb, info->key_ids[i], 16) != 16) {
6392 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6393 ret = AVERROR_INVALIDDATA;
6398 if (pb->eof_reached) {
6399 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6400 ret = AVERROR_INVALIDDATA;
6405 extra_data_size = avio_rb32(pb);
6406 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6410 av_freep(&info->data); // malloc(0) may still allocate something.
6411 info->data = extra_data;
6412 info->data_size = extra_data_size;
6414 // If there is existing initialization data, append to the list.
6415 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6416 if (old_side_data) {
6417 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6418 if (old_init_info) {
6419 // Append to the end of the list.
6420 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6426 info = old_init_info;
6428 // Assume existing side-data will be valid, so the only error we could get is OOM.
6429 ret = AVERROR(ENOMEM);
6434 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6436 ret = AVERROR(ENOMEM);
6439 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6440 side_data, side_data_size);
6445 av_encryption_init_info_free(info);
6449 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6452 MOVStreamContext *sc;
6454 if (c->fc->nb_streams < 1)
6456 st = c->fc->streams[c->fc->nb_streams-1];
6459 if (sc->pseudo_stream_id != 0) {
6460 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6461 return AVERROR_PATCHWELCOME;
6465 return AVERROR_INVALIDDATA;
6467 avio_rb32(pb); /* version and flags */
6469 if (!sc->cenc.default_encrypted_sample) {
6470 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6471 if (!sc->cenc.default_encrypted_sample) {
6472 return AVERROR(ENOMEM);
6476 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6480 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6483 MOVStreamContext *sc;
6484 unsigned int version, pattern, is_protected, iv_size;
6486 if (c->fc->nb_streams < 1)
6488 st = c->fc->streams[c->fc->nb_streams-1];
6491 if (sc->pseudo_stream_id != 0) {
6492 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6493 return AVERROR_PATCHWELCOME;
6496 if (!sc->cenc.default_encrypted_sample) {
6497 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6498 if (!sc->cenc.default_encrypted_sample) {
6499 return AVERROR(ENOMEM);
6504 return AVERROR_INVALIDDATA;
6506 version = avio_r8(pb); /* version */
6507 avio_rb24(pb); /* flags */
6509 avio_r8(pb); /* reserved */
6510 pattern = avio_r8(pb);
6513 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6514 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6517 is_protected = avio_r8(pb);
6518 if (is_protected && !sc->cenc.encryption_index) {
6519 // The whole stream should be by-default encrypted.
6520 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6521 if (!sc->cenc.encryption_index)
6522 return AVERROR(ENOMEM);
6524 sc->cenc.per_sample_iv_size = avio_r8(pb);
6525 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6526 sc->cenc.per_sample_iv_size != 16) {
6527 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6528 return AVERROR_INVALIDDATA;
6530 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6531 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6532 return AVERROR_INVALIDDATA;
6535 if (is_protected && !sc->cenc.per_sample_iv_size) {
6536 iv_size = avio_r8(pb);
6537 if (iv_size != 8 && iv_size != 16) {
6538 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6539 return AVERROR_INVALIDDATA;
6542 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6543 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6544 return AVERROR_INVALIDDATA;
6551 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6554 int last, type, size, ret;
6557 if (c->fc->nb_streams < 1)
6559 st = c->fc->streams[c->fc->nb_streams-1];
6561 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6562 return AVERROR_INVALIDDATA;
6564 /* Check FlacSpecificBox version. */
6565 if (avio_r8(pb) != 0)
6566 return AVERROR_INVALIDDATA;
6568 avio_rb24(pb); /* Flags */
6570 avio_read(pb, buf, sizeof(buf));
6571 flac_parse_block_header(buf, &last, &type, &size);
6573 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6574 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6575 return AVERROR_INVALIDDATA;
6578 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6583 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6588 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6592 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6593 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6594 return AVERROR_PATCHWELCOME;
6597 if (!sc->cenc.aes_ctr) {
6598 /* initialize the cipher */
6599 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6600 if (!sc->cenc.aes_ctr) {
6601 return AVERROR(ENOMEM);
6604 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6610 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6612 if (!sample->subsample_count)
6614 /* decrypt the whole packet */
6615 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6619 for (i = 0; i < sample->subsample_count; i++)
6621 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6622 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6623 return AVERROR_INVALIDDATA;
6626 /* skip the clear bytes */
6627 input += sample->subsamples[i].bytes_of_clear_data;
6628 size -= sample->subsamples[i].bytes_of_clear_data;
6630 /* decrypt the encrypted bytes */
6631 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6632 input += sample->subsamples[i].bytes_of_protected_data;
6633 size -= sample->subsamples[i].bytes_of_protected_data;
6637 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6638 return AVERROR_INVALIDDATA;
6644 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6646 MOVFragmentStreamInfo *frag_stream_info;
6647 MOVEncryptionIndex *encryption_index;
6648 AVEncryptionInfo *encrypted_sample;
6649 int encrypted_index, ret;
6651 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6652 encrypted_index = current_index;
6653 encryption_index = NULL;
6654 if (frag_stream_info) {
6655 // Note this only supports encryption info in the first sample descriptor.
6656 if (mov->fragment.stsd_id == 1) {
6657 if (frag_stream_info->encryption_index) {
6658 encrypted_index = current_index - frag_stream_info->index_entry;
6659 encryption_index = frag_stream_info->encryption_index;
6661 encryption_index = sc->cenc.encryption_index;
6665 encryption_index = sc->cenc.encryption_index;
6668 if (encryption_index) {
6669 if (encryption_index->auxiliary_info_sample_count &&
6670 !encryption_index->nb_encrypted_samples) {
6671 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6672 return AVERROR_INVALIDDATA;
6674 if (encryption_index->auxiliary_offsets_count &&
6675 !encryption_index->nb_encrypted_samples) {
6676 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6677 return AVERROR_INVALIDDATA;
6680 if (!encryption_index->nb_encrypted_samples) {
6681 // Full-sample encryption with default settings.
6682 encrypted_sample = sc->cenc.default_encrypted_sample;
6683 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6684 // Per-sample setting override.
6685 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6687 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6688 return AVERROR_INVALIDDATA;
6691 if (mov->decryption_key) {
6692 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6695 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6697 return AVERROR(ENOMEM);
6698 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6708 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6710 const int OPUS_SEEK_PREROLL_MS = 80;
6716 if (c->fc->nb_streams < 1)
6718 st = c->fc->streams[c->fc->nb_streams-1];
6720 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6721 return AVERROR_INVALIDDATA;
6723 /* Check OpusSpecificBox version. */
6724 if (avio_r8(pb) != 0) {
6725 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6726 return AVERROR_INVALIDDATA;
6729 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6730 size = atom.size + 8;
6732 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
6735 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6736 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6737 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6738 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6740 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6741 little-endian; aside from the preceeding magic and version they're
6742 otherwise currently identical. Data after output gain at offset 16
6743 doesn't need to be bytewapped. */
6744 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6745 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6746 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6747 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6749 st->codecpar->initial_padding = pre_skip;
6750 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6751 (AVRational){1, 1000},
6752 (AVRational){1, 48000});
6757 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6760 unsigned format_info;
6761 int channel_assignment, channel_assignment1, channel_assignment2;
6764 if (c->fc->nb_streams < 1)
6766 st = c->fc->streams[c->fc->nb_streams-1];
6769 return AVERROR_INVALIDDATA;
6771 format_info = avio_rb32(pb);
6773 ratebits = (format_info >> 28) & 0xF;
6774 channel_assignment1 = (format_info >> 15) & 0x1F;
6775 channel_assignment2 = format_info & 0x1FFF;
6776 if (channel_assignment2)
6777 channel_assignment = channel_assignment2;
6779 channel_assignment = channel_assignment1;
6781 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6782 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6783 st->codecpar->channels = truehd_channels(channel_assignment);
6784 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6789 static const MOVParseTableEntry mov_default_parse_table[] = {
6790 { MKTAG('A','C','L','R'), mov_read_aclr },
6791 { MKTAG('A','P','R','G'), mov_read_avid },
6792 { MKTAG('A','A','L','P'), mov_read_avid },
6793 { MKTAG('A','R','E','S'), mov_read_ares },
6794 { MKTAG('a','v','s','s'), mov_read_avss },
6795 { MKTAG('a','v','1','C'), mov_read_av1c },
6796 { MKTAG('c','h','p','l'), mov_read_chpl },
6797 { MKTAG('c','o','6','4'), mov_read_stco },
6798 { MKTAG('c','o','l','r'), mov_read_colr },
6799 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6800 { MKTAG('d','i','n','f'), mov_read_default },
6801 { MKTAG('D','p','x','E'), mov_read_dpxe },
6802 { MKTAG('d','r','e','f'), mov_read_dref },
6803 { MKTAG('e','d','t','s'), mov_read_default },
6804 { MKTAG('e','l','s','t'), mov_read_elst },
6805 { MKTAG('e','n','d','a'), mov_read_enda },
6806 { MKTAG('f','i','e','l'), mov_read_fiel },
6807 { MKTAG('a','d','r','m'), mov_read_adrm },
6808 { MKTAG('f','t','y','p'), mov_read_ftyp },
6809 { MKTAG('g','l','b','l'), mov_read_glbl },
6810 { MKTAG('h','d','l','r'), mov_read_hdlr },
6811 { MKTAG('i','l','s','t'), mov_read_ilst },
6812 { MKTAG('j','p','2','h'), mov_read_jp2h },
6813 { MKTAG('m','d','a','t'), mov_read_mdat },
6814 { MKTAG('m','d','h','d'), mov_read_mdhd },
6815 { MKTAG('m','d','i','a'), mov_read_default },
6816 { MKTAG('m','e','t','a'), mov_read_meta },
6817 { MKTAG('m','i','n','f'), mov_read_default },
6818 { MKTAG('m','o','o','f'), mov_read_moof },
6819 { MKTAG('m','o','o','v'), mov_read_moov },
6820 { MKTAG('m','v','e','x'), mov_read_default },
6821 { MKTAG('m','v','h','d'), mov_read_mvhd },
6822 { MKTAG('S','M','I',' '), mov_read_svq3 },
6823 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6824 { MKTAG('a','v','c','C'), mov_read_glbl },
6825 { MKTAG('p','a','s','p'), mov_read_pasp },
6826 { MKTAG('s','i','d','x'), mov_read_sidx },
6827 { MKTAG('s','t','b','l'), mov_read_default },
6828 { MKTAG('s','t','c','o'), mov_read_stco },
6829 { MKTAG('s','t','p','s'), mov_read_stps },
6830 { MKTAG('s','t','r','f'), mov_read_strf },
6831 { MKTAG('s','t','s','c'), mov_read_stsc },
6832 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6833 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6834 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6835 { MKTAG('s','t','t','s'), mov_read_stts },
6836 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6837 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
6838 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6839 { MKTAG('t','f','d','t'), mov_read_tfdt },
6840 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6841 { MKTAG('t','r','a','k'), mov_read_trak },
6842 { MKTAG('t','r','a','f'), mov_read_default },
6843 { MKTAG('t','r','e','f'), mov_read_default },
6844 { MKTAG('t','m','c','d'), mov_read_tmcd },
6845 { MKTAG('c','h','a','p'), mov_read_chap },
6846 { MKTAG('t','r','e','x'), mov_read_trex },
6847 { MKTAG('t','r','u','n'), mov_read_trun },
6848 { MKTAG('u','d','t','a'), mov_read_default },
6849 { MKTAG('w','a','v','e'), mov_read_wave },
6850 { MKTAG('e','s','d','s'), mov_read_esds },
6851 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6852 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6853 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6854 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6855 { MKTAG('w','f','e','x'), mov_read_wfex },
6856 { MKTAG('c','m','o','v'), mov_read_cmov },
6857 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6858 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6859 { MKTAG('s','b','g','p'), mov_read_sbgp },
6860 { MKTAG('h','v','c','C'), mov_read_glbl },
6861 { MKTAG('u','u','i','d'), mov_read_uuid },
6862 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6863 { MKTAG('f','r','e','e'), mov_read_free },
6864 { MKTAG('-','-','-','-'), mov_read_custom },
6865 { MKTAG('s','i','n','f'), mov_read_default },
6866 { MKTAG('f','r','m','a'), mov_read_frma },
6867 { MKTAG('s','e','n','c'), mov_read_senc },
6868 { MKTAG('s','a','i','z'), mov_read_saiz },
6869 { MKTAG('s','a','i','o'), mov_read_saio },
6870 { MKTAG('p','s','s','h'), mov_read_pssh },
6871 { MKTAG('s','c','h','m'), mov_read_schm },
6872 { MKTAG('s','c','h','i'), mov_read_default },
6873 { MKTAG('t','e','n','c'), mov_read_tenc },
6874 { MKTAG('d','f','L','a'), mov_read_dfla },
6875 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6876 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6877 { MKTAG('d','O','p','s'), mov_read_dops },
6878 { MKTAG('d','m','l','p'), mov_read_dmlp },
6879 { MKTAG('S','m','D','m'), mov_read_smdm },
6880 { MKTAG('C','o','L','L'), mov_read_coll },
6881 { MKTAG('v','p','c','C'), mov_read_vpcc },
6882 { MKTAG('m','d','c','v'), mov_read_mdcv },
6883 { MKTAG('c','l','l','i'), mov_read_clli },
6887 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6889 int64_t total_size = 0;
6893 if (c->atom_depth > 10) {
6894 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6895 return AVERROR_INVALIDDATA;
6900 atom.size = INT64_MAX;
6901 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6902 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
6905 if (atom.size >= 8) {
6906 a.size = avio_rb32(pb);
6907 a.type = avio_rl32(pb);
6908 if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
6909 a.type == MKTAG('h','o','o','v')) &&
6911 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
6913 uint32_t *type = (uint32_t *)buf + 1;
6914 if (avio_read(pb, buf, 8) != 8)
6915 return AVERROR_INVALIDDATA;
6916 avio_seek(pb, -8, SEEK_CUR);
6917 if (*type == MKTAG('m','v','h','d') ||
6918 *type == MKTAG('c','m','o','v')) {
6919 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
6920 a.type = MKTAG('m','o','o','v');
6923 if (atom.type != MKTAG('r','o','o','t') &&
6924 atom.type != MKTAG('m','o','o','v'))
6926 if (a.type == MKTAG('t','r','a','k') || a.type == MKTAG('m','d','a','t'))
6928 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
6935 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
6936 a.size = avio_rb64(pb) - 8;
6940 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
6941 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
6943 a.size = atom.size - total_size + 8;
6948 a.size = FFMIN(a.size, atom.size - total_size);
6950 for (i = 0; mov_default_parse_table[i].type; i++)
6951 if (mov_default_parse_table[i].type == a.type) {
6952 parse = mov_default_parse_table[i].parse;
6956 // container is user data
6957 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
6958 atom.type == MKTAG('i','l','s','t')))
6959 parse = mov_read_udta_string;
6961 // Supports parsing the QuickTime Metadata Keys.
6962 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
6963 if (!parse && c->found_hdlr_mdta &&
6964 atom.type == MKTAG('m','e','t','a') &&
6965 a.type == MKTAG('k','e','y','s')) {
6966 parse = mov_read_keys;
6969 if (!parse) { /* skip leaf atoms data */
6970 avio_skip(pb, a.size);
6972 int64_t start_pos = avio_tell(pb);
6974 int err = parse(c, pb, a);
6979 if (c->found_moov && c->found_mdat &&
6980 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
6981 start_pos + a.size == avio_size(pb))) {
6982 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
6983 c->next_root_atom = start_pos + a.size;
6987 left = a.size - avio_tell(pb) + start_pos;
6988 if (left > 0) /* skip garbage at atom end */
6989 avio_skip(pb, left);
6990 else if (left < 0) {
6991 av_log(c->fc, AV_LOG_WARNING,
6992 "overread end of atom '%.4s' by %"PRId64" bytes\n",
6993 (char*)&a.type, -left);
6994 avio_seek(pb, left, SEEK_CUR);
6998 total_size += a.size;
7001 if (total_size < atom.size && atom.size < 0x7ffff)
7002 avio_skip(pb, atom.size - total_size);
7008 static int mov_probe(const AVProbeData *p)
7013 int moov_offset = -1;
7015 /* check file header */
7018 /* ignore invalid offset */
7019 if ((offset + 8) > (unsigned int)p->buf_size)
7021 tag = AV_RL32(p->buf + offset + 4);
7023 /* check for obvious tags */
7024 case MKTAG('m','o','o','v'):
7025 moov_offset = offset + 4;
7026 case MKTAG('m','d','a','t'):
7027 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
7028 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
7029 case MKTAG('f','t','y','p'):
7030 if (AV_RB32(p->buf+offset) < 8 &&
7031 (AV_RB32(p->buf+offset) != 1 ||
7032 offset + 12 > (unsigned int)p->buf_size ||
7033 AV_RB64(p->buf+offset + 8) == 0)) {
7034 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7035 } else if (tag == MKTAG('f','t','y','p') &&
7036 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
7037 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
7039 score = FFMAX(score, 5);
7041 score = AVPROBE_SCORE_MAX;
7043 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7045 /* those are more common words, so rate then a bit less */
7046 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
7047 case MKTAG('w','i','d','e'):
7048 case MKTAG('f','r','e','e'):
7049 case MKTAG('j','u','n','k'):
7050 case MKTAG('p','i','c','t'):
7051 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
7052 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7054 case MKTAG(0x82,0x82,0x7f,0x7d):
7055 case MKTAG('s','k','i','p'):
7056 case MKTAG('u','u','i','d'):
7057 case MKTAG('p','r','f','l'):
7058 /* if we only find those cause probedata is too small at least rate them */
7059 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7060 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7063 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7066 if(score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
7067 /* moov atom in the header - we should make sure that this is not a
7068 * MOV-packed MPEG-PS */
7069 offset = moov_offset;
7071 while(offset < (p->buf_size - 16)){ /* Sufficient space */
7072 /* We found an actual hdlr atom */
7073 if(AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7074 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7075 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')){
7076 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7077 /* We found a media handler reference atom describing an
7078 * MPEG-PS-in-MOV, return a
7079 * low score to force expanding the probe window until
7080 * mpegps_probe finds what it needs */
7091 // must be done after parsing all trak because there's no order requirement
7092 static void mov_read_chapters(AVFormatContext *s)
7094 MOVContext *mov = s->priv_data;
7096 MOVStreamContext *sc;
7101 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7102 chapter_track = mov->chapter_tracks[j];
7104 for (i = 0; i < s->nb_streams; i++)
7105 if (s->streams[i]->id == chapter_track) {
7110 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7115 cur_pos = avio_tell(sc->pb);
7117 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7118 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7119 if (st->nb_index_entries) {
7120 // Retrieve the first frame, if possible
7122 AVIndexEntry *sample = &st->index_entries[0];
7123 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7124 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7128 if (av_get_packet(sc->pb, &pkt, sample->size) < 0)
7131 st->attached_pic = pkt;
7132 st->attached_pic.stream_index = st->index;
7133 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
7136 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7137 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7138 st->discard = AVDISCARD_ALL;
7139 for (i = 0; i < st->nb_index_entries; i++) {
7140 AVIndexEntry *sample = &st->index_entries[i];
7141 int64_t end = i+1 < st->nb_index_entries ? st->index_entries[i+1].timestamp : st->duration;
7146 if (end < sample->timestamp) {
7147 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7148 end = AV_NOPTS_VALUE;
7151 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7152 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7156 // the first two bytes are the length of the title
7157 len = avio_rb16(sc->pb);
7158 if (len > sample->size-2)
7160 title_len = 2*len + 1;
7161 if (!(title = av_mallocz(title_len)))
7164 // The samples could theoretically be in any encoding if there's an encd
7165 // atom following, but in practice are only utf-8 or utf-16, distinguished
7166 // instead by the presence of a BOM
7170 ch = avio_rb16(sc->pb);
7172 avio_get_str16be(sc->pb, len, title, title_len);
7173 else if (ch == 0xfffe)
7174 avio_get_str16le(sc->pb, len, title, title_len);
7177 if (len == 1 || len == 2)
7180 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7184 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7189 avio_seek(sc->pb, cur_pos, SEEK_SET);
7193 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7194 uint32_t value, int flags)
7197 char buf[AV_TIMECODE_STR_SIZE];
7198 AVRational rate = st->avg_frame_rate;
7199 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7202 av_dict_set(&st->metadata, "timecode",
7203 av_timecode_make_string(&tc, buf, value), 0);
7207 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7209 MOVStreamContext *sc = st->priv_data;
7210 char buf[AV_TIMECODE_STR_SIZE];
7211 int64_t cur_pos = avio_tell(sc->pb);
7212 int hh, mm, ss, ff, drop;
7214 if (!st->nb_index_entries)
7217 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7218 avio_skip(s->pb, 13);
7219 hh = avio_r8(s->pb);
7220 mm = avio_r8(s->pb);
7221 ss = avio_r8(s->pb);
7222 drop = avio_r8(s->pb);
7223 ff = avio_r8(s->pb);
7224 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7225 hh, mm, ss, drop ? ';' : ':', ff);
7226 av_dict_set(&st->metadata, "timecode", buf, 0);
7228 avio_seek(sc->pb, cur_pos, SEEK_SET);
7232 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7234 MOVStreamContext *sc = st->priv_data;
7236 int64_t cur_pos = avio_tell(sc->pb);
7239 if (!st->nb_index_entries)
7242 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7243 value = avio_rb32(s->pb);
7245 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7246 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7247 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7249 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7250 * not the case) and thus assume "frame number format" instead of QT one.
7251 * No sample with tmcd track can be found with a QT timecode at the moment,
7252 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7254 parse_timecode_in_framenum_format(s, st, value, flags);
7256 avio_seek(sc->pb, cur_pos, SEEK_SET);
7260 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7262 if (!index || !*index) return;
7263 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7264 av_encryption_info_free((*index)->encrypted_samples[i]);
7266 av_freep(&(*index)->encrypted_samples);
7267 av_freep(&(*index)->auxiliary_info_sizes);
7268 av_freep(&(*index)->auxiliary_offsets);
7272 static int mov_read_close(AVFormatContext *s)
7274 MOVContext *mov = s->priv_data;
7277 for (i = 0; i < s->nb_streams; i++) {
7278 AVStream *st = s->streams[i];
7279 MOVStreamContext *sc = st->priv_data;
7284 av_freep(&sc->ctts_data);
7285 for (j = 0; j < sc->drefs_count; j++) {
7286 av_freep(&sc->drefs[j].path);
7287 av_freep(&sc->drefs[j].dir);
7289 av_freep(&sc->drefs);
7291 sc->drefs_count = 0;
7293 if (!sc->pb_is_copied)
7294 ff_format_io_close(s, &sc->pb);
7297 av_freep(&sc->chunk_offsets);
7298 av_freep(&sc->stsc_data);
7299 av_freep(&sc->sample_sizes);
7300 av_freep(&sc->keyframes);
7301 av_freep(&sc->stts_data);
7302 av_freep(&sc->sdtp_data);
7303 av_freep(&sc->stps_data);
7304 av_freep(&sc->elst_data);
7305 av_freep(&sc->rap_group);
7306 av_freep(&sc->display_matrix);
7307 av_freep(&sc->index_ranges);
7310 for (j = 0; j < sc->stsd_count; j++)
7311 av_free(sc->extradata[j]);
7312 av_freep(&sc->extradata);
7313 av_freep(&sc->extradata_size);
7315 mov_free_encryption_index(&sc->cenc.encryption_index);
7316 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7317 av_aes_ctr_free(sc->cenc.aes_ctr);
7319 av_freep(&sc->stereo3d);
7320 av_freep(&sc->spherical);
7321 av_freep(&sc->mastering);
7322 av_freep(&sc->coll);
7325 if (mov->dv_demux) {
7326 avformat_free_context(mov->dv_fctx);
7327 mov->dv_fctx = NULL;
7330 if (mov->meta_keys) {
7331 for (i = 1; i < mov->meta_keys_count; i++) {
7332 av_freep(&mov->meta_keys[i]);
7334 av_freep(&mov->meta_keys);
7337 av_freep(&mov->trex_data);
7338 av_freep(&mov->bitrates);
7340 for (i = 0; i < mov->frag_index.nb_items; i++) {
7341 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7342 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7343 mov_free_encryption_index(&frag[j].encryption_index);
7345 av_freep(&mov->frag_index.item[i].stream_info);
7347 av_freep(&mov->frag_index.item);
7349 av_freep(&mov->aes_decrypt);
7350 av_freep(&mov->chapter_tracks);
7355 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7359 for (i = 0; i < s->nb_streams; i++) {
7360 AVStream *st = s->streams[i];
7361 MOVStreamContext *sc = st->priv_data;
7363 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7364 sc->timecode_track == tmcd_id)
7370 /* look for a tmcd track not referenced by any video track, and export it globally */
7371 static void export_orphan_timecode(AVFormatContext *s)
7375 for (i = 0; i < s->nb_streams; i++) {
7376 AVStream *st = s->streams[i];
7378 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7379 !tmcd_is_referenced(s, i + 1)) {
7380 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7382 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7389 static int read_tfra(MOVContext *mov, AVIOContext *f)
7391 int version, fieldlength, i, j;
7392 int64_t pos = avio_tell(f);
7393 uint32_t size = avio_rb32(f);
7394 unsigned track_id, item_count;
7396 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7399 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7401 version = avio_r8(f);
7403 track_id = avio_rb32(f);
7404 fieldlength = avio_rb32(f);
7405 item_count = avio_rb32(f);
7406 for (i = 0; i < item_count; i++) {
7407 int64_t time, offset;
7409 MOVFragmentStreamInfo * frag_stream_info;
7412 return AVERROR_INVALIDDATA;
7416 time = avio_rb64(f);
7417 offset = avio_rb64(f);
7419 time = avio_rb32(f);
7420 offset = avio_rb32(f);
7423 // The first sample of each stream in a fragment is always a random
7424 // access sample. So it's entry in the tfra can be used as the
7425 // initial PTS of the fragment.
7426 index = update_frag_index(mov, offset);
7427 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7428 if (frag_stream_info &&
7429 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7430 frag_stream_info->first_tfra_pts = time;
7432 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7434 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7436 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7440 avio_seek(f, pos + size, SEEK_SET);
7444 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7446 int64_t stream_size = avio_size(f);
7447 int64_t original_pos = avio_tell(f);
7451 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7455 mfra_size = avio_rb32(f);
7456 if (mfra_size < 0 || mfra_size > stream_size) {
7457 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7460 if ((seek_ret = avio_seek(f, -mfra_size, SEEK_CUR)) < 0) {
7464 if (avio_rb32(f) != mfra_size) {
7465 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7468 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7469 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7472 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7474 ret = read_tfra(c, f);
7480 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7482 av_log(c->fc, AV_LOG_ERROR,
7483 "failed to seek back after looking for mfra\n");
7489 static int mov_read_header(AVFormatContext *s)
7491 MOVContext *mov = s->priv_data;
7492 AVIOContext *pb = s->pb;
7494 MOVAtom atom = { AV_RL32("root") };
7497 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7498 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7499 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7500 return AVERROR(EINVAL);
7504 mov->trak_index = -1;
7505 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7506 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7507 atom.size = avio_size(pb);
7509 atom.size = INT64_MAX;
7511 /* check MOV header */
7513 if (mov->moov_retry)
7514 avio_seek(pb, 0, SEEK_SET);
7515 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7516 av_log(s, AV_LOG_ERROR, "error reading header\n");
7520 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7521 if (!mov->found_moov) {
7522 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7524 return AVERROR_INVALIDDATA;
7526 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7528 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7529 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7530 mov_read_chapters(s);
7531 for (i = 0; i < s->nb_streams; i++)
7532 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7533 mov_read_timecode_track(s, s->streams[i]);
7534 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7535 mov_read_rtmd_track(s, s->streams[i]);
7539 /* copy timecode metadata from tmcd tracks to the related video streams */
7540 for (i = 0; i < s->nb_streams; i++) {
7541 AVStream *st = s->streams[i];
7542 MOVStreamContext *sc = st->priv_data;
7543 if (sc->timecode_track > 0) {
7544 AVDictionaryEntry *tcr;
7545 int tmcd_st_id = -1;
7547 for (j = 0; j < s->nb_streams; j++)
7548 if (s->streams[j]->id == sc->timecode_track)
7551 if (tmcd_st_id < 0 || tmcd_st_id == i)
7553 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7555 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7558 export_orphan_timecode(s);
7560 for (i = 0; i < s->nb_streams; i++) {
7561 AVStream *st = s->streams[i];
7562 MOVStreamContext *sc = st->priv_data;
7563 fix_timescale(mov, sc);
7564 if(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7565 st->skip_samples = sc->start_pad;
7567 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7568 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7569 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7570 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7571 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7572 st->codecpar->width = sc->width;
7573 st->codecpar->height = sc->height;
7575 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7576 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7580 if (mov->handbrake_version &&
7581 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7582 st->codecpar->codec_id == AV_CODEC_ID_MP3
7584 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7585 st->need_parsing = AVSTREAM_PARSE_FULL;
7589 if (mov->trex_data) {
7590 for (i = 0; i < s->nb_streams; i++) {
7591 AVStream *st = s->streams[i];
7592 MOVStreamContext *sc = st->priv_data;
7593 if (st->duration > 0) {
7594 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7595 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7596 sc->data_size, sc->time_scale);
7598 return AVERROR_INVALIDDATA;
7600 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7605 if (mov->use_mfra_for > 0) {
7606 for (i = 0; i < s->nb_streams; i++) {
7607 AVStream *st = s->streams[i];
7608 MOVStreamContext *sc = st->priv_data;
7609 if (sc->duration_for_fps > 0) {
7610 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7611 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7612 sc->data_size, sc->time_scale);
7614 return AVERROR_INVALIDDATA;
7616 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7617 sc->duration_for_fps;
7622 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7623 if (mov->bitrates[i]) {
7624 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7628 ff_rfps_calculate(s);
7630 for (i = 0; i < s->nb_streams; i++) {
7631 AVStream *st = s->streams[i];
7632 MOVStreamContext *sc = st->priv_data;
7634 switch (st->codecpar->codec_type) {
7635 case AVMEDIA_TYPE_AUDIO:
7636 err = ff_replaygain_export(st, s->metadata);
7642 case AVMEDIA_TYPE_VIDEO:
7643 if (sc->display_matrix) {
7644 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7645 sizeof(int32_t) * 9);
7649 sc->display_matrix = NULL;
7652 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7653 (uint8_t *)sc->stereo3d,
7654 sizeof(*sc->stereo3d));
7658 sc->stereo3d = NULL;
7660 if (sc->spherical) {
7661 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7662 (uint8_t *)sc->spherical,
7663 sc->spherical_size);
7667 sc->spherical = NULL;
7669 if (sc->mastering) {
7670 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7671 (uint8_t *)sc->mastering,
7672 sizeof(*sc->mastering));
7676 sc->mastering = NULL;
7679 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7680 (uint8_t *)sc->coll,
7690 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7692 for (i = 0; i < mov->frag_index.nb_items; i++)
7693 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7694 mov->frag_index.item[i].headers_read = 1;
7699 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7701 AVIndexEntry *sample = NULL;
7702 int64_t best_dts = INT64_MAX;
7704 for (i = 0; i < s->nb_streams; i++) {
7705 AVStream *avst = s->streams[i];
7706 MOVStreamContext *msc = avst->priv_data;
7707 if (msc->pb && msc->current_sample < avst->nb_index_entries) {
7708 AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample];
7709 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7710 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7711 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7712 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7713 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb &&
7714 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7715 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7716 sample = current_sample;
7725 static int should_retry(AVIOContext *pb, int error_code) {
7726 if (error_code == AVERROR_EOF || avio_feof(pb))
7732 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7735 MOVContext *mov = s->priv_data;
7737 if (index >= 0 && index < mov->frag_index.nb_items)
7738 target = mov->frag_index.item[index].moof_offset;
7739 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7740 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7741 return AVERROR_INVALIDDATA;
7744 mov->next_root_atom = 0;
7745 if (index < 0 || index >= mov->frag_index.nb_items)
7746 index = search_frag_moof_offset(&mov->frag_index, target);
7747 if (index < mov->frag_index.nb_items &&
7748 mov->frag_index.item[index].moof_offset == target) {
7749 if (index + 1 < mov->frag_index.nb_items)
7750 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7751 if (mov->frag_index.item[index].headers_read)
7753 mov->frag_index.item[index].headers_read = 1;
7756 mov->found_mdat = 0;
7758 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7761 if (avio_feof(s->pb))
7763 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7768 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7770 uint8_t *side, *extradata;
7773 /* Save the current index. */
7774 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7776 /* Notify the decoder that extradata changed. */
7777 extradata_size = sc->extradata_size[sc->last_stsd_index];
7778 extradata = sc->extradata[sc->last_stsd_index];
7779 if (extradata_size > 0 && extradata) {
7780 side = av_packet_new_side_data(pkt,
7781 AV_PKT_DATA_NEW_EXTRADATA,
7784 return AVERROR(ENOMEM);
7785 memcpy(side, extradata, extradata_size);
7791 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7793 MOVContext *mov = s->priv_data;
7794 MOVStreamContext *sc;
7795 AVIndexEntry *sample;
7796 AVStream *st = NULL;
7797 int64_t current_index;
7801 sample = mov_find_next_sample(s, &st);
7802 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7803 if (!mov->next_root_atom)
7805 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7810 /* must be done just before reading, to avoid infinite loop on sample */
7811 current_index = sc->current_index;
7812 mov_current_sample_inc(sc);
7814 if (mov->next_root_atom) {
7815 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7816 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7819 if (st->discard != AVDISCARD_ALL) {
7820 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7821 if (ret64 != sample->pos) {
7822 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7823 sc->ffindex, sample->pos);
7824 if (should_retry(sc->pb, ret64)) {
7825 mov_current_sample_dec(sc);
7827 return AVERROR_INVALIDDATA;
7830 if( st->discard == AVDISCARD_NONKEY && 0==(sample->flags & AVINDEX_KEYFRAME) ) {
7831 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7835 ret = av_get_packet(sc->pb, pkt, sample->size);
7837 if (should_retry(sc->pb, ret)) {
7838 mov_current_sample_dec(sc);
7842 if (sc->has_palette) {
7845 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7847 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7849 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7850 sc->has_palette = 0;
7853 #if CONFIG_DV_DEMUXER
7854 if (mov->dv_demux && sc->dv_audio_container) {
7855 avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7856 av_freep(&pkt->data);
7858 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7863 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7864 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7865 st->need_parsing = AVSTREAM_PARSE_FULL;
7869 pkt->stream_index = sc->ffindex;
7870 pkt->dts = sample->timestamp;
7871 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7872 pkt->flags |= AV_PKT_FLAG_DISCARD;
7874 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7875 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
7876 /* update ctts context */
7878 if (sc->ctts_index < sc->ctts_count &&
7879 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
7881 sc->ctts_sample = 0;
7884 int64_t next_dts = (sc->current_sample < st->nb_index_entries) ?
7885 st->index_entries[sc->current_sample].timestamp : st->duration;
7887 if (next_dts >= pkt->dts)
7888 pkt->duration = next_dts - pkt->dts;
7889 pkt->pts = pkt->dts;
7891 if (st->discard == AVDISCARD_ALL)
7893 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
7894 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
7895 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
7896 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
7898 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
7899 pkt->pos = sample->pos;
7901 /* Multiple stsd handling. */
7902 if (sc->stsc_data) {
7903 /* Keep track of the stsc index for the given sample, then check
7904 * if the stsd index is different from the last used one. */
7906 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
7907 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
7909 sc->stsc_sample = 0;
7910 /* Do not check indexes after a switch. */
7911 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
7912 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
7913 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
7914 ret = mov_change_extradata(sc, pkt);
7921 aax_filter(pkt->data, pkt->size, mov);
7923 ret = cenc_filter(mov, st, sc, pkt, current_index);
7931 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
7933 MOVContext *mov = s->priv_data;
7936 if (!mov->frag_index.complete)
7939 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
7942 if (!mov->frag_index.item[index].headers_read)
7943 return mov_switch_root(s, -1, index);
7944 if (index + 1 < mov->frag_index.nb_items)
7945 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7950 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
7952 MOVStreamContext *sc = st->priv_data;
7953 int sample, time_sample, ret;
7956 // Here we consider timestamp to be PTS, hence try to offset it so that we
7957 // can search over the DTS timeline.
7958 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
7960 ret = mov_seek_fragment(s, st, timestamp);
7964 sample = av_index_search_timestamp(st, timestamp, flags);
7965 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
7966 if (sample < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp)
7968 if (sample < 0) /* not sure what to do */
7969 return AVERROR_INVALIDDATA;
7970 mov_current_sample_set(sc, sample);
7971 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
7972 /* adjust ctts index */
7973 if (sc->ctts_data) {
7975 for (i = 0; i < sc->ctts_count; i++) {
7976 int next = time_sample + sc->ctts_data[i].count;
7977 if (next > sc->current_sample) {
7979 sc->ctts_sample = sc->current_sample - time_sample;
7986 /* adjust stsd index */
7987 if (sc->chunk_count) {
7989 for (i = 0; i < sc->stsc_count; i++) {
7990 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
7991 if (next > sc->current_sample) {
7993 sc->stsc_sample = sc->current_sample - time_sample;
7996 av_assert0(next == (int)next);
8004 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
8006 MOVContext *mc = s->priv_data;
8011 if (stream_index >= s->nb_streams)
8012 return AVERROR_INVALIDDATA;
8014 st = s->streams[stream_index];
8015 sample = mov_seek_stream(s, st, sample_time, flags);
8019 if (mc->seek_individually) {
8020 /* adjust seek timestamp to found sample timestamp */
8021 int64_t seek_timestamp = st->index_entries[sample].timestamp;
8023 for (i = 0; i < s->nb_streams; i++) {
8025 MOVStreamContext *sc = s->streams[i]->priv_data;
8027 st->skip_samples = (sample_time <= 0) ? sc->start_pad : 0;
8029 if (stream_index == i)
8032 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
8033 mov_seek_stream(s, st, timestamp, flags);
8036 for (i = 0; i < s->nb_streams; i++) {
8037 MOVStreamContext *sc;
8040 mov_current_sample_set(sc, 0);
8043 MOVStreamContext *sc;
8044 AVIndexEntry *entry = mov_find_next_sample(s, &st);
8046 return AVERROR_INVALIDDATA;
8048 if (sc->ffindex == stream_index && sc->current_sample == sample)
8050 mov_current_sample_inc(sc);
8056 #define OFFSET(x) offsetof(MOVContext, x)
8057 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
8058 static const AVOption mov_options[] = {
8059 {"use_absolute_path",
8060 "allow using absolute path when opening alias, this is a possible security issue",
8061 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
8063 {"seek_streams_individually",
8064 "Seek each stream individually to the closest point",
8065 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
8067 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
8069 {"advanced_editlist",
8070 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
8071 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
8073 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8076 "use mfra for fragment timestamps",
8077 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8078 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8080 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8081 FLAGS, "use_mfra_for" },
8082 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8083 FLAGS, "use_mfra_for" },
8084 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8085 FLAGS, "use_mfra_for" },
8086 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8087 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8088 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8089 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8090 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8091 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8092 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8093 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8094 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8095 .flags = AV_OPT_FLAG_DECODING_PARAM },
8096 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8097 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8098 {.i64 = 0}, 0, 1, FLAGS },
8103 static const AVClass mov_class = {
8104 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8105 .item_name = av_default_item_name,
8106 .option = mov_options,
8107 .version = LIBAVUTIL_VERSION_INT,
8110 AVInputFormat ff_mov_demuxer = {
8111 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8112 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8113 .priv_class = &mov_class,
8114 .priv_data_size = sizeof(MOVContext),
8115 .extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
8116 .read_probe = mov_probe,
8117 .read_header = mov_read_header,
8118 .read_packet = mov_read_packet,
8119 .read_close = mov_read_close,
8120 .read_seek = mov_read_seek,
8121 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,