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 c->aes_decrypt = av_aes_alloc();
1009 if (!c->aes_decrypt) {
1010 ret = AVERROR(ENOMEM);
1014 /* drm blob processing */
1015 avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1016 avio_read(pb, input, DRM_BLOB_SIZE);
1017 avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1018 avio_read(pb, file_checksum, 20);
1020 av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == "); // required by external tools
1021 for (i = 0; i < 20; i++)
1022 av_log(c->fc, AV_LOG_INFO, "%02x", file_checksum[i]);
1023 av_log(c->fc, AV_LOG_INFO, "\n");
1025 /* verify activation data */
1026 if (!activation_bytes) {
1027 av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1028 ret = 0; /* allow ffprobe to continue working on .aax files */
1031 if (c->activation_bytes_size != 4) {
1032 av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1033 ret = AVERROR(EINVAL);
1037 /* verify fixed key */
1038 if (c->audible_fixed_key_size != 16) {
1039 av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1040 ret = AVERROR(EINVAL);
1044 /* AAX (and AAX+) key derivation */
1045 av_sha_init(sha, 160);
1046 av_sha_update(sha, fixed_key, 16);
1047 av_sha_update(sha, activation_bytes, 4);
1048 av_sha_final(sha, intermediate_key);
1049 av_sha_init(sha, 160);
1050 av_sha_update(sha, fixed_key, 16);
1051 av_sha_update(sha, intermediate_key, 20);
1052 av_sha_update(sha, activation_bytes, 4);
1053 av_sha_final(sha, intermediate_iv);
1054 av_sha_init(sha, 160);
1055 av_sha_update(sha, intermediate_key, 16);
1056 av_sha_update(sha, intermediate_iv, 16);
1057 av_sha_final(sha, calculated_checksum);
1058 if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1059 av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1060 ret = AVERROR_INVALIDDATA;
1063 av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1064 av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1065 for (i = 0; i < 4; i++) {
1066 // file data (in output) is stored in big-endian mode
1067 if (activation_bytes[i] != output[3 - i]) { // critical error
1068 av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1069 ret = AVERROR_INVALIDDATA;
1073 memcpy(c->file_key, output + 8, 16);
1074 memcpy(input, output + 26, 16);
1075 av_sha_init(sha, 160);
1076 av_sha_update(sha, input, 16);
1077 av_sha_update(sha, c->file_key, 16);
1078 av_sha_update(sha, fixed_key, 16);
1079 av_sha_final(sha, c->file_iv);
1087 // Audible AAX (and AAX+) bytestream decryption
1088 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1091 unsigned char iv[16];
1093 memcpy(iv, c->file_iv, 16); // iv is overwritten
1094 blocks = size >> 4; // trailing bytes are not encrypted!
1095 av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1096 av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1101 /* read major brand, minor version and compatible brands and store them as metadata */
1102 static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1105 int comp_brand_size;
1106 char* comp_brands_str;
1107 uint8_t type[5] = {0};
1108 int ret = ffio_read_size(pb, type, 4);
1112 if (strcmp(type, "qt "))
1114 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1115 av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1116 minor_ver = avio_rb32(pb); /* minor version */
1117 av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1119 comp_brand_size = atom.size - 8;
1120 if (comp_brand_size < 0)
1121 return AVERROR_INVALIDDATA;
1122 comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1123 if (!comp_brands_str)
1124 return AVERROR(ENOMEM);
1126 ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1128 av_freep(&comp_brands_str);
1131 comp_brands_str[comp_brand_size] = 0;
1132 av_dict_set(&c->fc->metadata, "compatible_brands", comp_brands_str, 0);
1133 av_freep(&comp_brands_str);
1138 /* this atom should contain all header atoms */
1139 static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1143 if (c->found_moov) {
1144 av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1145 avio_skip(pb, atom.size);
1149 if ((ret = mov_read_default(c, pb, atom)) < 0)
1151 /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1152 /* so we don't parse the whole file if over a network */
1154 return 0; /* now go for mdat */
1157 static MOVFragmentStreamInfo * get_frag_stream_info(
1158 MOVFragmentIndex *frag_index,
1163 MOVFragmentIndexItem * item;
1165 if (index < 0 || index >= frag_index->nb_items)
1167 item = &frag_index->item[index];
1168 for (i = 0; i < item->nb_stream_info; i++)
1169 if (item->stream_info[i].id == id)
1170 return &item->stream_info[i];
1172 // This shouldn't happen
1176 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1179 MOVFragmentIndexItem * item;
1181 if (frag_index->current < 0 ||
1182 frag_index->current >= frag_index->nb_items)
1185 item = &frag_index->item[frag_index->current];
1186 for (i = 0; i < item->nb_stream_info; i++)
1187 if (item->stream_info[i].id == id) {
1192 // id not found. This shouldn't happen.
1196 static MOVFragmentStreamInfo * get_current_frag_stream_info(
1197 MOVFragmentIndex *frag_index)
1199 MOVFragmentIndexItem *item;
1200 if (frag_index->current < 0 ||
1201 frag_index->current >= frag_index->nb_items)
1204 item = &frag_index->item[frag_index->current];
1205 if (item->current >= 0 && item->current < item->nb_stream_info)
1206 return &item->stream_info[item->current];
1208 // This shouldn't happen
1212 static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
1215 int64_t moof_offset;
1217 // Optimize for appending new entries
1218 if (!frag_index->nb_items ||
1219 frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1220 return frag_index->nb_items;
1223 b = frag_index->nb_items;
1227 moof_offset = frag_index->item[m].moof_offset;
1228 if (moof_offset >= offset)
1230 if (moof_offset <= offset)
1236 static int64_t get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
1238 av_assert0(frag_stream_info);
1239 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1240 return frag_stream_info->sidx_pts;
1241 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1242 return frag_stream_info->first_tfra_pts;
1243 return frag_stream_info->tfdt_dts;
1246 static int64_t get_frag_time(MOVFragmentIndex *frag_index,
1247 int index, int track_id)
1249 MOVFragmentStreamInfo * frag_stream_info;
1253 if (track_id >= 0) {
1254 frag_stream_info = get_frag_stream_info(frag_index, index, track_id);
1255 return frag_stream_info->sidx_pts;
1258 for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1259 frag_stream_info = &frag_index->item[index].stream_info[i];
1260 timestamp = get_stream_info_time(frag_stream_info);
1261 if (timestamp != AV_NOPTS_VALUE)
1264 return AV_NOPTS_VALUE;
1267 static int search_frag_timestamp(MOVFragmentIndex *frag_index,
1268 AVStream *st, int64_t timestamp)
1275 // If the stream is referenced by any sidx, limit the search
1276 // to fragments that referenced this stream in the sidx
1277 MOVStreamContext *sc = st->priv_data;
1283 b = frag_index->nb_items;
1286 m0 = m = (a + b) >> 1;
1289 (frag_time = get_frag_time(frag_index, m, id)) == AV_NOPTS_VALUE)
1292 if (m < b && frag_time <= timestamp)
1301 static int update_frag_index(MOVContext *c, int64_t offset)
1304 MOVFragmentIndexItem * item;
1305 MOVFragmentStreamInfo * frag_stream_info;
1307 // If moof_offset already exists in frag_index, return index to it
1308 index = search_frag_moof_offset(&c->frag_index, offset);
1309 if (index < c->frag_index.nb_items &&
1310 c->frag_index.item[index].moof_offset == offset)
1313 // offset is not yet in frag index.
1314 // Insert new item at index (sorted by moof offset)
1315 item = av_fast_realloc(c->frag_index.item,
1316 &c->frag_index.allocated_size,
1317 (c->frag_index.nb_items + 1) *
1318 sizeof(*c->frag_index.item));
1321 c->frag_index.item = item;
1323 frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1324 sizeof(*item->stream_info));
1325 if (!frag_stream_info)
1328 for (i = 0; i < c->fc->nb_streams; i++) {
1329 // Avoid building frag index if streams lack track id.
1330 if (c->fc->streams[i]->id < 0)
1331 return AVERROR_INVALIDDATA;
1333 frag_stream_info[i].id = c->fc->streams[i]->id;
1334 frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1335 frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1336 frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1337 frag_stream_info[i].index_entry = -1;
1338 frag_stream_info[i].encryption_index = NULL;
1341 if (index < c->frag_index.nb_items)
1342 memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1343 (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1345 item = &c->frag_index.item[index];
1346 item->headers_read = 0;
1348 item->nb_stream_info = c->fc->nb_streams;
1349 item->moof_offset = offset;
1350 item->stream_info = frag_stream_info;
1351 c->frag_index.nb_items++;
1356 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1357 int id, int entries)
1360 MOVFragmentStreamInfo * frag_stream_info;
1364 for (i = index; i < frag_index->nb_items; i++) {
1365 frag_stream_info = get_frag_stream_info(frag_index, i, id);
1366 if (frag_stream_info && frag_stream_info->index_entry >= 0)
1367 frag_stream_info->index_entry += entries;
1371 static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1373 // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1374 c->fragment.found_tfhd = 0;
1376 if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1377 c->has_looked_for_mfra = 1;
1378 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1380 av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1382 if ((ret = mov_read_mfra(c, pb)) < 0) {
1383 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1384 "read the mfra (may be a live ismv)\n");
1387 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1388 "seekable, can not look for mfra\n");
1391 c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1392 av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1393 c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1394 return mov_read_default(c, pb, atom);
1397 static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time)
1400 if(time >= 2082844800)
1401 time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1403 if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1404 av_log(NULL, AV_LOG_DEBUG, "creation_time is not representable\n");
1408 avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1412 static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1415 MOVStreamContext *sc;
1417 char language[4] = {0};
1419 int64_t creation_time;
1421 if (c->fc->nb_streams < 1)
1423 st = c->fc->streams[c->fc->nb_streams-1];
1426 if (sc->time_scale) {
1427 av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1428 return AVERROR_INVALIDDATA;
1431 version = avio_r8(pb);
1433 avpriv_request_sample(c->fc, "Version %d", version);
1434 return AVERROR_PATCHWELCOME;
1436 avio_rb24(pb); /* flags */
1438 creation_time = avio_rb64(pb);
1441 creation_time = avio_rb32(pb);
1442 avio_rb32(pb); /* modification time */
1444 mov_metadata_creation_time(&st->metadata, creation_time);
1446 sc->time_scale = avio_rb32(pb);
1447 if (sc->time_scale <= 0) {
1448 av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1451 st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1453 lang = avio_rb16(pb); /* language */
1454 if (ff_mov_lang_to_iso639(lang, language))
1455 av_dict_set(&st->metadata, "language", language, 0);
1456 avio_rb16(pb); /* quality */
1461 static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1464 int64_t creation_time;
1465 int version = avio_r8(pb); /* version */
1466 avio_rb24(pb); /* flags */
1469 creation_time = avio_rb64(pb);
1472 creation_time = avio_rb32(pb);
1473 avio_rb32(pb); /* modification time */
1475 mov_metadata_creation_time(&c->fc->metadata, creation_time);
1476 c->time_scale = avio_rb32(pb); /* time scale */
1477 if (c->time_scale <= 0) {
1478 av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1481 av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1483 c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1484 // set the AVCodecContext duration because the duration of individual tracks
1485 // may be inaccurate
1486 if (c->time_scale > 0 && !c->trex_data)
1487 c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale);
1488 avio_rb32(pb); /* preferred scale */
1490 avio_rb16(pb); /* preferred volume */
1492 avio_skip(pb, 10); /* reserved */
1494 /* movie display matrix, store it in main context and use it later on */
1495 for (i = 0; i < 3; i++) {
1496 c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1497 c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1498 c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1501 avio_rb32(pb); /* preview time */
1502 avio_rb32(pb); /* preview duration */
1503 avio_rb32(pb); /* poster time */
1504 avio_rb32(pb); /* selection time */
1505 avio_rb32(pb); /* selection duration */
1506 avio_rb32(pb); /* current time */
1507 avio_rb32(pb); /* next track ID */
1512 static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1517 if (c->fc->nb_streams < 1)
1519 st = c->fc->streams[c->fc->nb_streams-1];
1521 little_endian = avio_rb16(pb) & 0xFF;
1522 av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1523 if (little_endian == 1) {
1524 switch (st->codecpar->codec_id) {
1525 case AV_CODEC_ID_PCM_S24BE:
1526 st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE;
1528 case AV_CODEC_ID_PCM_S32BE:
1529 st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE;
1531 case AV_CODEC_ID_PCM_F32BE:
1532 st->codecpar->codec_id = AV_CODEC_ID_PCM_F32LE;
1534 case AV_CODEC_ID_PCM_F64BE:
1535 st->codecpar->codec_id = AV_CODEC_ID_PCM_F64LE;
1544 static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1547 char color_parameter_type[5] = { 0 };
1548 uint16_t color_primaries, color_trc, color_matrix;
1551 if (c->fc->nb_streams < 1)
1553 st = c->fc->streams[c->fc->nb_streams - 1];
1555 ret = ffio_read_size(pb, color_parameter_type, 4);
1558 if (strncmp(color_parameter_type, "nclx", 4) &&
1559 strncmp(color_parameter_type, "nclc", 4)) {
1560 av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
1561 color_parameter_type);
1565 color_primaries = avio_rb16(pb);
1566 color_trc = avio_rb16(pb);
1567 color_matrix = avio_rb16(pb);
1569 av_log(c->fc, AV_LOG_TRACE,
1570 "%s: pri %d trc %d matrix %d",
1571 color_parameter_type, color_primaries, color_trc, color_matrix);
1573 if (!strncmp(color_parameter_type, "nclx", 4)) {
1574 uint8_t color_range = avio_r8(pb) >> 7;
1575 av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
1577 st->codecpar->color_range = AVCOL_RANGE_JPEG;
1579 st->codecpar->color_range = AVCOL_RANGE_MPEG;
1582 if (!av_color_primaries_name(color_primaries))
1583 color_primaries = AVCOL_PRI_UNSPECIFIED;
1584 if (!av_color_transfer_name(color_trc))
1585 color_trc = AVCOL_TRC_UNSPECIFIED;
1586 if (!av_color_space_name(color_matrix))
1587 color_matrix = AVCOL_SPC_UNSPECIFIED;
1589 st->codecpar->color_primaries = color_primaries;
1590 st->codecpar->color_trc = color_trc;
1591 st->codecpar->color_space = color_matrix;
1592 av_log(c->fc, AV_LOG_TRACE, "\n");
1597 static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1600 unsigned mov_field_order;
1601 enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
1603 if (c->fc->nb_streams < 1) // will happen with jp2 files
1605 st = c->fc->streams[c->fc->nb_streams-1];
1607 return AVERROR_INVALIDDATA;
1608 mov_field_order = avio_rb16(pb);
1609 if ((mov_field_order & 0xFF00) == 0x0100)
1610 decoded_field_order = AV_FIELD_PROGRESSIVE;
1611 else if ((mov_field_order & 0xFF00) == 0x0200) {
1612 switch (mov_field_order & 0xFF) {
1613 case 0x01: decoded_field_order = AV_FIELD_TT;
1615 case 0x06: decoded_field_order = AV_FIELD_BB;
1617 case 0x09: decoded_field_order = AV_FIELD_TB;
1619 case 0x0E: decoded_field_order = AV_FIELD_BT;
1623 if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
1624 av_log(NULL, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
1626 st->codecpar->field_order = decoded_field_order;
1631 static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
1634 uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
1635 if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
1636 return AVERROR_INVALIDDATA;
1637 if ((err = av_reallocp(&par->extradata, size)) < 0) {
1638 par->extradata_size = 0;
1641 par->extradata_size = size - AV_INPUT_BUFFER_PADDING_SIZE;
1645 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
1646 static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1647 AVCodecParameters *par, uint8_t *buf)
1649 int64_t result = atom.size;
1652 AV_WB32(buf , atom.size + 8);
1653 AV_WL32(buf + 4, atom.type);
1654 err = ffio_read_size(pb, buf + 8, atom.size);
1656 par->extradata_size -= atom.size;
1658 } else if (err < atom.size) {
1659 av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
1660 par->extradata_size -= atom.size - err;
1663 memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1667 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
1668 static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1669 enum AVCodecID codec_id)
1672 uint64_t original_size;
1675 if (c->fc->nb_streams < 1) // will happen with jp2 files
1677 st = c->fc->streams[c->fc->nb_streams-1];
1679 if (st->codecpar->codec_id != codec_id)
1680 return 0; /* unexpected codec_id - don't mess with extradata */
1682 original_size = st->codecpar->extradata_size;
1683 err = mov_realloc_extradata(st->codecpar, atom);
1687 err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
1690 return 0; // Note: this is the original behavior to ignore truncation.
1693 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
1694 static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1696 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
1699 static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1701 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS);
1704 static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1706 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
1709 static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1711 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
1714 static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1716 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
1718 ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
1722 static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1724 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
1726 if (!ret && c->fc->nb_streams >= 1) {
1727 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1728 if (par->extradata_size >= 40) {
1729 par->height = AV_RB16(&par->extradata[36]);
1730 par->width = AV_RB16(&par->extradata[38]);
1736 static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1738 if (c->fc->nb_streams >= 1) {
1739 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1740 if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
1741 par->codec_id == AV_CODEC_ID_H264 &&
1745 cid = avio_rb16(pb);
1746 /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
1747 if (cid == 0xd4d || cid == 0xd4e)
1750 } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
1751 par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
1752 par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
1756 num = avio_rb32(pb);
1757 den = avio_rb32(pb);
1758 if (num <= 0 || den <= 0)
1760 switch (avio_rb32(pb)) {
1762 if (den >= INT_MAX / 2)
1766 c->fc->streams[c->fc->nb_streams-1]->display_aspect_ratio.num = num;
1767 c->fc->streams[c->fc->nb_streams-1]->display_aspect_ratio.den = den;
1774 return mov_read_avid(c, pb, atom);
1777 static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1781 uint64_t original_size;
1782 if (c->fc->nb_streams >= 1) {
1783 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1784 if (par->codec_id == AV_CODEC_ID_H264)
1786 if (atom.size == 16) {
1787 original_size = par->extradata_size;
1788 ret = mov_realloc_extradata(par, atom);
1790 length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
1791 if (length == atom.size) {
1792 const uint8_t range_value = par->extradata[original_size + 19];
1793 switch (range_value) {
1795 par->color_range = AVCOL_RANGE_MPEG;
1798 par->color_range = AVCOL_RANGE_JPEG;
1801 av_log(c, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
1804 ff_dlog(c, "color_range: %d\n", par->color_range);
1806 /* For some reason the whole atom was not added to the extradata */
1807 av_log(c, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
1810 av_log(c, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
1813 av_log(c, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
1820 static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1822 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
1825 static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1830 if (c->fc->nb_streams < 1)
1832 st = c->fc->streams[c->fc->nb_streams-1];
1834 if ((uint64_t)atom.size > (1<<30))
1835 return AVERROR_INVALIDDATA;
1837 if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
1838 st->codecpar->codec_id == AV_CODEC_ID_QDMC ||
1839 st->codecpar->codec_id == AV_CODEC_ID_SPEEX) {
1840 // pass all frma atom to codec, needed at least for QDMC and QDM2
1841 av_freep(&st->codecpar->extradata);
1842 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1845 } else if (atom.size > 8) { /* to read frma, esds atoms */
1846 if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
1848 ret = ffio_ensure_seekback(pb, 8);
1851 buffer = avio_rb64(pb);
1853 if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
1854 && buffer >> 32 <= atom.size
1855 && buffer >> 32 >= 8) {
1858 } else if (!st->codecpar->extradata_size) {
1859 #define ALAC_EXTRADATA_SIZE 36
1860 st->codecpar->extradata = av_mallocz(ALAC_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
1861 if (!st->codecpar->extradata)
1862 return AVERROR(ENOMEM);
1863 st->codecpar->extradata_size = ALAC_EXTRADATA_SIZE;
1864 AV_WB32(st->codecpar->extradata , ALAC_EXTRADATA_SIZE);
1865 AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
1866 AV_WB64(st->codecpar->extradata + 12, buffer);
1867 avio_read(pb, st->codecpar->extradata + 20, 16);
1868 avio_skip(pb, atom.size - 24);
1872 if ((ret = mov_read_default(c, pb, atom)) < 0)
1875 avio_skip(pb, atom.size);
1880 * This function reads atom content and puts data in extradata without tag
1881 * nor size unlike mov_read_extradata.
1883 static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1888 if (c->fc->nb_streams < 1)
1890 st = c->fc->streams[c->fc->nb_streams-1];
1892 if ((uint64_t)atom.size > (1<<30))
1893 return AVERROR_INVALIDDATA;
1895 if (atom.size >= 10) {
1896 // Broken files created by legacy versions of libavformat will
1897 // wrap a whole fiel atom inside of a glbl atom.
1898 unsigned size = avio_rb32(pb);
1899 unsigned type = avio_rl32(pb);
1900 avio_seek(pb, -8, SEEK_CUR);
1901 if (type == MKTAG('f','i','e','l') && size == atom.size)
1902 return mov_read_default(c, pb, atom);
1904 if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
1905 av_log(c, AV_LOG_WARNING, "ignoring multiple glbl\n");
1908 av_freep(&st->codecpar->extradata);
1909 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1912 if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
1913 /* HEVC-based Dolby Vision derived from hvc1.
1914 Happens to match with an identifier
1915 previously utilized for DV. Thus, if we have
1916 the hvcC extradata box available as specified,
1917 set codec to HEVC */
1918 st->codecpar->codec_id = AV_CODEC_ID_HEVC;
1923 static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1926 uint8_t profile_level;
1929 if (c->fc->nb_streams < 1)
1931 st = c->fc->streams[c->fc->nb_streams-1];
1933 if (atom.size >= (1<<28) || atom.size < 7)
1934 return AVERROR_INVALIDDATA;
1936 profile_level = avio_r8(pb);
1937 if ((profile_level & 0xf0) != 0xc0)
1940 avio_seek(pb, 6, SEEK_CUR);
1941 av_freep(&st->codecpar->extradata);
1942 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
1950 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
1951 * but can have extradata appended at the end after the 40 bytes belonging
1954 static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1959 if (c->fc->nb_streams < 1)
1961 if (atom.size <= 40)
1963 st = c->fc->streams[c->fc->nb_streams-1];
1965 if ((uint64_t)atom.size > (1<<30))
1966 return AVERROR_INVALIDDATA;
1969 av_freep(&st->codecpar->extradata);
1970 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
1977 static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1980 MOVStreamContext *sc;
1981 unsigned int i, entries;
1983 if (c->fc->nb_streams < 1)
1985 st = c->fc->streams[c->fc->nb_streams-1];
1988 avio_r8(pb); /* version */
1989 avio_rb24(pb); /* flags */
1991 entries = avio_rb32(pb);
1996 if (sc->chunk_offsets)
1997 av_log(c->fc, AV_LOG_WARNING, "Duplicated STCO atom\n");
1998 av_free(sc->chunk_offsets);
1999 sc->chunk_count = 0;
2000 sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2001 if (!sc->chunk_offsets)
2002 return AVERROR(ENOMEM);
2003 sc->chunk_count = entries;
2005 if (atom.type == MKTAG('s','t','c','o'))
2006 for (i = 0; i < entries && !pb->eof_reached; i++)
2007 sc->chunk_offsets[i] = avio_rb32(pb);
2008 else if (atom.type == MKTAG('c','o','6','4'))
2009 for (i = 0; i < entries && !pb->eof_reached; i++)
2010 sc->chunk_offsets[i] = avio_rb64(pb);
2012 return AVERROR_INVALIDDATA;
2014 sc->chunk_count = i;
2016 if (pb->eof_reached) {
2017 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2024 static int mov_codec_id(AVStream *st, uint32_t format)
2026 int id = ff_codec_get_id(ff_codec_movaudio_tags, format);
2029 ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2030 (format & 0xFFFF) == 'T' + ('S' << 8)))
2031 id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format) & 0xFFFF);
2033 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2034 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2035 } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2036 /* skip old ASF MPEG-4 tag */
2037 format && format != MKTAG('m','p','4','s')) {
2038 id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2040 id = ff_codec_get_id(ff_codec_bmp_tags, format);
2042 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
2043 else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2044 (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE &&
2045 st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2046 id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
2048 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
2050 id = ff_codec_get_id(ff_codec_movdata_tags, format);
2054 st->codecpar->codec_tag = format;
2059 static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
2060 AVStream *st, MOVStreamContext *sc)
2062 uint8_t codec_name[32] = { 0 };
2066 /* The first 16 bytes of the video sample description are already
2067 * read in ff_mov_read_stsd_entries() */
2068 stsd_start = avio_tell(pb) - 16;
2070 avio_rb16(pb); /* version */
2071 avio_rb16(pb); /* revision level */
2072 avio_rb32(pb); /* vendor */
2073 avio_rb32(pb); /* temporal quality */
2074 avio_rb32(pb); /* spatial quality */
2076 st->codecpar->width = avio_rb16(pb); /* width */
2077 st->codecpar->height = avio_rb16(pb); /* height */
2079 avio_rb32(pb); /* horiz resolution */
2080 avio_rb32(pb); /* vert resolution */
2081 avio_rb32(pb); /* data size, always 0 */
2082 avio_rb16(pb); /* frames per samples */
2084 len = avio_r8(pb); /* codec name, pascal string */
2087 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2089 avio_skip(pb, 31 - len);
2092 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2094 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2095 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2096 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2097 st->codecpar->width &= ~1;
2098 st->codecpar->height &= ~1;
2100 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2101 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2102 !strncmp(codec_name, "Sorenson H263", 13))
2103 st->codecpar->codec_id = AV_CODEC_ID_FLV1;
2105 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2107 avio_seek(pb, stsd_start, SEEK_SET);
2109 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2110 st->codecpar->bits_per_coded_sample &= 0x1F;
2111 sc->has_palette = 1;
2115 static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
2116 AVStream *st, MOVStreamContext *sc)
2118 int bits_per_sample, flags;
2119 uint16_t version = avio_rb16(pb);
2120 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2122 avio_rb16(pb); /* revision level */
2123 avio_rb32(pb); /* vendor */
2125 st->codecpar->channels = avio_rb16(pb); /* channel count */
2126 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2127 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", st->codecpar->channels);
2129 sc->audio_cid = avio_rb16(pb);
2130 avio_rb16(pb); /* packet size = 0 */
2132 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2134 // Read QT version 1 fields. In version 0 these do not exist.
2135 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2137 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2138 (sc->stsd_version == 0 && version > 0)) {
2140 sc->samples_per_frame = avio_rb32(pb);
2141 avio_rb32(pb); /* bytes per packet */
2142 sc->bytes_per_frame = avio_rb32(pb);
2143 avio_rb32(pb); /* bytes per sample */
2144 } else if (version == 2) {
2145 avio_rb32(pb); /* sizeof struct only */
2146 st->codecpar->sample_rate = av_int2double(avio_rb64(pb));
2147 st->codecpar->channels = avio_rb32(pb);
2148 avio_rb32(pb); /* always 0x7F000000 */
2149 st->codecpar->bits_per_coded_sample = avio_rb32(pb);
2151 flags = avio_rb32(pb); /* lpcm format specific flag */
2152 sc->bytes_per_frame = avio_rb32(pb);
2153 sc->samples_per_frame = avio_rb32(pb);
2154 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2155 st->codecpar->codec_id =
2156 ff_mov_get_lpcm_codec_id(st->codecpar->bits_per_coded_sample,
2159 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2160 /* can't correctly handle variable sized packet as audio unit */
2161 switch (st->codecpar->codec_id) {
2162 case AV_CODEC_ID_MP2:
2163 case AV_CODEC_ID_MP3:
2164 st->need_parsing = AVSTREAM_PARSE_FULL;
2170 if (sc->format == 0) {
2171 if (st->codecpar->bits_per_coded_sample == 8)
2172 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2173 else if (st->codecpar->bits_per_coded_sample == 16)
2174 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2177 switch (st->codecpar->codec_id) {
2178 case AV_CODEC_ID_PCM_S8:
2179 case AV_CODEC_ID_PCM_U8:
2180 if (st->codecpar->bits_per_coded_sample == 16)
2181 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16BE;
2183 case AV_CODEC_ID_PCM_S16LE:
2184 case AV_CODEC_ID_PCM_S16BE:
2185 if (st->codecpar->bits_per_coded_sample == 8)
2186 st->codecpar->codec_id = AV_CODEC_ID_PCM_S8;
2187 else if (st->codecpar->bits_per_coded_sample == 24)
2188 st->codecpar->codec_id =
2189 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2190 AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
2191 else if (st->codecpar->bits_per_coded_sample == 32)
2192 st->codecpar->codec_id =
2193 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2194 AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
2196 /* set values for old format before stsd version 1 appeared */
2197 case AV_CODEC_ID_MACE3:
2198 sc->samples_per_frame = 6;
2199 sc->bytes_per_frame = 2 * st->codecpar->channels;
2201 case AV_CODEC_ID_MACE6:
2202 sc->samples_per_frame = 6;
2203 sc->bytes_per_frame = 1 * st->codecpar->channels;
2205 case AV_CODEC_ID_ADPCM_IMA_QT:
2206 sc->samples_per_frame = 64;
2207 sc->bytes_per_frame = 34 * st->codecpar->channels;
2209 case AV_CODEC_ID_GSM:
2210 sc->samples_per_frame = 160;
2211 sc->bytes_per_frame = 33;
2217 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2218 if (bits_per_sample) {
2219 st->codecpar->bits_per_coded_sample = bits_per_sample;
2220 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->channels;
2224 static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
2225 AVStream *st, MOVStreamContext *sc,
2228 // ttxt stsd contains display flags, justification, background
2229 // color, fonts, and default styles, so fake an atom to read it
2230 MOVAtom fake_atom = { .size = size };
2231 // mp4s contains a regular esds atom
2232 if (st->codecpar->codec_tag != AV_RL32("mp4s"))
2233 mov_read_glbl(c, pb, fake_atom);
2234 st->codecpar->width = sc->width;
2235 st->codecpar->height = sc->height;
2238 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2243 y = (ycbcr >> 16) & 0xFF;
2244 cr = (ycbcr >> 8) & 0xFF;
2247 b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
2248 g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
2249 r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
2251 return (r << 16) | (g << 8) | b;
2254 static int mov_rewrite_dvd_sub_extradata(AVStream *st)
2256 char buf[256] = {0};
2257 uint8_t *src = st->codecpar->extradata;
2260 if (st->codecpar->extradata_size != 64)
2263 if (st->codecpar->width > 0 && st->codecpar->height > 0)
2264 snprintf(buf, sizeof(buf), "size: %dx%d\n",
2265 st->codecpar->width, st->codecpar->height);
2266 av_strlcat(buf, "palette: ", sizeof(buf));
2268 for (i = 0; i < 16; i++) {
2269 uint32_t yuv = AV_RB32(src + i * 4);
2270 uint32_t rgba = yuv_to_rgba(yuv);
2272 av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2275 if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2278 av_freep(&st->codecpar->extradata);
2279 st->codecpar->extradata_size = 0;
2280 st->codecpar->extradata = av_mallocz(strlen(buf) + AV_INPUT_BUFFER_PADDING_SIZE);
2281 if (!st->codecpar->extradata)
2282 return AVERROR(ENOMEM);
2283 st->codecpar->extradata_size = strlen(buf);
2284 memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2289 static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
2290 AVStream *st, MOVStreamContext *sc,
2295 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2296 if ((int)size != size)
2297 return AVERROR(ENOMEM);
2299 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2303 MOVStreamContext *tmcd_ctx = st->priv_data;
2305 val = AV_RB32(st->codecpar->extradata + 4);
2306 tmcd_ctx->tmcd_flags = val;
2307 st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2308 st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2309 #if FF_API_LAVF_AVCTX
2310 FF_DISABLE_DEPRECATION_WARNINGS
2311 st->codec->time_base = av_inv_q(st->avg_frame_rate);
2312 FF_ENABLE_DEPRECATION_WARNINGS
2314 /* adjust for per frame dur in counter mode */
2315 if (tmcd_ctx->tmcd_flags & 0x0008) {
2316 int timescale = AV_RB32(st->codecpar->extradata + 8);
2317 int framedur = AV_RB32(st->codecpar->extradata + 12);
2318 st->avg_frame_rate.num *= timescale;
2319 st->avg_frame_rate.den *= framedur;
2320 #if FF_API_LAVF_AVCTX
2321 FF_DISABLE_DEPRECATION_WARNINGS
2322 st->codec->time_base.den *= timescale;
2323 st->codec->time_base.num *= framedur;
2324 FF_ENABLE_DEPRECATION_WARNINGS
2328 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2329 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2330 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2331 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2332 if (str_size > 0 && size >= (int)str_size + 26) {
2333 char *reel_name = av_malloc(str_size + 1);
2335 return AVERROR(ENOMEM);
2336 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2337 reel_name[str_size] = 0; /* Add null terminator */
2338 /* don't add reel_name if emtpy string */
2339 if (*reel_name == 0) {
2342 av_dict_set(&st->metadata, "reel_name", reel_name, AV_DICT_DONT_STRDUP_VAL);
2349 /* other codec type, just skip (rtp, mp4s ...) */
2350 avio_skip(pb, size);
2355 static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
2356 AVStream *st, MOVStreamContext *sc)
2358 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2359 !st->codecpar->sample_rate && sc->time_scale > 1)
2360 st->codecpar->sample_rate = sc->time_scale;
2362 /* special codec parameters handling */
2363 switch (st->codecpar->codec_id) {
2364 #if CONFIG_DV_DEMUXER
2365 case AV_CODEC_ID_DVAUDIO:
2366 c->dv_fctx = avformat_alloc_context();
2368 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2369 return AVERROR(ENOMEM);
2371 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2373 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2374 return AVERROR(ENOMEM);
2376 sc->dv_audio_container = 1;
2377 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
2380 /* no ifdef since parameters are always those */
2381 case AV_CODEC_ID_QCELP:
2382 st->codecpar->channels = 1;
2383 // force sample rate for qcelp when not stored in mov
2384 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2385 st->codecpar->sample_rate = 8000;
2386 // FIXME: Why is the following needed for some files?
2387 sc->samples_per_frame = 160;
2388 if (!sc->bytes_per_frame)
2389 sc->bytes_per_frame = 35;
2391 case AV_CODEC_ID_AMR_NB:
2392 st->codecpar->channels = 1;
2393 /* force sample rate for amr, stsd in 3gp does not store sample rate */
2394 st->codecpar->sample_rate = 8000;
2396 case AV_CODEC_ID_AMR_WB:
2397 st->codecpar->channels = 1;
2398 st->codecpar->sample_rate = 16000;
2400 case AV_CODEC_ID_MP2:
2401 case AV_CODEC_ID_MP3:
2402 /* force type after stsd for m1a hdlr */
2403 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2405 case AV_CODEC_ID_GSM:
2406 case AV_CODEC_ID_ADPCM_MS:
2407 case AV_CODEC_ID_ADPCM_IMA_WAV:
2408 case AV_CODEC_ID_ILBC:
2409 case AV_CODEC_ID_MACE3:
2410 case AV_CODEC_ID_MACE6:
2411 case AV_CODEC_ID_QDM2:
2412 st->codecpar->block_align = sc->bytes_per_frame;
2414 case AV_CODEC_ID_ALAC:
2415 if (st->codecpar->extradata_size == 36) {
2416 st->codecpar->channels = AV_RB8 (st->codecpar->extradata + 21);
2417 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2420 case AV_CODEC_ID_AC3:
2421 case AV_CODEC_ID_EAC3:
2422 case AV_CODEC_ID_MPEG1VIDEO:
2423 case AV_CODEC_ID_VC1:
2424 case AV_CODEC_ID_VP8:
2425 case AV_CODEC_ID_VP9:
2426 st->need_parsing = AVSTREAM_PARSE_FULL;
2434 static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
2435 int codec_tag, int format,
2438 int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2441 (codec_tag != format &&
2442 // AVID 1:1 samples with differing data format and codec tag exist
2443 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
2444 // prores is allowed to have differing data format and codec tag
2445 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
2447 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
2448 (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id
2449 : codec_tag != MKTAG('j','p','e','g')))) {
2450 /* Multiple fourcc, we skip JPEG. This is not correct, we should
2451 * export it as a separate AVStream but this needs a few changes
2452 * in the MOV demuxer, patch welcome. */
2454 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
2455 avio_skip(pb, size);
2462 int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
2465 MOVStreamContext *sc;
2466 int pseudo_stream_id;
2468 av_assert0 (c->fc->nb_streams >= 1);
2469 st = c->fc->streams[c->fc->nb_streams-1];
2472 for (pseudo_stream_id = 0;
2473 pseudo_stream_id < entries && !pb->eof_reached;
2474 pseudo_stream_id++) {
2475 //Parsing Sample description table
2477 int ret, dref_id = 1;
2478 MOVAtom a = { AV_RL32("stsd") };
2479 int64_t start_pos = avio_tell(pb);
2480 int64_t size = avio_rb32(pb); /* size */
2481 uint32_t format = avio_rl32(pb); /* data format */
2484 avio_rb32(pb); /* reserved */
2485 avio_rb16(pb); /* reserved */
2486 dref_id = avio_rb16(pb);
2487 } else if (size <= 7) {
2488 av_log(c->fc, AV_LOG_ERROR,
2489 "invalid size %"PRId64" in stsd\n", size);
2490 return AVERROR_INVALIDDATA;
2493 if (mov_skip_multiple_stsd(c, pb, st->codecpar->codec_tag, format,
2494 size - (avio_tell(pb) - start_pos))) {
2499 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
2500 sc->dref_id= dref_id;
2501 sc->format = format;
2503 id = mov_codec_id(st, format);
2505 av_log(c->fc, AV_LOG_TRACE,
2506 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
2507 av_fourcc2str(format), st->codecpar->codec_type);
2509 st->codecpar->codec_id = id;
2510 if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) {
2511 mov_parse_stsd_video(c, pb, st, sc);
2512 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
2513 mov_parse_stsd_audio(c, pb, st, sc);
2514 if (st->codecpar->sample_rate < 0) {
2515 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
2516 return AVERROR_INVALIDDATA;
2518 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
2519 mov_parse_stsd_subtitle(c, pb, st, sc,
2520 size - (avio_tell(pb) - start_pos));
2522 ret = mov_parse_stsd_data(c, pb, st, sc,
2523 size - (avio_tell(pb) - start_pos));
2527 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
2528 a.size = size - (avio_tell(pb) - start_pos);
2530 if ((ret = mov_read_default(c, pb, a)) < 0)
2532 } else if (a.size > 0)
2533 avio_skip(pb, a.size);
2535 if (sc->extradata && st->codecpar->extradata) {
2536 int extra_size = st->codecpar->extradata_size;
2538 /* Move the current stream extradata to the stream context one. */
2539 sc->extradata_size[pseudo_stream_id] = extra_size;
2540 sc->extradata[pseudo_stream_id] = av_malloc(extra_size + AV_INPUT_BUFFER_PADDING_SIZE);
2541 if (!sc->extradata[pseudo_stream_id])
2542 return AVERROR(ENOMEM);
2543 memcpy(sc->extradata[pseudo_stream_id], st->codecpar->extradata, extra_size);
2544 av_freep(&st->codecpar->extradata);
2545 st->codecpar->extradata_size = 0;
2550 if (pb->eof_reached) {
2551 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
2558 static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2561 MOVStreamContext *sc;
2564 if (c->fc->nb_streams < 1)
2566 st = c->fc->streams[c->fc->nb_streams - 1];
2569 sc->stsd_version = avio_r8(pb);
2570 avio_rb24(pb); /* flags */
2571 entries = avio_rb32(pb);
2573 /* Each entry contains a size (4 bytes) and format (4 bytes). */
2574 if (entries <= 0 || entries > atom.size / 8) {
2575 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
2576 return AVERROR_INVALIDDATA;
2579 if (sc->extradata) {
2580 av_log(c->fc, AV_LOG_ERROR,
2581 "Duplicate stsd found in this track.\n");
2582 return AVERROR_INVALIDDATA;
2585 /* Prepare space for hosting multiple extradata. */
2586 sc->extradata = av_mallocz_array(entries, sizeof(*sc->extradata));
2588 return AVERROR(ENOMEM);
2590 sc->extradata_size = av_mallocz_array(entries, sizeof(*sc->extradata_size));
2591 if (!sc->extradata_size) {
2592 ret = AVERROR(ENOMEM);
2596 ret = ff_mov_read_stsd_entries(c, pb, entries);
2600 /* Restore back the primary extradata. */
2601 av_freep(&st->codecpar->extradata);
2602 st->codecpar->extradata_size = sc->extradata_size[0];
2603 if (sc->extradata_size[0]) {
2604 st->codecpar->extradata = av_mallocz(sc->extradata_size[0] + AV_INPUT_BUFFER_PADDING_SIZE);
2605 if (!st->codecpar->extradata)
2606 return AVERROR(ENOMEM);
2607 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
2610 return mov_finalize_stsd_codec(c, pb, st, sc);
2612 if (sc->extradata) {
2614 for (j = 0; j < sc->stsd_count; j++)
2615 av_freep(&sc->extradata[j]);
2618 av_freep(&sc->extradata);
2619 av_freep(&sc->extradata_size);
2623 static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2626 MOVStreamContext *sc;
2627 unsigned int i, entries;
2629 if (c->fc->nb_streams < 1)
2631 st = c->fc->streams[c->fc->nb_streams-1];
2634 avio_r8(pb); /* version */
2635 avio_rb24(pb); /* flags */
2637 entries = avio_rb32(pb);
2638 if ((uint64_t)entries * 12 + 4 > atom.size)
2639 return AVERROR_INVALIDDATA;
2641 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
2646 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSC atom\n");
2647 av_free(sc->stsc_data);
2649 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
2651 return AVERROR(ENOMEM);
2653 for (i = 0; i < entries && !pb->eof_reached; i++) {
2654 sc->stsc_data[i].first = avio_rb32(pb);
2655 sc->stsc_data[i].count = avio_rb32(pb);
2656 sc->stsc_data[i].id = avio_rb32(pb);
2660 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
2661 int64_t first_min = i + 1;
2662 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
2663 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
2664 sc->stsc_data[i].first < first_min ||
2665 sc->stsc_data[i].count < 1 ||
2666 sc->stsc_data[i].id < 1) {
2667 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);
2668 if (i+1 >= sc->stsc_count) {
2669 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
2670 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
2671 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
2672 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
2673 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
2676 av_assert0(sc->stsc_data[i+1].first >= 2);
2677 // We replace this entry by the next valid
2678 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
2679 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
2680 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
2684 if (pb->eof_reached) {
2685 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
2692 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
2694 return index < count - 1;
2697 /* Compute the samples value for the stsc entry at the given index. */
2698 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
2702 if (mov_stsc_index_valid(index, sc->stsc_count))
2703 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
2705 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
2706 av_assert0(sc->stsc_data[index].first <= sc->chunk_count);
2707 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
2710 return sc->stsc_data[index].count * (int64_t)chunk_count;
2713 static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2716 MOVStreamContext *sc;
2717 unsigned i, entries;
2719 if (c->fc->nb_streams < 1)
2721 st = c->fc->streams[c->fc->nb_streams-1];
2724 avio_rb32(pb); // version + flags
2726 entries = avio_rb32(pb);
2728 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
2729 av_free(sc->stps_data);
2731 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
2733 return AVERROR(ENOMEM);
2735 for (i = 0; i < entries && !pb->eof_reached; i++) {
2736 sc->stps_data[i] = avio_rb32(pb);
2741 if (pb->eof_reached) {
2742 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
2749 static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2752 MOVStreamContext *sc;
2753 unsigned int i, entries;
2755 if (c->fc->nb_streams < 1)
2757 st = c->fc->streams[c->fc->nb_streams-1];
2760 avio_r8(pb); /* version */
2761 avio_rb24(pb); /* flags */
2763 entries = avio_rb32(pb);
2765 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
2769 sc->keyframe_absent = 1;
2770 if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
2771 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2775 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
2776 if (entries >= UINT_MAX / sizeof(int))
2777 return AVERROR_INVALIDDATA;
2778 av_freep(&sc->keyframes);
2779 sc->keyframe_count = 0;
2780 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
2782 return AVERROR(ENOMEM);
2784 for (i = 0; i < entries && !pb->eof_reached; i++) {
2785 sc->keyframes[i] = avio_rb32(pb);
2788 sc->keyframe_count = i;
2790 if (pb->eof_reached) {
2791 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
2798 static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2801 MOVStreamContext *sc;
2802 unsigned int i, entries, sample_size, field_size, num_bytes;
2807 if (c->fc->nb_streams < 1)
2809 st = c->fc->streams[c->fc->nb_streams-1];
2812 avio_r8(pb); /* version */
2813 avio_rb24(pb); /* flags */
2815 if (atom.type == MKTAG('s','t','s','z')) {
2816 sample_size = avio_rb32(pb);
2817 if (!sc->sample_size) /* do not overwrite value computed in stsd */
2818 sc->sample_size = sample_size;
2819 sc->stsz_sample_size = sample_size;
2823 avio_rb24(pb); /* reserved */
2824 field_size = avio_r8(pb);
2826 entries = avio_rb32(pb);
2828 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
2830 sc->sample_count = entries;
2834 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
2835 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
2836 return AVERROR_INVALIDDATA;
2841 if (entries >= (UINT_MAX - 4) / field_size)
2842 return AVERROR_INVALIDDATA;
2843 if (sc->sample_sizes)
2844 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
2845 av_free(sc->sample_sizes);
2846 sc->sample_count = 0;
2847 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
2848 if (!sc->sample_sizes)
2849 return AVERROR(ENOMEM);
2851 num_bytes = (entries*field_size+4)>>3;
2853 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
2855 av_freep(&sc->sample_sizes);
2856 return AVERROR(ENOMEM);
2859 ret = ffio_read_size(pb, buf, num_bytes);
2861 av_freep(&sc->sample_sizes);
2863 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
2867 init_get_bits(&gb, buf, 8*num_bytes);
2869 for (i = 0; i < entries && !pb->eof_reached; i++) {
2870 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
2871 sc->data_size += sc->sample_sizes[i];
2874 sc->sample_count = i;
2878 if (pb->eof_reached) {
2879 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSZ atom\n");
2886 static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2889 MOVStreamContext *sc;
2890 unsigned int i, entries, alloc_size = 0;
2892 int64_t total_sample_count=0;
2894 if (c->fc->nb_streams < 1)
2896 st = c->fc->streams[c->fc->nb_streams-1];
2899 avio_r8(pb); /* version */
2900 avio_rb24(pb); /* flags */
2901 entries = avio_rb32(pb);
2903 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
2904 c->fc->nb_streams-1, entries);
2907 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
2908 av_freep(&sc->stts_data);
2910 if (entries >= INT_MAX / sizeof(*sc->stts_data))
2911 return AVERROR(ENOMEM);
2913 for (i = 0; i < entries && !pb->eof_reached; i++) {
2914 int sample_duration;
2915 unsigned int sample_count;
2916 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
2917 MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
2918 min_entries * sizeof(*sc->stts_data));
2920 av_freep(&sc->stts_data);
2922 return AVERROR(ENOMEM);
2924 sc->stts_count = min_entries;
2925 sc->stts_data = stts_data;
2927 sample_count=avio_rb32(pb);
2928 sample_duration = avio_rb32(pb);
2930 sc->stts_data[i].count= sample_count;
2931 sc->stts_data[i].duration= sample_duration;
2933 av_log(c->fc, AV_LOG_TRACE, "sample_count=%d, sample_duration=%d\n",
2934 sample_count, sample_duration);
2936 duration+=(int64_t)sample_duration*(uint64_t)sample_count;
2937 total_sample_count+=sample_count;
2943 duration <= INT64_MAX - sc->duration_for_fps &&
2944 total_sample_count <= INT_MAX - sc->nb_frames_for_fps
2946 sc->duration_for_fps += duration;
2947 sc->nb_frames_for_fps += total_sample_count;
2950 if (pb->eof_reached) {
2951 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
2955 st->nb_frames= total_sample_count;
2957 st->duration= FFMIN(st->duration, duration);
2958 sc->track_end = duration;
2962 static void mov_update_dts_shift(MOVStreamContext *sc, int duration)
2965 if (duration == INT_MIN) {
2966 av_log(NULL, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
2969 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
2973 static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2976 MOVStreamContext *sc;
2977 unsigned int i, entries, ctts_count = 0;
2979 if (c->fc->nb_streams < 1)
2981 st = c->fc->streams[c->fc->nb_streams-1];
2984 avio_r8(pb); /* version */
2985 avio_rb24(pb); /* flags */
2986 entries = avio_rb32(pb);
2988 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
2992 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
2993 return AVERROR_INVALIDDATA;
2994 av_freep(&sc->ctts_data);
2995 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
2997 return AVERROR(ENOMEM);
2999 for (i = 0; i < entries && !pb->eof_reached; i++) {
3000 int count =avio_rb32(pb);
3001 int duration =avio_rb32(pb);
3004 av_log(c->fc, AV_LOG_TRACE,
3005 "ignoring CTTS entry with count=%d duration=%d\n",
3010 add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3013 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3016 if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3017 av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3018 av_freep(&sc->ctts_data);
3024 mov_update_dts_shift(sc, duration);
3027 sc->ctts_count = ctts_count;
3029 if (pb->eof_reached) {
3030 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3034 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3039 static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3042 MOVStreamContext *sc;
3043 unsigned int i, entries;
3045 uint32_t grouping_type;
3047 if (c->fc->nb_streams < 1)
3049 st = c->fc->streams[c->fc->nb_streams-1];
3052 version = avio_r8(pb); /* version */
3053 avio_rb24(pb); /* flags */
3054 grouping_type = avio_rl32(pb);
3055 if (grouping_type != MKTAG( 'r','a','p',' '))
3056 return 0; /* only support 'rap ' grouping */
3058 avio_rb32(pb); /* grouping_type_parameter */
3060 entries = avio_rb32(pb);
3064 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP atom\n");
3065 av_free(sc->rap_group);
3066 sc->rap_group_count = 0;
3067 sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group));
3069 return AVERROR(ENOMEM);
3071 for (i = 0; i < entries && !pb->eof_reached; i++) {
3072 sc->rap_group[i].count = avio_rb32(pb); /* sample_count */
3073 sc->rap_group[i].index = avio_rb32(pb); /* group_description_index */
3076 sc->rap_group_count = i;
3078 if (pb->eof_reached) {
3079 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3087 * Get ith edit list entry (media time, duration).
3089 static int get_edit_list_entry(MOVContext *mov,
3090 const MOVStreamContext *msc,
3091 unsigned int edit_list_index,
3092 int64_t *edit_list_media_time,
3093 int64_t *edit_list_duration,
3094 int64_t global_timescale)
3096 if (edit_list_index == msc->elst_count) {
3099 *edit_list_media_time = msc->elst_data[edit_list_index].time;
3100 *edit_list_duration = msc->elst_data[edit_list_index].duration;
3102 /* duration is in global timescale units;convert to msc timescale */
3103 if (global_timescale == 0) {
3104 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3107 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3113 * Find the closest previous frame to the timestamp_pts, in e_old index
3114 * entries. Searching for just any frame / just key frames can be controlled by
3115 * last argument 'flag'.
3116 * Note that if ctts_data is not NULL, we will always search for a key frame
3117 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3118 * return the first frame of the video.
3120 * Here the timestamp_pts is considered to be a presentation timestamp and
3121 * the timestamp of index entries are considered to be decoding timestamps.
3123 * Returns 0 if successful in finding a frame, else returns -1.
3124 * Places the found index corresponding output arg.
3126 * If ctts_old is not NULL, then refines the searched entry by searching
3127 * backwards from the found timestamp, to find the frame with correct PTS.
3129 * Places the found ctts_index and ctts_sample in corresponding output args.
3131 static int find_prev_closest_index(AVStream *st,
3132 AVIndexEntry *e_old,
3136 int64_t timestamp_pts,
3139 int64_t* ctts_index,
3140 int64_t* ctts_sample)
3142 MOVStreamContext *msc = st->priv_data;
3143 AVIndexEntry *e_keep = st->index_entries;
3144 int nb_keep = st->nb_index_entries;
3146 int64_t index_ctts_count;
3150 // If dts_shift > 0, then all the index timestamps will have to be offset by
3151 // at least dts_shift amount to obtain PTS.
3152 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3153 if (msc->dts_shift > 0) {
3154 timestamp_pts -= msc->dts_shift;
3157 st->index_entries = e_old;
3158 st->nb_index_entries = nb_old;
3159 *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3161 // Keep going backwards in the index entries until the timestamp is the same.
3163 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3165 if ((flag & AVSEEK_FLAG_ANY) ||
3166 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3172 // If we have CTTS then refine the search, by searching backwards over PTS
3173 // computed by adding corresponding CTTS durations to index timestamps.
3174 if (ctts_data && *index >= 0) {
3175 av_assert0(ctts_index);
3176 av_assert0(ctts_sample);
3177 // Find out the ctts_index for the found frame.
3180 for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3181 if (*ctts_index < ctts_count) {
3183 if (ctts_data[*ctts_index].count == *ctts_sample) {
3190 while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3191 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3192 // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3193 // compensated by dts_shift above.
3194 if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3195 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3200 if (*ctts_sample == 0) {
3202 if (*ctts_index >= 0)
3203 *ctts_sample = ctts_data[*ctts_index].count - 1;
3210 /* restore AVStream state*/
3211 st->index_entries = e_keep;
3212 st->nb_index_entries = nb_keep;
3213 return *index >= 0 ? 0 : -1;
3217 * Add index entry with the given values, to the end of st->index_entries.
3218 * Returns the new size st->index_entries if successful, else returns -1.
3220 * This function is similar to ff_add_index_entry in libavformat/utils.c
3221 * except that here we are always unconditionally adding an index entry to
3222 * the end, instead of searching the entries list and skipping the add if
3223 * there is an existing entry with the same timestamp.
3224 * This is needed because the mov_fix_index calls this func with the same
3225 * unincremented timestamp for successive discarded frames.
3227 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3228 int size, int distance, int flags)
3230 AVIndexEntry *entries, *ie;
3232 const size_t min_size_needed = (st->nb_index_entries + 1) * sizeof(AVIndexEntry);
3234 // Double the allocation each time, to lower memory fragmentation.
3235 // Another difference from ff_add_index_entry function.
3236 const size_t requested_size =
3237 min_size_needed > st->index_entries_allocated_size ?
3238 FFMAX(min_size_needed, 2 * st->index_entries_allocated_size) :
3241 if((unsigned)st->nb_index_entries + 1 >= UINT_MAX / sizeof(AVIndexEntry))
3244 entries = av_fast_realloc(st->index_entries,
3245 &st->index_entries_allocated_size,
3250 st->index_entries= entries;
3252 index= st->nb_index_entries++;
3253 ie= &entries[index];
3256 ie->timestamp = timestamp;
3257 ie->min_distance= distance;
3264 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3265 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3267 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3268 int64_t* frame_duration_buffer,
3269 int frame_duration_buffer_size) {
3271 av_assert0(end_index >= 0 && end_index <= st->nb_index_entries);
3272 for (i = 0; i < frame_duration_buffer_size; i++) {
3273 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3274 st->index_entries[end_index - 1 - i].timestamp = end_ts;
3279 * Append a new ctts entry to ctts_data.
3280 * Returns the new ctts_count if successful, else returns -1.
3282 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3283 int count, int duration)
3285 MOVStts *ctts_buf_new;
3286 const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVStts);
3287 const size_t requested_size =
3288 min_size_needed > *allocated_size ?
3289 FFMAX(min_size_needed, 2 * (*allocated_size)) :
3292 if((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
3295 ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3300 *ctts_data = ctts_buf_new;
3302 ctts_buf_new[*ctts_count].count = count;
3303 ctts_buf_new[*ctts_count].duration = duration;
3305 *ctts_count = (*ctts_count) + 1;
3309 #define MAX_REORDER_DELAY 16
3310 static void mov_estimate_video_delay(MOVContext *c, AVStream* st) {
3311 MOVStreamContext *msc = st->priv_data;
3314 int ctts_sample = 0;
3315 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3317 int j, r, num_swaps;
3319 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3320 pts_buf[j] = INT64_MIN;
3322 if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3323 st->codecpar->codec_id == AV_CODEC_ID_H264) {
3324 st->codecpar->video_delay = 0;
3325 for(ind = 0; ind < st->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3326 // Point j to the last elem of the buffer and insert the current pts there.
3328 buf_start = (buf_start + 1);
3329 if (buf_start == MAX_REORDER_DELAY + 1)
3332 pts_buf[j] = st->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3334 // The timestamps that are already in the sorted buffer, and are greater than the
3335 // current pts, are exactly the timestamps that need to be buffered to output PTS
3336 // in correct sorted order.
3337 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3338 // can be computed as the maximum no. of swaps any particular timestamp needs to
3339 // go through, to keep this buffer in sorted order.
3341 while (j != buf_start) {
3343 if (r < 0) r = MAX_REORDER_DELAY;
3344 if (pts_buf[j] < pts_buf[r]) {
3345 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3352 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3355 if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3360 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3361 st->codecpar->video_delay, st->index);
3365 static void mov_current_sample_inc(MOVStreamContext *sc)
3367 sc->current_sample++;
3368 sc->current_index++;
3369 if (sc->index_ranges &&
3370 sc->current_index >= sc->current_index_range->end &&
3371 sc->current_index_range->end) {
3372 sc->current_index_range++;
3373 sc->current_index = sc->current_index_range->start;
3377 static void mov_current_sample_dec(MOVStreamContext *sc)
3379 sc->current_sample--;
3380 sc->current_index--;
3381 if (sc->index_ranges &&
3382 sc->current_index < sc->current_index_range->start &&
3383 sc->current_index_range > sc->index_ranges) {
3384 sc->current_index_range--;
3385 sc->current_index = sc->current_index_range->end - 1;
3389 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3393 sc->current_sample = current_sample;
3394 sc->current_index = current_sample;
3395 if (!sc->index_ranges) {
3399 for (sc->current_index_range = sc->index_ranges;
3400 sc->current_index_range->end;
3401 sc->current_index_range++) {
3402 range_size = sc->current_index_range->end - sc->current_index_range->start;
3403 if (range_size > current_sample) {
3404 sc->current_index = sc->current_index_range->start + current_sample;
3407 current_sample -= range_size;
3412 * Fix st->index_entries, so that it contains only the entries (and the entries
3413 * which are needed to decode them) that fall in the edit list time ranges.
3414 * Also fixes the timestamps of the index entries to match the timeline
3415 * specified the edit lists.
3417 static void mov_fix_index(MOVContext *mov, AVStream *st)
3419 MOVStreamContext *msc = st->priv_data;
3420 AVIndexEntry *e_old = st->index_entries;
3421 int nb_old = st->nb_index_entries;
3422 const AVIndexEntry *e_old_end = e_old + nb_old;
3423 const AVIndexEntry *current = NULL;
3424 MOVStts *ctts_data_old = msc->ctts_data;
3425 int64_t ctts_index_old = 0;
3426 int64_t ctts_sample_old = 0;
3427 int64_t ctts_count_old = msc->ctts_count;
3428 int64_t edit_list_media_time = 0;
3429 int64_t edit_list_duration = 0;
3430 int64_t frame_duration = 0;
3431 int64_t edit_list_dts_counter = 0;
3432 int64_t edit_list_dts_entry_end = 0;
3433 int64_t edit_list_start_ctts_sample = 0;
3435 int64_t curr_ctts = 0;
3436 int64_t empty_edits_sum_duration = 0;
3437 int64_t edit_list_index = 0;
3440 int64_t start_dts = 0;
3441 int64_t edit_list_start_encountered = 0;
3442 int64_t search_timestamp = 0;
3443 int64_t* frame_duration_buffer = NULL;
3444 int num_discarded_begin = 0;
3445 int first_non_zero_audio_edit = -1;
3446 int packet_skip_samples = 0;
3447 MOVIndexRange *current_index_range;
3449 int found_keyframe_after_edit = 0;
3450 int found_non_empty_edit = 0;
3452 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
3456 // allocate the index ranges array
3457 msc->index_ranges = av_malloc((msc->elst_count + 1) * sizeof(msc->index_ranges[0]));
3458 if (!msc->index_ranges) {
3459 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
3462 msc->current_index_range = msc->index_ranges;
3463 current_index_range = msc->index_ranges - 1;
3465 // Clean AVStream from traces of old index
3466 st->index_entries = NULL;
3467 st->index_entries_allocated_size = 0;
3468 st->nb_index_entries = 0;
3470 // Clean ctts fields of MOVStreamContext
3471 msc->ctts_data = NULL;
3472 msc->ctts_count = 0;
3473 msc->ctts_index = 0;
3474 msc->ctts_sample = 0;
3475 msc->ctts_allocated_size = 0;
3477 // Reinitialize min_corrected_pts so that it can be computed again.
3478 msc->min_corrected_pts = -1;
3480 // If the dts_shift is positive (in case of negative ctts values in mov),
3481 // then negate the DTS by dts_shift
3482 if (msc->dts_shift > 0) {
3483 edit_list_dts_entry_end -= msc->dts_shift;
3484 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
3487 start_dts = edit_list_dts_entry_end;
3489 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
3490 &edit_list_duration, mov->time_scale)) {
3491 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
3492 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
3494 edit_list_dts_counter = edit_list_dts_entry_end;
3495 edit_list_dts_entry_end += edit_list_duration;
3496 num_discarded_begin = 0;
3497 if (!found_non_empty_edit && edit_list_media_time == -1) {
3498 empty_edits_sum_duration += edit_list_duration;
3501 found_non_empty_edit = 1;
3503 // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
3504 // according to the edit list below.
3505 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3506 if (first_non_zero_audio_edit < 0) {
3507 first_non_zero_audio_edit = 1;
3509 first_non_zero_audio_edit = 0;
3512 if (first_non_zero_audio_edit > 0)
3513 st->skip_samples = msc->start_pad = 0;
3516 // While reordering frame index according to edit list we must handle properly
3517 // the scenario when edit list entry starts from none key frame.
3518 // We find closest previous key frame and preserve it and consequent frames in index.
3519 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
3520 search_timestamp = edit_list_media_time;
3521 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3522 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
3523 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
3524 // edit_list_media_time to cover the decoder delay.
3525 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
3528 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
3529 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3530 av_log(mov->fc, AV_LOG_WARNING,
3531 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
3532 st->index, edit_list_index, search_timestamp);
3533 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
3534 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3535 av_log(mov->fc, AV_LOG_WARNING,
3536 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
3537 st->index, edit_list_index, search_timestamp);
3540 ctts_sample_old = 0;
3543 current = e_old + index;
3544 edit_list_start_ctts_sample = ctts_sample_old;
3546 // Iterate over index and arrange it according to edit list
3547 edit_list_start_encountered = 0;
3548 found_keyframe_after_edit = 0;
3549 for (; current < e_old_end; current++, index++) {
3550 // check if frame outside edit list mark it for discard
3551 frame_duration = (current + 1 < e_old_end) ?
3552 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
3554 flags = current->flags;
3556 // frames (pts) before or after edit list
3557 curr_cts = current->timestamp + msc->dts_shift;
3560 if (ctts_data_old && ctts_index_old < ctts_count_old) {
3561 curr_ctts = ctts_data_old[ctts_index_old].duration;
3562 av_log(mov->fc, AV_LOG_DEBUG, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
3563 curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
3564 curr_cts += curr_ctts;
3566 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
3567 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3568 &msc->ctts_allocated_size,
3569 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3570 ctts_data_old[ctts_index_old].duration) == -1) {
3571 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3573 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3574 ctts_data_old[ctts_index_old].duration);
3578 ctts_sample_old = 0;
3579 edit_list_start_ctts_sample = 0;
3583 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
3584 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
3585 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
3586 first_non_zero_audio_edit > 0) {
3587 packet_skip_samples = edit_list_media_time - curr_cts;
3588 st->skip_samples += packet_skip_samples;
3590 // Shift the index entry timestamp by packet_skip_samples to be correct.
3591 edit_list_dts_counter -= packet_skip_samples;
3592 if (edit_list_start_encountered == 0) {
3593 edit_list_start_encountered = 1;
3594 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
3595 // discarded packets.
3596 if (frame_duration_buffer) {
3597 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3598 frame_duration_buffer, num_discarded_begin);
3599 av_freep(&frame_duration_buffer);
3603 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
3605 flags |= AVINDEX_DISCARD_FRAME;
3606 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
3608 if (edit_list_start_encountered == 0) {
3609 num_discarded_begin++;
3610 frame_duration_buffer = av_realloc(frame_duration_buffer,
3611 num_discarded_begin * sizeof(int64_t));
3612 if (!frame_duration_buffer) {
3613 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
3616 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
3618 // Increment skip_samples for the first non-zero audio edit list
3619 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3620 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
3621 st->skip_samples += frame_duration;
3626 if (msc->min_corrected_pts < 0) {
3627 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
3629 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
3631 if (edit_list_start_encountered == 0) {
3632 edit_list_start_encountered = 1;
3633 // Make timestamps strictly monotonically increasing by rewriting timestamps for
3634 // discarded packets.
3635 if (frame_duration_buffer) {
3636 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3637 frame_duration_buffer, num_discarded_begin);
3638 av_freep(&frame_duration_buffer);
3643 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
3644 current->min_distance, flags) == -1) {
3645 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
3649 // Update the index ranges array
3650 if (current_index_range < msc->index_ranges || index != current_index_range->end) {
3651 current_index_range++;
3652 current_index_range->start = index;
3654 current_index_range->end = index + 1;
3656 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
3657 if (edit_list_start_encountered > 0) {
3658 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
3661 // Break when found first key frame after edit entry completion
3662 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
3663 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
3664 if (ctts_data_old) {
3665 // If we have CTTS and this is the first keyframe after edit elist,
3666 // wait for one more, because there might be trailing B-frames after this I-frame
3667 // that do belong to the edit.
3668 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
3669 found_keyframe_after_edit = 1;
3672 if (ctts_sample_old != 0) {
3673 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3674 &msc->ctts_allocated_size,
3675 ctts_sample_old - edit_list_start_ctts_sample,
3676 ctts_data_old[ctts_index_old].duration) == -1) {
3677 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3678 ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
3679 ctts_data_old[ctts_index_old].duration);
3688 // If there are empty edits, then msc->min_corrected_pts might be positive
3689 // intentionally. So we subtract the sum duration of emtpy edits here.
3690 msc->min_corrected_pts -= empty_edits_sum_duration;
3692 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
3693 // dts by that amount to make the first pts zero.
3694 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
3695 if (msc->min_corrected_pts > 0) {
3696 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
3697 for (i = 0; i < st->nb_index_entries; ++i) {
3698 st->index_entries[i].timestamp -= msc->min_corrected_pts;
3702 // Start time should be equal to zero or the duration of any empty edits.
3703 st->start_time = empty_edits_sum_duration;
3705 // Update av stream length, if it ends up shorter than the track's media duration
3706 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
3707 msc->start_pad = st->skip_samples;
3709 // Free the old index and the old CTTS structures
3711 av_free(ctts_data_old);
3712 av_freep(&frame_duration_buffer);
3714 // Null terminate the index ranges array
3715 current_index_range++;
3716 current_index_range->start = 0;
3717 current_index_range->end = 0;
3718 msc->current_index = msc->index_ranges[0].start;
3721 static void mov_build_index(MOVContext *mov, AVStream *st)
3723 MOVStreamContext *sc = st->priv_data;
3724 int64_t current_offset;
3725 int64_t current_dts = 0;
3726 unsigned int stts_index = 0;
3727 unsigned int stsc_index = 0;
3728 unsigned int stss_index = 0;
3729 unsigned int stps_index = 0;
3731 uint64_t stream_size = 0;
3732 MOVStts *ctts_data_old = sc->ctts_data;
3733 unsigned int ctts_count_old = sc->ctts_count;
3735 if (sc->elst_count) {
3736 int i, edit_start_index = 0, multiple_edits = 0;
3737 int64_t empty_duration = 0; // empty duration of the first edit list entry
3738 int64_t start_time = 0; // start time of the media
3740 for (i = 0; i < sc->elst_count; i++) {
3741 const MOVElst *e = &sc->elst_data[i];
3742 if (i == 0 && e->time == -1) {
3743 /* if empty, the first entry is the start time of the stream
3744 * relative to the presentation itself */
3745 empty_duration = e->duration;
3746 edit_start_index = 1;
3747 } else if (i == edit_start_index && e->time >= 0) {
3748 start_time = e->time;
3754 if (multiple_edits && !mov->advanced_editlist)
3755 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
3756 "Use -advanced_editlist to correctly decode otherwise "
3757 "a/v desync might occur\n");
3759 /* adjust first dts according to edit list */
3760 if ((empty_duration || start_time) && mov->time_scale > 0) {
3762 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
3763 sc->time_offset = start_time - empty_duration;
3764 sc->min_corrected_pts = start_time;
3765 if (!mov->advanced_editlist)
3766 current_dts = -sc->time_offset;
3769 if (!multiple_edits && !mov->advanced_editlist &&
3770 st->codecpar->codec_id == AV_CODEC_ID_AAC && start_time > 0)
3771 sc->start_pad = start_time;
3774 /* only use old uncompressed audio chunk demuxing when stts specifies it */
3775 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3776 sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
3777 unsigned int current_sample = 0;
3778 unsigned int stts_sample = 0;
3779 unsigned int sample_size;
3780 unsigned int distance = 0;
3781 unsigned int rap_group_index = 0;
3782 unsigned int rap_group_sample = 0;
3783 int64_t last_dts = 0;
3784 int64_t dts_correction = 0;
3785 int rap_group_present = sc->rap_group_count && sc->rap_group;
3786 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
3788 current_dts -= sc->dts_shift;
3789 last_dts = current_dts;
3791 if (!sc->sample_count || st->nb_index_entries)
3793 if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
3795 if (av_reallocp_array(&st->index_entries,
3796 st->nb_index_entries + sc->sample_count,
3797 sizeof(*st->index_entries)) < 0) {
3798 st->nb_index_entries = 0;
3801 st->index_entries_allocated_size = (st->nb_index_entries + sc->sample_count) * sizeof(*st->index_entries);
3803 if (ctts_data_old) {
3804 // Expand ctts entries such that we have a 1-1 mapping with samples
3805 if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
3808 sc->ctts_allocated_size = 0;
3809 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size,
3810 sc->sample_count * sizeof(*sc->ctts_data));
3811 if (!sc->ctts_data) {
3812 av_free(ctts_data_old);
3816 memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
3818 for (i = 0; i < ctts_count_old &&
3819 sc->ctts_count < sc->sample_count; i++)
3820 for (j = 0; j < ctts_data_old[i].count &&
3821 sc->ctts_count < sc->sample_count; j++)
3822 add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
3823 &sc->ctts_allocated_size, 1,
3824 ctts_data_old[i].duration);
3825 av_free(ctts_data_old);
3828 for (i = 0; i < sc->chunk_count; i++) {
3829 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
3830 current_offset = sc->chunk_offsets[i];
3831 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3832 i + 1 == sc->stsc_data[stsc_index + 1].first)
3835 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
3836 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
3837 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
3838 sc->stsz_sample_size = sc->sample_size;
3840 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
3841 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
3842 sc->stsz_sample_size = sc->sample_size;
3845 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
3847 if (current_sample >= sc->sample_count) {
3848 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
3852 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
3854 if (stss_index + 1 < sc->keyframe_count)
3856 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
3858 if (stps_index + 1 < sc->stps_count)
3861 if (rap_group_present && rap_group_index < sc->rap_group_count) {
3862 if (sc->rap_group[rap_group_index].index > 0)
3864 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
3865 rap_group_sample = 0;
3869 if (sc->keyframe_absent
3871 && !rap_group_present
3872 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
3876 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
3877 if (sc->pseudo_stream_id == -1 ||
3878 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
3880 if (sample_size > 0x3FFFFFFF) {
3881 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
3884 e = &st->index_entries[st->nb_index_entries++];
3885 e->pos = current_offset;
3886 e->timestamp = current_dts;
3887 e->size = sample_size;
3888 e->min_distance = distance;
3889 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
3890 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
3891 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
3892 current_offset, current_dts, sample_size, distance, keyframe);
3893 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries < 100)
3894 ff_rfps_add_frame(mov->fc, st, current_dts);
3897 current_offset += sample_size;
3898 stream_size += sample_size;
3900 /* A negative sample duration is invalid based on the spec,
3901 * but some samples need it to correct the DTS. */
3902 if (sc->stts_data[stts_index].duration < 0) {
3903 av_log(mov->fc, AV_LOG_WARNING,
3904 "Invalid SampleDelta %d in STTS, at %d st:%d\n",
3905 sc->stts_data[stts_index].duration, stts_index,
3907 dts_correction += sc->stts_data[stts_index].duration - 1;
3908 sc->stts_data[stts_index].duration = 1;
3910 current_dts += sc->stts_data[stts_index].duration;
3911 if (!dts_correction || current_dts + dts_correction > last_dts) {
3912 current_dts += dts_correction;
3915 /* Avoid creating non-monotonous DTS */
3916 dts_correction += current_dts - last_dts - 1;
3917 current_dts = last_dts + 1;
3919 last_dts = current_dts;
3923 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
3929 if (st->duration > 0)
3930 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
3932 unsigned chunk_samples, total = 0;
3934 if (!sc->chunk_count)
3937 // compute total chunk count
3938 for (i = 0; i < sc->stsc_count; i++) {
3939 unsigned count, chunk_count;
3941 chunk_samples = sc->stsc_data[i].count;
3942 if (i != sc->stsc_count - 1 &&
3943 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
3944 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
3948 if (sc->samples_per_frame >= 160) { // gsm
3949 count = chunk_samples / sc->samples_per_frame;
3950 } else if (sc->samples_per_frame > 1) {
3951 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
3952 count = (chunk_samples+samples-1) / samples;
3954 count = (chunk_samples+1023) / 1024;
3957 if (mov_stsc_index_valid(i, sc->stsc_count))
3958 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
3960 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
3961 total += chunk_count * count;
3964 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
3965 if (total >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
3967 if (av_reallocp_array(&st->index_entries,
3968 st->nb_index_entries + total,
3969 sizeof(*st->index_entries)) < 0) {
3970 st->nb_index_entries = 0;
3973 st->index_entries_allocated_size = (st->nb_index_entries + total) * sizeof(*st->index_entries);
3976 for (i = 0; i < sc->chunk_count; i++) {
3977 current_offset = sc->chunk_offsets[i];
3978 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3979 i + 1 == sc->stsc_data[stsc_index + 1].first)
3981 chunk_samples = sc->stsc_data[stsc_index].count;
3983 while (chunk_samples > 0) {
3985 unsigned size, samples;
3987 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
3988 avpriv_request_sample(mov->fc,
3989 "Zero bytes per frame, but %d samples per frame",
3990 sc->samples_per_frame);
3994 if (sc->samples_per_frame >= 160) { // gsm
3995 samples = sc->samples_per_frame;
3996 size = sc->bytes_per_frame;
3998 if (sc->samples_per_frame > 1) {
3999 samples = FFMIN((1024 / sc->samples_per_frame)*
4000 sc->samples_per_frame, chunk_samples);
4001 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
4003 samples = FFMIN(1024, chunk_samples);
4004 size = samples * sc->sample_size;
4008 if (st->nb_index_entries >= total) {
4009 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4012 if (size > 0x3FFFFFFF) {
4013 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4016 e = &st->index_entries[st->nb_index_entries++];
4017 e->pos = current_offset;
4018 e->timestamp = current_dts;
4020 e->min_distance = 0;
4021 e->flags = AVINDEX_KEYFRAME;
4022 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4023 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4026 current_offset += size;
4027 current_dts += samples;
4028 chunk_samples -= samples;
4033 if (!mov->ignore_editlist && mov->advanced_editlist) {
4034 // Fix index according to edit lists.
4035 mov_fix_index(mov, st);
4038 // Update start time of the stream.
4039 if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries > 0) {
4040 st->start_time = st->index_entries[0].timestamp + sc->dts_shift;
4041 if (sc->ctts_data) {
4042 st->start_time += sc->ctts_data[0].duration;
4046 mov_estimate_video_delay(mov, st);
4049 static int test_same_origin(const char *src, const char *ref) {
4059 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4060 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4062 if (strlen(src) == 0) {
4064 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4065 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4066 strlen(src_host) + 1 >= sizeof(src_host) ||
4067 strlen(ref_host) + 1 >= sizeof(ref_host)) {
4069 } else if (strcmp(src_proto, ref_proto) ||
4070 strcmp(src_auth, ref_auth) ||
4071 strcmp(src_host, ref_host) ||
4072 src_port != ref_port) {
4078 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4080 /* try relative path, we do not try the absolute because it can leak information about our
4081 system to an attacker */
4082 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4083 char filename[1025];
4084 const char *src_path;
4087 /* find a source dir */
4088 src_path = strrchr(src, '/');
4094 /* find a next level down to target */
4095 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4096 if (ref->path[l] == '/') {
4097 if (i == ref->nlvl_to - 1)
4103 /* compose filename if next level down to target was found */
4104 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4105 memcpy(filename, src, src_path - src);
4106 filename[src_path - src] = 0;
4108 for (i = 1; i < ref->nlvl_from; i++)
4109 av_strlcat(filename, "../", sizeof(filename));
4111 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4112 if (!c->use_absolute_path) {
4113 int same_origin = test_same_origin(src, filename);
4116 av_log(c->fc, AV_LOG_ERROR,
4117 "Reference with mismatching origin, %s not tried for security reasons, "
4118 "set demuxer option use_absolute_path to allow it anyway\n",
4120 return AVERROR(ENOENT);
4123 if(strstr(ref->path + l + 1, "..") ||
4124 strstr(ref->path + l + 1, ":") ||
4125 (ref->nlvl_from > 1 && same_origin < 0) ||
4126 (filename[0] == '/' && src_path == src))
4127 return AVERROR(ENOENT);
4130 if (strlen(filename) + 1 == sizeof(filename))
4131 return AVERROR(ENOENT);
4132 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4135 } else if (c->use_absolute_path) {
4136 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4137 "this is a possible security issue\n");
4138 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4141 av_log(c->fc, AV_LOG_ERROR,
4142 "Absolute path %s not tried for security reasons, "
4143 "set demuxer option use_absolute_path to allow absolute paths\n",
4147 return AVERROR(ENOENT);
4150 static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
4152 if (sc->time_scale <= 0) {
4153 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4154 sc->time_scale = c->time_scale;
4155 if (sc->time_scale <= 0)
4160 static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4163 MOVStreamContext *sc;
4166 st = avformat_new_stream(c->fc, NULL);
4167 if (!st) return AVERROR(ENOMEM);
4169 sc = av_mallocz(sizeof(MOVStreamContext));
4170 if (!sc) return AVERROR(ENOMEM);
4173 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
4174 sc->ffindex = st->index;
4175 c->trak_index = st->index;
4177 if ((ret = mov_read_default(c, pb, atom)) < 0)
4182 // Here stsc refers to a chunk not described in stco. This is technically invalid,
4183 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4184 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4186 av_freep(&sc->stsc_data);
4190 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4191 (!sc->sample_size && !sc->sample_count))) ||
4192 (!sc->chunk_count && sc->sample_count)) {
4193 av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4197 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4198 av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4200 return AVERROR_INVALIDDATA;
4203 fix_timescale(c, sc);
4205 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4207 mov_build_index(c, st);
4209 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4210 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4211 if (c->enable_drefs) {
4212 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4213 av_log(c->fc, AV_LOG_ERROR,
4214 "stream %d, error opening alias: path='%s', dir='%s', "
4215 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4216 st->index, dref->path, dref->dir, dref->filename,
4217 dref->volume, dref->nlvl_from, dref->nlvl_to);
4219 av_log(c->fc, AV_LOG_WARNING,
4220 "Skipped opening external track: "
4221 "stream %d, alias: path='%s', dir='%s', "
4222 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4223 "Set enable_drefs to allow this.\n",
4224 st->index, dref->path, dref->dir, dref->filename,
4225 dref->volume, dref->nlvl_from, dref->nlvl_to);
4229 sc->pb_is_copied = 1;
4232 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4233 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4234 sc->height && sc->width &&
4235 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4236 st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4237 ((double)st->codecpar->width * sc->height), INT_MAX);
4240 #if FF_API_R_FRAME_RATE
4241 if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4242 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
4243 sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4247 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4248 if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4249 TAG_IS_AVCI(st->codecpar->codec_tag)) {
4250 ret = ff_generate_avci_extradata(st);
4255 switch (st->codecpar->codec_id) {
4256 #if CONFIG_H261_DECODER
4257 case AV_CODEC_ID_H261:
4259 #if CONFIG_H263_DECODER
4260 case AV_CODEC_ID_H263:
4262 #if CONFIG_MPEG4_DECODER
4263 case AV_CODEC_ID_MPEG4:
4265 st->codecpar->width = 0; /* let decoder init width/height */
4266 st->codecpar->height= 0;
4270 // If the duration of the mp3 packets is not constant, then they could need a parser
4271 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4272 && sc->stts_count > 3
4273 && sc->stts_count*10 > st->nb_frames
4274 && sc->time_scale == st->codecpar->sample_rate) {
4275 st->need_parsing = AVSTREAM_PARSE_FULL;
4277 /* Do not need those anymore. */
4278 av_freep(&sc->chunk_offsets);
4279 av_freep(&sc->sample_sizes);
4280 av_freep(&sc->keyframes);
4281 av_freep(&sc->stts_data);
4282 av_freep(&sc->stps_data);
4283 av_freep(&sc->elst_data);
4284 av_freep(&sc->rap_group);
4289 static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4292 c->itunes_metadata = 1;
4293 ret = mov_read_default(c, pb, atom);
4294 c->itunes_metadata = 0;
4298 static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4307 count = avio_rb32(pb);
4308 if (count > UINT_MAX / sizeof(*c->meta_keys) - 1) {
4309 av_log(c->fc, AV_LOG_ERROR,
4310 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
4311 return AVERROR_INVALIDDATA;
4314 c->meta_keys_count = count + 1;
4315 c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
4317 return AVERROR(ENOMEM);
4319 for (i = 1; i <= count; ++i) {
4320 uint32_t key_size = avio_rb32(pb);
4321 uint32_t type = avio_rl32(pb);
4323 av_log(c->fc, AV_LOG_ERROR,
4324 "The key# %"PRIu32" in meta has invalid size:"
4325 "%"PRIu32"\n", i, key_size);
4326 return AVERROR_INVALIDDATA;
4329 if (type != MKTAG('m','d','t','a')) {
4330 avio_skip(pb, key_size);
4332 c->meta_keys[i] = av_mallocz(key_size + 1);
4333 if (!c->meta_keys[i])
4334 return AVERROR(ENOMEM);
4335 avio_read(pb, c->meta_keys[i], key_size);
4341 static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4343 int64_t end = avio_tell(pb) + atom.size;
4344 uint8_t *key = NULL, *val = NULL, *mean = NULL;
4348 MOVStreamContext *sc;
4350 if (c->fc->nb_streams < 1)
4352 st = c->fc->streams[c->fc->nb_streams-1];
4355 for (i = 0; i < 3; i++) {
4359 if (end - avio_tell(pb) <= 12)
4362 len = avio_rb32(pb);
4363 tag = avio_rl32(pb);
4364 avio_skip(pb, 4); // flags
4366 if (len < 12 || len - 12 > end - avio_tell(pb))
4370 if (tag == MKTAG('m', 'e', 'a', 'n'))
4372 else if (tag == MKTAG('n', 'a', 'm', 'e'))
4374 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
4381 *p = av_malloc(len + 1);
4383 ret = AVERROR(ENOMEM);
4386 ret = ffio_read_size(pb, *p, len);
4394 if (mean && key && val) {
4395 if (strcmp(key, "iTunSMPB") == 0) {
4396 int priming, remainder, samples;
4397 if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
4398 if(priming>0 && priming<16384)
4399 sc->start_pad = priming;
4402 if (strcmp(key, "cdec") != 0) {
4403 av_dict_set(&c->fc->metadata, key, val,
4404 AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
4408 av_log(c->fc, AV_LOG_VERBOSE,
4409 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
4412 avio_seek(pb, end, SEEK_SET);
4419 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4421 while (atom.size > 8) {
4422 uint32_t tag = avio_rl32(pb);
4424 if (tag == MKTAG('h','d','l','r')) {
4425 avio_seek(pb, -8, SEEK_CUR);
4427 return mov_read_default(c, pb, atom);
4433 // return 1 when matrix is identity, 0 otherwise
4434 #define IS_MATRIX_IDENT(matrix) \
4435 ( (matrix)[0][0] == (1 << 16) && \
4436 (matrix)[1][1] == (1 << 16) && \
4437 (matrix)[2][2] == (1 << 30) && \
4438 !(matrix)[0][1] && !(matrix)[0][2] && \
4439 !(matrix)[1][0] && !(matrix)[1][2] && \
4440 !(matrix)[2][0] && !(matrix)[2][1])
4442 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4447 int display_matrix[3][3];
4448 int res_display_matrix[3][3] = { { 0 } };
4450 MOVStreamContext *sc;
4454 if (c->fc->nb_streams < 1)
4456 st = c->fc->streams[c->fc->nb_streams-1];
4459 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4460 // avoids corrupting AVStreams mapped to an earlier tkhd.
4462 return AVERROR_INVALIDDATA;
4464 version = avio_r8(pb);
4465 flags = avio_rb24(pb);
4466 st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
4472 avio_rb32(pb); /* creation time */
4473 avio_rb32(pb); /* modification time */
4475 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4476 avio_rb32(pb); /* reserved */
4478 /* highlevel (considering edits) duration in movie timebase */
4479 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4480 avio_rb32(pb); /* reserved */
4481 avio_rb32(pb); /* reserved */
4483 avio_rb16(pb); /* layer */
4484 avio_rb16(pb); /* alternate group */
4485 avio_rb16(pb); /* volume */
4486 avio_rb16(pb); /* reserved */
4488 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4489 // they're kept in fixed point format through all calculations
4490 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4491 // side data, but the scale factor is not needed to calculate aspect ratio
4492 for (i = 0; i < 3; i++) {
4493 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
4494 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
4495 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
4498 width = avio_rb32(pb); // 16.16 fixed point track width
4499 height = avio_rb32(pb); // 16.16 fixed point track height
4500 sc->width = width >> 16;
4501 sc->height = height >> 16;
4503 // apply the moov display matrix (after the tkhd one)
4504 for (i = 0; i < 3; i++) {
4505 const int sh[3] = { 16, 16, 30 };
4506 for (j = 0; j < 3; j++) {
4507 for (e = 0; e < 3; e++) {
4508 res_display_matrix[i][j] +=
4509 ((int64_t) display_matrix[i][e] *
4510 c->movie_display_matrix[e][j]) >> sh[e];
4515 // save the matrix when it is not the default identity
4516 if (!IS_MATRIX_IDENT(res_display_matrix)) {
4519 av_freep(&sc->display_matrix);
4520 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4521 if (!sc->display_matrix)
4522 return AVERROR(ENOMEM);
4524 for (i = 0; i < 3; i++)
4525 for (j = 0; j < 3; j++)
4526 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4528 #if FF_API_OLD_ROTATE_API
4529 rotate = av_display_rotation_get(sc->display_matrix);
4530 if (!isnan(rotate)) {
4531 char rotate_buf[64];
4533 if (rotate < 0) // for backward compatibility
4535 snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate);
4536 av_dict_set(&st->metadata, "rotate", rotate_buf, 0);
4541 // transform the display width/height according to the matrix
4542 // to keep the same scale, use [width height 1<<16]
4543 if (width && height && sc->display_matrix) {
4544 double disp_transform[2];
4546 for (i = 0; i < 2; i++)
4547 disp_transform[i] = hypot(sc->display_matrix[0 + i],
4548 sc->display_matrix[3 + i]);
4550 if (disp_transform[0] > 0 && disp_transform[1] > 0 &&
4551 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4552 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4553 st->sample_aspect_ratio = av_d2q(
4554 disp_transform[0] / disp_transform[1],
4560 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4562 MOVFragment *frag = &c->fragment;
4563 MOVTrackExt *trex = NULL;
4564 int flags, track_id, i;
4566 avio_r8(pb); /* version */
4567 flags = avio_rb24(pb);
4569 track_id = avio_rb32(pb);
4571 return AVERROR_INVALIDDATA;
4572 for (i = 0; i < c->trex_count; i++)
4573 if (c->trex_data[i].track_id == track_id) {
4574 trex = &c->trex_data[i];
4578 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4581 c->fragment.found_tfhd = 1;
4582 frag->track_id = track_id;
4583 set_frag_stream(&c->frag_index, track_id);
4585 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4586 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4587 frag->moof_offset : frag->implicit_offset;
4588 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4590 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4591 avio_rb32(pb) : trex->duration;
4592 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4593 avio_rb32(pb) : trex->size;
4594 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4595 avio_rb32(pb) : trex->flags;
4596 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4601 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4606 num = atom.size / 4;
4607 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4608 return AVERROR(ENOMEM);
4610 av_free(c->chapter_tracks);
4611 c->chapter_tracks = new_tracks;
4612 c->nb_chapter_tracks = num;
4614 for (i = 0; i < num && !pb->eof_reached; i++)
4615 c->chapter_tracks[i] = avio_rb32(pb);
4620 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4625 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4626 return AVERROR_INVALIDDATA;
4627 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4628 sizeof(*c->trex_data))) < 0) {
4633 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4635 trex = &c->trex_data[c->trex_count++];
4636 avio_r8(pb); /* version */
4637 avio_rb24(pb); /* flags */
4638 trex->track_id = avio_rb32(pb);
4639 trex->stsd_id = avio_rb32(pb);
4640 trex->duration = avio_rb32(pb);
4641 trex->size = avio_rb32(pb);
4642 trex->flags = avio_rb32(pb);
4646 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4648 MOVFragment *frag = &c->fragment;
4649 AVStream *st = NULL;
4650 MOVStreamContext *sc;
4652 MOVFragmentStreamInfo * frag_stream_info;
4653 int64_t base_media_decode_time;
4655 for (i = 0; i < c->fc->nb_streams; i++) {
4656 if (c->fc->streams[i]->id == frag->track_id) {
4657 st = c->fc->streams[i];
4662 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4666 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4668 version = avio_r8(pb);
4669 avio_rb24(pb); /* flags */
4671 base_media_decode_time = avio_rb64(pb);
4673 base_media_decode_time = avio_rb32(pb);
4676 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4677 if (frag_stream_info)
4678 frag_stream_info->tfdt_dts = base_media_decode_time;
4679 sc->track_end = base_media_decode_time;
4684 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4686 MOVFragment *frag = &c->fragment;
4687 AVStream *st = NULL;
4688 MOVStreamContext *sc;
4691 int64_t dts, pts = AV_NOPTS_VALUE;
4692 int data_offset = 0;
4693 unsigned entries, first_sample_flags = frag->flags;
4694 int flags, distance, i;
4695 int64_t prev_dts = AV_NOPTS_VALUE;
4696 int next_frag_index = -1, index_entry_pos;
4697 size_t requested_size;
4698 size_t old_ctts_allocated_size;
4699 AVIndexEntry *new_entries;
4700 MOVFragmentStreamInfo * frag_stream_info;
4702 if (!frag->found_tfhd) {
4703 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4704 return AVERROR_INVALIDDATA;
4707 for (i = 0; i < c->fc->nb_streams; i++) {
4708 if (c->fc->streams[i]->id == frag->track_id) {
4709 st = c->fc->streams[i];
4714 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4718 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4721 // Find the next frag_index index that has a valid index_entry for
4722 // the current track_id.
4724 // A valid index_entry means the trun for the fragment was read
4725 // and it's samples are in index_entries at the given position.
4726 // New index entries will be inserted before the index_entry found.
4727 index_entry_pos = st->nb_index_entries;
4728 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4729 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4730 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4731 next_frag_index = i;
4732 index_entry_pos = frag_stream_info->index_entry;
4736 av_assert0(index_entry_pos <= st->nb_index_entries);
4738 avio_r8(pb); /* version */
4739 flags = avio_rb24(pb);
4740 entries = avio_rb32(pb);
4741 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4743 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4744 return AVERROR_INVALIDDATA;
4745 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4746 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4748 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4749 if (frag_stream_info)
4751 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4752 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4753 pts = frag_stream_info->first_tfra_pts;
4754 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4755 ", using it for pts\n", pts);
4756 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4757 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4758 // pts = frag_stream_info->sidx_pts;
4759 dts = frag_stream_info->sidx_pts - sc->time_offset;
4760 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4761 ", using it for pts\n", pts);
4762 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4763 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4764 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4765 ", using it for dts\n", dts);
4767 dts = sc->track_end - sc->time_offset;
4768 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4769 ", using it for dts\n", dts);
4772 dts = sc->track_end - sc->time_offset;
4773 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4774 ", using it for dts\n", dts);
4776 offset = frag->base_data_offset + data_offset;
4778 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4780 // realloc space for new index entries
4781 if((uint64_t)st->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4782 entries = UINT_MAX / sizeof(AVIndexEntry) - st->nb_index_entries;
4783 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4788 requested_size = (st->nb_index_entries + entries) * sizeof(AVIndexEntry);
4789 new_entries = av_fast_realloc(st->index_entries,
4790 &st->index_entries_allocated_size,
4793 return AVERROR(ENOMEM);
4794 st->index_entries= new_entries;
4796 requested_size = (st->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4797 old_ctts_allocated_size = sc->ctts_allocated_size;
4798 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4801 return AVERROR(ENOMEM);
4802 sc->ctts_data = ctts_data;
4804 // In case there were samples without ctts entries, ensure they get
4805 // zero valued entries. This ensures clips which mix boxes with and
4806 // without ctts entries don't pickup uninitialized data.
4807 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4808 sc->ctts_allocated_size - old_ctts_allocated_size);
4810 if (index_entry_pos < st->nb_index_entries) {
4811 // Make hole in index_entries and ctts_data for new samples
4812 memmove(st->index_entries + index_entry_pos + entries,
4813 st->index_entries + index_entry_pos,
4814 sizeof(*st->index_entries) *
4815 (st->nb_index_entries - index_entry_pos));
4816 memmove(sc->ctts_data + index_entry_pos + entries,
4817 sc->ctts_data + index_entry_pos,
4818 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4819 if (index_entry_pos < sc->current_sample) {
4820 sc->current_sample += entries;
4824 st->nb_index_entries += entries;
4825 sc->ctts_count = st->nb_index_entries;
4827 // Record the index_entry position in frag_index of this fragment
4828 if (frag_stream_info)
4829 frag_stream_info->index_entry = index_entry_pos;
4831 if (index_entry_pos > 0)
4832 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4834 for (i = 0; i < entries && !pb->eof_reached; i++) {
4835 unsigned sample_size = frag->size;
4836 int sample_flags = i ? frag->flags : first_sample_flags;
4837 unsigned sample_duration = frag->duration;
4838 unsigned ctts_duration = 0;
4840 int index_entry_flags = 0;
4842 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4843 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4844 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4845 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4847 mov_update_dts_shift(sc, ctts_duration);
4848 if (pts != AV_NOPTS_VALUE) {
4849 dts = pts - sc->dts_shift;
4850 if (flags & MOV_TRUN_SAMPLE_CTS) {
4851 dts -= ctts_duration;
4853 dts -= sc->time_offset;
4855 av_log(c->fc, AV_LOG_DEBUG,
4856 "pts %"PRId64" calculated dts %"PRId64
4857 " sc->dts_shift %d ctts.duration %d"
4858 " sc->time_offset %"PRId64
4859 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4861 sc->dts_shift, ctts_duration,
4862 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4863 pts = AV_NOPTS_VALUE;
4866 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4870 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4871 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4874 index_entry_flags |= AVINDEX_KEYFRAME;
4876 // Fragments can overlap in time. Discard overlapping frames after
4878 if (prev_dts >= dts)
4879 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4881 st->index_entries[index_entry_pos].pos = offset;
4882 st->index_entries[index_entry_pos].timestamp = dts;
4883 st->index_entries[index_entry_pos].size= sample_size;
4884 st->index_entries[index_entry_pos].min_distance= distance;
4885 st->index_entries[index_entry_pos].flags = index_entry_flags;
4887 sc->ctts_data[index_entry_pos].count = 1;
4888 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4891 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4892 "size %u, distance %d, keyframe %d\n", st->index,
4893 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4895 dts += sample_duration;
4896 offset += sample_size;
4897 sc->data_size += sample_size;
4899 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4900 1 <= INT_MAX - sc->nb_frames_for_fps
4902 sc->duration_for_fps += sample_duration;
4903 sc->nb_frames_for_fps ++;
4907 // EOF found before reading all entries. Fix the hole this would
4908 // leave in index_entries and ctts_data
4909 int gap = entries - i;
4910 memmove(st->index_entries + index_entry_pos,
4911 st->index_entries + index_entry_pos + gap,
4912 sizeof(*st->index_entries) *
4913 (st->nb_index_entries - (index_entry_pos + gap)));
4914 memmove(sc->ctts_data + index_entry_pos,
4915 sc->ctts_data + index_entry_pos + gap,
4916 sizeof(*sc->ctts_data) *
4917 (sc->ctts_count - (index_entry_pos + gap)));
4919 st->nb_index_entries -= gap;
4920 sc->ctts_count -= gap;
4921 if (index_entry_pos < sc->current_sample) {
4922 sc->current_sample -= gap;
4927 // The end of this new fragment may overlap in time with the start
4928 // of the next fragment in index_entries. Mark the samples in the next
4929 // fragment that overlap with AVINDEX_DISCARD_FRAME
4930 prev_dts = AV_NOPTS_VALUE;
4931 if (index_entry_pos > 0)
4932 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4933 for (i = index_entry_pos; i < st->nb_index_entries; i++) {
4934 if (prev_dts < st->index_entries[i].timestamp)
4936 st->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
4939 // If a hole was created to insert the new index_entries into,
4940 // the index_entry recorded for all subsequent moof must
4941 // be incremented by the number of entries inserted.
4942 fix_frag_index_entries(&c->frag_index, next_frag_index,
4943 frag->track_id, entries);
4945 if (pb->eof_reached) {
4946 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
4950 frag->implicit_offset = offset;
4952 sc->track_end = dts + sc->time_offset;
4953 if (st->duration < sc->track_end)
4954 st->duration = sc->track_end;
4959 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4961 int64_t offset = avio_tell(pb) + atom.size, pts, timestamp;
4963 unsigned i, j, track_id, item_count;
4964 AVStream *st = NULL;
4965 AVStream *ref_st = NULL;
4966 MOVStreamContext *sc, *ref_sc = NULL;
4967 AVRational timescale;
4969 version = avio_r8(pb);
4971 avpriv_request_sample(c->fc, "sidx version %u", version);
4975 avio_rb24(pb); // flags
4977 track_id = avio_rb32(pb); // Reference ID
4978 for (i = 0; i < c->fc->nb_streams; i++) {
4979 if (c->fc->streams[i]->id == track_id) {
4980 st = c->fc->streams[i];
4985 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
4991 timescale = av_make_q(1, avio_rb32(pb));
4993 if (timescale.den <= 0) {
4994 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
4995 return AVERROR_INVALIDDATA;
4999 pts = avio_rb32(pb);
5000 offset += avio_rb32(pb);
5002 pts = avio_rb64(pb);
5003 offset += avio_rb64(pb);
5006 avio_rb16(pb); // reserved
5008 item_count = avio_rb16(pb);
5010 for (i = 0; i < item_count; i++) {
5012 MOVFragmentStreamInfo * frag_stream_info;
5013 uint32_t size = avio_rb32(pb);
5014 uint32_t duration = avio_rb32(pb);
5015 if (size & 0x80000000) {
5016 avpriv_request_sample(c->fc, "sidx reference_type 1");
5017 return AVERROR_PATCHWELCOME;
5019 avio_rb32(pb); // sap_flags
5020 timestamp = av_rescale_q(pts, st->time_base, timescale);
5022 index = update_frag_index(c, offset);
5023 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5024 if (frag_stream_info)
5025 frag_stream_info->sidx_pts = timestamp;
5031 st->duration = sc->track_end = pts;
5035 if (offset == avio_size(pb)) {
5036 // Find first entry in fragment index that came from an sidx.
5037 // This will pretty much always be the first entry.
5038 for (i = 0; i < c->frag_index.nb_items; i++) {
5039 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5040 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5041 MOVFragmentStreamInfo * si;
5042 si = &item->stream_info[j];
5043 if (si->sidx_pts != AV_NOPTS_VALUE) {
5044 ref_st = c->fc->streams[j];
5045 ref_sc = ref_st->priv_data;
5050 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5051 st = c->fc->streams[i];
5053 if (!sc->has_sidx) {
5054 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5058 c->frag_index.complete = 1;
5064 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5065 /* like the files created with Adobe Premiere 5.0, for samples see */
5066 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5067 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5072 return 0; /* continue */
5073 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5074 avio_skip(pb, atom.size - 4);
5077 atom.type = avio_rl32(pb);
5079 if (atom.type != MKTAG('m','d','a','t')) {
5080 avio_skip(pb, atom.size);
5083 err = mov_read_mdat(c, pb, atom);
5087 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5092 uint8_t *moov_data; /* uncompressed data */
5093 long cmov_len, moov_len;
5096 avio_rb32(pb); /* dcom atom */
5097 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5098 return AVERROR_INVALIDDATA;
5099 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5100 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5101 return AVERROR_INVALIDDATA;
5103 avio_rb32(pb); /* cmvd atom */
5104 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5105 return AVERROR_INVALIDDATA;
5106 moov_len = avio_rb32(pb); /* uncompressed size */
5107 cmov_len = atom.size - 6 * 4;
5109 cmov_data = av_malloc(cmov_len);
5111 return AVERROR(ENOMEM);
5112 moov_data = av_malloc(moov_len);
5115 return AVERROR(ENOMEM);
5117 ret = ffio_read_size(pb, cmov_data, cmov_len);
5119 goto free_and_return;
5121 ret = AVERROR_INVALIDDATA;
5122 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5123 goto free_and_return;
5124 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5125 goto free_and_return;
5126 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5127 atom.type = MKTAG('m','o','o','v');
5128 atom.size = moov_len;
5129 ret = mov_read_default(c, &ctx, atom);
5135 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5136 return AVERROR(ENOSYS);
5140 /* edit list atom */
5141 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5143 MOVStreamContext *sc;
5144 int i, edit_count, version;
5145 int64_t elst_entry_size;
5147 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5149 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5151 version = avio_r8(pb); /* version */
5152 avio_rb24(pb); /* flags */
5153 edit_count = avio_rb32(pb); /* entries */
5156 elst_entry_size = version == 1 ? 20 : 12;
5157 if (atom.size != edit_count * elst_entry_size) {
5158 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5159 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5160 edit_count, atom.size + 8);
5161 return AVERROR_INVALIDDATA;
5163 edit_count = atom.size / elst_entry_size;
5164 if (edit_count * elst_entry_size != atom.size) {
5165 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.", atom.size, edit_count);
5173 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5174 av_free(sc->elst_data);
5176 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5178 return AVERROR(ENOMEM);
5180 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5181 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5182 MOVElst *e = &sc->elst_data[i];
5185 e->duration = avio_rb64(pb);
5186 e->time = avio_rb64(pb);
5189 e->duration = avio_rb32(pb); /* segment duration */
5190 e->time = (int32_t)avio_rb32(pb); /* media time */
5193 e->rate = avio_rb32(pb) / 65536.0;
5195 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5196 e->duration, e->time, e->rate);
5198 if (e->time < 0 && e->time != -1 &&
5199 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5200 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5201 c->fc->nb_streams-1, i, e->time);
5202 return AVERROR_INVALIDDATA;
5210 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5212 MOVStreamContext *sc;
5214 if (c->fc->nb_streams < 1)
5215 return AVERROR_INVALIDDATA;
5216 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5217 sc->timecode_track = avio_rb32(pb);
5221 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5226 if (c->fc->nb_streams < 1)
5228 st = c->fc->streams[c->fc->nb_streams - 1];
5230 if (atom.size < 4) {
5231 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5232 return AVERROR_INVALIDDATA;
5235 /* For now, propagate only the OBUs, if any. Once libavcodec is
5236 updated to handle isobmff style extradata this can be removed. */
5242 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5249 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5252 int version, color_range, color_primaries, color_trc, color_space;
5254 if (c->fc->nb_streams < 1)
5256 st = c->fc->streams[c->fc->nb_streams - 1];
5258 if (atom.size < 5) {
5259 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5260 return AVERROR_INVALIDDATA;
5263 version = avio_r8(pb);
5265 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5268 avio_skip(pb, 3); /* flags */
5270 avio_skip(pb, 2); /* profile + level */
5271 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5272 color_primaries = avio_r8(pb);
5273 color_trc = avio_r8(pb);
5274 color_space = avio_r8(pb);
5275 if (avio_rb16(pb)) /* codecIntializationDataSize */
5276 return AVERROR_INVALIDDATA;
5278 if (!av_color_primaries_name(color_primaries))
5279 color_primaries = AVCOL_PRI_UNSPECIFIED;
5280 if (!av_color_transfer_name(color_trc))
5281 color_trc = AVCOL_TRC_UNSPECIFIED;
5282 if (!av_color_space_name(color_space))
5283 color_space = AVCOL_SPC_UNSPECIFIED;
5285 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5286 st->codecpar->color_primaries = color_primaries;
5287 st->codecpar->color_trc = color_trc;
5288 st->codecpar->color_space = color_space;
5293 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5295 MOVStreamContext *sc;
5298 if (c->fc->nb_streams < 1)
5299 return AVERROR_INVALIDDATA;
5301 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5303 if (atom.size < 5) {
5304 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5305 return AVERROR_INVALIDDATA;
5308 version = avio_r8(pb);
5310 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5313 avio_skip(pb, 3); /* flags */
5315 sc->mastering = av_mastering_display_metadata_alloc();
5317 return AVERROR(ENOMEM);
5319 for (i = 0; i < 3; i++) {
5320 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5321 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5323 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5324 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5326 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5327 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5329 sc->mastering->has_primaries = 1;
5330 sc->mastering->has_luminance = 1;
5335 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5337 MOVStreamContext *sc;
5338 const int mapping[3] = {1, 2, 0};
5339 const int chroma_den = 50000;
5340 const int luma_den = 10000;
5343 if (c->fc->nb_streams < 1)
5344 return AVERROR_INVALIDDATA;
5346 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5348 if (atom.size < 24) {
5349 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5350 return AVERROR_INVALIDDATA;
5353 sc->mastering = av_mastering_display_metadata_alloc();
5355 return AVERROR(ENOMEM);
5357 for (i = 0; i < 3; i++) {
5358 const int j = mapping[i];
5359 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5360 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5362 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5363 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5365 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5366 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5368 sc->mastering->has_luminance = 1;
5369 sc->mastering->has_primaries = 1;
5374 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5376 MOVStreamContext *sc;
5379 if (c->fc->nb_streams < 1)
5380 return AVERROR_INVALIDDATA;
5382 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5384 if (atom.size < 5) {
5385 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5386 return AVERROR_INVALIDDATA;
5389 version = avio_r8(pb);
5391 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5394 avio_skip(pb, 3); /* flags */
5396 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5398 return AVERROR(ENOMEM);
5400 sc->coll->MaxCLL = avio_rb16(pb);
5401 sc->coll->MaxFALL = avio_rb16(pb);
5406 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5408 MOVStreamContext *sc;
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 < 4) {
5416 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5417 return AVERROR_INVALIDDATA;
5420 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5422 return AVERROR(ENOMEM);
5424 sc->coll->MaxCLL = avio_rb16(pb);
5425 sc->coll->MaxFALL = avio_rb16(pb);
5430 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5433 MOVStreamContext *sc;
5434 enum AVStereo3DType type;
5437 if (c->fc->nb_streams < 1)
5440 st = c->fc->streams[c->fc->nb_streams - 1];
5443 if (atom.size < 5) {
5444 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5445 return AVERROR_INVALIDDATA;
5447 avio_skip(pb, 4); /* version + flags */
5452 type = AV_STEREO3D_2D;
5455 type = AV_STEREO3D_TOPBOTTOM;
5458 type = AV_STEREO3D_SIDEBYSIDE;
5461 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5465 sc->stereo3d = av_stereo3d_alloc();
5467 return AVERROR(ENOMEM);
5469 sc->stereo3d->type = type;
5473 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5476 MOVStreamContext *sc;
5477 int size, version, layout;
5478 int32_t yaw, pitch, roll;
5479 uint32_t l = 0, t = 0, r = 0, b = 0;
5480 uint32_t tag, padding = 0;
5481 enum AVSphericalProjection projection;
5483 if (c->fc->nb_streams < 1)
5486 st = c->fc->streams[c->fc->nb_streams - 1];
5489 if (atom.size < 8) {
5490 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5491 return AVERROR_INVALIDDATA;
5494 size = avio_rb32(pb);
5495 if (size <= 12 || size > atom.size)
5496 return AVERROR_INVALIDDATA;
5498 tag = avio_rl32(pb);
5499 if (tag != MKTAG('s','v','h','d')) {
5500 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5503 version = avio_r8(pb);
5505 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5509 avio_skip(pb, 3); /* flags */
5510 avio_skip(pb, size - 12); /* metadata_source */
5512 size = avio_rb32(pb);
5513 if (size > atom.size)
5514 return AVERROR_INVALIDDATA;
5516 tag = avio_rl32(pb);
5517 if (tag != MKTAG('p','r','o','j')) {
5518 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5522 size = avio_rb32(pb);
5523 if (size > atom.size)
5524 return AVERROR_INVALIDDATA;
5526 tag = avio_rl32(pb);
5527 if (tag != MKTAG('p','r','h','d')) {
5528 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5531 version = avio_r8(pb);
5533 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5537 avio_skip(pb, 3); /* flags */
5539 /* 16.16 fixed point */
5540 yaw = avio_rb32(pb);
5541 pitch = avio_rb32(pb);
5542 roll = avio_rb32(pb);
5544 size = avio_rb32(pb);
5545 if (size > atom.size)
5546 return AVERROR_INVALIDDATA;
5548 tag = avio_rl32(pb);
5549 version = avio_r8(pb);
5551 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5555 avio_skip(pb, 3); /* flags */
5557 case MKTAG('c','b','m','p'):
5558 layout = avio_rb32(pb);
5560 av_log(c->fc, AV_LOG_WARNING,
5561 "Unsupported cubemap layout %d\n", layout);
5564 projection = AV_SPHERICAL_CUBEMAP;
5565 padding = avio_rb32(pb);
5567 case MKTAG('e','q','u','i'):
5573 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5574 av_log(c->fc, AV_LOG_ERROR,
5575 "Invalid bounding rectangle coordinates "
5576 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5577 return AVERROR_INVALIDDATA;
5580 if (l || t || r || b)
5581 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5583 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5586 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5590 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5592 return AVERROR(ENOMEM);
5594 sc->spherical->projection = projection;
5596 sc->spherical->yaw = yaw;
5597 sc->spherical->pitch = pitch;
5598 sc->spherical->roll = roll;
5600 sc->spherical->padding = padding;
5602 sc->spherical->bound_left = l;
5603 sc->spherical->bound_top = t;
5604 sc->spherical->bound_right = r;
5605 sc->spherical->bound_bottom = b;
5610 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5613 uint8_t *buffer = av_malloc(len + 1);
5617 return AVERROR(ENOMEM);
5620 ret = ffio_read_size(pb, buffer, len);
5624 /* Check for mandatory keys and values, try to support XML as best-effort */
5625 if (!sc->spherical &&
5626 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5627 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5628 av_stristr(val, "true") &&
5629 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5630 av_stristr(val, "true") &&
5631 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5632 av_stristr(val, "equirectangular")) {
5633 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5637 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5639 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5640 enum AVStereo3DType mode;
5642 if (av_stristr(buffer, "left-right"))
5643 mode = AV_STEREO3D_SIDEBYSIDE;
5644 else if (av_stristr(buffer, "top-bottom"))
5645 mode = AV_STEREO3D_TOPBOTTOM;
5647 mode = AV_STEREO3D_2D;
5649 sc->stereo3d = av_stereo3d_alloc();
5653 sc->stereo3d->type = mode;
5657 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5659 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5660 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5662 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5663 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5665 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5673 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5676 MOVStreamContext *sc;
5679 static const uint8_t uuid_isml_manifest[] = {
5680 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5681 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5683 static const uint8_t uuid_xmp[] = {
5684 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5685 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5687 static const uint8_t uuid_spherical[] = {
5688 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5689 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5692 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5693 return AVERROR_INVALIDDATA;
5695 if (c->fc->nb_streams < 1)
5697 st = c->fc->streams[c->fc->nb_streams - 1];
5700 ret = avio_read(pb, uuid, sizeof(uuid));
5703 } else if (ret != sizeof(uuid)) {
5704 return AVERROR_INVALIDDATA;
5706 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5707 uint8_t *buffer, *ptr;
5709 size_t len = atom.size - sizeof(uuid);
5712 return AVERROR_INVALIDDATA;
5714 ret = avio_skip(pb, 4); // zeroes
5717 buffer = av_mallocz(len + 1);
5719 return AVERROR(ENOMEM);
5721 ret = avio_read(pb, buffer, len);
5725 } else if (ret != len) {
5727 return AVERROR_INVALIDDATA;
5731 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5732 ptr += sizeof("systemBitrate=\"") - 1;
5733 c->bitrates_count++;
5734 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5736 c->bitrates_count = 0;
5738 return AVERROR(ENOMEM);
5741 ret = strtol(ptr, &endptr, 10);
5742 if (ret < 0 || errno || *endptr != '"') {
5743 c->bitrates[c->bitrates_count - 1] = 0;
5745 c->bitrates[c->bitrates_count - 1] = ret;
5750 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5752 size_t len = atom.size - sizeof(uuid);
5753 if (c->export_xmp) {
5754 buffer = av_mallocz(len + 1);
5756 return AVERROR(ENOMEM);
5758 ret = avio_read(pb, buffer, len);
5762 } else if (ret != len) {
5764 return AVERROR_INVALIDDATA;
5767 av_dict_set(&c->fc->metadata, "xmp", buffer, 0);
5770 // skip all uuid atom, which makes it fast for long uuid-xmp file
5771 ret = avio_skip(pb, len);
5775 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5776 size_t len = atom.size - sizeof(uuid);
5777 ret = mov_parse_uuid_spherical(sc, pb, len);
5781 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5787 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5790 uint8_t content[16];
5795 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5801 && !memcmp(content, "Anevia\x1A\x1A", 8)
5802 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5803 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5809 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5811 uint32_t format = avio_rl32(pb);
5812 MOVStreamContext *sc;
5816 if (c->fc->nb_streams < 1)
5818 st = c->fc->streams[c->fc->nb_streams - 1];
5823 case MKTAG('e','n','c','v'): // encrypted video
5824 case MKTAG('e','n','c','a'): // encrypted audio
5825 id = mov_codec_id(st, format);
5826 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5827 st->codecpar->codec_id != id) {
5828 av_log(c->fc, AV_LOG_WARNING,
5829 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5830 (char*)&format, st->codecpar->codec_id);
5834 st->codecpar->codec_id = id;
5835 sc->format = format;
5839 if (format != sc->format) {
5840 av_log(c->fc, AV_LOG_WARNING,
5841 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5842 (char*)&format, (char*)&sc->format);
5851 * Gets the current encryption info and associated current stream context. If
5852 * we are parsing a track fragment, this will return the specific encryption
5853 * info for this fragment; otherwise this will return the global encryption
5854 * info for the current stream.
5856 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5858 MOVFragmentStreamInfo *frag_stream_info;
5862 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5863 if (frag_stream_info) {
5864 for (i = 0; i < c->fc->nb_streams; i++) {
5865 if (c->fc->streams[i]->id == frag_stream_info->id) {
5866 st = c->fc->streams[i];
5870 if (i == c->fc->nb_streams)
5872 *sc = st->priv_data;
5874 if (!frag_stream_info->encryption_index) {
5875 // If this stream isn't encrypted, don't create the index.
5876 if (!(*sc)->cenc.default_encrypted_sample)
5878 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5879 if (!frag_stream_info->encryption_index)
5880 return AVERROR(ENOMEM);
5882 *encryption_index = frag_stream_info->encryption_index;
5885 // No current track fragment, using stream level encryption info.
5887 if (c->fc->nb_streams < 1)
5889 st = c->fc->streams[c->fc->nb_streams - 1];
5890 *sc = st->priv_data;
5892 if (!(*sc)->cenc.encryption_index) {
5893 // If this stream isn't encrypted, don't create the index.
5894 if (!(*sc)->cenc.default_encrypted_sample)
5896 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5897 if (!(*sc)->cenc.encryption_index)
5898 return AVERROR(ENOMEM);
5901 *encryption_index = (*sc)->cenc.encryption_index;
5906 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
5909 unsigned int subsample_count;
5910 AVSubsampleEncryptionInfo *subsamples;
5912 if (!sc->cenc.default_encrypted_sample) {
5913 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
5914 return AVERROR_INVALIDDATA;
5917 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
5919 return AVERROR(ENOMEM);
5921 if (sc->cenc.per_sample_iv_size != 0) {
5922 if (avio_read(pb, (*sample)->iv, sc->cenc.per_sample_iv_size) != sc->cenc.per_sample_iv_size) {
5923 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
5924 av_encryption_info_free(*sample);
5926 return AVERROR_INVALIDDATA;
5930 if (use_subsamples) {
5931 subsample_count = avio_rb16(pb);
5932 av_free((*sample)->subsamples);
5933 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
5934 if (!(*sample)->subsamples) {
5935 av_encryption_info_free(*sample);
5937 return AVERROR(ENOMEM);
5940 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
5941 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
5942 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
5945 if (pb->eof_reached) {
5946 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
5947 av_encryption_info_free(*sample);
5949 return AVERROR_INVALIDDATA;
5951 (*sample)->subsample_count = subsample_count;
5957 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5959 AVEncryptionInfo **encrypted_samples;
5960 MOVEncryptionIndex *encryption_index;
5961 MOVStreamContext *sc;
5962 int use_subsamples, ret;
5963 unsigned int sample_count, i, alloc_size = 0;
5965 ret = get_current_encryption_info(c, &encryption_index, &sc);
5969 if (encryption_index->nb_encrypted_samples) {
5970 // This can happen if we have both saio/saiz and senc atoms.
5971 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
5975 avio_r8(pb); /* version */
5976 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
5978 sample_count = avio_rb32(pb);
5979 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
5980 return AVERROR(ENOMEM);
5982 for (i = 0; i < sample_count; i++) {
5983 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
5984 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
5985 min_samples * sizeof(*encrypted_samples));
5986 if (encrypted_samples) {
5987 encryption_index->encrypted_samples = encrypted_samples;
5989 ret = mov_read_sample_encryption_info(
5990 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
5992 ret = AVERROR(ENOMEM);
5994 if (pb->eof_reached) {
5995 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
5996 ret = AVERROR_INVALIDDATA;
6001 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6002 av_freep(&encryption_index->encrypted_samples);
6006 encryption_index->nb_encrypted_samples = sample_count;
6011 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6013 AVEncryptionInfo **sample, **encrypted_samples;
6015 size_t sample_count, sample_info_size, i;
6017 unsigned int alloc_size = 0;
6019 if (encryption_index->nb_encrypted_samples)
6021 sample_count = encryption_index->auxiliary_info_sample_count;
6022 if (encryption_index->auxiliary_offsets_count != 1) {
6023 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6024 return AVERROR_PATCHWELCOME;
6026 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6027 return AVERROR(ENOMEM);
6029 prev_pos = avio_tell(pb);
6030 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6031 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6032 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6036 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6037 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6038 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6039 min_samples * sizeof(*encrypted_samples));
6040 if (!encrypted_samples) {
6041 ret = AVERROR(ENOMEM);
6044 encryption_index->encrypted_samples = encrypted_samples;
6046 sample = &encryption_index->encrypted_samples[i];
6047 sample_info_size = encryption_index->auxiliary_info_default_size
6048 ? encryption_index->auxiliary_info_default_size
6049 : encryption_index->auxiliary_info_sizes[i];
6051 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6055 if (pb->eof_reached) {
6056 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6057 ret = AVERROR_INVALIDDATA;
6059 encryption_index->nb_encrypted_samples = sample_count;
6063 avio_seek(pb, prev_pos, SEEK_SET);
6065 for (; i > 0; i--) {
6066 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6068 av_freep(&encryption_index->encrypted_samples);
6074 * Tries to read the given number of bytes from the stream and puts it in a
6075 * newly allocated buffer. This reads in small chunks to avoid allocating large
6076 * memory if the file contains an invalid/malicious size value.
6078 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6080 const unsigned int block_size = 1024 * 1024;
6081 uint8_t *buffer = NULL;
6082 unsigned int alloc_size = 0, offset = 0;
6083 while (offset < size) {
6084 unsigned int new_size =
6085 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6086 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6087 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6090 return AVERROR(ENOMEM);
6092 buffer = new_buffer;
6094 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6096 return AVERROR_INVALIDDATA;
6105 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6107 MOVEncryptionIndex *encryption_index;
6108 MOVStreamContext *sc;
6110 unsigned int sample_count, aux_info_type, aux_info_param;
6112 ret = get_current_encryption_info(c, &encryption_index, &sc);
6116 if (encryption_index->nb_encrypted_samples) {
6117 // This can happen if we have both saio/saiz and senc atoms.
6118 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6122 if (encryption_index->auxiliary_info_sample_count) {
6123 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6124 return AVERROR_INVALIDDATA;
6127 avio_r8(pb); /* version */
6128 if (avio_rb24(pb) & 0x01) { /* flags */
6129 aux_info_type = avio_rb32(pb);
6130 aux_info_param = avio_rb32(pb);
6131 if (sc->cenc.default_encrypted_sample) {
6132 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6133 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6136 if (aux_info_param != 0) {
6137 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6141 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6142 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6143 aux_info_type == MKBETAG('c','e','n','s') ||
6144 aux_info_type == MKBETAG('c','b','c','1') ||
6145 aux_info_type == MKBETAG('c','b','c','s')) &&
6146 aux_info_param == 0) {
6147 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6148 return AVERROR_INVALIDDATA;
6153 } else if (!sc->cenc.default_encrypted_sample) {
6154 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6158 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6159 sample_count = avio_rb32(pb);
6160 encryption_index->auxiliary_info_sample_count = sample_count;
6162 if (encryption_index->auxiliary_info_default_size == 0) {
6163 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6165 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6170 if (encryption_index->auxiliary_offsets_count) {
6171 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6177 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6179 uint64_t *auxiliary_offsets;
6180 MOVEncryptionIndex *encryption_index;
6181 MOVStreamContext *sc;
6183 unsigned int version, entry_count, aux_info_type, aux_info_param;
6184 unsigned int alloc_size = 0;
6186 ret = get_current_encryption_info(c, &encryption_index, &sc);
6190 if (encryption_index->nb_encrypted_samples) {
6191 // This can happen if we have both saio/saiz and senc atoms.
6192 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6196 if (encryption_index->auxiliary_offsets_count) {
6197 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6198 return AVERROR_INVALIDDATA;
6201 version = avio_r8(pb); /* version */
6202 if (avio_rb24(pb) & 0x01) { /* flags */
6203 aux_info_type = avio_rb32(pb);
6204 aux_info_param = avio_rb32(pb);
6205 if (sc->cenc.default_encrypted_sample) {
6206 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6207 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6210 if (aux_info_param != 0) {
6211 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6215 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6216 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6217 aux_info_type == MKBETAG('c','e','n','s') ||
6218 aux_info_type == MKBETAG('c','b','c','1') ||
6219 aux_info_type == MKBETAG('c','b','c','s')) &&
6220 aux_info_param == 0) {
6221 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6222 return AVERROR_INVALIDDATA;
6227 } else if (!sc->cenc.default_encrypted_sample) {
6228 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6232 entry_count = avio_rb32(pb);
6233 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6234 return AVERROR(ENOMEM);
6236 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6237 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6238 auxiliary_offsets = av_fast_realloc(
6239 encryption_index->auxiliary_offsets, &alloc_size,
6240 min_offsets * sizeof(*auxiliary_offsets));
6241 if (!auxiliary_offsets) {
6242 av_freep(&encryption_index->auxiliary_offsets);
6243 return AVERROR(ENOMEM);
6245 encryption_index->auxiliary_offsets = auxiliary_offsets;
6248 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6250 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6252 if (c->frag_index.current >= 0) {
6253 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6257 if (pb->eof_reached) {
6258 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6259 av_freep(&encryption_index->auxiliary_offsets);
6260 return AVERROR_INVALIDDATA;
6263 encryption_index->auxiliary_offsets_count = entry_count;
6265 if (encryption_index->auxiliary_info_sample_count) {
6266 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6272 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6274 AVEncryptionInitInfo *info, *old_init_info;
6277 uint8_t *side_data, *extra_data, *old_side_data;
6278 size_t side_data_size;
6279 int ret = 0, old_side_data_size;
6280 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6282 if (c->fc->nb_streams < 1)
6284 st = c->fc->streams[c->fc->nb_streams-1];
6286 version = avio_r8(pb); /* version */
6287 avio_rb24(pb); /* flags */
6289 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6290 /* key_id_size */ 16, /* data_size */ 0);
6292 return AVERROR(ENOMEM);
6294 if (avio_read(pb, info->system_id, 16) != 16) {
6295 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6296 ret = AVERROR_INVALIDDATA;
6301 kid_count = avio_rb32(pb);
6302 if (kid_count >= INT_MAX / sizeof(*key_ids))
6303 return AVERROR(ENOMEM);
6305 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6306 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6307 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6308 min_kid_count * sizeof(*key_ids));
6310 ret = AVERROR(ENOMEM);
6313 info->key_ids = key_ids;
6315 info->key_ids[i] = av_mallocz(16);
6316 if (!info->key_ids[i]) {
6317 ret = AVERROR(ENOMEM);
6320 info->num_key_ids = i + 1;
6322 if (avio_read(pb, info->key_ids[i], 16) != 16) {
6323 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6324 ret = AVERROR_INVALIDDATA;
6329 if (pb->eof_reached) {
6330 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6331 ret = AVERROR_INVALIDDATA;
6336 extra_data_size = avio_rb32(pb);
6337 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6341 av_freep(&info->data); // malloc(0) may still allocate something.
6342 info->data = extra_data;
6343 info->data_size = extra_data_size;
6345 // If there is existing initialization data, append to the list.
6346 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6347 if (old_side_data) {
6348 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6349 if (old_init_info) {
6350 // Append to the end of the list.
6351 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6357 info = old_init_info;
6359 // Assume existing side-data will be valid, so the only error we could get is OOM.
6360 ret = AVERROR(ENOMEM);
6365 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6367 ret = AVERROR(ENOMEM);
6370 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6371 side_data, side_data_size);
6376 av_encryption_init_info_free(info);
6380 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6383 MOVStreamContext *sc;
6385 if (c->fc->nb_streams < 1)
6387 st = c->fc->streams[c->fc->nb_streams-1];
6390 if (sc->pseudo_stream_id != 0) {
6391 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6392 return AVERROR_PATCHWELCOME;
6396 return AVERROR_INVALIDDATA;
6398 avio_rb32(pb); /* version and flags */
6400 if (!sc->cenc.default_encrypted_sample) {
6401 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6402 if (!sc->cenc.default_encrypted_sample) {
6403 return AVERROR(ENOMEM);
6407 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6411 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6414 MOVStreamContext *sc;
6415 unsigned int version, pattern, is_protected, iv_size;
6417 if (c->fc->nb_streams < 1)
6419 st = c->fc->streams[c->fc->nb_streams-1];
6422 if (sc->pseudo_stream_id != 0) {
6423 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6424 return AVERROR_PATCHWELCOME;
6427 if (!sc->cenc.default_encrypted_sample) {
6428 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6429 if (!sc->cenc.default_encrypted_sample) {
6430 return AVERROR(ENOMEM);
6435 return AVERROR_INVALIDDATA;
6437 version = avio_r8(pb); /* version */
6438 avio_rb24(pb); /* flags */
6440 avio_r8(pb); /* reserved */
6441 pattern = avio_r8(pb);
6444 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6445 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6448 is_protected = avio_r8(pb);
6449 if (is_protected && !sc->cenc.encryption_index) {
6450 // The whole stream should be by-default encrypted.
6451 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6452 if (!sc->cenc.encryption_index)
6453 return AVERROR(ENOMEM);
6455 sc->cenc.per_sample_iv_size = avio_r8(pb);
6456 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6457 sc->cenc.per_sample_iv_size != 16) {
6458 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6459 return AVERROR_INVALIDDATA;
6461 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6462 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6463 return AVERROR_INVALIDDATA;
6466 if (is_protected && !sc->cenc.per_sample_iv_size) {
6467 iv_size = avio_r8(pb);
6468 if (iv_size != 8 && iv_size != 16) {
6469 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6470 return AVERROR_INVALIDDATA;
6473 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6474 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6475 return AVERROR_INVALIDDATA;
6482 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6485 int last, type, size, ret;
6488 if (c->fc->nb_streams < 1)
6490 st = c->fc->streams[c->fc->nb_streams-1];
6492 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6493 return AVERROR_INVALIDDATA;
6495 /* Check FlacSpecificBox version. */
6496 if (avio_r8(pb) != 0)
6497 return AVERROR_INVALIDDATA;
6499 avio_rb24(pb); /* Flags */
6501 avio_read(pb, buf, sizeof(buf));
6502 flac_parse_block_header(buf, &last, &type, &size);
6504 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6505 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6506 return AVERROR_INVALIDDATA;
6509 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6514 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6519 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6523 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6524 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6525 return AVERROR_PATCHWELCOME;
6528 if (!sc->cenc.aes_ctr) {
6529 /* initialize the cipher */
6530 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6531 if (!sc->cenc.aes_ctr) {
6532 return AVERROR(ENOMEM);
6535 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6541 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6543 if (!sample->subsample_count)
6545 /* decrypt the whole packet */
6546 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6550 for (i = 0; i < sample->subsample_count; i++)
6552 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6553 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6554 return AVERROR_INVALIDDATA;
6557 /* skip the clear bytes */
6558 input += sample->subsamples[i].bytes_of_clear_data;
6559 size -= sample->subsamples[i].bytes_of_clear_data;
6561 /* decrypt the encrypted bytes */
6562 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6563 input += sample->subsamples[i].bytes_of_protected_data;
6564 size -= sample->subsamples[i].bytes_of_protected_data;
6568 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6569 return AVERROR_INVALIDDATA;
6575 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6577 MOVFragmentStreamInfo *frag_stream_info;
6578 MOVEncryptionIndex *encryption_index;
6579 AVEncryptionInfo *encrypted_sample;
6580 int encrypted_index, ret;
6582 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6583 encrypted_index = current_index;
6584 encryption_index = NULL;
6585 if (frag_stream_info) {
6586 // Note this only supports encryption info in the first sample descriptor.
6587 if (mov->fragment.stsd_id == 1) {
6588 if (frag_stream_info->encryption_index) {
6589 encrypted_index = current_index - frag_stream_info->index_entry;
6590 encryption_index = frag_stream_info->encryption_index;
6592 encryption_index = sc->cenc.encryption_index;
6596 encryption_index = sc->cenc.encryption_index;
6599 if (encryption_index) {
6600 if (encryption_index->auxiliary_info_sample_count &&
6601 !encryption_index->nb_encrypted_samples) {
6602 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6603 return AVERROR_INVALIDDATA;
6605 if (encryption_index->auxiliary_offsets_count &&
6606 !encryption_index->nb_encrypted_samples) {
6607 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6608 return AVERROR_INVALIDDATA;
6611 if (!encryption_index->nb_encrypted_samples) {
6612 // Full-sample encryption with default settings.
6613 encrypted_sample = sc->cenc.default_encrypted_sample;
6614 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6615 // Per-sample setting override.
6616 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6618 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6619 return AVERROR_INVALIDDATA;
6622 if (mov->decryption_key) {
6623 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6626 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6628 return AVERROR(ENOMEM);
6629 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6639 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6641 const int OPUS_SEEK_PREROLL_MS = 80;
6646 if (c->fc->nb_streams < 1)
6648 st = c->fc->streams[c->fc->nb_streams-1];
6650 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6651 return AVERROR_INVALIDDATA;
6653 /* Check OpusSpecificBox version. */
6654 if (avio_r8(pb) != 0) {
6655 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6656 return AVERROR_INVALIDDATA;
6659 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6660 size = atom.size + 8;
6662 if (ff_alloc_extradata(st->codecpar, size))
6663 return AVERROR(ENOMEM);
6665 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6666 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6667 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6668 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6670 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6671 little-endian; aside from the preceeding magic and version they're
6672 otherwise currently identical. Data after output gain at offset 16
6673 doesn't need to be bytewapped. */
6674 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6675 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6676 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6677 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6679 st->codecpar->initial_padding = pre_skip;
6680 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6681 (AVRational){1, 1000},
6682 (AVRational){1, 48000});
6687 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6690 unsigned format_info;
6691 int channel_assignment, channel_assignment1, channel_assignment2;
6694 if (c->fc->nb_streams < 1)
6696 st = c->fc->streams[c->fc->nb_streams-1];
6699 return AVERROR_INVALIDDATA;
6701 format_info = avio_rb32(pb);
6703 ratebits = (format_info >> 28) & 0xF;
6704 channel_assignment1 = (format_info >> 15) & 0x1F;
6705 channel_assignment2 = format_info & 0x1FFF;
6706 if (channel_assignment2)
6707 channel_assignment = channel_assignment2;
6709 channel_assignment = channel_assignment1;
6711 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6712 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6713 st->codecpar->channels = truehd_channels(channel_assignment);
6714 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6719 static const MOVParseTableEntry mov_default_parse_table[] = {
6720 { MKTAG('A','C','L','R'), mov_read_aclr },
6721 { MKTAG('A','P','R','G'), mov_read_avid },
6722 { MKTAG('A','A','L','P'), mov_read_avid },
6723 { MKTAG('A','R','E','S'), mov_read_ares },
6724 { MKTAG('a','v','s','s'), mov_read_avss },
6725 { MKTAG('a','v','1','C'), mov_read_av1c },
6726 { MKTAG('c','h','p','l'), mov_read_chpl },
6727 { MKTAG('c','o','6','4'), mov_read_stco },
6728 { MKTAG('c','o','l','r'), mov_read_colr },
6729 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6730 { MKTAG('d','i','n','f'), mov_read_default },
6731 { MKTAG('D','p','x','E'), mov_read_dpxe },
6732 { MKTAG('d','r','e','f'), mov_read_dref },
6733 { MKTAG('e','d','t','s'), mov_read_default },
6734 { MKTAG('e','l','s','t'), mov_read_elst },
6735 { MKTAG('e','n','d','a'), mov_read_enda },
6736 { MKTAG('f','i','e','l'), mov_read_fiel },
6737 { MKTAG('a','d','r','m'), mov_read_adrm },
6738 { MKTAG('f','t','y','p'), mov_read_ftyp },
6739 { MKTAG('g','l','b','l'), mov_read_glbl },
6740 { MKTAG('h','d','l','r'), mov_read_hdlr },
6741 { MKTAG('i','l','s','t'), mov_read_ilst },
6742 { MKTAG('j','p','2','h'), mov_read_jp2h },
6743 { MKTAG('m','d','a','t'), mov_read_mdat },
6744 { MKTAG('m','d','h','d'), mov_read_mdhd },
6745 { MKTAG('m','d','i','a'), mov_read_default },
6746 { MKTAG('m','e','t','a'), mov_read_meta },
6747 { MKTAG('m','i','n','f'), mov_read_default },
6748 { MKTAG('m','o','o','f'), mov_read_moof },
6749 { MKTAG('m','o','o','v'), mov_read_moov },
6750 { MKTAG('m','v','e','x'), mov_read_default },
6751 { MKTAG('m','v','h','d'), mov_read_mvhd },
6752 { MKTAG('S','M','I',' '), mov_read_svq3 },
6753 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6754 { MKTAG('a','v','c','C'), mov_read_glbl },
6755 { MKTAG('p','a','s','p'), mov_read_pasp },
6756 { MKTAG('s','i','d','x'), mov_read_sidx },
6757 { MKTAG('s','t','b','l'), mov_read_default },
6758 { MKTAG('s','t','c','o'), mov_read_stco },
6759 { MKTAG('s','t','p','s'), mov_read_stps },
6760 { MKTAG('s','t','r','f'), mov_read_strf },
6761 { MKTAG('s','t','s','c'), mov_read_stsc },
6762 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6763 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6764 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6765 { MKTAG('s','t','t','s'), mov_read_stts },
6766 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6767 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6768 { MKTAG('t','f','d','t'), mov_read_tfdt },
6769 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6770 { MKTAG('t','r','a','k'), mov_read_trak },
6771 { MKTAG('t','r','a','f'), mov_read_default },
6772 { MKTAG('t','r','e','f'), mov_read_default },
6773 { MKTAG('t','m','c','d'), mov_read_tmcd },
6774 { MKTAG('c','h','a','p'), mov_read_chap },
6775 { MKTAG('t','r','e','x'), mov_read_trex },
6776 { MKTAG('t','r','u','n'), mov_read_trun },
6777 { MKTAG('u','d','t','a'), mov_read_default },
6778 { MKTAG('w','a','v','e'), mov_read_wave },
6779 { MKTAG('e','s','d','s'), mov_read_esds },
6780 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6781 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6782 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6783 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6784 { MKTAG('w','f','e','x'), mov_read_wfex },
6785 { MKTAG('c','m','o','v'), mov_read_cmov },
6786 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6787 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6788 { MKTAG('s','b','g','p'), mov_read_sbgp },
6789 { MKTAG('h','v','c','C'), mov_read_glbl },
6790 { MKTAG('u','u','i','d'), mov_read_uuid },
6791 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6792 { MKTAG('f','r','e','e'), mov_read_free },
6793 { MKTAG('-','-','-','-'), mov_read_custom },
6794 { MKTAG('s','i','n','f'), mov_read_default },
6795 { MKTAG('f','r','m','a'), mov_read_frma },
6796 { MKTAG('s','e','n','c'), mov_read_senc },
6797 { MKTAG('s','a','i','z'), mov_read_saiz },
6798 { MKTAG('s','a','i','o'), mov_read_saio },
6799 { MKTAG('p','s','s','h'), mov_read_pssh },
6800 { MKTAG('s','c','h','m'), mov_read_schm },
6801 { MKTAG('s','c','h','i'), mov_read_default },
6802 { MKTAG('t','e','n','c'), mov_read_tenc },
6803 { MKTAG('d','f','L','a'), mov_read_dfla },
6804 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6805 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6806 { MKTAG('d','O','p','s'), mov_read_dops },
6807 { MKTAG('d','m','l','p'), mov_read_dmlp },
6808 { MKTAG('S','m','D','m'), mov_read_smdm },
6809 { MKTAG('C','o','L','L'), mov_read_coll },
6810 { MKTAG('v','p','c','C'), mov_read_vpcc },
6811 { MKTAG('m','d','c','v'), mov_read_mdcv },
6812 { MKTAG('c','l','l','i'), mov_read_clli },
6816 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6818 int64_t total_size = 0;
6822 if (c->atom_depth > 10) {
6823 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6824 return AVERROR_INVALIDDATA;
6829 atom.size = INT64_MAX;
6830 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6831 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
6834 if (atom.size >= 8) {
6835 a.size = avio_rb32(pb);
6836 a.type = avio_rl32(pb);
6837 if (a.type == MKTAG('f','r','e','e') &&
6839 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT &&
6842 uint32_t *type = (uint32_t *)buf + 1;
6843 if (avio_read(pb, buf, 8) != 8)
6844 return AVERROR_INVALIDDATA;
6845 avio_seek(pb, -8, SEEK_CUR);
6846 if (*type == MKTAG('m','v','h','d') ||
6847 *type == MKTAG('c','m','o','v')) {
6848 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free atom.\n");
6849 a.type = MKTAG('m','o','o','v');
6852 if (atom.type != MKTAG('r','o','o','t') &&
6853 atom.type != MKTAG('m','o','o','v'))
6855 if (a.type == MKTAG('t','r','a','k') || a.type == MKTAG('m','d','a','t'))
6857 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
6864 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
6865 a.size = avio_rb64(pb) - 8;
6869 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
6870 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
6872 a.size = atom.size - total_size + 8;
6877 a.size = FFMIN(a.size, atom.size - total_size);
6879 for (i = 0; mov_default_parse_table[i].type; i++)
6880 if (mov_default_parse_table[i].type == a.type) {
6881 parse = mov_default_parse_table[i].parse;
6885 // container is user data
6886 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
6887 atom.type == MKTAG('i','l','s','t')))
6888 parse = mov_read_udta_string;
6890 // Supports parsing the QuickTime Metadata Keys.
6891 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
6892 if (!parse && c->found_hdlr_mdta &&
6893 atom.type == MKTAG('m','e','t','a') &&
6894 a.type == MKTAG('k','e','y','s')) {
6895 parse = mov_read_keys;
6898 if (!parse) { /* skip leaf atoms data */
6899 avio_skip(pb, a.size);
6901 int64_t start_pos = avio_tell(pb);
6903 int err = parse(c, pb, a);
6908 if (c->found_moov && c->found_mdat &&
6909 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
6910 start_pos + a.size == avio_size(pb))) {
6911 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
6912 c->next_root_atom = start_pos + a.size;
6916 left = a.size - avio_tell(pb) + start_pos;
6917 if (left > 0) /* skip garbage at atom end */
6918 avio_skip(pb, left);
6919 else if (left < 0) {
6920 av_log(c->fc, AV_LOG_WARNING,
6921 "overread end of atom '%.4s' by %"PRId64" bytes\n",
6922 (char*)&a.type, -left);
6923 avio_seek(pb, left, SEEK_CUR);
6927 total_size += a.size;
6930 if (total_size < atom.size && atom.size < 0x7ffff)
6931 avio_skip(pb, atom.size - total_size);
6937 static int mov_probe(const AVProbeData *p)
6942 int moov_offset = -1;
6944 /* check file header */
6947 /* ignore invalid offset */
6948 if ((offset + 8) > (unsigned int)p->buf_size)
6950 tag = AV_RL32(p->buf + offset + 4);
6952 /* check for obvious tags */
6953 case MKTAG('m','o','o','v'):
6954 moov_offset = offset + 4;
6955 case MKTAG('m','d','a','t'):
6956 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
6957 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
6958 case MKTAG('f','t','y','p'):
6959 if (AV_RB32(p->buf+offset) < 8 &&
6960 (AV_RB32(p->buf+offset) != 1 ||
6961 offset + 12 > (unsigned int)p->buf_size ||
6962 AV_RB64(p->buf+offset + 8) == 0)) {
6963 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
6964 } else if (tag == MKTAG('f','t','y','p') &&
6965 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
6966 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
6968 score = FFMAX(score, 5);
6970 score = AVPROBE_SCORE_MAX;
6972 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
6974 /* those are more common words, so rate then a bit less */
6975 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
6976 case MKTAG('w','i','d','e'):
6977 case MKTAG('f','r','e','e'):
6978 case MKTAG('j','u','n','k'):
6979 case MKTAG('p','i','c','t'):
6980 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
6981 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
6983 case MKTAG(0x82,0x82,0x7f,0x7d):
6984 case MKTAG('s','k','i','p'):
6985 case MKTAG('u','u','i','d'):
6986 case MKTAG('p','r','f','l'):
6987 /* if we only find those cause probedata is too small at least rate them */
6988 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
6989 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
6992 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
6995 if(score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
6996 /* moov atom in the header - we should make sure that this is not a
6997 * MOV-packed MPEG-PS */
6998 offset = moov_offset;
7000 while(offset < (p->buf_size - 16)){ /* Sufficient space */
7001 /* We found an actual hdlr atom */
7002 if(AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7003 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7004 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')){
7005 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7006 /* We found a media handler reference atom describing an
7007 * MPEG-PS-in-MOV, return a
7008 * low score to force expanding the probe window until
7009 * mpegps_probe finds what it needs */
7020 // must be done after parsing all trak because there's no order requirement
7021 static void mov_read_chapters(AVFormatContext *s)
7023 MOVContext *mov = s->priv_data;
7025 MOVStreamContext *sc;
7030 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7031 chapter_track = mov->chapter_tracks[j];
7033 for (i = 0; i < s->nb_streams; i++)
7034 if (s->streams[i]->id == chapter_track) {
7039 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7044 cur_pos = avio_tell(sc->pb);
7046 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7047 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7048 if (st->nb_index_entries) {
7049 // Retrieve the first frame, if possible
7051 AVIndexEntry *sample = &st->index_entries[0];
7052 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7053 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7057 if (av_get_packet(sc->pb, &pkt, sample->size) < 0)
7060 st->attached_pic = pkt;
7061 st->attached_pic.stream_index = st->index;
7062 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
7065 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7066 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7067 st->discard = AVDISCARD_ALL;
7068 for (i = 0; i < st->nb_index_entries; i++) {
7069 AVIndexEntry *sample = &st->index_entries[i];
7070 int64_t end = i+1 < st->nb_index_entries ? st->index_entries[i+1].timestamp : st->duration;
7075 if (end < sample->timestamp) {
7076 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7077 end = AV_NOPTS_VALUE;
7080 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7081 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7085 // the first two bytes are the length of the title
7086 len = avio_rb16(sc->pb);
7087 if (len > sample->size-2)
7089 title_len = 2*len + 1;
7090 if (!(title = av_mallocz(title_len)))
7093 // The samples could theoretically be in any encoding if there's an encd
7094 // atom following, but in practice are only utf-8 or utf-16, distinguished
7095 // instead by the presence of a BOM
7099 ch = avio_rb16(sc->pb);
7101 avio_get_str16be(sc->pb, len, title, title_len);
7102 else if (ch == 0xfffe)
7103 avio_get_str16le(sc->pb, len, title, title_len);
7106 if (len == 1 || len == 2)
7109 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7113 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7118 avio_seek(sc->pb, cur_pos, SEEK_SET);
7122 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7123 uint32_t value, int flags)
7126 char buf[AV_TIMECODE_STR_SIZE];
7127 AVRational rate = st->avg_frame_rate;
7128 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7131 av_dict_set(&st->metadata, "timecode",
7132 av_timecode_make_string(&tc, buf, value), 0);
7136 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7138 MOVStreamContext *sc = st->priv_data;
7139 char buf[AV_TIMECODE_STR_SIZE];
7140 int64_t cur_pos = avio_tell(sc->pb);
7141 int hh, mm, ss, ff, drop;
7143 if (!st->nb_index_entries)
7146 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7147 avio_skip(s->pb, 13);
7148 hh = avio_r8(s->pb);
7149 mm = avio_r8(s->pb);
7150 ss = avio_r8(s->pb);
7151 drop = avio_r8(s->pb);
7152 ff = avio_r8(s->pb);
7153 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7154 hh, mm, ss, drop ? ';' : ':', ff);
7155 av_dict_set(&st->metadata, "timecode", buf, 0);
7157 avio_seek(sc->pb, cur_pos, SEEK_SET);
7161 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7163 MOVStreamContext *sc = st->priv_data;
7165 int64_t cur_pos = avio_tell(sc->pb);
7168 if (!st->nb_index_entries)
7171 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7172 value = avio_rb32(s->pb);
7174 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7175 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7176 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7178 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7179 * not the case) and thus assume "frame number format" instead of QT one.
7180 * No sample with tmcd track can be found with a QT timecode at the moment,
7181 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7183 parse_timecode_in_framenum_format(s, st, value, flags);
7185 avio_seek(sc->pb, cur_pos, SEEK_SET);
7189 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7191 if (!index || !*index) return;
7192 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7193 av_encryption_info_free((*index)->encrypted_samples[i]);
7195 av_freep(&(*index)->encrypted_samples);
7196 av_freep(&(*index)->auxiliary_info_sizes);
7197 av_freep(&(*index)->auxiliary_offsets);
7201 static int mov_read_close(AVFormatContext *s)
7203 MOVContext *mov = s->priv_data;
7206 for (i = 0; i < s->nb_streams; i++) {
7207 AVStream *st = s->streams[i];
7208 MOVStreamContext *sc = st->priv_data;
7213 av_freep(&sc->ctts_data);
7214 for (j = 0; j < sc->drefs_count; j++) {
7215 av_freep(&sc->drefs[j].path);
7216 av_freep(&sc->drefs[j].dir);
7218 av_freep(&sc->drefs);
7220 sc->drefs_count = 0;
7222 if (!sc->pb_is_copied)
7223 ff_format_io_close(s, &sc->pb);
7226 av_freep(&sc->chunk_offsets);
7227 av_freep(&sc->stsc_data);
7228 av_freep(&sc->sample_sizes);
7229 av_freep(&sc->keyframes);
7230 av_freep(&sc->stts_data);
7231 av_freep(&sc->stps_data);
7232 av_freep(&sc->elst_data);
7233 av_freep(&sc->rap_group);
7234 av_freep(&sc->display_matrix);
7235 av_freep(&sc->index_ranges);
7238 for (j = 0; j < sc->stsd_count; j++)
7239 av_free(sc->extradata[j]);
7240 av_freep(&sc->extradata);
7241 av_freep(&sc->extradata_size);
7243 mov_free_encryption_index(&sc->cenc.encryption_index);
7244 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7245 av_aes_ctr_free(sc->cenc.aes_ctr);
7247 av_freep(&sc->stereo3d);
7248 av_freep(&sc->spherical);
7249 av_freep(&sc->mastering);
7250 av_freep(&sc->coll);
7253 if (mov->dv_demux) {
7254 avformat_free_context(mov->dv_fctx);
7255 mov->dv_fctx = NULL;
7258 if (mov->meta_keys) {
7259 for (i = 1; i < mov->meta_keys_count; i++) {
7260 av_freep(&mov->meta_keys[i]);
7262 av_freep(&mov->meta_keys);
7265 av_freep(&mov->trex_data);
7266 av_freep(&mov->bitrates);
7268 for (i = 0; i < mov->frag_index.nb_items; i++) {
7269 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7270 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7271 mov_free_encryption_index(&frag[j].encryption_index);
7273 av_freep(&mov->frag_index.item[i].stream_info);
7275 av_freep(&mov->frag_index.item);
7277 av_freep(&mov->aes_decrypt);
7278 av_freep(&mov->chapter_tracks);
7283 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7287 for (i = 0; i < s->nb_streams; i++) {
7288 AVStream *st = s->streams[i];
7289 MOVStreamContext *sc = st->priv_data;
7291 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7292 sc->timecode_track == tmcd_id)
7298 /* look for a tmcd track not referenced by any video track, and export it globally */
7299 static void export_orphan_timecode(AVFormatContext *s)
7303 for (i = 0; i < s->nb_streams; i++) {
7304 AVStream *st = s->streams[i];
7306 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7307 !tmcd_is_referenced(s, i + 1)) {
7308 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7310 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7317 static int read_tfra(MOVContext *mov, AVIOContext *f)
7319 int version, fieldlength, i, j;
7320 int64_t pos = avio_tell(f);
7321 uint32_t size = avio_rb32(f);
7322 unsigned track_id, item_count;
7324 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7327 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7329 version = avio_r8(f);
7331 track_id = avio_rb32(f);
7332 fieldlength = avio_rb32(f);
7333 item_count = avio_rb32(f);
7334 for (i = 0; i < item_count; i++) {
7335 int64_t time, offset;
7337 MOVFragmentStreamInfo * frag_stream_info;
7340 return AVERROR_INVALIDDATA;
7344 time = avio_rb64(f);
7345 offset = avio_rb64(f);
7347 time = avio_rb32(f);
7348 offset = avio_rb32(f);
7351 // The first sample of each stream in a fragment is always a random
7352 // access sample. So it's entry in the tfra can be used as the
7353 // initial PTS of the fragment.
7354 index = update_frag_index(mov, offset);
7355 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7356 if (frag_stream_info &&
7357 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7358 frag_stream_info->first_tfra_pts = time;
7360 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7362 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7364 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7368 avio_seek(f, pos + size, SEEK_SET);
7372 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7374 int64_t stream_size = avio_size(f);
7375 int64_t original_pos = avio_tell(f);
7379 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7383 mfra_size = avio_rb32(f);
7384 if (mfra_size < 0 || mfra_size > stream_size) {
7385 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7388 if ((seek_ret = avio_seek(f, -mfra_size, SEEK_CUR)) < 0) {
7392 if (avio_rb32(f) != mfra_size) {
7393 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7396 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7397 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7400 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7402 ret = read_tfra(c, f);
7408 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7410 av_log(c->fc, AV_LOG_ERROR,
7411 "failed to seek back after looking for mfra\n");
7417 static int mov_read_header(AVFormatContext *s)
7419 MOVContext *mov = s->priv_data;
7420 AVIOContext *pb = s->pb;
7422 MOVAtom atom = { AV_RL32("root") };
7425 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7426 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7427 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7428 return AVERROR(EINVAL);
7432 mov->trak_index = -1;
7433 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7434 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7435 atom.size = avio_size(pb);
7437 atom.size = INT64_MAX;
7439 /* check MOV header */
7441 if (mov->moov_retry)
7442 avio_seek(pb, 0, SEEK_SET);
7443 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7444 av_log(s, AV_LOG_ERROR, "error reading header\n");
7448 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7449 if (!mov->found_moov) {
7450 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7452 return AVERROR_INVALIDDATA;
7454 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7456 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7457 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7458 mov_read_chapters(s);
7459 for (i = 0; i < s->nb_streams; i++)
7460 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7461 mov_read_timecode_track(s, s->streams[i]);
7462 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7463 mov_read_rtmd_track(s, s->streams[i]);
7467 /* copy timecode metadata from tmcd tracks to the related video streams */
7468 for (i = 0; i < s->nb_streams; i++) {
7469 AVStream *st = s->streams[i];
7470 MOVStreamContext *sc = st->priv_data;
7471 if (sc->timecode_track > 0) {
7472 AVDictionaryEntry *tcr;
7473 int tmcd_st_id = -1;
7475 for (j = 0; j < s->nb_streams; j++)
7476 if (s->streams[j]->id == sc->timecode_track)
7479 if (tmcd_st_id < 0 || tmcd_st_id == i)
7481 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7483 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7486 export_orphan_timecode(s);
7488 for (i = 0; i < s->nb_streams; i++) {
7489 AVStream *st = s->streams[i];
7490 MOVStreamContext *sc = st->priv_data;
7491 fix_timescale(mov, sc);
7492 if(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7493 st->skip_samples = sc->start_pad;
7495 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7496 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7497 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7498 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7499 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7500 st->codecpar->width = sc->width;
7501 st->codecpar->height = sc->height;
7503 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7504 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7508 if (mov->handbrake_version &&
7509 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7510 st->codecpar->codec_id == AV_CODEC_ID_MP3
7512 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7513 st->need_parsing = AVSTREAM_PARSE_FULL;
7517 if (mov->trex_data) {
7518 for (i = 0; i < s->nb_streams; i++) {
7519 AVStream *st = s->streams[i];
7520 MOVStreamContext *sc = st->priv_data;
7521 if (st->duration > 0) {
7522 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7523 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7524 sc->data_size, sc->time_scale);
7526 return AVERROR_INVALIDDATA;
7528 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7533 if (mov->use_mfra_for > 0) {
7534 for (i = 0; i < s->nb_streams; i++) {
7535 AVStream *st = s->streams[i];
7536 MOVStreamContext *sc = st->priv_data;
7537 if (sc->duration_for_fps > 0) {
7538 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7539 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7540 sc->data_size, sc->time_scale);
7542 return AVERROR_INVALIDDATA;
7544 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7545 sc->duration_for_fps;
7550 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7551 if (mov->bitrates[i]) {
7552 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7556 ff_rfps_calculate(s);
7558 for (i = 0; i < s->nb_streams; i++) {
7559 AVStream *st = s->streams[i];
7560 MOVStreamContext *sc = st->priv_data;
7562 switch (st->codecpar->codec_type) {
7563 case AVMEDIA_TYPE_AUDIO:
7564 err = ff_replaygain_export(st, s->metadata);
7570 case AVMEDIA_TYPE_VIDEO:
7571 if (sc->display_matrix) {
7572 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7573 sizeof(int32_t) * 9);
7577 sc->display_matrix = NULL;
7580 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7581 (uint8_t *)sc->stereo3d,
7582 sizeof(*sc->stereo3d));
7586 sc->stereo3d = NULL;
7588 if (sc->spherical) {
7589 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7590 (uint8_t *)sc->spherical,
7591 sc->spherical_size);
7595 sc->spherical = NULL;
7597 if (sc->mastering) {
7598 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7599 (uint8_t *)sc->mastering,
7600 sizeof(*sc->mastering));
7604 sc->mastering = NULL;
7607 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7608 (uint8_t *)sc->coll,
7618 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7620 for (i = 0; i < mov->frag_index.nb_items; i++)
7621 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7622 mov->frag_index.item[i].headers_read = 1;
7627 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7629 AVIndexEntry *sample = NULL;
7630 int64_t best_dts = INT64_MAX;
7632 for (i = 0; i < s->nb_streams; i++) {
7633 AVStream *avst = s->streams[i];
7634 MOVStreamContext *msc = avst->priv_data;
7635 if (msc->pb && msc->current_sample < avst->nb_index_entries) {
7636 AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample];
7637 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7638 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7639 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7640 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7641 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb &&
7642 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7643 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7644 sample = current_sample;
7653 static int should_retry(AVIOContext *pb, int error_code) {
7654 if (error_code == AVERROR_EOF || avio_feof(pb))
7660 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7663 MOVContext *mov = s->priv_data;
7665 if (index >= 0 && index < mov->frag_index.nb_items)
7666 target = mov->frag_index.item[index].moof_offset;
7667 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7668 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7669 return AVERROR_INVALIDDATA;
7672 mov->next_root_atom = 0;
7673 if (index < 0 || index >= mov->frag_index.nb_items)
7674 index = search_frag_moof_offset(&mov->frag_index, target);
7675 if (index < mov->frag_index.nb_items) {
7676 if (index + 1 < mov->frag_index.nb_items)
7677 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7678 if (mov->frag_index.item[index].headers_read)
7680 mov->frag_index.item[index].headers_read = 1;
7683 mov->found_mdat = 0;
7685 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7688 if (avio_feof(s->pb))
7690 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7695 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7697 uint8_t *side, *extradata;
7700 /* Save the current index. */
7701 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7703 /* Notify the decoder that extradata changed. */
7704 extradata_size = sc->extradata_size[sc->last_stsd_index];
7705 extradata = sc->extradata[sc->last_stsd_index];
7706 if (extradata_size > 0 && extradata) {
7707 side = av_packet_new_side_data(pkt,
7708 AV_PKT_DATA_NEW_EXTRADATA,
7711 return AVERROR(ENOMEM);
7712 memcpy(side, extradata, extradata_size);
7718 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7720 MOVContext *mov = s->priv_data;
7721 MOVStreamContext *sc;
7722 AVIndexEntry *sample;
7723 AVStream *st = NULL;
7724 int64_t current_index;
7728 sample = mov_find_next_sample(s, &st);
7729 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7730 if (!mov->next_root_atom)
7732 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7737 /* must be done just before reading, to avoid infinite loop on sample */
7738 current_index = sc->current_index;
7739 mov_current_sample_inc(sc);
7741 if (mov->next_root_atom) {
7742 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7743 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7746 if (st->discard != AVDISCARD_ALL) {
7747 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7748 if (ret64 != sample->pos) {
7749 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7750 sc->ffindex, sample->pos);
7751 if (should_retry(sc->pb, ret64)) {
7752 mov_current_sample_dec(sc);
7754 return AVERROR_INVALIDDATA;
7757 if( st->discard == AVDISCARD_NONKEY && 0==(sample->flags & AVINDEX_KEYFRAME) ) {
7758 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7762 ret = av_get_packet(sc->pb, pkt, sample->size);
7764 if (should_retry(sc->pb, ret)) {
7765 mov_current_sample_dec(sc);
7769 if (sc->has_palette) {
7772 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7774 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7776 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7777 sc->has_palette = 0;
7780 #if CONFIG_DV_DEMUXER
7781 if (mov->dv_demux && sc->dv_audio_container) {
7782 avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7783 av_freep(&pkt->data);
7785 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7790 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7791 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7792 st->need_parsing = AVSTREAM_PARSE_FULL;
7796 pkt->stream_index = sc->ffindex;
7797 pkt->dts = sample->timestamp;
7798 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7799 pkt->flags |= AV_PKT_FLAG_DISCARD;
7801 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7802 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
7803 /* update ctts context */
7805 if (sc->ctts_index < sc->ctts_count &&
7806 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
7808 sc->ctts_sample = 0;
7811 int64_t next_dts = (sc->current_sample < st->nb_index_entries) ?
7812 st->index_entries[sc->current_sample].timestamp : st->duration;
7814 if (next_dts >= pkt->dts)
7815 pkt->duration = next_dts - pkt->dts;
7816 pkt->pts = pkt->dts;
7818 if (st->discard == AVDISCARD_ALL)
7820 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
7821 pkt->pos = sample->pos;
7823 /* Multiple stsd handling. */
7824 if (sc->stsc_data) {
7825 /* Keep track of the stsc index for the given sample, then check
7826 * if the stsd index is different from the last used one. */
7828 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
7829 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
7831 sc->stsc_sample = 0;
7832 /* Do not check indexes after a switch. */
7833 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
7834 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
7835 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
7836 ret = mov_change_extradata(sc, pkt);
7843 aax_filter(pkt->data, pkt->size, mov);
7845 ret = cenc_filter(mov, st, sc, pkt, current_index);
7847 av_packet_unref(pkt);
7854 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
7856 MOVContext *mov = s->priv_data;
7859 if (!mov->frag_index.complete)
7862 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
7865 if (!mov->frag_index.item[index].headers_read)
7866 return mov_switch_root(s, -1, index);
7867 if (index + 1 < mov->frag_index.nb_items)
7868 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7873 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
7875 MOVStreamContext *sc = st->priv_data;
7876 int sample, time_sample, ret;
7879 // Here we consider timestamp to be PTS, hence try to offset it so that we
7880 // can search over the DTS timeline.
7881 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
7883 ret = mov_seek_fragment(s, st, timestamp);
7887 sample = av_index_search_timestamp(st, timestamp, flags);
7888 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
7889 if (sample < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp)
7891 if (sample < 0) /* not sure what to do */
7892 return AVERROR_INVALIDDATA;
7893 mov_current_sample_set(sc, sample);
7894 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
7895 /* adjust ctts index */
7896 if (sc->ctts_data) {
7898 for (i = 0; i < sc->ctts_count; i++) {
7899 int next = time_sample + sc->ctts_data[i].count;
7900 if (next > sc->current_sample) {
7902 sc->ctts_sample = sc->current_sample - time_sample;
7909 /* adjust stsd index */
7910 if (sc->chunk_count) {
7912 for (i = 0; i < sc->stsc_count; i++) {
7913 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
7914 if (next > sc->current_sample) {
7916 sc->stsc_sample = sc->current_sample - time_sample;
7919 av_assert0(next == (int)next);
7927 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
7929 MOVContext *mc = s->priv_data;
7934 if (stream_index >= s->nb_streams)
7935 return AVERROR_INVALIDDATA;
7937 st = s->streams[stream_index];
7938 sample = mov_seek_stream(s, st, sample_time, flags);
7942 if (mc->seek_individually) {
7943 /* adjust seek timestamp to found sample timestamp */
7944 int64_t seek_timestamp = st->index_entries[sample].timestamp;
7946 for (i = 0; i < s->nb_streams; i++) {
7948 MOVStreamContext *sc = s->streams[i]->priv_data;
7950 st->skip_samples = (sample_time <= 0) ? sc->start_pad : 0;
7952 if (stream_index == i)
7955 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
7956 mov_seek_stream(s, st, timestamp, flags);
7959 for (i = 0; i < s->nb_streams; i++) {
7960 MOVStreamContext *sc;
7963 mov_current_sample_set(sc, 0);
7966 MOVStreamContext *sc;
7967 AVIndexEntry *entry = mov_find_next_sample(s, &st);
7969 return AVERROR_INVALIDDATA;
7971 if (sc->ffindex == stream_index && sc->current_sample == sample)
7973 mov_current_sample_inc(sc);
7979 #define OFFSET(x) offsetof(MOVContext, x)
7980 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
7981 static const AVOption mov_options[] = {
7982 {"use_absolute_path",
7983 "allow using absolute path when opening alias, this is a possible security issue",
7984 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
7986 {"seek_streams_individually",
7987 "Seek each stream individually to the to the closest point",
7988 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
7990 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
7992 {"advanced_editlist",
7993 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
7994 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
7996 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
7999 "use mfra for fragment timestamps",
8000 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8001 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8003 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8004 FLAGS, "use_mfra_for" },
8005 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8006 FLAGS, "use_mfra_for" },
8007 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8008 FLAGS, "use_mfra_for" },
8009 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8010 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8011 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8012 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8013 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8014 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8015 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8016 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8017 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8018 .flags = AV_OPT_FLAG_DECODING_PARAM },
8019 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8020 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8021 {.i64 = 0}, 0, 1, FLAGS },
8026 static const AVClass mov_class = {
8027 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8028 .item_name = av_default_item_name,
8029 .option = mov_options,
8030 .version = LIBAVUTIL_VERSION_INT,
8033 AVInputFormat ff_mov_demuxer = {
8034 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8035 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8036 .priv_class = &mov_class,
8037 .priv_data_size = sizeof(MOVContext),
8038 .extensions = "mov,mp4,m4a,3gp,3g2,mj2",
8039 .read_probe = mov_probe,
8040 .read_header = mov_read_header,
8041 .read_packet = mov_read_packet,
8042 .read_close = mov_read_close,
8043 .read_seek = mov_read_seek,
8044 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,