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) {
4425 tag = avio_rl32(pb);
4427 if (tag == MKTAG('h','d','l','r')) {
4428 avio_seek(pb, -8, SEEK_CUR);
4430 return mov_read_default(c, pb, atom);
4436 // return 1 when matrix is identity, 0 otherwise
4437 #define IS_MATRIX_IDENT(matrix) \
4438 ( (matrix)[0][0] == (1 << 16) && \
4439 (matrix)[1][1] == (1 << 16) && \
4440 (matrix)[2][2] == (1 << 30) && \
4441 !(matrix)[0][1] && !(matrix)[0][2] && \
4442 !(matrix)[1][0] && !(matrix)[1][2] && \
4443 !(matrix)[2][0] && !(matrix)[2][1])
4445 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4450 int display_matrix[3][3];
4451 int res_display_matrix[3][3] = { { 0 } };
4453 MOVStreamContext *sc;
4457 if (c->fc->nb_streams < 1)
4459 st = c->fc->streams[c->fc->nb_streams-1];
4462 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4463 // avoids corrupting AVStreams mapped to an earlier tkhd.
4465 return AVERROR_INVALIDDATA;
4467 version = avio_r8(pb);
4468 flags = avio_rb24(pb);
4469 st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
4475 avio_rb32(pb); /* creation time */
4476 avio_rb32(pb); /* modification time */
4478 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4479 avio_rb32(pb); /* reserved */
4481 /* highlevel (considering edits) duration in movie timebase */
4482 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4483 avio_rb32(pb); /* reserved */
4484 avio_rb32(pb); /* reserved */
4486 avio_rb16(pb); /* layer */
4487 avio_rb16(pb); /* alternate group */
4488 avio_rb16(pb); /* volume */
4489 avio_rb16(pb); /* reserved */
4491 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4492 // they're kept in fixed point format through all calculations
4493 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4494 // side data, but the scale factor is not needed to calculate aspect ratio
4495 for (i = 0; i < 3; i++) {
4496 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
4497 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
4498 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
4501 width = avio_rb32(pb); // 16.16 fixed point track width
4502 height = avio_rb32(pb); // 16.16 fixed point track height
4503 sc->width = width >> 16;
4504 sc->height = height >> 16;
4506 // apply the moov display matrix (after the tkhd one)
4507 for (i = 0; i < 3; i++) {
4508 const int sh[3] = { 16, 16, 30 };
4509 for (j = 0; j < 3; j++) {
4510 for (e = 0; e < 3; e++) {
4511 res_display_matrix[i][j] +=
4512 ((int64_t) display_matrix[i][e] *
4513 c->movie_display_matrix[e][j]) >> sh[e];
4518 // save the matrix when it is not the default identity
4519 if (!IS_MATRIX_IDENT(res_display_matrix)) {
4522 av_freep(&sc->display_matrix);
4523 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4524 if (!sc->display_matrix)
4525 return AVERROR(ENOMEM);
4527 for (i = 0; i < 3; i++)
4528 for (j = 0; j < 3; j++)
4529 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4531 #if FF_API_OLD_ROTATE_API
4532 rotate = av_display_rotation_get(sc->display_matrix);
4533 if (!isnan(rotate)) {
4534 char rotate_buf[64];
4536 if (rotate < 0) // for backward compatibility
4538 snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate);
4539 av_dict_set(&st->metadata, "rotate", rotate_buf, 0);
4544 // transform the display width/height according to the matrix
4545 // to keep the same scale, use [width height 1<<16]
4546 if (width && height && sc->display_matrix) {
4547 double disp_transform[2];
4549 for (i = 0; i < 2; i++)
4550 disp_transform[i] = hypot(sc->display_matrix[0 + i],
4551 sc->display_matrix[3 + i]);
4553 if (disp_transform[0] > 0 && disp_transform[1] > 0 &&
4554 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4555 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4556 st->sample_aspect_ratio = av_d2q(
4557 disp_transform[0] / disp_transform[1],
4563 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4565 MOVFragment *frag = &c->fragment;
4566 MOVTrackExt *trex = NULL;
4567 int flags, track_id, i;
4569 avio_r8(pb); /* version */
4570 flags = avio_rb24(pb);
4572 track_id = avio_rb32(pb);
4574 return AVERROR_INVALIDDATA;
4575 for (i = 0; i < c->trex_count; i++)
4576 if (c->trex_data[i].track_id == track_id) {
4577 trex = &c->trex_data[i];
4581 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4584 c->fragment.found_tfhd = 1;
4585 frag->track_id = track_id;
4586 set_frag_stream(&c->frag_index, track_id);
4588 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4589 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4590 frag->moof_offset : frag->implicit_offset;
4591 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4593 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4594 avio_rb32(pb) : trex->duration;
4595 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4596 avio_rb32(pb) : trex->size;
4597 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4598 avio_rb32(pb) : trex->flags;
4599 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4604 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4609 num = atom.size / 4;
4610 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4611 return AVERROR(ENOMEM);
4613 av_free(c->chapter_tracks);
4614 c->chapter_tracks = new_tracks;
4615 c->nb_chapter_tracks = num;
4617 for (i = 0; i < num && !pb->eof_reached; i++)
4618 c->chapter_tracks[i] = avio_rb32(pb);
4623 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4628 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4629 return AVERROR_INVALIDDATA;
4630 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4631 sizeof(*c->trex_data))) < 0) {
4636 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4638 trex = &c->trex_data[c->trex_count++];
4639 avio_r8(pb); /* version */
4640 avio_rb24(pb); /* flags */
4641 trex->track_id = avio_rb32(pb);
4642 trex->stsd_id = avio_rb32(pb);
4643 trex->duration = avio_rb32(pb);
4644 trex->size = avio_rb32(pb);
4645 trex->flags = avio_rb32(pb);
4649 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4651 MOVFragment *frag = &c->fragment;
4652 AVStream *st = NULL;
4653 MOVStreamContext *sc;
4655 MOVFragmentStreamInfo * frag_stream_info;
4656 int64_t base_media_decode_time;
4658 for (i = 0; i < c->fc->nb_streams; i++) {
4659 if (c->fc->streams[i]->id == frag->track_id) {
4660 st = c->fc->streams[i];
4665 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4669 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4671 version = avio_r8(pb);
4672 avio_rb24(pb); /* flags */
4674 base_media_decode_time = avio_rb64(pb);
4676 base_media_decode_time = avio_rb32(pb);
4679 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4680 if (frag_stream_info)
4681 frag_stream_info->tfdt_dts = base_media_decode_time;
4682 sc->track_end = base_media_decode_time;
4687 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4689 MOVFragment *frag = &c->fragment;
4690 AVStream *st = NULL;
4691 MOVStreamContext *sc;
4694 int64_t dts, pts = AV_NOPTS_VALUE;
4695 int data_offset = 0;
4696 unsigned entries, first_sample_flags = frag->flags;
4697 int flags, distance, i;
4698 int64_t prev_dts = AV_NOPTS_VALUE;
4699 int next_frag_index = -1, index_entry_pos;
4700 size_t requested_size;
4701 size_t old_ctts_allocated_size;
4702 AVIndexEntry *new_entries;
4703 MOVFragmentStreamInfo * frag_stream_info;
4705 if (!frag->found_tfhd) {
4706 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4707 return AVERROR_INVALIDDATA;
4710 for (i = 0; i < c->fc->nb_streams; i++) {
4711 if (c->fc->streams[i]->id == frag->track_id) {
4712 st = c->fc->streams[i];
4717 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4721 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4724 // Find the next frag_index index that has a valid index_entry for
4725 // the current track_id.
4727 // A valid index_entry means the trun for the fragment was read
4728 // and it's samples are in index_entries at the given position.
4729 // New index entries will be inserted before the index_entry found.
4730 index_entry_pos = st->nb_index_entries;
4731 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4732 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4733 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4734 next_frag_index = i;
4735 index_entry_pos = frag_stream_info->index_entry;
4739 av_assert0(index_entry_pos <= st->nb_index_entries);
4741 avio_r8(pb); /* version */
4742 flags = avio_rb24(pb);
4743 entries = avio_rb32(pb);
4744 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4746 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4747 return AVERROR_INVALIDDATA;
4748 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4749 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4751 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4752 if (frag_stream_info)
4754 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4755 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4756 pts = frag_stream_info->first_tfra_pts;
4757 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4758 ", using it for pts\n", pts);
4759 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4760 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4761 // pts = frag_stream_info->sidx_pts;
4762 dts = frag_stream_info->sidx_pts - sc->time_offset;
4763 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4764 ", using it for pts\n", pts);
4765 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4766 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4767 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4768 ", using it for dts\n", dts);
4770 dts = sc->track_end - sc->time_offset;
4771 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4772 ", using it for dts\n", dts);
4775 dts = sc->track_end - sc->time_offset;
4776 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4777 ", using it for dts\n", dts);
4779 offset = frag->base_data_offset + data_offset;
4781 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4783 // realloc space for new index entries
4784 if((uint64_t)st->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4785 entries = UINT_MAX / sizeof(AVIndexEntry) - st->nb_index_entries;
4786 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4791 requested_size = (st->nb_index_entries + entries) * sizeof(AVIndexEntry);
4792 new_entries = av_fast_realloc(st->index_entries,
4793 &st->index_entries_allocated_size,
4796 return AVERROR(ENOMEM);
4797 st->index_entries= new_entries;
4799 requested_size = (st->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4800 old_ctts_allocated_size = sc->ctts_allocated_size;
4801 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4804 return AVERROR(ENOMEM);
4805 sc->ctts_data = ctts_data;
4807 // In case there were samples without ctts entries, ensure they get
4808 // zero valued entries. This ensures clips which mix boxes with and
4809 // without ctts entries don't pickup uninitialized data.
4810 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4811 sc->ctts_allocated_size - old_ctts_allocated_size);
4813 if (index_entry_pos < st->nb_index_entries) {
4814 // Make hole in index_entries and ctts_data for new samples
4815 memmove(st->index_entries + index_entry_pos + entries,
4816 st->index_entries + index_entry_pos,
4817 sizeof(*st->index_entries) *
4818 (st->nb_index_entries - index_entry_pos));
4819 memmove(sc->ctts_data + index_entry_pos + entries,
4820 sc->ctts_data + index_entry_pos,
4821 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4822 if (index_entry_pos < sc->current_sample) {
4823 sc->current_sample += entries;
4827 st->nb_index_entries += entries;
4828 sc->ctts_count = st->nb_index_entries;
4830 // Record the index_entry position in frag_index of this fragment
4831 if (frag_stream_info)
4832 frag_stream_info->index_entry = index_entry_pos;
4834 if (index_entry_pos > 0)
4835 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4837 for (i = 0; i < entries && !pb->eof_reached; i++) {
4838 unsigned sample_size = frag->size;
4839 int sample_flags = i ? frag->flags : first_sample_flags;
4840 unsigned sample_duration = frag->duration;
4841 unsigned ctts_duration = 0;
4843 int index_entry_flags = 0;
4845 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4846 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4847 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4848 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4850 mov_update_dts_shift(sc, ctts_duration);
4851 if (pts != AV_NOPTS_VALUE) {
4852 dts = pts - sc->dts_shift;
4853 if (flags & MOV_TRUN_SAMPLE_CTS) {
4854 dts -= ctts_duration;
4856 dts -= sc->time_offset;
4858 av_log(c->fc, AV_LOG_DEBUG,
4859 "pts %"PRId64" calculated dts %"PRId64
4860 " sc->dts_shift %d ctts.duration %d"
4861 " sc->time_offset %"PRId64
4862 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4864 sc->dts_shift, ctts_duration,
4865 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4866 pts = AV_NOPTS_VALUE;
4869 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4873 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4874 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4877 index_entry_flags |= AVINDEX_KEYFRAME;
4879 // Fragments can overlap in time. Discard overlapping frames after
4881 if (prev_dts >= dts)
4882 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4884 st->index_entries[index_entry_pos].pos = offset;
4885 st->index_entries[index_entry_pos].timestamp = dts;
4886 st->index_entries[index_entry_pos].size= sample_size;
4887 st->index_entries[index_entry_pos].min_distance= distance;
4888 st->index_entries[index_entry_pos].flags = index_entry_flags;
4890 sc->ctts_data[index_entry_pos].count = 1;
4891 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4894 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4895 "size %u, distance %d, keyframe %d\n", st->index,
4896 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4898 dts += sample_duration;
4899 offset += sample_size;
4900 sc->data_size += sample_size;
4902 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4903 1 <= INT_MAX - sc->nb_frames_for_fps
4905 sc->duration_for_fps += sample_duration;
4906 sc->nb_frames_for_fps ++;
4910 // EOF found before reading all entries. Fix the hole this would
4911 // leave in index_entries and ctts_data
4912 int gap = entries - i;
4913 memmove(st->index_entries + index_entry_pos,
4914 st->index_entries + index_entry_pos + gap,
4915 sizeof(*st->index_entries) *
4916 (st->nb_index_entries - (index_entry_pos + gap)));
4917 memmove(sc->ctts_data + index_entry_pos,
4918 sc->ctts_data + index_entry_pos + gap,
4919 sizeof(*sc->ctts_data) *
4920 (sc->ctts_count - (index_entry_pos + gap)));
4922 st->nb_index_entries -= gap;
4923 sc->ctts_count -= gap;
4924 if (index_entry_pos < sc->current_sample) {
4925 sc->current_sample -= gap;
4930 // The end of this new fragment may overlap in time with the start
4931 // of the next fragment in index_entries. Mark the samples in the next
4932 // fragment that overlap with AVINDEX_DISCARD_FRAME
4933 prev_dts = AV_NOPTS_VALUE;
4934 if (index_entry_pos > 0)
4935 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4936 for (i = index_entry_pos; i < st->nb_index_entries; i++) {
4937 if (prev_dts < st->index_entries[i].timestamp)
4939 st->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
4942 // If a hole was created to insert the new index_entries into,
4943 // the index_entry recorded for all subsequent moof must
4944 // be incremented by the number of entries inserted.
4945 fix_frag_index_entries(&c->frag_index, next_frag_index,
4946 frag->track_id, entries);
4948 if (pb->eof_reached) {
4949 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
4953 frag->implicit_offset = offset;
4955 sc->track_end = dts + sc->time_offset;
4956 if (st->duration < sc->track_end)
4957 st->duration = sc->track_end;
4962 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4964 int64_t offset = avio_tell(pb) + atom.size, pts, timestamp;
4966 unsigned i, j, track_id, item_count;
4967 AVStream *st = NULL;
4968 AVStream *ref_st = NULL;
4969 MOVStreamContext *sc, *ref_sc = NULL;
4970 AVRational timescale;
4972 version = avio_r8(pb);
4974 avpriv_request_sample(c->fc, "sidx version %u", version);
4978 avio_rb24(pb); // flags
4980 track_id = avio_rb32(pb); // Reference ID
4981 for (i = 0; i < c->fc->nb_streams; i++) {
4982 if (c->fc->streams[i]->id == track_id) {
4983 st = c->fc->streams[i];
4988 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
4994 timescale = av_make_q(1, avio_rb32(pb));
4996 if (timescale.den <= 0) {
4997 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
4998 return AVERROR_INVALIDDATA;
5002 pts = avio_rb32(pb);
5003 offset += avio_rb32(pb);
5005 pts = avio_rb64(pb);
5006 offset += avio_rb64(pb);
5009 avio_rb16(pb); // reserved
5011 item_count = avio_rb16(pb);
5013 for (i = 0; i < item_count; i++) {
5015 MOVFragmentStreamInfo * frag_stream_info;
5016 uint32_t size = avio_rb32(pb);
5017 uint32_t duration = avio_rb32(pb);
5018 if (size & 0x80000000) {
5019 avpriv_request_sample(c->fc, "sidx reference_type 1");
5020 return AVERROR_PATCHWELCOME;
5022 avio_rb32(pb); // sap_flags
5023 timestamp = av_rescale_q(pts, st->time_base, timescale);
5025 index = update_frag_index(c, offset);
5026 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5027 if (frag_stream_info)
5028 frag_stream_info->sidx_pts = timestamp;
5034 st->duration = sc->track_end = pts;
5038 if (offset == avio_size(pb)) {
5039 // Find first entry in fragment index that came from an sidx.
5040 // This will pretty much always be the first entry.
5041 for (i = 0; i < c->frag_index.nb_items; i++) {
5042 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5043 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5044 MOVFragmentStreamInfo * si;
5045 si = &item->stream_info[j];
5046 if (si->sidx_pts != AV_NOPTS_VALUE) {
5047 ref_st = c->fc->streams[j];
5048 ref_sc = ref_st->priv_data;
5053 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5054 st = c->fc->streams[i];
5056 if (!sc->has_sidx) {
5057 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5061 c->frag_index.complete = 1;
5067 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5068 /* like the files created with Adobe Premiere 5.0, for samples see */
5069 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5070 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5075 return 0; /* continue */
5076 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5077 avio_skip(pb, atom.size - 4);
5080 atom.type = avio_rl32(pb);
5082 if (atom.type != MKTAG('m','d','a','t')) {
5083 avio_skip(pb, atom.size);
5086 err = mov_read_mdat(c, pb, atom);
5090 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5095 uint8_t *moov_data; /* uncompressed data */
5096 long cmov_len, moov_len;
5099 avio_rb32(pb); /* dcom atom */
5100 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5101 return AVERROR_INVALIDDATA;
5102 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5103 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5104 return AVERROR_INVALIDDATA;
5106 avio_rb32(pb); /* cmvd atom */
5107 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5108 return AVERROR_INVALIDDATA;
5109 moov_len = avio_rb32(pb); /* uncompressed size */
5110 cmov_len = atom.size - 6 * 4;
5112 cmov_data = av_malloc(cmov_len);
5114 return AVERROR(ENOMEM);
5115 moov_data = av_malloc(moov_len);
5118 return AVERROR(ENOMEM);
5120 ret = ffio_read_size(pb, cmov_data, cmov_len);
5122 goto free_and_return;
5124 ret = AVERROR_INVALIDDATA;
5125 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5126 goto free_and_return;
5127 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5128 goto free_and_return;
5129 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5130 atom.type = MKTAG('m','o','o','v');
5131 atom.size = moov_len;
5132 ret = mov_read_default(c, &ctx, atom);
5138 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5139 return AVERROR(ENOSYS);
5143 /* edit list atom */
5144 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5146 MOVStreamContext *sc;
5147 int i, edit_count, version;
5148 int64_t elst_entry_size;
5150 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5152 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5154 version = avio_r8(pb); /* version */
5155 avio_rb24(pb); /* flags */
5156 edit_count = avio_rb32(pb); /* entries */
5159 elst_entry_size = version == 1 ? 20 : 12;
5160 if (atom.size != edit_count * elst_entry_size) {
5161 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5162 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5163 edit_count, atom.size + 8);
5164 return AVERROR_INVALIDDATA;
5166 edit_count = atom.size / elst_entry_size;
5167 if (edit_count * elst_entry_size != atom.size) {
5168 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.", atom.size, edit_count);
5176 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5177 av_free(sc->elst_data);
5179 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5181 return AVERROR(ENOMEM);
5183 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5184 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5185 MOVElst *e = &sc->elst_data[i];
5188 e->duration = avio_rb64(pb);
5189 e->time = avio_rb64(pb);
5192 e->duration = avio_rb32(pb); /* segment duration */
5193 e->time = (int32_t)avio_rb32(pb); /* media time */
5196 e->rate = avio_rb32(pb) / 65536.0;
5198 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5199 e->duration, e->time, e->rate);
5201 if (e->time < 0 && e->time != -1 &&
5202 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5203 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5204 c->fc->nb_streams-1, i, e->time);
5205 return AVERROR_INVALIDDATA;
5213 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5215 MOVStreamContext *sc;
5217 if (c->fc->nb_streams < 1)
5218 return AVERROR_INVALIDDATA;
5219 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5220 sc->timecode_track = avio_rb32(pb);
5224 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5229 if (c->fc->nb_streams < 1)
5231 st = c->fc->streams[c->fc->nb_streams - 1];
5233 if (atom.size < 4) {
5234 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5235 return AVERROR_INVALIDDATA;
5238 /* For now, propagate only the OBUs, if any. Once libavcodec is
5239 updated to handle isobmff style extradata this can be removed. */
5245 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5252 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5255 int version, color_range, color_primaries, color_trc, color_space;
5257 if (c->fc->nb_streams < 1)
5259 st = c->fc->streams[c->fc->nb_streams - 1];
5261 if (atom.size < 5) {
5262 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5263 return AVERROR_INVALIDDATA;
5266 version = avio_r8(pb);
5268 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5271 avio_skip(pb, 3); /* flags */
5273 avio_skip(pb, 2); /* profile + level */
5274 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5275 color_primaries = avio_r8(pb);
5276 color_trc = avio_r8(pb);
5277 color_space = avio_r8(pb);
5278 if (avio_rb16(pb)) /* codecIntializationDataSize */
5279 return AVERROR_INVALIDDATA;
5281 if (!av_color_primaries_name(color_primaries))
5282 color_primaries = AVCOL_PRI_UNSPECIFIED;
5283 if (!av_color_transfer_name(color_trc))
5284 color_trc = AVCOL_TRC_UNSPECIFIED;
5285 if (!av_color_space_name(color_space))
5286 color_space = AVCOL_SPC_UNSPECIFIED;
5288 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5289 st->codecpar->color_primaries = color_primaries;
5290 st->codecpar->color_trc = color_trc;
5291 st->codecpar->color_space = color_space;
5296 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5298 MOVStreamContext *sc;
5301 if (c->fc->nb_streams < 1)
5302 return AVERROR_INVALIDDATA;
5304 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5306 if (atom.size < 5) {
5307 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5308 return AVERROR_INVALIDDATA;
5311 version = avio_r8(pb);
5313 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5316 avio_skip(pb, 3); /* flags */
5318 sc->mastering = av_mastering_display_metadata_alloc();
5320 return AVERROR(ENOMEM);
5322 for (i = 0; i < 3; i++) {
5323 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5324 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5326 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5327 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5329 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5330 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5332 sc->mastering->has_primaries = 1;
5333 sc->mastering->has_luminance = 1;
5338 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5340 MOVStreamContext *sc;
5341 const int mapping[3] = {1, 2, 0};
5342 const int chroma_den = 50000;
5343 const int luma_den = 10000;
5346 if (c->fc->nb_streams < 1)
5347 return AVERROR_INVALIDDATA;
5349 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5351 if (atom.size < 24) {
5352 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5353 return AVERROR_INVALIDDATA;
5356 sc->mastering = av_mastering_display_metadata_alloc();
5358 return AVERROR(ENOMEM);
5360 for (i = 0; i < 3; i++) {
5361 const int j = mapping[i];
5362 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5363 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5365 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5366 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5368 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5369 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5371 sc->mastering->has_luminance = 1;
5372 sc->mastering->has_primaries = 1;
5377 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5379 MOVStreamContext *sc;
5382 if (c->fc->nb_streams < 1)
5383 return AVERROR_INVALIDDATA;
5385 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5387 if (atom.size < 5) {
5388 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5389 return AVERROR_INVALIDDATA;
5392 version = avio_r8(pb);
5394 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5397 avio_skip(pb, 3); /* flags */
5399 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5401 return AVERROR(ENOMEM);
5403 sc->coll->MaxCLL = avio_rb16(pb);
5404 sc->coll->MaxFALL = avio_rb16(pb);
5409 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5411 MOVStreamContext *sc;
5413 if (c->fc->nb_streams < 1)
5414 return AVERROR_INVALIDDATA;
5416 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5418 if (atom.size < 4) {
5419 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5420 return AVERROR_INVALIDDATA;
5423 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5425 return AVERROR(ENOMEM);
5427 sc->coll->MaxCLL = avio_rb16(pb);
5428 sc->coll->MaxFALL = avio_rb16(pb);
5433 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5436 MOVStreamContext *sc;
5437 enum AVStereo3DType type;
5440 if (c->fc->nb_streams < 1)
5443 st = c->fc->streams[c->fc->nb_streams - 1];
5446 if (atom.size < 5) {
5447 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5448 return AVERROR_INVALIDDATA;
5450 avio_skip(pb, 4); /* version + flags */
5455 type = AV_STEREO3D_2D;
5458 type = AV_STEREO3D_TOPBOTTOM;
5461 type = AV_STEREO3D_SIDEBYSIDE;
5464 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5468 sc->stereo3d = av_stereo3d_alloc();
5470 return AVERROR(ENOMEM);
5472 sc->stereo3d->type = type;
5476 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5479 MOVStreamContext *sc;
5480 int size, version, layout;
5481 int32_t yaw, pitch, roll;
5482 uint32_t l = 0, t = 0, r = 0, b = 0;
5483 uint32_t tag, padding = 0;
5484 enum AVSphericalProjection projection;
5486 if (c->fc->nb_streams < 1)
5489 st = c->fc->streams[c->fc->nb_streams - 1];
5492 if (atom.size < 8) {
5493 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5494 return AVERROR_INVALIDDATA;
5497 size = avio_rb32(pb);
5498 if (size <= 12 || size > atom.size)
5499 return AVERROR_INVALIDDATA;
5501 tag = avio_rl32(pb);
5502 if (tag != MKTAG('s','v','h','d')) {
5503 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5506 version = avio_r8(pb);
5508 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5512 avio_skip(pb, 3); /* flags */
5513 avio_skip(pb, size - 12); /* metadata_source */
5515 size = avio_rb32(pb);
5516 if (size > atom.size)
5517 return AVERROR_INVALIDDATA;
5519 tag = avio_rl32(pb);
5520 if (tag != MKTAG('p','r','o','j')) {
5521 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5525 size = avio_rb32(pb);
5526 if (size > atom.size)
5527 return AVERROR_INVALIDDATA;
5529 tag = avio_rl32(pb);
5530 if (tag != MKTAG('p','r','h','d')) {
5531 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5534 version = avio_r8(pb);
5536 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5540 avio_skip(pb, 3); /* flags */
5542 /* 16.16 fixed point */
5543 yaw = avio_rb32(pb);
5544 pitch = avio_rb32(pb);
5545 roll = avio_rb32(pb);
5547 size = avio_rb32(pb);
5548 if (size > atom.size)
5549 return AVERROR_INVALIDDATA;
5551 tag = avio_rl32(pb);
5552 version = avio_r8(pb);
5554 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5558 avio_skip(pb, 3); /* flags */
5560 case MKTAG('c','b','m','p'):
5561 layout = avio_rb32(pb);
5563 av_log(c->fc, AV_LOG_WARNING,
5564 "Unsupported cubemap layout %d\n", layout);
5567 projection = AV_SPHERICAL_CUBEMAP;
5568 padding = avio_rb32(pb);
5570 case MKTAG('e','q','u','i'):
5576 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5577 av_log(c->fc, AV_LOG_ERROR,
5578 "Invalid bounding rectangle coordinates "
5579 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5580 return AVERROR_INVALIDDATA;
5583 if (l || t || r || b)
5584 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5586 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5589 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5593 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5595 return AVERROR(ENOMEM);
5597 sc->spherical->projection = projection;
5599 sc->spherical->yaw = yaw;
5600 sc->spherical->pitch = pitch;
5601 sc->spherical->roll = roll;
5603 sc->spherical->padding = padding;
5605 sc->spherical->bound_left = l;
5606 sc->spherical->bound_top = t;
5607 sc->spherical->bound_right = r;
5608 sc->spherical->bound_bottom = b;
5613 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5616 uint8_t *buffer = av_malloc(len + 1);
5620 return AVERROR(ENOMEM);
5623 ret = ffio_read_size(pb, buffer, len);
5627 /* Check for mandatory keys and values, try to support XML as best-effort */
5628 if (!sc->spherical &&
5629 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5630 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5631 av_stristr(val, "true") &&
5632 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5633 av_stristr(val, "true") &&
5634 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5635 av_stristr(val, "equirectangular")) {
5636 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5640 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5642 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5643 enum AVStereo3DType mode;
5645 if (av_stristr(buffer, "left-right"))
5646 mode = AV_STEREO3D_SIDEBYSIDE;
5647 else if (av_stristr(buffer, "top-bottom"))
5648 mode = AV_STEREO3D_TOPBOTTOM;
5650 mode = AV_STEREO3D_2D;
5652 sc->stereo3d = av_stereo3d_alloc();
5656 sc->stereo3d->type = mode;
5660 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5662 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5663 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5665 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5666 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5668 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5676 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5679 MOVStreamContext *sc;
5682 static const uint8_t uuid_isml_manifest[] = {
5683 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5684 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5686 static const uint8_t uuid_xmp[] = {
5687 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5688 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5690 static const uint8_t uuid_spherical[] = {
5691 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5692 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5695 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5696 return AVERROR_INVALIDDATA;
5698 if (c->fc->nb_streams < 1)
5700 st = c->fc->streams[c->fc->nb_streams - 1];
5703 ret = avio_read(pb, uuid, sizeof(uuid));
5706 } else if (ret != sizeof(uuid)) {
5707 return AVERROR_INVALIDDATA;
5709 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5710 uint8_t *buffer, *ptr;
5712 size_t len = atom.size - sizeof(uuid);
5715 return AVERROR_INVALIDDATA;
5717 ret = avio_skip(pb, 4); // zeroes
5720 buffer = av_mallocz(len + 1);
5722 return AVERROR(ENOMEM);
5724 ret = avio_read(pb, buffer, len);
5728 } else if (ret != len) {
5730 return AVERROR_INVALIDDATA;
5734 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5735 ptr += sizeof("systemBitrate=\"") - 1;
5736 c->bitrates_count++;
5737 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5739 c->bitrates_count = 0;
5741 return AVERROR(ENOMEM);
5744 ret = strtol(ptr, &endptr, 10);
5745 if (ret < 0 || errno || *endptr != '"') {
5746 c->bitrates[c->bitrates_count - 1] = 0;
5748 c->bitrates[c->bitrates_count - 1] = ret;
5753 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5755 size_t len = atom.size - sizeof(uuid);
5756 if (c->export_xmp) {
5757 buffer = av_mallocz(len + 1);
5759 return AVERROR(ENOMEM);
5761 ret = avio_read(pb, buffer, len);
5765 } else if (ret != len) {
5767 return AVERROR_INVALIDDATA;
5770 av_dict_set(&c->fc->metadata, "xmp", buffer, 0);
5773 // skip all uuid atom, which makes it fast for long uuid-xmp file
5774 ret = avio_skip(pb, len);
5778 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5779 size_t len = atom.size - sizeof(uuid);
5780 ret = mov_parse_uuid_spherical(sc, pb, len);
5784 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5790 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5793 uint8_t content[16];
5798 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5804 && !memcmp(content, "Anevia\x1A\x1A", 8)
5805 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5806 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5812 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5814 uint32_t format = avio_rl32(pb);
5815 MOVStreamContext *sc;
5819 if (c->fc->nb_streams < 1)
5821 st = c->fc->streams[c->fc->nb_streams - 1];
5826 case MKTAG('e','n','c','v'): // encrypted video
5827 case MKTAG('e','n','c','a'): // encrypted audio
5828 id = mov_codec_id(st, format);
5829 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5830 st->codecpar->codec_id != id) {
5831 av_log(c->fc, AV_LOG_WARNING,
5832 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5833 (char*)&format, st->codecpar->codec_id);
5837 st->codecpar->codec_id = id;
5838 sc->format = format;
5842 if (format != sc->format) {
5843 av_log(c->fc, AV_LOG_WARNING,
5844 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5845 (char*)&format, (char*)&sc->format);
5854 * Gets the current encryption info and associated current stream context. If
5855 * we are parsing a track fragment, this will return the specific encryption
5856 * info for this fragment; otherwise this will return the global encryption
5857 * info for the current stream.
5859 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5861 MOVFragmentStreamInfo *frag_stream_info;
5865 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5866 if (frag_stream_info) {
5867 for (i = 0; i < c->fc->nb_streams; i++) {
5868 if (c->fc->streams[i]->id == frag_stream_info->id) {
5869 st = c->fc->streams[i];
5873 if (i == c->fc->nb_streams)
5875 *sc = st->priv_data;
5877 if (!frag_stream_info->encryption_index) {
5878 // If this stream isn't encrypted, don't create the index.
5879 if (!(*sc)->cenc.default_encrypted_sample)
5881 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5882 if (!frag_stream_info->encryption_index)
5883 return AVERROR(ENOMEM);
5885 *encryption_index = frag_stream_info->encryption_index;
5888 // No current track fragment, using stream level encryption info.
5890 if (c->fc->nb_streams < 1)
5892 st = c->fc->streams[c->fc->nb_streams - 1];
5893 *sc = st->priv_data;
5895 if (!(*sc)->cenc.encryption_index) {
5896 // If this stream isn't encrypted, don't create the index.
5897 if (!(*sc)->cenc.default_encrypted_sample)
5899 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5900 if (!(*sc)->cenc.encryption_index)
5901 return AVERROR(ENOMEM);
5904 *encryption_index = (*sc)->cenc.encryption_index;
5909 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
5912 unsigned int subsample_count;
5913 AVSubsampleEncryptionInfo *subsamples;
5915 if (!sc->cenc.default_encrypted_sample) {
5916 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
5917 return AVERROR_INVALIDDATA;
5920 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
5922 return AVERROR(ENOMEM);
5924 if (sc->cenc.per_sample_iv_size != 0) {
5925 if (avio_read(pb, (*sample)->iv, sc->cenc.per_sample_iv_size) != sc->cenc.per_sample_iv_size) {
5926 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
5927 av_encryption_info_free(*sample);
5929 return AVERROR_INVALIDDATA;
5933 if (use_subsamples) {
5934 subsample_count = avio_rb16(pb);
5935 av_free((*sample)->subsamples);
5936 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
5937 if (!(*sample)->subsamples) {
5938 av_encryption_info_free(*sample);
5940 return AVERROR(ENOMEM);
5943 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
5944 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
5945 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
5948 if (pb->eof_reached) {
5949 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
5950 av_encryption_info_free(*sample);
5952 return AVERROR_INVALIDDATA;
5954 (*sample)->subsample_count = subsample_count;
5960 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5962 AVEncryptionInfo **encrypted_samples;
5963 MOVEncryptionIndex *encryption_index;
5964 MOVStreamContext *sc;
5965 int use_subsamples, ret;
5966 unsigned int sample_count, i, alloc_size = 0;
5968 ret = get_current_encryption_info(c, &encryption_index, &sc);
5972 if (encryption_index->nb_encrypted_samples) {
5973 // This can happen if we have both saio/saiz and senc atoms.
5974 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
5978 avio_r8(pb); /* version */
5979 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
5981 sample_count = avio_rb32(pb);
5982 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
5983 return AVERROR(ENOMEM);
5985 for (i = 0; i < sample_count; i++) {
5986 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
5987 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
5988 min_samples * sizeof(*encrypted_samples));
5989 if (encrypted_samples) {
5990 encryption_index->encrypted_samples = encrypted_samples;
5992 ret = mov_read_sample_encryption_info(
5993 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
5995 ret = AVERROR(ENOMEM);
5997 if (pb->eof_reached) {
5998 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
5999 ret = AVERROR_INVALIDDATA;
6004 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6005 av_freep(&encryption_index->encrypted_samples);
6009 encryption_index->nb_encrypted_samples = sample_count;
6014 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6016 AVEncryptionInfo **sample, **encrypted_samples;
6018 size_t sample_count, sample_info_size, i;
6020 unsigned int alloc_size = 0;
6022 if (encryption_index->nb_encrypted_samples)
6024 sample_count = encryption_index->auxiliary_info_sample_count;
6025 if (encryption_index->auxiliary_offsets_count != 1) {
6026 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6027 return AVERROR_PATCHWELCOME;
6029 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6030 return AVERROR(ENOMEM);
6032 prev_pos = avio_tell(pb);
6033 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6034 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6035 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6039 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6040 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6041 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6042 min_samples * sizeof(*encrypted_samples));
6043 if (!encrypted_samples) {
6044 ret = AVERROR(ENOMEM);
6047 encryption_index->encrypted_samples = encrypted_samples;
6049 sample = &encryption_index->encrypted_samples[i];
6050 sample_info_size = encryption_index->auxiliary_info_default_size
6051 ? encryption_index->auxiliary_info_default_size
6052 : encryption_index->auxiliary_info_sizes[i];
6054 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6058 if (pb->eof_reached) {
6059 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6060 ret = AVERROR_INVALIDDATA;
6062 encryption_index->nb_encrypted_samples = sample_count;
6066 avio_seek(pb, prev_pos, SEEK_SET);
6068 for (; i > 0; i--) {
6069 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6071 av_freep(&encryption_index->encrypted_samples);
6077 * Tries to read the given number of bytes from the stream and puts it in a
6078 * newly allocated buffer. This reads in small chunks to avoid allocating large
6079 * memory if the file contains an invalid/malicious size value.
6081 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6083 const unsigned int block_size = 1024 * 1024;
6084 uint8_t *buffer = NULL;
6085 unsigned int alloc_size = 0, offset = 0;
6086 while (offset < size) {
6087 unsigned int new_size =
6088 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6089 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6090 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6093 return AVERROR(ENOMEM);
6095 buffer = new_buffer;
6097 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6099 return AVERROR_INVALIDDATA;
6108 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6110 MOVEncryptionIndex *encryption_index;
6111 MOVStreamContext *sc;
6113 unsigned int sample_count, aux_info_type, aux_info_param;
6115 ret = get_current_encryption_info(c, &encryption_index, &sc);
6119 if (encryption_index->nb_encrypted_samples) {
6120 // This can happen if we have both saio/saiz and senc atoms.
6121 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6125 if (encryption_index->auxiliary_info_sample_count) {
6126 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6127 return AVERROR_INVALIDDATA;
6130 avio_r8(pb); /* version */
6131 if (avio_rb24(pb) & 0x01) { /* flags */
6132 aux_info_type = avio_rb32(pb);
6133 aux_info_param = avio_rb32(pb);
6134 if (sc->cenc.default_encrypted_sample) {
6135 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6136 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6139 if (aux_info_param != 0) {
6140 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6144 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6145 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6146 aux_info_type == MKBETAG('c','e','n','s') ||
6147 aux_info_type == MKBETAG('c','b','c','1') ||
6148 aux_info_type == MKBETAG('c','b','c','s')) &&
6149 aux_info_param == 0) {
6150 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6151 return AVERROR_INVALIDDATA;
6156 } else if (!sc->cenc.default_encrypted_sample) {
6157 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6161 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6162 sample_count = avio_rb32(pb);
6163 encryption_index->auxiliary_info_sample_count = sample_count;
6165 if (encryption_index->auxiliary_info_default_size == 0) {
6166 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6168 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6173 if (encryption_index->auxiliary_offsets_count) {
6174 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6180 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6182 uint64_t *auxiliary_offsets;
6183 MOVEncryptionIndex *encryption_index;
6184 MOVStreamContext *sc;
6186 unsigned int version, entry_count, aux_info_type, aux_info_param;
6187 unsigned int alloc_size = 0;
6189 ret = get_current_encryption_info(c, &encryption_index, &sc);
6193 if (encryption_index->nb_encrypted_samples) {
6194 // This can happen if we have both saio/saiz and senc atoms.
6195 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6199 if (encryption_index->auxiliary_offsets_count) {
6200 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6201 return AVERROR_INVALIDDATA;
6204 version = avio_r8(pb); /* version */
6205 if (avio_rb24(pb) & 0x01) { /* flags */
6206 aux_info_type = avio_rb32(pb);
6207 aux_info_param = avio_rb32(pb);
6208 if (sc->cenc.default_encrypted_sample) {
6209 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6210 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6213 if (aux_info_param != 0) {
6214 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6218 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6219 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6220 aux_info_type == MKBETAG('c','e','n','s') ||
6221 aux_info_type == MKBETAG('c','b','c','1') ||
6222 aux_info_type == MKBETAG('c','b','c','s')) &&
6223 aux_info_param == 0) {
6224 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6225 return AVERROR_INVALIDDATA;
6230 } else if (!sc->cenc.default_encrypted_sample) {
6231 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6235 entry_count = avio_rb32(pb);
6236 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6237 return AVERROR(ENOMEM);
6239 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6240 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6241 auxiliary_offsets = av_fast_realloc(
6242 encryption_index->auxiliary_offsets, &alloc_size,
6243 min_offsets * sizeof(*auxiliary_offsets));
6244 if (!auxiliary_offsets) {
6245 av_freep(&encryption_index->auxiliary_offsets);
6246 return AVERROR(ENOMEM);
6248 encryption_index->auxiliary_offsets = auxiliary_offsets;
6251 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6253 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6255 if (c->frag_index.current >= 0) {
6256 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6260 if (pb->eof_reached) {
6261 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6262 av_freep(&encryption_index->auxiliary_offsets);
6263 return AVERROR_INVALIDDATA;
6266 encryption_index->auxiliary_offsets_count = entry_count;
6268 if (encryption_index->auxiliary_info_sample_count) {
6269 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6275 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6277 AVEncryptionInitInfo *info, *old_init_info;
6280 uint8_t *side_data, *extra_data, *old_side_data;
6281 size_t side_data_size;
6282 int ret = 0, old_side_data_size;
6283 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6285 if (c->fc->nb_streams < 1)
6287 st = c->fc->streams[c->fc->nb_streams-1];
6289 version = avio_r8(pb); /* version */
6290 avio_rb24(pb); /* flags */
6292 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6293 /* key_id_size */ 16, /* data_size */ 0);
6295 return AVERROR(ENOMEM);
6297 if (avio_read(pb, info->system_id, 16) != 16) {
6298 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6299 ret = AVERROR_INVALIDDATA;
6304 kid_count = avio_rb32(pb);
6305 if (kid_count >= INT_MAX / sizeof(*key_ids))
6306 return AVERROR(ENOMEM);
6308 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6309 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6310 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6311 min_kid_count * sizeof(*key_ids));
6313 ret = AVERROR(ENOMEM);
6316 info->key_ids = key_ids;
6318 info->key_ids[i] = av_mallocz(16);
6319 if (!info->key_ids[i]) {
6320 ret = AVERROR(ENOMEM);
6323 info->num_key_ids = i + 1;
6325 if (avio_read(pb, info->key_ids[i], 16) != 16) {
6326 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6327 ret = AVERROR_INVALIDDATA;
6332 if (pb->eof_reached) {
6333 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6334 ret = AVERROR_INVALIDDATA;
6339 extra_data_size = avio_rb32(pb);
6340 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6344 av_freep(&info->data); // malloc(0) may still allocate something.
6345 info->data = extra_data;
6346 info->data_size = extra_data_size;
6348 // If there is existing initialization data, append to the list.
6349 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6350 if (old_side_data) {
6351 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6352 if (old_init_info) {
6353 // Append to the end of the list.
6354 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6360 info = old_init_info;
6362 // Assume existing side-data will be valid, so the only error we could get is OOM.
6363 ret = AVERROR(ENOMEM);
6368 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6370 ret = AVERROR(ENOMEM);
6373 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6374 side_data, side_data_size);
6379 av_encryption_init_info_free(info);
6383 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6386 MOVStreamContext *sc;
6388 if (c->fc->nb_streams < 1)
6390 st = c->fc->streams[c->fc->nb_streams-1];
6393 if (sc->pseudo_stream_id != 0) {
6394 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6395 return AVERROR_PATCHWELCOME;
6399 return AVERROR_INVALIDDATA;
6401 avio_rb32(pb); /* version and flags */
6403 if (!sc->cenc.default_encrypted_sample) {
6404 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6405 if (!sc->cenc.default_encrypted_sample) {
6406 return AVERROR(ENOMEM);
6410 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6414 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6417 MOVStreamContext *sc;
6418 unsigned int version, pattern, is_protected, iv_size;
6420 if (c->fc->nb_streams < 1)
6422 st = c->fc->streams[c->fc->nb_streams-1];
6425 if (sc->pseudo_stream_id != 0) {
6426 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6427 return AVERROR_PATCHWELCOME;
6430 if (!sc->cenc.default_encrypted_sample) {
6431 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6432 if (!sc->cenc.default_encrypted_sample) {
6433 return AVERROR(ENOMEM);
6438 return AVERROR_INVALIDDATA;
6440 version = avio_r8(pb); /* version */
6441 avio_rb24(pb); /* flags */
6443 avio_r8(pb); /* reserved */
6444 pattern = avio_r8(pb);
6447 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6448 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6451 is_protected = avio_r8(pb);
6452 if (is_protected && !sc->cenc.encryption_index) {
6453 // The whole stream should be by-default encrypted.
6454 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6455 if (!sc->cenc.encryption_index)
6456 return AVERROR(ENOMEM);
6458 sc->cenc.per_sample_iv_size = avio_r8(pb);
6459 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6460 sc->cenc.per_sample_iv_size != 16) {
6461 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6462 return AVERROR_INVALIDDATA;
6464 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6465 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6466 return AVERROR_INVALIDDATA;
6469 if (is_protected && !sc->cenc.per_sample_iv_size) {
6470 iv_size = avio_r8(pb);
6471 if (iv_size != 8 && iv_size != 16) {
6472 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6473 return AVERROR_INVALIDDATA;
6476 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6477 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6478 return AVERROR_INVALIDDATA;
6485 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6488 int last, type, size, ret;
6491 if (c->fc->nb_streams < 1)
6493 st = c->fc->streams[c->fc->nb_streams-1];
6495 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6496 return AVERROR_INVALIDDATA;
6498 /* Check FlacSpecificBox version. */
6499 if (avio_r8(pb) != 0)
6500 return AVERROR_INVALIDDATA;
6502 avio_rb24(pb); /* Flags */
6504 avio_read(pb, buf, sizeof(buf));
6505 flac_parse_block_header(buf, &last, &type, &size);
6507 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6508 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6509 return AVERROR_INVALIDDATA;
6512 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6517 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6522 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6526 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6527 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6528 return AVERROR_PATCHWELCOME;
6531 if (!sc->cenc.aes_ctr) {
6532 /* initialize the cipher */
6533 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6534 if (!sc->cenc.aes_ctr) {
6535 return AVERROR(ENOMEM);
6538 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6544 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6546 if (!sample->subsample_count)
6548 /* decrypt the whole packet */
6549 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6553 for (i = 0; i < sample->subsample_count; i++)
6555 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6556 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6557 return AVERROR_INVALIDDATA;
6560 /* skip the clear bytes */
6561 input += sample->subsamples[i].bytes_of_clear_data;
6562 size -= sample->subsamples[i].bytes_of_clear_data;
6564 /* decrypt the encrypted bytes */
6565 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6566 input += sample->subsamples[i].bytes_of_protected_data;
6567 size -= sample->subsamples[i].bytes_of_protected_data;
6571 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6572 return AVERROR_INVALIDDATA;
6578 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6580 MOVFragmentStreamInfo *frag_stream_info;
6581 MOVEncryptionIndex *encryption_index;
6582 AVEncryptionInfo *encrypted_sample;
6583 int encrypted_index, ret;
6585 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6586 encrypted_index = current_index;
6587 encryption_index = NULL;
6588 if (frag_stream_info) {
6589 // Note this only supports encryption info in the first sample descriptor.
6590 if (mov->fragment.stsd_id == 1) {
6591 if (frag_stream_info->encryption_index) {
6592 encrypted_index = current_index - frag_stream_info->index_entry;
6593 encryption_index = frag_stream_info->encryption_index;
6595 encryption_index = sc->cenc.encryption_index;
6599 encryption_index = sc->cenc.encryption_index;
6602 if (encryption_index) {
6603 if (encryption_index->auxiliary_info_sample_count &&
6604 !encryption_index->nb_encrypted_samples) {
6605 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6606 return AVERROR_INVALIDDATA;
6608 if (encryption_index->auxiliary_offsets_count &&
6609 !encryption_index->nb_encrypted_samples) {
6610 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6611 return AVERROR_INVALIDDATA;
6614 if (!encryption_index->nb_encrypted_samples) {
6615 // Full-sample encryption with default settings.
6616 encrypted_sample = sc->cenc.default_encrypted_sample;
6617 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6618 // Per-sample setting override.
6619 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6621 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6622 return AVERROR_INVALIDDATA;
6625 if (mov->decryption_key) {
6626 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6629 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6631 return AVERROR(ENOMEM);
6632 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6642 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6644 const int OPUS_SEEK_PREROLL_MS = 80;
6649 if (c->fc->nb_streams < 1)
6651 st = c->fc->streams[c->fc->nb_streams-1];
6653 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6654 return AVERROR_INVALIDDATA;
6656 /* Check OpusSpecificBox version. */
6657 if (avio_r8(pb) != 0) {
6658 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6659 return AVERROR_INVALIDDATA;
6662 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6663 size = atom.size + 8;
6665 if (ff_alloc_extradata(st->codecpar, size))
6666 return AVERROR(ENOMEM);
6668 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6669 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6670 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6671 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6673 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6674 little-endian; aside from the preceeding magic and version they're
6675 otherwise currently identical. Data after output gain at offset 16
6676 doesn't need to be bytewapped. */
6677 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6678 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6679 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6680 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6682 st->codecpar->initial_padding = pre_skip;
6683 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6684 (AVRational){1, 1000},
6685 (AVRational){1, 48000});
6690 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6693 unsigned format_info;
6694 int channel_assignment, channel_assignment1, channel_assignment2;
6697 if (c->fc->nb_streams < 1)
6699 st = c->fc->streams[c->fc->nb_streams-1];
6702 return AVERROR_INVALIDDATA;
6704 format_info = avio_rb32(pb);
6706 ratebits = (format_info >> 28) & 0xF;
6707 channel_assignment1 = (format_info >> 15) & 0x1F;
6708 channel_assignment2 = format_info & 0x1FFF;
6709 if (channel_assignment2)
6710 channel_assignment = channel_assignment2;
6712 channel_assignment = channel_assignment1;
6714 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6715 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6716 st->codecpar->channels = truehd_channels(channel_assignment);
6717 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6722 static const MOVParseTableEntry mov_default_parse_table[] = {
6723 { MKTAG('A','C','L','R'), mov_read_aclr },
6724 { MKTAG('A','P','R','G'), mov_read_avid },
6725 { MKTAG('A','A','L','P'), mov_read_avid },
6726 { MKTAG('A','R','E','S'), mov_read_ares },
6727 { MKTAG('a','v','s','s'), mov_read_avss },
6728 { MKTAG('a','v','1','C'), mov_read_av1c },
6729 { MKTAG('c','h','p','l'), mov_read_chpl },
6730 { MKTAG('c','o','6','4'), mov_read_stco },
6731 { MKTAG('c','o','l','r'), mov_read_colr },
6732 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6733 { MKTAG('d','i','n','f'), mov_read_default },
6734 { MKTAG('D','p','x','E'), mov_read_dpxe },
6735 { MKTAG('d','r','e','f'), mov_read_dref },
6736 { MKTAG('e','d','t','s'), mov_read_default },
6737 { MKTAG('e','l','s','t'), mov_read_elst },
6738 { MKTAG('e','n','d','a'), mov_read_enda },
6739 { MKTAG('f','i','e','l'), mov_read_fiel },
6740 { MKTAG('a','d','r','m'), mov_read_adrm },
6741 { MKTAG('f','t','y','p'), mov_read_ftyp },
6742 { MKTAG('g','l','b','l'), mov_read_glbl },
6743 { MKTAG('h','d','l','r'), mov_read_hdlr },
6744 { MKTAG('i','l','s','t'), mov_read_ilst },
6745 { MKTAG('j','p','2','h'), mov_read_jp2h },
6746 { MKTAG('m','d','a','t'), mov_read_mdat },
6747 { MKTAG('m','d','h','d'), mov_read_mdhd },
6748 { MKTAG('m','d','i','a'), mov_read_default },
6749 { MKTAG('m','e','t','a'), mov_read_meta },
6750 { MKTAG('m','i','n','f'), mov_read_default },
6751 { MKTAG('m','o','o','f'), mov_read_moof },
6752 { MKTAG('m','o','o','v'), mov_read_moov },
6753 { MKTAG('m','v','e','x'), mov_read_default },
6754 { MKTAG('m','v','h','d'), mov_read_mvhd },
6755 { MKTAG('S','M','I',' '), mov_read_svq3 },
6756 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6757 { MKTAG('a','v','c','C'), mov_read_glbl },
6758 { MKTAG('p','a','s','p'), mov_read_pasp },
6759 { MKTAG('s','i','d','x'), mov_read_sidx },
6760 { MKTAG('s','t','b','l'), mov_read_default },
6761 { MKTAG('s','t','c','o'), mov_read_stco },
6762 { MKTAG('s','t','p','s'), mov_read_stps },
6763 { MKTAG('s','t','r','f'), mov_read_strf },
6764 { MKTAG('s','t','s','c'), mov_read_stsc },
6765 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6766 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6767 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6768 { MKTAG('s','t','t','s'), mov_read_stts },
6769 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6770 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6771 { MKTAG('t','f','d','t'), mov_read_tfdt },
6772 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6773 { MKTAG('t','r','a','k'), mov_read_trak },
6774 { MKTAG('t','r','a','f'), mov_read_default },
6775 { MKTAG('t','r','e','f'), mov_read_default },
6776 { MKTAG('t','m','c','d'), mov_read_tmcd },
6777 { MKTAG('c','h','a','p'), mov_read_chap },
6778 { MKTAG('t','r','e','x'), mov_read_trex },
6779 { MKTAG('t','r','u','n'), mov_read_trun },
6780 { MKTAG('u','d','t','a'), mov_read_default },
6781 { MKTAG('w','a','v','e'), mov_read_wave },
6782 { MKTAG('e','s','d','s'), mov_read_esds },
6783 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6784 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6785 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6786 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6787 { MKTAG('w','f','e','x'), mov_read_wfex },
6788 { MKTAG('c','m','o','v'), mov_read_cmov },
6789 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6790 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6791 { MKTAG('s','b','g','p'), mov_read_sbgp },
6792 { MKTAG('h','v','c','C'), mov_read_glbl },
6793 { MKTAG('u','u','i','d'), mov_read_uuid },
6794 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6795 { MKTAG('f','r','e','e'), mov_read_free },
6796 { MKTAG('-','-','-','-'), mov_read_custom },
6797 { MKTAG('s','i','n','f'), mov_read_default },
6798 { MKTAG('f','r','m','a'), mov_read_frma },
6799 { MKTAG('s','e','n','c'), mov_read_senc },
6800 { MKTAG('s','a','i','z'), mov_read_saiz },
6801 { MKTAG('s','a','i','o'), mov_read_saio },
6802 { MKTAG('p','s','s','h'), mov_read_pssh },
6803 { MKTAG('s','c','h','m'), mov_read_schm },
6804 { MKTAG('s','c','h','i'), mov_read_default },
6805 { MKTAG('t','e','n','c'), mov_read_tenc },
6806 { MKTAG('d','f','L','a'), mov_read_dfla },
6807 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6808 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6809 { MKTAG('d','O','p','s'), mov_read_dops },
6810 { MKTAG('d','m','l','p'), mov_read_dmlp },
6811 { MKTAG('S','m','D','m'), mov_read_smdm },
6812 { MKTAG('C','o','L','L'), mov_read_coll },
6813 { MKTAG('v','p','c','C'), mov_read_vpcc },
6814 { MKTAG('m','d','c','v'), mov_read_mdcv },
6815 { MKTAG('c','l','l','i'), mov_read_clli },
6819 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6821 int64_t total_size = 0;
6825 if (c->atom_depth > 10) {
6826 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6827 return AVERROR_INVALIDDATA;
6832 atom.size = INT64_MAX;
6833 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6834 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
6837 if (atom.size >= 8) {
6838 a.size = avio_rb32(pb);
6839 a.type = avio_rl32(pb);
6840 if (a.type == MKTAG('f','r','e','e') &&
6842 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT &&
6845 uint32_t *type = (uint32_t *)buf + 1;
6846 if (avio_read(pb, buf, 8) != 8)
6847 return AVERROR_INVALIDDATA;
6848 avio_seek(pb, -8, SEEK_CUR);
6849 if (*type == MKTAG('m','v','h','d') ||
6850 *type == MKTAG('c','m','o','v')) {
6851 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free atom.\n");
6852 a.type = MKTAG('m','o','o','v');
6855 if (atom.type != MKTAG('r','o','o','t') &&
6856 atom.type != MKTAG('m','o','o','v'))
6858 if (a.type == MKTAG('t','r','a','k') || a.type == MKTAG('m','d','a','t'))
6860 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
6867 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
6868 a.size = avio_rb64(pb) - 8;
6872 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
6873 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
6875 a.size = atom.size - total_size + 8;
6880 a.size = FFMIN(a.size, atom.size - total_size);
6882 for (i = 0; mov_default_parse_table[i].type; i++)
6883 if (mov_default_parse_table[i].type == a.type) {
6884 parse = mov_default_parse_table[i].parse;
6888 // container is user data
6889 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
6890 atom.type == MKTAG('i','l','s','t')))
6891 parse = mov_read_udta_string;
6893 // Supports parsing the QuickTime Metadata Keys.
6894 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
6895 if (!parse && c->found_hdlr_mdta &&
6896 atom.type == MKTAG('m','e','t','a') &&
6897 a.type == MKTAG('k','e','y','s')) {
6898 parse = mov_read_keys;
6901 if (!parse) { /* skip leaf atoms data */
6902 avio_skip(pb, a.size);
6904 int64_t start_pos = avio_tell(pb);
6906 int err = parse(c, pb, a);
6911 if (c->found_moov && c->found_mdat &&
6912 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
6913 start_pos + a.size == avio_size(pb))) {
6914 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
6915 c->next_root_atom = start_pos + a.size;
6919 left = a.size - avio_tell(pb) + start_pos;
6920 if (left > 0) /* skip garbage at atom end */
6921 avio_skip(pb, left);
6922 else if (left < 0) {
6923 av_log(c->fc, AV_LOG_WARNING,
6924 "overread end of atom '%.4s' by %"PRId64" bytes\n",
6925 (char*)&a.type, -left);
6926 avio_seek(pb, left, SEEK_CUR);
6930 total_size += a.size;
6933 if (total_size < atom.size && atom.size < 0x7ffff)
6934 avio_skip(pb, atom.size - total_size);
6940 static int mov_probe(const AVProbeData *p)
6945 int moov_offset = -1;
6947 /* check file header */
6950 /* ignore invalid offset */
6951 if ((offset + 8) > (unsigned int)p->buf_size)
6953 tag = AV_RL32(p->buf + offset + 4);
6955 /* check for obvious tags */
6956 case MKTAG('m','o','o','v'):
6957 moov_offset = offset + 4;
6958 case MKTAG('m','d','a','t'):
6959 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
6960 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
6961 case MKTAG('f','t','y','p'):
6962 if (AV_RB32(p->buf+offset) < 8 &&
6963 (AV_RB32(p->buf+offset) != 1 ||
6964 offset + 12 > (unsigned int)p->buf_size ||
6965 AV_RB64(p->buf+offset + 8) == 0)) {
6966 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
6967 } else if (tag == MKTAG('f','t','y','p') &&
6968 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
6969 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
6971 score = FFMAX(score, 5);
6973 score = AVPROBE_SCORE_MAX;
6975 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
6977 /* those are more common words, so rate then a bit less */
6978 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
6979 case MKTAG('w','i','d','e'):
6980 case MKTAG('f','r','e','e'):
6981 case MKTAG('j','u','n','k'):
6982 case MKTAG('p','i','c','t'):
6983 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
6984 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
6986 case MKTAG(0x82,0x82,0x7f,0x7d):
6987 case MKTAG('s','k','i','p'):
6988 case MKTAG('u','u','i','d'):
6989 case MKTAG('p','r','f','l'):
6990 /* if we only find those cause probedata is too small at least rate them */
6991 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
6992 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
6995 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
6998 if(score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
6999 /* moov atom in the header - we should make sure that this is not a
7000 * MOV-packed MPEG-PS */
7001 offset = moov_offset;
7003 while(offset < (p->buf_size - 16)){ /* Sufficient space */
7004 /* We found an actual hdlr atom */
7005 if(AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7006 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7007 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')){
7008 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7009 /* We found a media handler reference atom describing an
7010 * MPEG-PS-in-MOV, return a
7011 * low score to force expanding the probe window until
7012 * mpegps_probe finds what it needs */
7023 // must be done after parsing all trak because there's no order requirement
7024 static void mov_read_chapters(AVFormatContext *s)
7026 MOVContext *mov = s->priv_data;
7028 MOVStreamContext *sc;
7033 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7034 chapter_track = mov->chapter_tracks[j];
7036 for (i = 0; i < s->nb_streams; i++)
7037 if (s->streams[i]->id == chapter_track) {
7042 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7047 cur_pos = avio_tell(sc->pb);
7049 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7050 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7051 if (st->nb_index_entries) {
7052 // Retrieve the first frame, if possible
7054 AVIndexEntry *sample = &st->index_entries[0];
7055 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7056 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7060 if (av_get_packet(sc->pb, &pkt, sample->size) < 0)
7063 st->attached_pic = pkt;
7064 st->attached_pic.stream_index = st->index;
7065 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
7068 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7069 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7070 st->discard = AVDISCARD_ALL;
7071 for (i = 0; i < st->nb_index_entries; i++) {
7072 AVIndexEntry *sample = &st->index_entries[i];
7073 int64_t end = i+1 < st->nb_index_entries ? st->index_entries[i+1].timestamp : st->duration;
7078 if (end < sample->timestamp) {
7079 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7080 end = AV_NOPTS_VALUE;
7083 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7084 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7088 // the first two bytes are the length of the title
7089 len = avio_rb16(sc->pb);
7090 if (len > sample->size-2)
7092 title_len = 2*len + 1;
7093 if (!(title = av_mallocz(title_len)))
7096 // The samples could theoretically be in any encoding if there's an encd
7097 // atom following, but in practice are only utf-8 or utf-16, distinguished
7098 // instead by the presence of a BOM
7102 ch = avio_rb16(sc->pb);
7104 avio_get_str16be(sc->pb, len, title, title_len);
7105 else if (ch == 0xfffe)
7106 avio_get_str16le(sc->pb, len, title, title_len);
7109 if (len == 1 || len == 2)
7112 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7116 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7121 avio_seek(sc->pb, cur_pos, SEEK_SET);
7125 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7126 uint32_t value, int flags)
7129 char buf[AV_TIMECODE_STR_SIZE];
7130 AVRational rate = st->avg_frame_rate;
7131 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7134 av_dict_set(&st->metadata, "timecode",
7135 av_timecode_make_string(&tc, buf, value), 0);
7139 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7141 MOVStreamContext *sc = st->priv_data;
7142 char buf[AV_TIMECODE_STR_SIZE];
7143 int64_t cur_pos = avio_tell(sc->pb);
7144 int hh, mm, ss, ff, drop;
7146 if (!st->nb_index_entries)
7149 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7150 avio_skip(s->pb, 13);
7151 hh = avio_r8(s->pb);
7152 mm = avio_r8(s->pb);
7153 ss = avio_r8(s->pb);
7154 drop = avio_r8(s->pb);
7155 ff = avio_r8(s->pb);
7156 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7157 hh, mm, ss, drop ? ';' : ':', ff);
7158 av_dict_set(&st->metadata, "timecode", buf, 0);
7160 avio_seek(sc->pb, cur_pos, SEEK_SET);
7164 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7166 MOVStreamContext *sc = st->priv_data;
7168 int64_t cur_pos = avio_tell(sc->pb);
7171 if (!st->nb_index_entries)
7174 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7175 value = avio_rb32(s->pb);
7177 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7178 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7179 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7181 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7182 * not the case) and thus assume "frame number format" instead of QT one.
7183 * No sample with tmcd track can be found with a QT timecode at the moment,
7184 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7186 parse_timecode_in_framenum_format(s, st, value, flags);
7188 avio_seek(sc->pb, cur_pos, SEEK_SET);
7192 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7194 if (!index || !*index) return;
7195 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7196 av_encryption_info_free((*index)->encrypted_samples[i]);
7198 av_freep(&(*index)->encrypted_samples);
7199 av_freep(&(*index)->auxiliary_info_sizes);
7200 av_freep(&(*index)->auxiliary_offsets);
7204 static int mov_read_close(AVFormatContext *s)
7206 MOVContext *mov = s->priv_data;
7209 for (i = 0; i < s->nb_streams; i++) {
7210 AVStream *st = s->streams[i];
7211 MOVStreamContext *sc = st->priv_data;
7216 av_freep(&sc->ctts_data);
7217 for (j = 0; j < sc->drefs_count; j++) {
7218 av_freep(&sc->drefs[j].path);
7219 av_freep(&sc->drefs[j].dir);
7221 av_freep(&sc->drefs);
7223 sc->drefs_count = 0;
7225 if (!sc->pb_is_copied)
7226 ff_format_io_close(s, &sc->pb);
7229 av_freep(&sc->chunk_offsets);
7230 av_freep(&sc->stsc_data);
7231 av_freep(&sc->sample_sizes);
7232 av_freep(&sc->keyframes);
7233 av_freep(&sc->stts_data);
7234 av_freep(&sc->stps_data);
7235 av_freep(&sc->elst_data);
7236 av_freep(&sc->rap_group);
7237 av_freep(&sc->display_matrix);
7238 av_freep(&sc->index_ranges);
7241 for (j = 0; j < sc->stsd_count; j++)
7242 av_free(sc->extradata[j]);
7243 av_freep(&sc->extradata);
7244 av_freep(&sc->extradata_size);
7246 mov_free_encryption_index(&sc->cenc.encryption_index);
7247 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7248 av_aes_ctr_free(sc->cenc.aes_ctr);
7250 av_freep(&sc->stereo3d);
7251 av_freep(&sc->spherical);
7252 av_freep(&sc->mastering);
7253 av_freep(&sc->coll);
7256 if (mov->dv_demux) {
7257 avformat_free_context(mov->dv_fctx);
7258 mov->dv_fctx = NULL;
7261 if (mov->meta_keys) {
7262 for (i = 1; i < mov->meta_keys_count; i++) {
7263 av_freep(&mov->meta_keys[i]);
7265 av_freep(&mov->meta_keys);
7268 av_freep(&mov->trex_data);
7269 av_freep(&mov->bitrates);
7271 for (i = 0; i < mov->frag_index.nb_items; i++) {
7272 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7273 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7274 mov_free_encryption_index(&frag[j].encryption_index);
7276 av_freep(&mov->frag_index.item[i].stream_info);
7278 av_freep(&mov->frag_index.item);
7280 av_freep(&mov->aes_decrypt);
7281 av_freep(&mov->chapter_tracks);
7286 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7290 for (i = 0; i < s->nb_streams; i++) {
7291 AVStream *st = s->streams[i];
7292 MOVStreamContext *sc = st->priv_data;
7294 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7295 sc->timecode_track == tmcd_id)
7301 /* look for a tmcd track not referenced by any video track, and export it globally */
7302 static void export_orphan_timecode(AVFormatContext *s)
7306 for (i = 0; i < s->nb_streams; i++) {
7307 AVStream *st = s->streams[i];
7309 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7310 !tmcd_is_referenced(s, i + 1)) {
7311 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7313 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7320 static int read_tfra(MOVContext *mov, AVIOContext *f)
7322 int version, fieldlength, i, j;
7323 int64_t pos = avio_tell(f);
7324 uint32_t size = avio_rb32(f);
7325 unsigned track_id, item_count;
7327 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7330 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7332 version = avio_r8(f);
7334 track_id = avio_rb32(f);
7335 fieldlength = avio_rb32(f);
7336 item_count = avio_rb32(f);
7337 for (i = 0; i < item_count; i++) {
7338 int64_t time, offset;
7340 MOVFragmentStreamInfo * frag_stream_info;
7343 return AVERROR_INVALIDDATA;
7347 time = avio_rb64(f);
7348 offset = avio_rb64(f);
7350 time = avio_rb32(f);
7351 offset = avio_rb32(f);
7354 // The first sample of each stream in a fragment is always a random
7355 // access sample. So it's entry in the tfra can be used as the
7356 // initial PTS of the fragment.
7357 index = update_frag_index(mov, offset);
7358 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7359 if (frag_stream_info &&
7360 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7361 frag_stream_info->first_tfra_pts = time;
7363 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7365 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7367 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7371 avio_seek(f, pos + size, SEEK_SET);
7375 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7377 int64_t stream_size = avio_size(f);
7378 int64_t original_pos = avio_tell(f);
7382 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7386 mfra_size = avio_rb32(f);
7387 if (mfra_size < 0 || mfra_size > stream_size) {
7388 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7391 if ((seek_ret = avio_seek(f, -mfra_size, SEEK_CUR)) < 0) {
7395 if (avio_rb32(f) != mfra_size) {
7396 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7399 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7400 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7403 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7405 ret = read_tfra(c, f);
7411 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7413 av_log(c->fc, AV_LOG_ERROR,
7414 "failed to seek back after looking for mfra\n");
7420 static int mov_read_header(AVFormatContext *s)
7422 MOVContext *mov = s->priv_data;
7423 AVIOContext *pb = s->pb;
7425 MOVAtom atom = { AV_RL32("root") };
7428 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7429 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7430 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7431 return AVERROR(EINVAL);
7435 mov->trak_index = -1;
7436 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7437 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7438 atom.size = avio_size(pb);
7440 atom.size = INT64_MAX;
7442 /* check MOV header */
7444 if (mov->moov_retry)
7445 avio_seek(pb, 0, SEEK_SET);
7446 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7447 av_log(s, AV_LOG_ERROR, "error reading header\n");
7451 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7452 if (!mov->found_moov) {
7453 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7455 return AVERROR_INVALIDDATA;
7457 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7459 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7460 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7461 mov_read_chapters(s);
7462 for (i = 0; i < s->nb_streams; i++)
7463 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7464 mov_read_timecode_track(s, s->streams[i]);
7465 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7466 mov_read_rtmd_track(s, s->streams[i]);
7470 /* copy timecode metadata from tmcd tracks to the related video streams */
7471 for (i = 0; i < s->nb_streams; i++) {
7472 AVStream *st = s->streams[i];
7473 MOVStreamContext *sc = st->priv_data;
7474 if (sc->timecode_track > 0) {
7475 AVDictionaryEntry *tcr;
7476 int tmcd_st_id = -1;
7478 for (j = 0; j < s->nb_streams; j++)
7479 if (s->streams[j]->id == sc->timecode_track)
7482 if (tmcd_st_id < 0 || tmcd_st_id == i)
7484 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7486 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7489 export_orphan_timecode(s);
7491 for (i = 0; i < s->nb_streams; i++) {
7492 AVStream *st = s->streams[i];
7493 MOVStreamContext *sc = st->priv_data;
7494 fix_timescale(mov, sc);
7495 if(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7496 st->skip_samples = sc->start_pad;
7498 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7499 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7500 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7501 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7502 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7503 st->codecpar->width = sc->width;
7504 st->codecpar->height = sc->height;
7506 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7507 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7511 if (mov->handbrake_version &&
7512 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7513 st->codecpar->codec_id == AV_CODEC_ID_MP3
7515 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7516 st->need_parsing = AVSTREAM_PARSE_FULL;
7520 if (mov->trex_data) {
7521 for (i = 0; i < s->nb_streams; i++) {
7522 AVStream *st = s->streams[i];
7523 MOVStreamContext *sc = st->priv_data;
7524 if (st->duration > 0) {
7525 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7526 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7527 sc->data_size, sc->time_scale);
7529 return AVERROR_INVALIDDATA;
7531 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7536 if (mov->use_mfra_for > 0) {
7537 for (i = 0; i < s->nb_streams; i++) {
7538 AVStream *st = s->streams[i];
7539 MOVStreamContext *sc = st->priv_data;
7540 if (sc->duration_for_fps > 0) {
7541 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7542 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7543 sc->data_size, sc->time_scale);
7545 return AVERROR_INVALIDDATA;
7547 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7548 sc->duration_for_fps;
7553 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7554 if (mov->bitrates[i]) {
7555 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7559 ff_rfps_calculate(s);
7561 for (i = 0; i < s->nb_streams; i++) {
7562 AVStream *st = s->streams[i];
7563 MOVStreamContext *sc = st->priv_data;
7565 switch (st->codecpar->codec_type) {
7566 case AVMEDIA_TYPE_AUDIO:
7567 err = ff_replaygain_export(st, s->metadata);
7573 case AVMEDIA_TYPE_VIDEO:
7574 if (sc->display_matrix) {
7575 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7576 sizeof(int32_t) * 9);
7580 sc->display_matrix = NULL;
7583 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7584 (uint8_t *)sc->stereo3d,
7585 sizeof(*sc->stereo3d));
7589 sc->stereo3d = NULL;
7591 if (sc->spherical) {
7592 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7593 (uint8_t *)sc->spherical,
7594 sc->spherical_size);
7598 sc->spherical = NULL;
7600 if (sc->mastering) {
7601 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7602 (uint8_t *)sc->mastering,
7603 sizeof(*sc->mastering));
7607 sc->mastering = NULL;
7610 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7611 (uint8_t *)sc->coll,
7621 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7623 for (i = 0; i < mov->frag_index.nb_items; i++)
7624 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7625 mov->frag_index.item[i].headers_read = 1;
7630 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7632 AVIndexEntry *sample = NULL;
7633 int64_t best_dts = INT64_MAX;
7635 for (i = 0; i < s->nb_streams; i++) {
7636 AVStream *avst = s->streams[i];
7637 MOVStreamContext *msc = avst->priv_data;
7638 if (msc->pb && msc->current_sample < avst->nb_index_entries) {
7639 AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample];
7640 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7641 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7642 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7643 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7644 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb &&
7645 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7646 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7647 sample = current_sample;
7656 static int should_retry(AVIOContext *pb, int error_code) {
7657 if (error_code == AVERROR_EOF || avio_feof(pb))
7663 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7666 MOVContext *mov = s->priv_data;
7668 if (index >= 0 && index < mov->frag_index.nb_items)
7669 target = mov->frag_index.item[index].moof_offset;
7670 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7671 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7672 return AVERROR_INVALIDDATA;
7675 mov->next_root_atom = 0;
7676 if (index < 0 || index >= mov->frag_index.nb_items)
7677 index = search_frag_moof_offset(&mov->frag_index, target);
7678 if (index < mov->frag_index.nb_items) {
7679 if (index + 1 < mov->frag_index.nb_items)
7680 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7681 if (mov->frag_index.item[index].headers_read)
7683 mov->frag_index.item[index].headers_read = 1;
7686 mov->found_mdat = 0;
7688 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7691 if (avio_feof(s->pb))
7693 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7698 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7700 uint8_t *side, *extradata;
7703 /* Save the current index. */
7704 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7706 /* Notify the decoder that extradata changed. */
7707 extradata_size = sc->extradata_size[sc->last_stsd_index];
7708 extradata = sc->extradata[sc->last_stsd_index];
7709 if (extradata_size > 0 && extradata) {
7710 side = av_packet_new_side_data(pkt,
7711 AV_PKT_DATA_NEW_EXTRADATA,
7714 return AVERROR(ENOMEM);
7715 memcpy(side, extradata, extradata_size);
7721 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7723 MOVContext *mov = s->priv_data;
7724 MOVStreamContext *sc;
7725 AVIndexEntry *sample;
7726 AVStream *st = NULL;
7727 int64_t current_index;
7731 sample = mov_find_next_sample(s, &st);
7732 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7733 if (!mov->next_root_atom)
7735 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7740 /* must be done just before reading, to avoid infinite loop on sample */
7741 current_index = sc->current_index;
7742 mov_current_sample_inc(sc);
7744 if (mov->next_root_atom) {
7745 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7746 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7749 if (st->discard != AVDISCARD_ALL) {
7750 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7751 if (ret64 != sample->pos) {
7752 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7753 sc->ffindex, sample->pos);
7754 if (should_retry(sc->pb, ret64)) {
7755 mov_current_sample_dec(sc);
7757 return AVERROR_INVALIDDATA;
7760 if( st->discard == AVDISCARD_NONKEY && 0==(sample->flags & AVINDEX_KEYFRAME) ) {
7761 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7765 ret = av_get_packet(sc->pb, pkt, sample->size);
7767 if (should_retry(sc->pb, ret)) {
7768 mov_current_sample_dec(sc);
7772 if (sc->has_palette) {
7775 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7777 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7779 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7780 sc->has_palette = 0;
7783 #if CONFIG_DV_DEMUXER
7784 if (mov->dv_demux && sc->dv_audio_container) {
7785 avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7786 av_freep(&pkt->data);
7788 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7793 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7794 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7795 st->need_parsing = AVSTREAM_PARSE_FULL;
7799 pkt->stream_index = sc->ffindex;
7800 pkt->dts = sample->timestamp;
7801 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7802 pkt->flags |= AV_PKT_FLAG_DISCARD;
7804 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7805 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
7806 /* update ctts context */
7808 if (sc->ctts_index < sc->ctts_count &&
7809 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
7811 sc->ctts_sample = 0;
7814 int64_t next_dts = (sc->current_sample < st->nb_index_entries) ?
7815 st->index_entries[sc->current_sample].timestamp : st->duration;
7817 if (next_dts >= pkt->dts)
7818 pkt->duration = next_dts - pkt->dts;
7819 pkt->pts = pkt->dts;
7821 if (st->discard == AVDISCARD_ALL)
7823 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
7824 pkt->pos = sample->pos;
7826 /* Multiple stsd handling. */
7827 if (sc->stsc_data) {
7828 /* Keep track of the stsc index for the given sample, then check
7829 * if the stsd index is different from the last used one. */
7831 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
7832 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
7834 sc->stsc_sample = 0;
7835 /* Do not check indexes after a switch. */
7836 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
7837 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
7838 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
7839 ret = mov_change_extradata(sc, pkt);
7846 aax_filter(pkt->data, pkt->size, mov);
7848 ret = cenc_filter(mov, st, sc, pkt, current_index);
7850 av_packet_unref(pkt);
7857 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
7859 MOVContext *mov = s->priv_data;
7862 if (!mov->frag_index.complete)
7865 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
7868 if (!mov->frag_index.item[index].headers_read)
7869 return mov_switch_root(s, -1, index);
7870 if (index + 1 < mov->frag_index.nb_items)
7871 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7876 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
7878 MOVStreamContext *sc = st->priv_data;
7879 int sample, time_sample, ret;
7882 // Here we consider timestamp to be PTS, hence try to offset it so that we
7883 // can search over the DTS timeline.
7884 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
7886 ret = mov_seek_fragment(s, st, timestamp);
7890 sample = av_index_search_timestamp(st, timestamp, flags);
7891 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
7892 if (sample < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp)
7894 if (sample < 0) /* not sure what to do */
7895 return AVERROR_INVALIDDATA;
7896 mov_current_sample_set(sc, sample);
7897 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
7898 /* adjust ctts index */
7899 if (sc->ctts_data) {
7901 for (i = 0; i < sc->ctts_count; i++) {
7902 int next = time_sample + sc->ctts_data[i].count;
7903 if (next > sc->current_sample) {
7905 sc->ctts_sample = sc->current_sample - time_sample;
7912 /* adjust stsd index */
7913 if (sc->chunk_count) {
7915 for (i = 0; i < sc->stsc_count; i++) {
7916 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
7917 if (next > sc->current_sample) {
7919 sc->stsc_sample = sc->current_sample - time_sample;
7922 av_assert0(next == (int)next);
7930 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
7932 MOVContext *mc = s->priv_data;
7937 if (stream_index >= s->nb_streams)
7938 return AVERROR_INVALIDDATA;
7940 st = s->streams[stream_index];
7941 sample = mov_seek_stream(s, st, sample_time, flags);
7945 if (mc->seek_individually) {
7946 /* adjust seek timestamp to found sample timestamp */
7947 int64_t seek_timestamp = st->index_entries[sample].timestamp;
7949 for (i = 0; i < s->nb_streams; i++) {
7951 MOVStreamContext *sc = s->streams[i]->priv_data;
7953 st->skip_samples = (sample_time <= 0) ? sc->start_pad : 0;
7955 if (stream_index == i)
7958 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
7959 mov_seek_stream(s, st, timestamp, flags);
7962 for (i = 0; i < s->nb_streams; i++) {
7963 MOVStreamContext *sc;
7966 mov_current_sample_set(sc, 0);
7969 MOVStreamContext *sc;
7970 AVIndexEntry *entry = mov_find_next_sample(s, &st);
7972 return AVERROR_INVALIDDATA;
7974 if (sc->ffindex == stream_index && sc->current_sample == sample)
7976 mov_current_sample_inc(sc);
7982 #define OFFSET(x) offsetof(MOVContext, x)
7983 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
7984 static const AVOption mov_options[] = {
7985 {"use_absolute_path",
7986 "allow using absolute path when opening alias, this is a possible security issue",
7987 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
7989 {"seek_streams_individually",
7990 "Seek each stream individually to the to the closest point",
7991 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
7993 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
7995 {"advanced_editlist",
7996 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
7997 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
7999 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8002 "use mfra for fragment timestamps",
8003 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8004 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8006 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8007 FLAGS, "use_mfra_for" },
8008 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8009 FLAGS, "use_mfra_for" },
8010 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8011 FLAGS, "use_mfra_for" },
8012 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8013 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8014 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8015 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8016 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8017 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8018 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8019 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8020 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8021 .flags = AV_OPT_FLAG_DECODING_PARAM },
8022 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8023 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8024 {.i64 = 0}, 0, 1, FLAGS },
8029 static const AVClass mov_class = {
8030 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8031 .item_name = av_default_item_name,
8032 .option = mov_options,
8033 .version = LIBAVUTIL_VERSION_INT,
8036 AVInputFormat ff_mov_demuxer = {
8037 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8038 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8039 .priv_class = &mov_class,
8040 .priv_data_size = sizeof(MOVContext),
8041 .extensions = "mov,mp4,m4a,3gp,3g2,mj2",
8042 .read_probe = mov_probe,
8043 .read_header = mov_read_header,
8044 .read_packet = mov_read_packet,
8045 .read_close = mov_read_close,
8046 .read_seek = mov_read_seek,
8047 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,