3 * Copyright (c) 2001 Fabrice Bellard
4 * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
6 * first version by Francois Revol <revol@free.fr>
7 * seek function by Gael Chardon <gael.dev@4now.net>
9 * This file is part of FFmpeg.
11 * FFmpeg is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * FFmpeg is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with FFmpeg; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30 #include "libavutil/attributes.h"
31 #include "libavutil/channel_layout.h"
32 #include "libavutil/internal.h"
33 #include "libavutil/intreadwrite.h"
34 #include "libavutil/intfloat.h"
35 #include "libavutil/mathematics.h"
36 #include "libavutil/time_internal.h"
37 #include "libavutil/avassert.h"
38 #include "libavutil/avstring.h"
39 #include "libavutil/dict.h"
40 #include "libavutil/display.h"
41 #include "libavutil/opt.h"
42 #include "libavutil/aes.h"
43 #include "libavutil/aes_ctr.h"
44 #include "libavutil/pixdesc.h"
45 #include "libavutil/sha.h"
46 #include "libavutil/spherical.h"
47 #include "libavutil/stereo3d.h"
48 #include "libavutil/timecode.h"
49 #include "libavcodec/ac3tab.h"
50 #include "libavcodec/flac.h"
51 #include "libavcodec/mpegaudiodecheader.h"
52 #include "libavcodec/mlp_parse.h"
55 #include "avio_internal.h"
58 #include "libavcodec/get_bits.h"
61 #include "replaygain.h"
67 #include "qtpalette.h"
69 /* those functions parse an atom */
70 /* links atom IDs to parse functions */
71 typedef struct MOVParseTableEntry {
73 int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
76 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
77 static int mov_read_mfra(MOVContext *c, AVIOContext *f);
78 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
79 int count, int duration);
81 static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb,
82 unsigned len, const char *key)
86 short current, total = 0;
87 avio_rb16(pb); // unknown
88 current = avio_rb16(pb);
90 total = avio_rb16(pb);
92 snprintf(buf, sizeof(buf), "%d", current);
94 snprintf(buf, sizeof(buf), "%d/%d", current, total);
95 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
96 av_dict_set(&c->fc->metadata, key, buf, 0);
101 static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb,
102 unsigned len, const char *key)
104 /* bypass padding bytes */
109 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
110 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
115 static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb,
116 unsigned len, const char *key)
118 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
119 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
124 static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb,
125 unsigned len, const char *key)
129 avio_r8(pb); // unknown
132 if (genre < 1 || genre > ID3v1_GENRE_MAX)
134 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
135 av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
140 static const uint32_t mac_to_unicode[128] = {
141 0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
142 0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
143 0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
144 0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
145 0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
146 0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
147 0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
148 0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
149 0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
150 0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
151 0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
152 0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
153 0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
154 0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
155 0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
156 0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
159 static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len,
160 char *dst, int dstlen)
163 char *end = dst+dstlen-1;
166 for (i = 0; i < len; i++) {
167 uint8_t t, c = avio_r8(pb);
175 PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
181 static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
185 MOVStreamContext *sc;
190 case 0xd: id = AV_CODEC_ID_MJPEG; break;
191 case 0xe: id = AV_CODEC_ID_PNG; break;
192 case 0x1b: id = AV_CODEC_ID_BMP; break;
194 av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
199 st = avformat_new_stream(c->fc, NULL);
201 return AVERROR(ENOMEM);
202 sc = av_mallocz(sizeof(*sc));
204 return AVERROR(ENOMEM);
207 ret = av_get_packet(pb, &pkt, len);
211 if (pkt.size >= 8 && id != AV_CODEC_ID_BMP) {
212 if (AV_RB64(pkt.data) == 0x89504e470d0a1a0a) {
213 id = AV_CODEC_ID_PNG;
215 id = AV_CODEC_ID_MJPEG;
219 st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
221 st->attached_pic = pkt;
222 st->attached_pic.stream_index = st->index;
223 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
225 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
226 st->codecpar->codec_id = id;
232 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
234 char language[4] = { 0 };
235 char buf[200], place[100];
236 uint16_t langcode = 0;
237 double longitude, latitude, altitude;
238 const char *key = "location";
240 if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
241 av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
242 return AVERROR_INVALIDDATA;
245 avio_skip(pb, 4); // version+flags
246 langcode = avio_rb16(pb);
247 ff_mov_lang_to_iso639(langcode, language);
250 len -= avio_get_str(pb, len, place, sizeof(place));
252 av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
253 return AVERROR_INVALIDDATA;
255 avio_skip(pb, 1); // role
259 av_log(c->fc, AV_LOG_ERROR,
260 "loci too short (%u bytes left, need at least %d)\n", len, 12);
261 return AVERROR_INVALIDDATA;
263 longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
264 latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
265 altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
267 // Try to output in the same format as the ?xyz field
268 snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
270 av_strlcatf(buf, sizeof(buf), "%+f", altitude);
271 av_strlcatf(buf, sizeof(buf), "/%s", place);
273 if (*language && strcmp(language, "und")) {
275 snprintf(key2, sizeof(key2), "%s-%s", key, language);
276 av_dict_set(&c->fc->metadata, key2, buf, 0);
278 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
279 return av_dict_set(&c->fc->metadata, key, buf, 0);
282 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
288 if (c->ignore_chapters)
291 n_hmmt = avio_rb32(pb);
292 for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
293 int moment_time = avio_rb32(pb);
294 avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
299 static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
302 char key2[32], language[4] = {0};
304 const char *key = NULL;
305 uint16_t langcode = 0;
306 uint32_t data_type = 0, str_size, str_size_alloc;
307 int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
312 case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
313 case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
314 case MKTAG( 'X','M','P','_'):
315 if (c->export_xmp) { key = "xmp"; raw = 1; } break;
316 case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
317 case MKTAG( 'a','k','I','D'): key = "account_type";
318 parse = mov_metadata_int8_no_padding; break;
319 case MKTAG( 'a','p','I','D'): key = "account_id"; break;
320 case MKTAG( 'c','a','t','g'): key = "category"; break;
321 case MKTAG( 'c','p','i','l'): key = "compilation";
322 parse = mov_metadata_int8_no_padding; break;
323 case MKTAG( 'c','p','r','t'): key = "copyright"; break;
324 case MKTAG( 'd','e','s','c'): key = "description"; break;
325 case MKTAG( 'd','i','s','k'): key = "disc";
326 parse = mov_metadata_track_or_disc_number; break;
327 case MKTAG( 'e','g','i','d'): key = "episode_uid";
328 parse = mov_metadata_int8_no_padding; break;
329 case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
330 case MKTAG( 'g','n','r','e'): key = "genre";
331 parse = mov_metadata_gnre; break;
332 case MKTAG( 'h','d','v','d'): key = "hd_video";
333 parse = mov_metadata_int8_no_padding; break;
334 case MKTAG( 'H','M','M','T'):
335 return mov_metadata_hmmt(c, pb, atom.size);
336 case MKTAG( 'k','e','y','w'): key = "keywords"; break;
337 case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
338 case MKTAG( 'l','o','c','i'):
339 return mov_metadata_loci(c, pb, atom.size);
340 case MKTAG( 'm','a','n','u'): key = "make"; break;
341 case MKTAG( 'm','o','d','l'): key = "model"; break;
342 case MKTAG( 'p','c','s','t'): key = "podcast";
343 parse = mov_metadata_int8_no_padding; break;
344 case MKTAG( 'p','g','a','p'): key = "gapless_playback";
345 parse = mov_metadata_int8_no_padding; break;
346 case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
347 case MKTAG( 'r','t','n','g'): key = "rating";
348 parse = mov_metadata_int8_no_padding; break;
349 case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
350 case MKTAG( 's','o','a','l'): key = "sort_album"; break;
351 case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
352 case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
353 case MKTAG( 's','o','n','m'): key = "sort_name"; break;
354 case MKTAG( 's','o','s','n'): key = "sort_show"; break;
355 case MKTAG( 's','t','i','k'): key = "media_type";
356 parse = mov_metadata_int8_no_padding; break;
357 case MKTAG( 't','r','k','n'): key = "track";
358 parse = mov_metadata_track_or_disc_number; break;
359 case MKTAG( 't','v','e','n'): key = "episode_id"; break;
360 case MKTAG( 't','v','e','s'): key = "episode_sort";
361 parse = mov_metadata_int8_bypass_padding; break;
362 case MKTAG( 't','v','n','n'): key = "network"; break;
363 case MKTAG( 't','v','s','h'): key = "show"; break;
364 case MKTAG( 't','v','s','n'): key = "season_number";
365 parse = mov_metadata_int8_bypass_padding; break;
366 case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
367 case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
368 case MKTAG(0xa9,'a','l','b'): key = "album"; break;
369 case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
370 case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
371 case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
372 case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
373 case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
374 case MKTAG(0xa9,'d','a','y'): key = "date"; break;
375 case MKTAG(0xa9,'d','i','r'): key = "director"; break;
376 case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
377 case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
378 case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
379 case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
380 case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
381 case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
382 case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
383 case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
384 case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
385 case MKTAG(0xa9,'m','a','k'): key = "make"; break;
386 case MKTAG(0xa9,'m','o','d'): key = "model"; break;
387 case MKTAG(0xa9,'n','a','m'): key = "title"; break;
388 case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
389 case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
390 case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
391 case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
392 case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
393 case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
394 case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
395 case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
396 case MKTAG(0xa9,'t','r','k'): key = "track"; break;
397 case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
398 case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
399 case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
400 case MKTAG(0xa9,'x','y','z'): key = "location"; break;
403 if (c->itunes_metadata && atom.size > 8) {
404 int data_size = avio_rb32(pb);
405 int tag = avio_rl32(pb);
406 if (tag == MKTAG('d','a','t','a') && data_size <= atom.size) {
407 data_type = avio_rb32(pb); // type
408 avio_rb32(pb); // unknown
409 str_size = data_size - 16;
412 if (atom.type == MKTAG('c', 'o', 'v', 'r')) {
413 int ret = mov_read_covr(c, pb, data_type, str_size);
415 av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
418 atom.size -= str_size;
422 } else if (!key && c->found_hdlr_mdta && c->meta_keys) {
423 uint32_t index = AV_RB32(&atom.type);
424 if (index < c->meta_keys_count && index > 0) {
425 key = c->meta_keys[index];
427 av_log(c->fc, AV_LOG_WARNING,
428 "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
429 index, c->meta_keys_count);
433 } else if (atom.size > 4 && key && !c->itunes_metadata && !raw) {
434 str_size = avio_rb16(pb); // string length
435 if (str_size > atom.size) {
437 avio_seek(pb, -2, SEEK_CUR);
438 av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
441 langcode = avio_rb16(pb);
442 ff_mov_lang_to_iso639(langcode, language);
445 str_size = atom.size;
447 if (c->export_all && !key) {
448 snprintf(tmp_key, 5, "%.4s", (char*)&atom.type);
454 if (atom.size < 0 || str_size >= INT_MAX/2)
455 return AVERROR_INVALIDDATA;
457 // Allocates enough space if data_type is a int32 or float32 number, otherwise
458 // worst-case requirement for output string in case of utf8 coded input
459 num = (data_type >= 21 && data_type <= 23);
460 str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
461 str = av_mallocz(str_size_alloc);
463 return AVERROR(ENOMEM);
466 parse(c, pb, str_size, key);
468 if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
469 mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
470 } else if (data_type == 21) { // BE signed integer, variable size
473 val = (int8_t)avio_r8(pb);
474 else if (str_size == 2)
475 val = (int16_t)avio_rb16(pb);
476 else if (str_size == 3)
477 val = ((int32_t)(avio_rb24(pb)<<8))>>8;
478 else if (str_size == 4)
479 val = (int32_t)avio_rb32(pb);
480 if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
481 av_log(c->fc, AV_LOG_ERROR,
482 "Failed to store the number (%d) in string.\n", val);
484 return AVERROR_INVALIDDATA;
486 } else if (data_type == 22) { // BE unsigned integer, variable size
487 unsigned int val = 0;
490 else if (str_size == 2)
492 else if (str_size == 3)
494 else if (str_size == 4)
496 if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
497 av_log(c->fc, AV_LOG_ERROR,
498 "Failed to store the number (%u) in string.\n", val);
500 return AVERROR_INVALIDDATA;
502 } else if (data_type == 23 && str_size >= 4) { // BE float32
503 float val = av_int2float(avio_rb32(pb));
504 if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
505 av_log(c->fc, AV_LOG_ERROR,
506 "Failed to store the float32 number (%f) in string.\n", val);
508 return AVERROR_INVALIDDATA;
511 int ret = ffio_read_size(pb, str, str_size);
518 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
519 av_dict_set(&c->fc->metadata, key, str, 0);
520 if (*language && strcmp(language, "und")) {
521 snprintf(key2, sizeof(key2), "%s-%s", key, language);
522 av_dict_set(&c->fc->metadata, key2, str, 0);
524 if (!strcmp(key, "encoder")) {
525 int major, minor, micro;
526 if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, µ) == 3) {
527 c->handbrake_version = 1000000*major + 1000*minor + micro;
536 static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
539 int i, nb_chapters, str_len, version;
543 if (c->ignore_chapters)
546 if ((atom.size -= 5) < 0)
549 version = avio_r8(pb);
552 avio_rb32(pb); // ???
553 nb_chapters = avio_r8(pb);
555 for (i = 0; i < nb_chapters; i++) {
559 start = avio_rb64(pb);
560 str_len = avio_r8(pb);
562 if ((atom.size -= 9+str_len) < 0)
565 ret = ffio_read_size(pb, str, str_len);
569 avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
574 #define MIN_DATA_ENTRY_BOX_SIZE 12
575 static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
578 MOVStreamContext *sc;
581 if (c->fc->nb_streams < 1)
583 st = c->fc->streams[c->fc->nb_streams-1];
586 avio_rb32(pb); // version + flags
587 entries = avio_rb32(pb);
589 entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
590 entries >= UINT_MAX / sizeof(*sc->drefs))
591 return AVERROR_INVALIDDATA;
595 sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
597 return AVERROR(ENOMEM);
598 sc->drefs_count = entries;
600 for (i = 0; i < entries; i++) {
601 MOVDref *dref = &sc->drefs[i];
602 uint32_t size = avio_rb32(pb);
603 int64_t next = avio_tell(pb) + size - 4;
606 return AVERROR_INVALIDDATA;
608 dref->type = avio_rl32(pb);
609 avio_rb32(pb); // version + flags
611 if (dref->type == MKTAG('a','l','i','s') && size > 150) {
612 /* macintosh alias record */
613 uint16_t volume_len, len;
619 volume_len = avio_r8(pb);
620 volume_len = FFMIN(volume_len, 27);
621 ret = ffio_read_size(pb, dref->volume, 27);
624 dref->volume[volume_len] = 0;
625 av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
630 len = FFMIN(len, 63);
631 ret = ffio_read_size(pb, dref->filename, 63);
634 dref->filename[len] = 0;
635 av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
639 /* read next level up_from_alias/down_to_target */
640 dref->nlvl_from = avio_rb16(pb);
641 dref->nlvl_to = avio_rb16(pb);
642 av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
643 dref->nlvl_from, dref->nlvl_to);
647 for (type = 0; type != -1 && avio_tell(pb) < next; ) {
650 type = avio_rb16(pb);
652 av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
655 if (type == 2) { // absolute path
657 dref->path = av_mallocz(len+1);
659 return AVERROR(ENOMEM);
661 ret = ffio_read_size(pb, dref->path, len);
663 av_freep(&dref->path);
666 if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
668 memmove(dref->path, dref->path+volume_len, len);
671 // trim string of any ending zeros
672 for (j = len - 1; j >= 0; j--) {
673 if (dref->path[j] == 0)
678 for (j = 0; j < len; j++)
679 if (dref->path[j] == ':' || dref->path[j] == 0)
681 av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
682 } else if (type == 0) { // directory name
684 dref->dir = av_malloc(len+1);
686 return AVERROR(ENOMEM);
688 ret = ffio_read_size(pb, dref->dir, len);
690 av_freep(&dref->dir);
694 for (j = 0; j < len; j++)
695 if (dref->dir[j] == ':')
697 av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
702 av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
707 avio_seek(pb, next, SEEK_SET);
712 static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
721 avio_r8(pb); /* version */
722 avio_rb24(pb); /* flags */
725 ctype = avio_rl32(pb);
726 type = avio_rl32(pb); /* component subtype */
728 av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
729 av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
731 if (c->trak_index < 0) { // meta not inside a trak
732 if (type == MKTAG('m','d','t','a')) {
733 c->found_hdlr_mdta = 1;
738 st = c->fc->streams[c->fc->nb_streams-1];
740 if (type == MKTAG('v','i','d','e'))
741 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
742 else if (type == MKTAG('s','o','u','n'))
743 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
744 else if (type == MKTAG('m','1','a',' '))
745 st->codecpar->codec_id = AV_CODEC_ID_MP2;
746 else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
747 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
749 avio_rb32(pb); /* component manufacture */
750 avio_rb32(pb); /* component flags */
751 avio_rb32(pb); /* component flags mask */
753 title_size = atom.size - 24;
754 if (title_size > 0) {
755 if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
756 return AVERROR_INVALIDDATA;
757 title_str = av_malloc(title_size + 1); /* Add null terminator */
759 return AVERROR(ENOMEM);
761 ret = ffio_read_size(pb, title_str, title_size);
763 av_freep(&title_str);
766 title_str[title_size] = 0;
768 int off = (!c->isom && title_str[0] == title_size - 1);
769 // flag added so as to not set stream handler name if already set from mdia->hdlr
770 av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
772 av_freep(&title_str);
778 static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
780 return ff_mov_read_esds(c->fc, pb);
783 static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
786 enum AVAudioServiceType *ast;
787 int ac3info, acmod, lfeon, bsmod;
789 if (c->fc->nb_streams < 1)
791 st = c->fc->streams[c->fc->nb_streams-1];
793 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
796 return AVERROR(ENOMEM);
798 ac3info = avio_rb24(pb);
799 bsmod = (ac3info >> 14) & 0x7;
800 acmod = (ac3info >> 11) & 0x7;
801 lfeon = (ac3info >> 10) & 0x1;
802 st->codecpar->channels = ((int[]){2,1,2,3,3,4,4,5})[acmod] + lfeon;
803 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
805 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
807 if (st->codecpar->channels > 1 && bsmod == 0x7)
808 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
810 #if FF_API_LAVF_AVCTX
811 FF_DISABLE_DEPRECATION_WARNINGS
812 st->codec->audio_service_type = *ast;
813 FF_ENABLE_DEPRECATION_WARNINGS
819 static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
822 enum AVAudioServiceType *ast;
823 int eac3info, acmod, lfeon, bsmod;
825 if (c->fc->nb_streams < 1)
827 st = c->fc->streams[c->fc->nb_streams-1];
829 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
832 return AVERROR(ENOMEM);
834 /* No need to parse fields for additional independent substreams and its
835 * associated dependent substreams since libavcodec's E-AC-3 decoder
836 * does not support them yet. */
837 avio_rb16(pb); /* data_rate and num_ind_sub */
838 eac3info = avio_rb24(pb);
839 bsmod = (eac3info >> 12) & 0x1f;
840 acmod = (eac3info >> 9) & 0x7;
841 lfeon = (eac3info >> 8) & 0x1;
842 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
844 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
845 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
847 if (st->codecpar->channels > 1 && bsmod == 0x7)
848 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
850 #if FF_API_LAVF_AVCTX
851 FF_DISABLE_DEPRECATION_WARNINGS
852 st->codec->audio_service_type = *ast;
853 FF_ENABLE_DEPRECATION_WARNINGS
859 static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
861 const uint32_t ddts_size = 20;
864 uint32_t frame_duration_code = 0;
865 uint32_t channel_layout_code = 0;
868 buf = av_malloc(ddts_size + AV_INPUT_BUFFER_PADDING_SIZE);
870 return AVERROR(ENOMEM);
872 if (avio_read(pb, buf, ddts_size) < ddts_size) {
874 return AVERROR_INVALIDDATA;
877 init_get_bits(&gb, buf, 8*ddts_size);
879 if (c->fc->nb_streams < 1) {
883 st = c->fc->streams[c->fc->nb_streams-1];
885 st->codecpar->sample_rate = get_bits_long(&gb, 32);
886 if (st->codecpar->sample_rate <= 0) {
887 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
889 return AVERROR_INVALIDDATA;
891 skip_bits_long(&gb, 32); /* max bitrate */
892 st->codecpar->bit_rate = get_bits_long(&gb, 32);
893 st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
894 frame_duration_code = get_bits(&gb, 2);
895 skip_bits(&gb, 30); /* various fields */
896 channel_layout_code = get_bits(&gb, 16);
898 st->codecpar->frame_size =
899 (frame_duration_code == 0) ? 512 :
900 (frame_duration_code == 1) ? 1024 :
901 (frame_duration_code == 2) ? 2048 :
902 (frame_duration_code == 3) ? 4096 : 0;
904 if (channel_layout_code > 0xff) {
905 av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout");
907 st->codecpar->channel_layout =
908 ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
909 ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
910 ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
911 ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
912 ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
913 ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0);
915 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
921 static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
925 if (c->fc->nb_streams < 1)
927 st = c->fc->streams[c->fc->nb_streams-1];
932 /* skip version and flags */
935 ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
940 static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
945 if (c->fc->nb_streams < 1)
947 st = c->fc->streams[c->fc->nb_streams-1];
949 if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
950 av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
955 static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
957 const int num = avio_rb32(pb);
958 const int den = avio_rb32(pb);
961 if (c->fc->nb_streams < 1)
963 st = c->fc->streams[c->fc->nb_streams-1];
965 if ((st->sample_aspect_ratio.den != 1 || st->sample_aspect_ratio.num) && // default
966 (den != st->sample_aspect_ratio.den || num != st->sample_aspect_ratio.num)) {
967 av_log(c->fc, AV_LOG_WARNING,
968 "sample aspect ratio already set to %d:%d, ignoring 'pasp' atom (%d:%d)\n",
969 st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
971 } else if (den != 0) {
972 av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den,
978 /* this atom contains actual media data */
979 static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
981 if (atom.size == 0) /* wrong one (MP4) */
984 return 0; /* now go for moov */
987 #define DRM_BLOB_SIZE 56
989 static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
991 uint8_t intermediate_key[20];
992 uint8_t intermediate_iv[20];
995 uint8_t file_checksum[20];
996 uint8_t calculated_checksum[20];
1000 uint8_t *activation_bytes = c->activation_bytes;
1001 uint8_t *fixed_key = c->audible_fixed_key;
1005 sha = av_sha_alloc();
1007 return AVERROR(ENOMEM);
1008 av_free(c->aes_decrypt);
1009 c->aes_decrypt = av_aes_alloc();
1010 if (!c->aes_decrypt) {
1011 ret = AVERROR(ENOMEM);
1015 /* drm blob processing */
1016 avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1017 avio_read(pb, input, DRM_BLOB_SIZE);
1018 avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1019 avio_read(pb, file_checksum, 20);
1021 av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == "); // required by external tools
1022 for (i = 0; i < 20; i++)
1023 av_log(c->fc, AV_LOG_INFO, "%02x", file_checksum[i]);
1024 av_log(c->fc, AV_LOG_INFO, "\n");
1026 /* verify activation data */
1027 if (!activation_bytes) {
1028 av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1029 ret = 0; /* allow ffprobe to continue working on .aax files */
1032 if (c->activation_bytes_size != 4) {
1033 av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1034 ret = AVERROR(EINVAL);
1038 /* verify fixed key */
1039 if (c->audible_fixed_key_size != 16) {
1040 av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1041 ret = AVERROR(EINVAL);
1045 /* AAX (and AAX+) key derivation */
1046 av_sha_init(sha, 160);
1047 av_sha_update(sha, fixed_key, 16);
1048 av_sha_update(sha, activation_bytes, 4);
1049 av_sha_final(sha, intermediate_key);
1050 av_sha_init(sha, 160);
1051 av_sha_update(sha, fixed_key, 16);
1052 av_sha_update(sha, intermediate_key, 20);
1053 av_sha_update(sha, activation_bytes, 4);
1054 av_sha_final(sha, intermediate_iv);
1055 av_sha_init(sha, 160);
1056 av_sha_update(sha, intermediate_key, 16);
1057 av_sha_update(sha, intermediate_iv, 16);
1058 av_sha_final(sha, calculated_checksum);
1059 if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1060 av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1061 ret = AVERROR_INVALIDDATA;
1064 av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1065 av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1066 for (i = 0; i < 4; i++) {
1067 // file data (in output) is stored in big-endian mode
1068 if (activation_bytes[i] != output[3 - i]) { // critical error
1069 av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1070 ret = AVERROR_INVALIDDATA;
1074 memcpy(c->file_key, output + 8, 16);
1075 memcpy(input, output + 26, 16);
1076 av_sha_init(sha, 160);
1077 av_sha_update(sha, input, 16);
1078 av_sha_update(sha, c->file_key, 16);
1079 av_sha_update(sha, fixed_key, 16);
1080 av_sha_final(sha, c->file_iv);
1088 // Audible AAX (and AAX+) bytestream decryption
1089 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1092 unsigned char iv[16];
1094 memcpy(iv, c->file_iv, 16); // iv is overwritten
1095 blocks = size >> 4; // trailing bytes are not encrypted!
1096 av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1097 av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1102 /* read major brand, minor version and compatible brands and store them as metadata */
1103 static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1106 int comp_brand_size;
1107 char* comp_brands_str;
1108 uint8_t type[5] = {0};
1109 int ret = ffio_read_size(pb, type, 4);
1113 if (strcmp(type, "qt "))
1115 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1116 av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1117 minor_ver = avio_rb32(pb); /* minor version */
1118 av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1120 comp_brand_size = atom.size - 8;
1121 if (comp_brand_size < 0)
1122 return AVERROR_INVALIDDATA;
1123 comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1124 if (!comp_brands_str)
1125 return AVERROR(ENOMEM);
1127 ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1129 av_freep(&comp_brands_str);
1132 comp_brands_str[comp_brand_size] = 0;
1133 av_dict_set(&c->fc->metadata, "compatible_brands",
1134 comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1139 /* this atom should contain all header atoms */
1140 static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1144 if (c->found_moov) {
1145 av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1146 avio_skip(pb, atom.size);
1150 if ((ret = mov_read_default(c, pb, atom)) < 0)
1152 /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1153 /* so we don't parse the whole file if over a network */
1155 return 0; /* now go for mdat */
1158 static MOVFragmentStreamInfo * get_frag_stream_info(
1159 MOVFragmentIndex *frag_index,
1164 MOVFragmentIndexItem * item;
1166 if (index < 0 || index >= frag_index->nb_items)
1168 item = &frag_index->item[index];
1169 for (i = 0; i < item->nb_stream_info; i++)
1170 if (item->stream_info[i].id == id)
1171 return &item->stream_info[i];
1173 // This shouldn't happen
1177 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1180 MOVFragmentIndexItem * item;
1182 if (frag_index->current < 0 ||
1183 frag_index->current >= frag_index->nb_items)
1186 item = &frag_index->item[frag_index->current];
1187 for (i = 0; i < item->nb_stream_info; i++)
1188 if (item->stream_info[i].id == id) {
1193 // id not found. This shouldn't happen.
1197 static MOVFragmentStreamInfo * get_current_frag_stream_info(
1198 MOVFragmentIndex *frag_index)
1200 MOVFragmentIndexItem *item;
1201 if (frag_index->current < 0 ||
1202 frag_index->current >= frag_index->nb_items)
1205 item = &frag_index->item[frag_index->current];
1206 if (item->current >= 0 && item->current < item->nb_stream_info)
1207 return &item->stream_info[item->current];
1209 // This shouldn't happen
1213 static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
1216 int64_t moof_offset;
1218 // Optimize for appending new entries
1219 if (!frag_index->nb_items ||
1220 frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1221 return frag_index->nb_items;
1224 b = frag_index->nb_items;
1228 moof_offset = frag_index->item[m].moof_offset;
1229 if (moof_offset >= offset)
1231 if (moof_offset <= offset)
1237 static int64_t get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
1239 av_assert0(frag_stream_info);
1240 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1241 return frag_stream_info->sidx_pts;
1242 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1243 return frag_stream_info->first_tfra_pts;
1244 return frag_stream_info->tfdt_dts;
1247 static int64_t get_frag_time(MOVFragmentIndex *frag_index,
1248 int index, int track_id)
1250 MOVFragmentStreamInfo * frag_stream_info;
1254 if (track_id >= 0) {
1255 frag_stream_info = get_frag_stream_info(frag_index, index, track_id);
1256 return frag_stream_info->sidx_pts;
1259 for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1260 frag_stream_info = &frag_index->item[index].stream_info[i];
1261 timestamp = get_stream_info_time(frag_stream_info);
1262 if (timestamp != AV_NOPTS_VALUE)
1265 return AV_NOPTS_VALUE;
1268 static int search_frag_timestamp(MOVFragmentIndex *frag_index,
1269 AVStream *st, int64_t timestamp)
1276 // If the stream is referenced by any sidx, limit the search
1277 // to fragments that referenced this stream in the sidx
1278 MOVStreamContext *sc = st->priv_data;
1284 b = frag_index->nb_items;
1287 m0 = m = (a + b) >> 1;
1290 (frag_time = get_frag_time(frag_index, m, id)) == AV_NOPTS_VALUE)
1293 if (m < b && frag_time <= timestamp)
1302 static int update_frag_index(MOVContext *c, int64_t offset)
1305 MOVFragmentIndexItem * item;
1306 MOVFragmentStreamInfo * frag_stream_info;
1308 // If moof_offset already exists in frag_index, return index to it
1309 index = search_frag_moof_offset(&c->frag_index, offset);
1310 if (index < c->frag_index.nb_items &&
1311 c->frag_index.item[index].moof_offset == offset)
1314 // offset is not yet in frag index.
1315 // Insert new item at index (sorted by moof offset)
1316 item = av_fast_realloc(c->frag_index.item,
1317 &c->frag_index.allocated_size,
1318 (c->frag_index.nb_items + 1) *
1319 sizeof(*c->frag_index.item));
1322 c->frag_index.item = item;
1324 frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1325 sizeof(*item->stream_info));
1326 if (!frag_stream_info)
1329 for (i = 0; i < c->fc->nb_streams; i++) {
1330 // Avoid building frag index if streams lack track id.
1331 if (c->fc->streams[i]->id < 0) {
1332 av_free(frag_stream_info);
1333 return AVERROR_INVALIDDATA;
1336 frag_stream_info[i].id = c->fc->streams[i]->id;
1337 frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1338 frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1339 frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1340 frag_stream_info[i].index_entry = -1;
1341 frag_stream_info[i].encryption_index = NULL;
1344 if (index < c->frag_index.nb_items)
1345 memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1346 (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1348 item = &c->frag_index.item[index];
1349 item->headers_read = 0;
1351 item->nb_stream_info = c->fc->nb_streams;
1352 item->moof_offset = offset;
1353 item->stream_info = frag_stream_info;
1354 c->frag_index.nb_items++;
1359 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1360 int id, int entries)
1363 MOVFragmentStreamInfo * frag_stream_info;
1367 for (i = index; i < frag_index->nb_items; i++) {
1368 frag_stream_info = get_frag_stream_info(frag_index, i, id);
1369 if (frag_stream_info && frag_stream_info->index_entry >= 0)
1370 frag_stream_info->index_entry += entries;
1374 static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1376 // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1377 c->fragment.found_tfhd = 0;
1379 if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1380 c->has_looked_for_mfra = 1;
1381 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1383 av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1385 if ((ret = mov_read_mfra(c, pb)) < 0) {
1386 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1387 "read the mfra (may be a live ismv)\n");
1390 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1391 "seekable, can not look for mfra\n");
1394 c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1395 av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1396 c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1397 return mov_read_default(c, pb, atom);
1400 static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time, void *logctx)
1403 if(time >= 2082844800)
1404 time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1406 if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1407 av_log(logctx, AV_LOG_DEBUG, "creation_time is not representable\n");
1411 avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1415 static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1418 MOVStreamContext *sc;
1420 char language[4] = {0};
1422 int64_t creation_time;
1424 if (c->fc->nb_streams < 1)
1426 st = c->fc->streams[c->fc->nb_streams-1];
1429 if (sc->time_scale) {
1430 av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1431 return AVERROR_INVALIDDATA;
1434 version = avio_r8(pb);
1436 avpriv_request_sample(c->fc, "Version %d", version);
1437 return AVERROR_PATCHWELCOME;
1439 avio_rb24(pb); /* flags */
1441 creation_time = avio_rb64(pb);
1444 creation_time = avio_rb32(pb);
1445 avio_rb32(pb); /* modification time */
1447 mov_metadata_creation_time(&st->metadata, creation_time, c->fc);
1449 sc->time_scale = avio_rb32(pb);
1450 if (sc->time_scale <= 0) {
1451 av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1454 st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1456 lang = avio_rb16(pb); /* language */
1457 if (ff_mov_lang_to_iso639(lang, language))
1458 av_dict_set(&st->metadata, "language", language, 0);
1459 avio_rb16(pb); /* quality */
1464 static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1467 int64_t creation_time;
1468 int version = avio_r8(pb); /* version */
1469 avio_rb24(pb); /* flags */
1472 creation_time = avio_rb64(pb);
1475 creation_time = avio_rb32(pb);
1476 avio_rb32(pb); /* modification time */
1478 mov_metadata_creation_time(&c->fc->metadata, creation_time, c->fc);
1479 c->time_scale = avio_rb32(pb); /* time scale */
1480 if (c->time_scale <= 0) {
1481 av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1484 av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1486 c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1487 // set the AVCodecContext duration because the duration of individual tracks
1488 // may be inaccurate
1489 if (c->time_scale > 0 && !c->trex_data)
1490 c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale);
1491 avio_rb32(pb); /* preferred scale */
1493 avio_rb16(pb); /* preferred volume */
1495 avio_skip(pb, 10); /* reserved */
1497 /* movie display matrix, store it in main context and use it later on */
1498 for (i = 0; i < 3; i++) {
1499 c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1500 c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1501 c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1504 avio_rb32(pb); /* preview time */
1505 avio_rb32(pb); /* preview duration */
1506 avio_rb32(pb); /* poster time */
1507 avio_rb32(pb); /* selection time */
1508 avio_rb32(pb); /* selection duration */
1509 avio_rb32(pb); /* current time */
1510 avio_rb32(pb); /* next track ID */
1515 static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1520 if (c->fc->nb_streams < 1)
1522 st = c->fc->streams[c->fc->nb_streams-1];
1524 little_endian = avio_rb16(pb) & 0xFF;
1525 av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1526 if (little_endian == 1) {
1527 switch (st->codecpar->codec_id) {
1528 case AV_CODEC_ID_PCM_S24BE:
1529 st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE;
1531 case AV_CODEC_ID_PCM_S32BE:
1532 st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE;
1534 case AV_CODEC_ID_PCM_F32BE:
1535 st->codecpar->codec_id = AV_CODEC_ID_PCM_F32LE;
1537 case AV_CODEC_ID_PCM_F64BE:
1538 st->codecpar->codec_id = AV_CODEC_ID_PCM_F64LE;
1547 static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1550 uint8_t *icc_profile;
1551 char color_parameter_type[5] = { 0 };
1552 uint16_t color_primaries, color_trc, color_matrix;
1555 if (c->fc->nb_streams < 1)
1557 st = c->fc->streams[c->fc->nb_streams - 1];
1559 ret = ffio_read_size(pb, color_parameter_type, 4);
1562 if (strncmp(color_parameter_type, "nclx", 4) &&
1563 strncmp(color_parameter_type, "nclc", 4) &&
1564 strncmp(color_parameter_type, "prof", 4)) {
1565 av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
1566 color_parameter_type);
1570 if (!strncmp(color_parameter_type, "prof", 4)) {
1571 icc_profile = av_stream_new_side_data(st, AV_PKT_DATA_ICC_PROFILE, atom.size - 4);
1573 return AVERROR(ENOMEM);
1574 ret = ffio_read_size(pb, icc_profile, atom.size - 4);
1579 color_primaries = avio_rb16(pb);
1580 color_trc = avio_rb16(pb);
1581 color_matrix = avio_rb16(pb);
1583 av_log(c->fc, AV_LOG_TRACE,
1584 "%s: pri %d trc %d matrix %d",
1585 color_parameter_type, color_primaries, color_trc, color_matrix);
1587 if (!strncmp(color_parameter_type, "nclx", 4)) {
1588 uint8_t color_range = avio_r8(pb) >> 7;
1589 av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
1591 st->codecpar->color_range = AVCOL_RANGE_JPEG;
1593 st->codecpar->color_range = AVCOL_RANGE_MPEG;
1596 if (!av_color_primaries_name(color_primaries))
1597 color_primaries = AVCOL_PRI_UNSPECIFIED;
1598 if (!av_color_transfer_name(color_trc))
1599 color_trc = AVCOL_TRC_UNSPECIFIED;
1600 if (!av_color_space_name(color_matrix))
1601 color_matrix = AVCOL_SPC_UNSPECIFIED;
1603 st->codecpar->color_primaries = color_primaries;
1604 st->codecpar->color_trc = color_trc;
1605 st->codecpar->color_space = color_matrix;
1606 av_log(c->fc, AV_LOG_TRACE, "\n");
1611 static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1614 unsigned mov_field_order;
1615 enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
1617 if (c->fc->nb_streams < 1) // will happen with jp2 files
1619 st = c->fc->streams[c->fc->nb_streams-1];
1621 return AVERROR_INVALIDDATA;
1622 mov_field_order = avio_rb16(pb);
1623 if ((mov_field_order & 0xFF00) == 0x0100)
1624 decoded_field_order = AV_FIELD_PROGRESSIVE;
1625 else if ((mov_field_order & 0xFF00) == 0x0200) {
1626 switch (mov_field_order & 0xFF) {
1627 case 0x01: decoded_field_order = AV_FIELD_TT;
1629 case 0x06: decoded_field_order = AV_FIELD_BB;
1631 case 0x09: decoded_field_order = AV_FIELD_TB;
1633 case 0x0E: decoded_field_order = AV_FIELD_BT;
1637 if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
1638 av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
1640 st->codecpar->field_order = decoded_field_order;
1645 static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
1648 uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
1649 if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
1650 return AVERROR_INVALIDDATA;
1651 if ((err = av_reallocp(&par->extradata, size)) < 0) {
1652 par->extradata_size = 0;
1655 par->extradata_size = size - AV_INPUT_BUFFER_PADDING_SIZE;
1659 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
1660 static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1661 AVCodecParameters *par, uint8_t *buf)
1663 int64_t result = atom.size;
1666 AV_WB32(buf , atom.size + 8);
1667 AV_WL32(buf + 4, atom.type);
1668 err = ffio_read_size(pb, buf + 8, atom.size);
1670 par->extradata_size -= atom.size;
1672 } else if (err < atom.size) {
1673 av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
1674 par->extradata_size -= atom.size - err;
1677 memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1681 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
1682 static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1683 enum AVCodecID codec_id)
1686 uint64_t original_size;
1689 if (c->fc->nb_streams < 1) // will happen with jp2 files
1691 st = c->fc->streams[c->fc->nb_streams-1];
1693 if (st->codecpar->codec_id != codec_id)
1694 return 0; /* unexpected codec_id - don't mess with extradata */
1696 original_size = st->codecpar->extradata_size;
1697 err = mov_realloc_extradata(st->codecpar, atom);
1701 err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
1704 return 0; // Note: this is the original behavior to ignore truncation.
1707 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
1708 static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1710 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
1713 static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1715 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS);
1718 static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1720 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
1723 static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1725 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
1728 static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1730 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
1732 ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
1736 static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1738 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
1740 if (!ret && c->fc->nb_streams >= 1) {
1741 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1742 if (par->extradata_size >= 40) {
1743 par->height = AV_RB16(&par->extradata[36]);
1744 par->width = AV_RB16(&par->extradata[38]);
1750 static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1752 if (c->fc->nb_streams >= 1) {
1753 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1754 if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
1755 par->codec_id == AV_CODEC_ID_H264 &&
1759 cid = avio_rb16(pb);
1760 /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
1761 if (cid == 0xd4d || cid == 0xd4e)
1764 } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
1765 par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
1766 par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
1770 num = avio_rb32(pb);
1771 den = avio_rb32(pb);
1772 if (num <= 0 || den <= 0)
1774 switch (avio_rb32(pb)) {
1776 if (den >= INT_MAX / 2)
1780 c->fc->streams[c->fc->nb_streams-1]->display_aspect_ratio.num = num;
1781 c->fc->streams[c->fc->nb_streams-1]->display_aspect_ratio.den = den;
1788 return mov_read_avid(c, pb, atom);
1791 static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1795 uint64_t original_size;
1796 if (c->fc->nb_streams >= 1) {
1797 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1798 if (par->codec_id == AV_CODEC_ID_H264)
1800 if (atom.size == 16) {
1801 original_size = par->extradata_size;
1802 ret = mov_realloc_extradata(par, atom);
1804 length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
1805 if (length == atom.size) {
1806 const uint8_t range_value = par->extradata[original_size + 19];
1807 switch (range_value) {
1809 par->color_range = AVCOL_RANGE_MPEG;
1812 par->color_range = AVCOL_RANGE_JPEG;
1815 av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
1818 ff_dlog(c->fc, "color_range: %d\n", par->color_range);
1820 /* For some reason the whole atom was not added to the extradata */
1821 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
1824 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
1827 av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
1834 static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1836 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
1839 static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1844 if (c->fc->nb_streams < 1)
1846 st = c->fc->streams[c->fc->nb_streams-1];
1848 if ((uint64_t)atom.size > (1<<30))
1849 return AVERROR_INVALIDDATA;
1851 if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
1852 st->codecpar->codec_id == AV_CODEC_ID_QDMC ||
1853 st->codecpar->codec_id == AV_CODEC_ID_SPEEX) {
1854 // pass all frma atom to codec, needed at least for QDMC and QDM2
1855 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1858 } else if (atom.size > 8) { /* to read frma, esds atoms */
1859 if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
1861 ret = ffio_ensure_seekback(pb, 8);
1864 buffer = avio_rb64(pb);
1866 if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
1867 && buffer >> 32 <= atom.size
1868 && buffer >> 32 >= 8) {
1871 } else if (!st->codecpar->extradata_size) {
1872 #define ALAC_EXTRADATA_SIZE 36
1873 st->codecpar->extradata = av_mallocz(ALAC_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
1874 if (!st->codecpar->extradata)
1875 return AVERROR(ENOMEM);
1876 st->codecpar->extradata_size = ALAC_EXTRADATA_SIZE;
1877 AV_WB32(st->codecpar->extradata , ALAC_EXTRADATA_SIZE);
1878 AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
1879 AV_WB64(st->codecpar->extradata + 12, buffer);
1880 avio_read(pb, st->codecpar->extradata + 20, 16);
1881 avio_skip(pb, atom.size - 24);
1885 if ((ret = mov_read_default(c, pb, atom)) < 0)
1888 avio_skip(pb, atom.size);
1893 * This function reads atom content and puts data in extradata without tag
1894 * nor size unlike mov_read_extradata.
1896 static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1901 if (c->fc->nb_streams < 1)
1903 st = c->fc->streams[c->fc->nb_streams-1];
1905 if ((uint64_t)atom.size > (1<<30))
1906 return AVERROR_INVALIDDATA;
1908 if (atom.size >= 10) {
1909 // Broken files created by legacy versions of libavformat will
1910 // wrap a whole fiel atom inside of a glbl atom.
1911 unsigned size = avio_rb32(pb);
1912 unsigned type = avio_rl32(pb);
1913 avio_seek(pb, -8, SEEK_CUR);
1914 if (type == MKTAG('f','i','e','l') && size == atom.size)
1915 return mov_read_default(c, pb, atom);
1917 if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
1918 av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
1921 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1924 if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
1925 /* HEVC-based Dolby Vision derived from hvc1.
1926 Happens to match with an identifier
1927 previously utilized for DV. Thus, if we have
1928 the hvcC extradata box available as specified,
1929 set codec to HEVC */
1930 st->codecpar->codec_id = AV_CODEC_ID_HEVC;
1935 static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1938 uint8_t profile_level;
1941 if (c->fc->nb_streams < 1)
1943 st = c->fc->streams[c->fc->nb_streams-1];
1945 if (atom.size >= (1<<28) || atom.size < 7)
1946 return AVERROR_INVALIDDATA;
1948 profile_level = avio_r8(pb);
1949 if ((profile_level & 0xf0) != 0xc0)
1952 avio_seek(pb, 6, SEEK_CUR);
1953 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
1961 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
1962 * but can have extradata appended at the end after the 40 bytes belonging
1965 static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1970 if (c->fc->nb_streams < 1)
1972 if (atom.size <= 40)
1974 st = c->fc->streams[c->fc->nb_streams-1];
1976 if ((uint64_t)atom.size > (1<<30))
1977 return AVERROR_INVALIDDATA;
1980 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
1987 static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1990 MOVStreamContext *sc;
1991 unsigned int i, entries;
1993 if (c->trak_index < 0) {
1994 av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
1997 if (c->fc->nb_streams < 1)
1999 st = c->fc->streams[c->fc->nb_streams-1];
2002 avio_r8(pb); /* version */
2003 avio_rb24(pb); /* flags */
2005 entries = avio_rb32(pb);
2010 if (sc->chunk_offsets)
2011 av_log(c->fc, AV_LOG_WARNING, "Duplicated STCO atom\n");
2012 av_free(sc->chunk_offsets);
2013 sc->chunk_count = 0;
2014 sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2015 if (!sc->chunk_offsets)
2016 return AVERROR(ENOMEM);
2017 sc->chunk_count = entries;
2019 if (atom.type == MKTAG('s','t','c','o'))
2020 for (i = 0; i < entries && !pb->eof_reached; i++)
2021 sc->chunk_offsets[i] = avio_rb32(pb);
2022 else if (atom.type == MKTAG('c','o','6','4'))
2023 for (i = 0; i < entries && !pb->eof_reached; i++)
2024 sc->chunk_offsets[i] = avio_rb64(pb);
2026 return AVERROR_INVALIDDATA;
2028 sc->chunk_count = i;
2030 if (pb->eof_reached) {
2031 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2038 static int mov_codec_id(AVStream *st, uint32_t format)
2040 int id = ff_codec_get_id(ff_codec_movaudio_tags, format);
2043 ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2044 (format & 0xFFFF) == 'T' + ('S' << 8)))
2045 id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format) & 0xFFFF);
2047 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2048 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2049 } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2050 /* skip old ASF MPEG-4 tag */
2051 format && format != MKTAG('m','p','4','s')) {
2052 id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2054 id = ff_codec_get_id(ff_codec_bmp_tags, format);
2056 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
2057 else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2058 (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE &&
2059 st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2060 id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
2062 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
2064 id = ff_codec_get_id(ff_codec_movdata_tags, format);
2068 st->codecpar->codec_tag = format;
2073 static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
2074 AVStream *st, MOVStreamContext *sc)
2076 uint8_t codec_name[32] = { 0 };
2080 /* The first 16 bytes of the video sample description are already
2081 * read in ff_mov_read_stsd_entries() */
2082 stsd_start = avio_tell(pb) - 16;
2084 avio_rb16(pb); /* version */
2085 avio_rb16(pb); /* revision level */
2086 avio_rb32(pb); /* vendor */
2087 avio_rb32(pb); /* temporal quality */
2088 avio_rb32(pb); /* spatial quality */
2090 st->codecpar->width = avio_rb16(pb); /* width */
2091 st->codecpar->height = avio_rb16(pb); /* height */
2093 avio_rb32(pb); /* horiz resolution */
2094 avio_rb32(pb); /* vert resolution */
2095 avio_rb32(pb); /* data size, always 0 */
2096 avio_rb16(pb); /* frames per samples */
2098 len = avio_r8(pb); /* codec name, pascal string */
2101 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2103 avio_skip(pb, 31 - len);
2106 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2108 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2109 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2110 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2111 st->codecpar->width &= ~1;
2112 st->codecpar->height &= ~1;
2114 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2115 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2116 !strncmp(codec_name, "Sorenson H263", 13))
2117 st->codecpar->codec_id = AV_CODEC_ID_FLV1;
2119 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2121 avio_seek(pb, stsd_start, SEEK_SET);
2123 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2124 st->codecpar->bits_per_coded_sample &= 0x1F;
2125 sc->has_palette = 1;
2129 static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
2130 AVStream *st, MOVStreamContext *sc)
2132 int bits_per_sample, flags;
2133 uint16_t version = avio_rb16(pb);
2134 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2136 avio_rb16(pb); /* revision level */
2137 avio_rb32(pb); /* vendor */
2139 st->codecpar->channels = avio_rb16(pb); /* channel count */
2140 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2141 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", st->codecpar->channels);
2143 sc->audio_cid = avio_rb16(pb);
2144 avio_rb16(pb); /* packet size = 0 */
2146 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2148 // Read QT version 1 fields. In version 0 these do not exist.
2149 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2151 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2152 (sc->stsd_version == 0 && version > 0)) {
2154 sc->samples_per_frame = avio_rb32(pb);
2155 avio_rb32(pb); /* bytes per packet */
2156 sc->bytes_per_frame = avio_rb32(pb);
2157 avio_rb32(pb); /* bytes per sample */
2158 } else if (version == 2) {
2159 avio_rb32(pb); /* sizeof struct only */
2160 st->codecpar->sample_rate = av_int2double(avio_rb64(pb));
2161 st->codecpar->channels = avio_rb32(pb);
2162 avio_rb32(pb); /* always 0x7F000000 */
2163 st->codecpar->bits_per_coded_sample = avio_rb32(pb);
2165 flags = avio_rb32(pb); /* lpcm format specific flag */
2166 sc->bytes_per_frame = avio_rb32(pb);
2167 sc->samples_per_frame = avio_rb32(pb);
2168 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2169 st->codecpar->codec_id =
2170 ff_mov_get_lpcm_codec_id(st->codecpar->bits_per_coded_sample,
2173 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2174 /* can't correctly handle variable sized packet as audio unit */
2175 switch (st->codecpar->codec_id) {
2176 case AV_CODEC_ID_MP2:
2177 case AV_CODEC_ID_MP3:
2178 st->need_parsing = AVSTREAM_PARSE_FULL;
2184 if (sc->format == 0) {
2185 if (st->codecpar->bits_per_coded_sample == 8)
2186 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2187 else if (st->codecpar->bits_per_coded_sample == 16)
2188 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2191 switch (st->codecpar->codec_id) {
2192 case AV_CODEC_ID_PCM_S8:
2193 case AV_CODEC_ID_PCM_U8:
2194 if (st->codecpar->bits_per_coded_sample == 16)
2195 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16BE;
2197 case AV_CODEC_ID_PCM_S16LE:
2198 case AV_CODEC_ID_PCM_S16BE:
2199 if (st->codecpar->bits_per_coded_sample == 8)
2200 st->codecpar->codec_id = AV_CODEC_ID_PCM_S8;
2201 else if (st->codecpar->bits_per_coded_sample == 24)
2202 st->codecpar->codec_id =
2203 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2204 AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
2205 else if (st->codecpar->bits_per_coded_sample == 32)
2206 st->codecpar->codec_id =
2207 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2208 AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
2210 /* set values for old format before stsd version 1 appeared */
2211 case AV_CODEC_ID_MACE3:
2212 sc->samples_per_frame = 6;
2213 sc->bytes_per_frame = 2 * st->codecpar->channels;
2215 case AV_CODEC_ID_MACE6:
2216 sc->samples_per_frame = 6;
2217 sc->bytes_per_frame = 1 * st->codecpar->channels;
2219 case AV_CODEC_ID_ADPCM_IMA_QT:
2220 sc->samples_per_frame = 64;
2221 sc->bytes_per_frame = 34 * st->codecpar->channels;
2223 case AV_CODEC_ID_GSM:
2224 sc->samples_per_frame = 160;
2225 sc->bytes_per_frame = 33;
2231 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2232 if (bits_per_sample) {
2233 st->codecpar->bits_per_coded_sample = bits_per_sample;
2234 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->channels;
2238 static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
2239 AVStream *st, MOVStreamContext *sc,
2242 // ttxt stsd contains display flags, justification, background
2243 // color, fonts, and default styles, so fake an atom to read it
2244 MOVAtom fake_atom = { .size = size };
2245 // mp4s contains a regular esds atom
2246 if (st->codecpar->codec_tag != AV_RL32("mp4s"))
2247 mov_read_glbl(c, pb, fake_atom);
2248 st->codecpar->width = sc->width;
2249 st->codecpar->height = sc->height;
2252 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2257 y = (ycbcr >> 16) & 0xFF;
2258 cr = (ycbcr >> 8) & 0xFF;
2261 b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
2262 g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
2263 r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
2265 return (r << 16) | (g << 8) | b;
2268 static int mov_rewrite_dvd_sub_extradata(AVStream *st)
2270 char buf[256] = {0};
2271 uint8_t *src = st->codecpar->extradata;
2274 if (st->codecpar->extradata_size != 64)
2277 if (st->codecpar->width > 0 && st->codecpar->height > 0)
2278 snprintf(buf, sizeof(buf), "size: %dx%d\n",
2279 st->codecpar->width, st->codecpar->height);
2280 av_strlcat(buf, "palette: ", sizeof(buf));
2282 for (i = 0; i < 16; i++) {
2283 uint32_t yuv = AV_RB32(src + i * 4);
2284 uint32_t rgba = yuv_to_rgba(yuv);
2286 av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2289 if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2292 ret = ff_alloc_extradata(st->codecpar, strlen(buf));
2295 memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2300 static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
2301 AVStream *st, MOVStreamContext *sc,
2306 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2307 if ((int)size != size)
2308 return AVERROR(ENOMEM);
2310 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2314 MOVStreamContext *tmcd_ctx = st->priv_data;
2316 val = AV_RB32(st->codecpar->extradata + 4);
2317 tmcd_ctx->tmcd_flags = val;
2318 st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2319 st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2320 #if FF_API_LAVF_AVCTX
2321 FF_DISABLE_DEPRECATION_WARNINGS
2322 st->codec->time_base = av_inv_q(st->avg_frame_rate);
2323 FF_ENABLE_DEPRECATION_WARNINGS
2325 /* adjust for per frame dur in counter mode */
2326 if (tmcd_ctx->tmcd_flags & 0x0008) {
2327 int timescale = AV_RB32(st->codecpar->extradata + 8);
2328 int framedur = AV_RB32(st->codecpar->extradata + 12);
2329 st->avg_frame_rate.num *= timescale;
2330 st->avg_frame_rate.den *= framedur;
2331 #if FF_API_LAVF_AVCTX
2332 FF_DISABLE_DEPRECATION_WARNINGS
2333 st->codec->time_base.den *= timescale;
2334 st->codec->time_base.num *= framedur;
2335 FF_ENABLE_DEPRECATION_WARNINGS
2339 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2340 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2341 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2342 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2343 if (str_size > 0 && size >= (int)str_size + 26) {
2344 char *reel_name = av_malloc(str_size + 1);
2346 return AVERROR(ENOMEM);
2347 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2348 reel_name[str_size] = 0; /* Add null terminator */
2349 /* don't add reel_name if emtpy string */
2350 if (*reel_name == 0) {
2353 av_dict_set(&st->metadata, "reel_name", reel_name, AV_DICT_DONT_STRDUP_VAL);
2360 /* other codec type, just skip (rtp, mp4s ...) */
2361 avio_skip(pb, size);
2366 static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
2367 AVStream *st, MOVStreamContext *sc)
2369 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2370 !st->codecpar->sample_rate && sc->time_scale > 1)
2371 st->codecpar->sample_rate = sc->time_scale;
2373 /* special codec parameters handling */
2374 switch (st->codecpar->codec_id) {
2375 #if CONFIG_DV_DEMUXER
2376 case AV_CODEC_ID_DVAUDIO:
2377 c->dv_fctx = avformat_alloc_context();
2379 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2380 return AVERROR(ENOMEM);
2382 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2384 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2385 return AVERROR(ENOMEM);
2387 sc->dv_audio_container = 1;
2388 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
2391 /* no ifdef since parameters are always those */
2392 case AV_CODEC_ID_QCELP:
2393 st->codecpar->channels = 1;
2394 // force sample rate for qcelp when not stored in mov
2395 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2396 st->codecpar->sample_rate = 8000;
2397 // FIXME: Why is the following needed for some files?
2398 sc->samples_per_frame = 160;
2399 if (!sc->bytes_per_frame)
2400 sc->bytes_per_frame = 35;
2402 case AV_CODEC_ID_AMR_NB:
2403 st->codecpar->channels = 1;
2404 /* force sample rate for amr, stsd in 3gp does not store sample rate */
2405 st->codecpar->sample_rate = 8000;
2407 case AV_CODEC_ID_AMR_WB:
2408 st->codecpar->channels = 1;
2409 st->codecpar->sample_rate = 16000;
2411 case AV_CODEC_ID_MP2:
2412 case AV_CODEC_ID_MP3:
2413 /* force type after stsd for m1a hdlr */
2414 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2416 case AV_CODEC_ID_GSM:
2417 case AV_CODEC_ID_ADPCM_MS:
2418 case AV_CODEC_ID_ADPCM_IMA_WAV:
2419 case AV_CODEC_ID_ILBC:
2420 case AV_CODEC_ID_MACE3:
2421 case AV_CODEC_ID_MACE6:
2422 case AV_CODEC_ID_QDM2:
2423 st->codecpar->block_align = sc->bytes_per_frame;
2425 case AV_CODEC_ID_ALAC:
2426 if (st->codecpar->extradata_size == 36) {
2427 st->codecpar->channels = AV_RB8 (st->codecpar->extradata + 21);
2428 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2431 case AV_CODEC_ID_AC3:
2432 case AV_CODEC_ID_EAC3:
2433 case AV_CODEC_ID_MPEG1VIDEO:
2434 case AV_CODEC_ID_VC1:
2435 case AV_CODEC_ID_VP8:
2436 case AV_CODEC_ID_VP9:
2437 st->need_parsing = AVSTREAM_PARSE_FULL;
2445 static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
2446 int codec_tag, int format,
2449 int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2452 (codec_tag != format &&
2453 // AVID 1:1 samples with differing data format and codec tag exist
2454 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
2455 // prores is allowed to have differing data format and codec tag
2456 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
2458 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
2459 (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id
2460 : codec_tag != MKTAG('j','p','e','g')))) {
2461 /* Multiple fourcc, we skip JPEG. This is not correct, we should
2462 * export it as a separate AVStream but this needs a few changes
2463 * in the MOV demuxer, patch welcome. */
2465 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
2466 avio_skip(pb, size);
2473 int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
2476 MOVStreamContext *sc;
2477 int pseudo_stream_id;
2479 av_assert0 (c->fc->nb_streams >= 1);
2480 st = c->fc->streams[c->fc->nb_streams-1];
2483 for (pseudo_stream_id = 0;
2484 pseudo_stream_id < entries && !pb->eof_reached;
2485 pseudo_stream_id++) {
2486 //Parsing Sample description table
2488 int ret, dref_id = 1;
2489 MOVAtom a = { AV_RL32("stsd") };
2490 int64_t start_pos = avio_tell(pb);
2491 int64_t size = avio_rb32(pb); /* size */
2492 uint32_t format = avio_rl32(pb); /* data format */
2495 avio_rb32(pb); /* reserved */
2496 avio_rb16(pb); /* reserved */
2497 dref_id = avio_rb16(pb);
2498 } else if (size <= 7) {
2499 av_log(c->fc, AV_LOG_ERROR,
2500 "invalid size %"PRId64" in stsd\n", size);
2501 return AVERROR_INVALIDDATA;
2504 if (mov_skip_multiple_stsd(c, pb, st->codecpar->codec_tag, format,
2505 size - (avio_tell(pb) - start_pos))) {
2510 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
2511 sc->dref_id= dref_id;
2512 sc->format = format;
2514 id = mov_codec_id(st, format);
2516 av_log(c->fc, AV_LOG_TRACE,
2517 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
2518 av_fourcc2str(format), st->codecpar->codec_type);
2520 st->codecpar->codec_id = id;
2521 if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) {
2522 mov_parse_stsd_video(c, pb, st, sc);
2523 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
2524 mov_parse_stsd_audio(c, pb, st, sc);
2525 if (st->codecpar->sample_rate < 0) {
2526 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
2527 return AVERROR_INVALIDDATA;
2529 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
2530 mov_parse_stsd_subtitle(c, pb, st, sc,
2531 size - (avio_tell(pb) - start_pos));
2533 ret = mov_parse_stsd_data(c, pb, st, sc,
2534 size - (avio_tell(pb) - start_pos));
2538 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
2539 a.size = size - (avio_tell(pb) - start_pos);
2541 if ((ret = mov_read_default(c, pb, a)) < 0)
2543 } else if (a.size > 0)
2544 avio_skip(pb, a.size);
2546 if (sc->extradata && st->codecpar->extradata) {
2547 int extra_size = st->codecpar->extradata_size;
2549 /* Move the current stream extradata to the stream context one. */
2550 sc->extradata_size[pseudo_stream_id] = extra_size;
2551 sc->extradata[pseudo_stream_id] = av_malloc(extra_size + AV_INPUT_BUFFER_PADDING_SIZE);
2552 if (!sc->extradata[pseudo_stream_id])
2553 return AVERROR(ENOMEM);
2554 memcpy(sc->extradata[pseudo_stream_id], st->codecpar->extradata, extra_size);
2555 av_freep(&st->codecpar->extradata);
2556 st->codecpar->extradata_size = 0;
2561 if (pb->eof_reached) {
2562 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
2569 static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2572 MOVStreamContext *sc;
2575 if (c->fc->nb_streams < 1)
2577 st = c->fc->streams[c->fc->nb_streams - 1];
2580 sc->stsd_version = avio_r8(pb);
2581 avio_rb24(pb); /* flags */
2582 entries = avio_rb32(pb);
2584 /* Each entry contains a size (4 bytes) and format (4 bytes). */
2585 if (entries <= 0 || entries > atom.size / 8) {
2586 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
2587 return AVERROR_INVALIDDATA;
2590 if (sc->extradata) {
2591 av_log(c->fc, AV_LOG_ERROR,
2592 "Duplicate stsd found in this track.\n");
2593 return AVERROR_INVALIDDATA;
2596 /* Prepare space for hosting multiple extradata. */
2597 sc->extradata = av_mallocz_array(entries, sizeof(*sc->extradata));
2599 return AVERROR(ENOMEM);
2601 sc->extradata_size = av_mallocz_array(entries, sizeof(*sc->extradata_size));
2602 if (!sc->extradata_size) {
2603 ret = AVERROR(ENOMEM);
2607 ret = ff_mov_read_stsd_entries(c, pb, entries);
2611 /* Restore back the primary extradata. */
2612 av_freep(&st->codecpar->extradata);
2613 st->codecpar->extradata_size = sc->extradata_size[0];
2614 if (sc->extradata_size[0]) {
2615 st->codecpar->extradata = av_mallocz(sc->extradata_size[0] + AV_INPUT_BUFFER_PADDING_SIZE);
2616 if (!st->codecpar->extradata)
2617 return AVERROR(ENOMEM);
2618 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
2621 return mov_finalize_stsd_codec(c, pb, st, sc);
2623 if (sc->extradata) {
2625 for (j = 0; j < sc->stsd_count; j++)
2626 av_freep(&sc->extradata[j]);
2629 av_freep(&sc->extradata);
2630 av_freep(&sc->extradata_size);
2634 static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2637 MOVStreamContext *sc;
2638 unsigned int i, entries;
2640 if (c->fc->nb_streams < 1)
2642 st = c->fc->streams[c->fc->nb_streams-1];
2645 avio_r8(pb); /* version */
2646 avio_rb24(pb); /* flags */
2648 entries = avio_rb32(pb);
2649 if ((uint64_t)entries * 12 + 4 > atom.size)
2650 return AVERROR_INVALIDDATA;
2652 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
2657 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSC atom\n");
2658 av_free(sc->stsc_data);
2660 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
2662 return AVERROR(ENOMEM);
2664 for (i = 0; i < entries && !pb->eof_reached; i++) {
2665 sc->stsc_data[i].first = avio_rb32(pb);
2666 sc->stsc_data[i].count = avio_rb32(pb);
2667 sc->stsc_data[i].id = avio_rb32(pb);
2671 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
2672 int64_t first_min = i + 1;
2673 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
2674 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
2675 sc->stsc_data[i].first < first_min ||
2676 sc->stsc_data[i].count < 1 ||
2677 sc->stsc_data[i].id < 1) {
2678 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);
2679 if (i+1 >= sc->stsc_count) {
2680 if (sc->stsc_data[i].count == 0 && i > 0) {
2684 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
2685 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
2686 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
2687 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
2688 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
2691 av_assert0(sc->stsc_data[i+1].first >= 2);
2692 // We replace this entry by the next valid
2693 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
2694 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
2695 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
2699 if (pb->eof_reached) {
2700 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
2707 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
2709 return index < count - 1;
2712 /* Compute the samples value for the stsc entry at the given index. */
2713 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
2717 if (mov_stsc_index_valid(index, sc->stsc_count))
2718 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
2720 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
2721 av_assert0(sc->stsc_data[index].first <= sc->chunk_count);
2722 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
2725 return sc->stsc_data[index].count * (int64_t)chunk_count;
2728 static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2731 MOVStreamContext *sc;
2732 unsigned i, entries;
2734 if (c->fc->nb_streams < 1)
2736 st = c->fc->streams[c->fc->nb_streams-1];
2739 avio_rb32(pb); // version + flags
2741 entries = avio_rb32(pb);
2743 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
2744 av_free(sc->stps_data);
2746 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
2748 return AVERROR(ENOMEM);
2750 for (i = 0; i < entries && !pb->eof_reached; i++) {
2751 sc->stps_data[i] = avio_rb32(pb);
2756 if (pb->eof_reached) {
2757 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
2764 static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2767 MOVStreamContext *sc;
2768 unsigned int i, entries;
2770 if (c->fc->nb_streams < 1)
2772 st = c->fc->streams[c->fc->nb_streams-1];
2775 avio_r8(pb); /* version */
2776 avio_rb24(pb); /* flags */
2778 entries = avio_rb32(pb);
2780 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
2784 sc->keyframe_absent = 1;
2785 if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
2786 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2790 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
2791 if (entries >= UINT_MAX / sizeof(int))
2792 return AVERROR_INVALIDDATA;
2793 av_freep(&sc->keyframes);
2794 sc->keyframe_count = 0;
2795 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
2797 return AVERROR(ENOMEM);
2799 for (i = 0; i < entries && !pb->eof_reached; i++) {
2800 sc->keyframes[i] = avio_rb32(pb);
2803 sc->keyframe_count = i;
2805 if (pb->eof_reached) {
2806 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
2813 static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2816 MOVStreamContext *sc;
2817 unsigned int i, entries, sample_size, field_size, num_bytes;
2822 if (c->fc->nb_streams < 1)
2824 st = c->fc->streams[c->fc->nb_streams-1];
2827 avio_r8(pb); /* version */
2828 avio_rb24(pb); /* flags */
2830 if (atom.type == MKTAG('s','t','s','z')) {
2831 sample_size = avio_rb32(pb);
2832 if (!sc->sample_size) /* do not overwrite value computed in stsd */
2833 sc->sample_size = sample_size;
2834 sc->stsz_sample_size = sample_size;
2838 avio_rb24(pb); /* reserved */
2839 field_size = avio_r8(pb);
2841 entries = avio_rb32(pb);
2843 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
2845 sc->sample_count = entries;
2849 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
2850 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
2851 return AVERROR_INVALIDDATA;
2856 if (entries >= (UINT_MAX - 4) / field_size)
2857 return AVERROR_INVALIDDATA;
2858 if (sc->sample_sizes)
2859 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
2860 av_free(sc->sample_sizes);
2861 sc->sample_count = 0;
2862 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
2863 if (!sc->sample_sizes)
2864 return AVERROR(ENOMEM);
2866 num_bytes = (entries*field_size+4)>>3;
2868 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
2870 av_freep(&sc->sample_sizes);
2871 return AVERROR(ENOMEM);
2874 ret = ffio_read_size(pb, buf, num_bytes);
2876 av_freep(&sc->sample_sizes);
2878 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
2882 init_get_bits(&gb, buf, 8*num_bytes);
2884 for (i = 0; i < entries && !pb->eof_reached; i++) {
2885 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
2886 sc->data_size += sc->sample_sizes[i];
2889 sc->sample_count = i;
2893 if (pb->eof_reached) {
2894 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSZ atom\n");
2901 static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2904 MOVStreamContext *sc;
2905 unsigned int i, entries, alloc_size = 0;
2907 int64_t total_sample_count=0;
2909 if (c->fc->nb_streams < 1)
2911 st = c->fc->streams[c->fc->nb_streams-1];
2914 avio_r8(pb); /* version */
2915 avio_rb24(pb); /* flags */
2916 entries = avio_rb32(pb);
2918 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
2919 c->fc->nb_streams-1, entries);
2922 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
2923 av_freep(&sc->stts_data);
2925 if (entries >= INT_MAX / sizeof(*sc->stts_data))
2926 return AVERROR(ENOMEM);
2928 for (i = 0; i < entries && !pb->eof_reached; i++) {
2929 int sample_duration;
2930 unsigned int sample_count;
2931 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
2932 MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
2933 min_entries * sizeof(*sc->stts_data));
2935 av_freep(&sc->stts_data);
2937 return AVERROR(ENOMEM);
2939 sc->stts_count = min_entries;
2940 sc->stts_data = stts_data;
2942 sample_count=avio_rb32(pb);
2943 sample_duration = avio_rb32(pb);
2945 sc->stts_data[i].count= sample_count;
2946 sc->stts_data[i].duration= sample_duration;
2948 av_log(c->fc, AV_LOG_TRACE, "sample_count=%d, sample_duration=%d\n",
2949 sample_count, sample_duration);
2951 duration+=(int64_t)sample_duration*(uint64_t)sample_count;
2952 total_sample_count+=sample_count;
2958 duration <= INT64_MAX - sc->duration_for_fps &&
2959 total_sample_count <= INT_MAX - sc->nb_frames_for_fps
2961 sc->duration_for_fps += duration;
2962 sc->nb_frames_for_fps += total_sample_count;
2965 if (pb->eof_reached) {
2966 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
2970 st->nb_frames= total_sample_count;
2972 st->duration= FFMIN(st->duration, duration);
2973 sc->track_end = duration;
2977 static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2980 MOVStreamContext *sc;
2983 if (c->fc->nb_streams < 1)
2985 st = c->fc->streams[c->fc->nb_streams - 1];
2988 avio_r8(pb); /* version */
2989 avio_rb24(pb); /* flags */
2990 entries = atom.size - 4;
2992 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
2993 c->fc->nb_streams - 1, entries);
2996 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
2997 av_freep(&sc->sdtp_data);
3000 sc->sdtp_data = av_mallocz(entries);
3002 return AVERROR(ENOMEM);
3004 for (i = 0; i < entries && !pb->eof_reached; i++)
3005 sc->sdtp_data[i] = avio_r8(pb);
3011 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3014 if (duration == INT_MIN) {
3015 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3018 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3022 static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3025 MOVStreamContext *sc;
3026 unsigned int i, entries, ctts_count = 0;
3028 if (c->fc->nb_streams < 1)
3030 st = c->fc->streams[c->fc->nb_streams-1];
3033 avio_r8(pb); /* version */
3034 avio_rb24(pb); /* flags */
3035 entries = avio_rb32(pb);
3037 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3041 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3042 return AVERROR_INVALIDDATA;
3043 av_freep(&sc->ctts_data);
3044 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3046 return AVERROR(ENOMEM);
3048 for (i = 0; i < entries && !pb->eof_reached; i++) {
3049 int count =avio_rb32(pb);
3050 int duration =avio_rb32(pb);
3053 av_log(c->fc, AV_LOG_TRACE,
3054 "ignoring CTTS entry with count=%d duration=%d\n",
3059 add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3062 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3065 if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3066 av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3067 av_freep(&sc->ctts_data);
3073 mov_update_dts_shift(sc, duration, c->fc);
3076 sc->ctts_count = ctts_count;
3078 if (pb->eof_reached) {
3079 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3083 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3088 static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3091 MOVStreamContext *sc;
3092 unsigned int i, entries;
3094 uint32_t grouping_type;
3096 if (c->fc->nb_streams < 1)
3098 st = c->fc->streams[c->fc->nb_streams-1];
3101 version = avio_r8(pb); /* version */
3102 avio_rb24(pb); /* flags */
3103 grouping_type = avio_rl32(pb);
3104 if (grouping_type != MKTAG( 'r','a','p',' '))
3105 return 0; /* only support 'rap ' grouping */
3107 avio_rb32(pb); /* grouping_type_parameter */
3109 entries = avio_rb32(pb);
3113 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP atom\n");
3114 av_free(sc->rap_group);
3115 sc->rap_group_count = 0;
3116 sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group));
3118 return AVERROR(ENOMEM);
3120 for (i = 0; i < entries && !pb->eof_reached; i++) {
3121 sc->rap_group[i].count = avio_rb32(pb); /* sample_count */
3122 sc->rap_group[i].index = avio_rb32(pb); /* group_description_index */
3125 sc->rap_group_count = i;
3127 if (pb->eof_reached) {
3128 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3136 * Get ith edit list entry (media time, duration).
3138 static int get_edit_list_entry(MOVContext *mov,
3139 const MOVStreamContext *msc,
3140 unsigned int edit_list_index,
3141 int64_t *edit_list_media_time,
3142 int64_t *edit_list_duration,
3143 int64_t global_timescale)
3145 if (edit_list_index == msc->elst_count) {
3148 *edit_list_media_time = msc->elst_data[edit_list_index].time;
3149 *edit_list_duration = msc->elst_data[edit_list_index].duration;
3151 /* duration is in global timescale units;convert to msc timescale */
3152 if (global_timescale == 0) {
3153 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3156 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3162 * Find the closest previous frame to the timestamp_pts, in e_old index
3163 * entries. Searching for just any frame / just key frames can be controlled by
3164 * last argument 'flag'.
3165 * Note that if ctts_data is not NULL, we will always search for a key frame
3166 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3167 * return the first frame of the video.
3169 * Here the timestamp_pts is considered to be a presentation timestamp and
3170 * the timestamp of index entries are considered to be decoding timestamps.
3172 * Returns 0 if successful in finding a frame, else returns -1.
3173 * Places the found index corresponding output arg.
3175 * If ctts_old is not NULL, then refines the searched entry by searching
3176 * backwards from the found timestamp, to find the frame with correct PTS.
3178 * Places the found ctts_index and ctts_sample in corresponding output args.
3180 static int find_prev_closest_index(AVStream *st,
3181 AVIndexEntry *e_old,
3185 int64_t timestamp_pts,
3188 int64_t* ctts_index,
3189 int64_t* ctts_sample)
3191 MOVStreamContext *msc = st->priv_data;
3192 AVIndexEntry *e_keep = st->index_entries;
3193 int nb_keep = st->nb_index_entries;
3195 int64_t index_ctts_count;
3199 // If dts_shift > 0, then all the index timestamps will have to be offset by
3200 // at least dts_shift amount to obtain PTS.
3201 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3202 if (msc->dts_shift > 0) {
3203 timestamp_pts -= msc->dts_shift;
3206 st->index_entries = e_old;
3207 st->nb_index_entries = nb_old;
3208 *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3210 // Keep going backwards in the index entries until the timestamp is the same.
3212 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3214 if ((flag & AVSEEK_FLAG_ANY) ||
3215 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3221 // If we have CTTS then refine the search, by searching backwards over PTS
3222 // computed by adding corresponding CTTS durations to index timestamps.
3223 if (ctts_data && *index >= 0) {
3224 av_assert0(ctts_index);
3225 av_assert0(ctts_sample);
3226 // Find out the ctts_index for the found frame.
3229 for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3230 if (*ctts_index < ctts_count) {
3232 if (ctts_data[*ctts_index].count == *ctts_sample) {
3239 while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3240 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3241 // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3242 // compensated by dts_shift above.
3243 if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3244 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3249 if (*ctts_sample == 0) {
3251 if (*ctts_index >= 0)
3252 *ctts_sample = ctts_data[*ctts_index].count - 1;
3259 /* restore AVStream state*/
3260 st->index_entries = e_keep;
3261 st->nb_index_entries = nb_keep;
3262 return *index >= 0 ? 0 : -1;
3266 * Add index entry with the given values, to the end of st->index_entries.
3267 * Returns the new size st->index_entries if successful, else returns -1.
3269 * This function is similar to ff_add_index_entry in libavformat/utils.c
3270 * except that here we are always unconditionally adding an index entry to
3271 * the end, instead of searching the entries list and skipping the add if
3272 * there is an existing entry with the same timestamp.
3273 * This is needed because the mov_fix_index calls this func with the same
3274 * unincremented timestamp for successive discarded frames.
3276 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3277 int size, int distance, int flags)
3279 AVIndexEntry *entries, *ie;
3281 const size_t min_size_needed = (st->nb_index_entries + 1) * sizeof(AVIndexEntry);
3283 // Double the allocation each time, to lower memory fragmentation.
3284 // Another difference from ff_add_index_entry function.
3285 const size_t requested_size =
3286 min_size_needed > st->index_entries_allocated_size ?
3287 FFMAX(min_size_needed, 2 * st->index_entries_allocated_size) :
3290 if((unsigned)st->nb_index_entries + 1 >= UINT_MAX / sizeof(AVIndexEntry))
3293 entries = av_fast_realloc(st->index_entries,
3294 &st->index_entries_allocated_size,
3299 st->index_entries= entries;
3301 index= st->nb_index_entries++;
3302 ie= &entries[index];
3305 ie->timestamp = timestamp;
3306 ie->min_distance= distance;
3313 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3314 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3316 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3317 int64_t* frame_duration_buffer,
3318 int frame_duration_buffer_size) {
3320 av_assert0(end_index >= 0 && end_index <= st->nb_index_entries);
3321 for (i = 0; i < frame_duration_buffer_size; i++) {
3322 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3323 st->index_entries[end_index - 1 - i].timestamp = end_ts;
3328 * Append a new ctts entry to ctts_data.
3329 * Returns the new ctts_count if successful, else returns -1.
3331 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3332 int count, int duration)
3334 MOVStts *ctts_buf_new;
3335 const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVStts);
3336 const size_t requested_size =
3337 min_size_needed > *allocated_size ?
3338 FFMAX(min_size_needed, 2 * (*allocated_size)) :
3341 if((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
3344 ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3349 *ctts_data = ctts_buf_new;
3351 ctts_buf_new[*ctts_count].count = count;
3352 ctts_buf_new[*ctts_count].duration = duration;
3354 *ctts_count = (*ctts_count) + 1;
3358 #define MAX_REORDER_DELAY 16
3359 static void mov_estimate_video_delay(MOVContext *c, AVStream* st) {
3360 MOVStreamContext *msc = st->priv_data;
3363 int ctts_sample = 0;
3364 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3366 int j, r, num_swaps;
3368 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3369 pts_buf[j] = INT64_MIN;
3371 if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3372 st->codecpar->codec_id == AV_CODEC_ID_H264) {
3373 st->codecpar->video_delay = 0;
3374 for(ind = 0; ind < st->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3375 // Point j to the last elem of the buffer and insert the current pts there.
3377 buf_start = (buf_start + 1);
3378 if (buf_start == MAX_REORDER_DELAY + 1)
3381 pts_buf[j] = st->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3383 // The timestamps that are already in the sorted buffer, and are greater than the
3384 // current pts, are exactly the timestamps that need to be buffered to output PTS
3385 // in correct sorted order.
3386 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3387 // can be computed as the maximum no. of swaps any particular timestamp needs to
3388 // go through, to keep this buffer in sorted order.
3390 while (j != buf_start) {
3392 if (r < 0) r = MAX_REORDER_DELAY;
3393 if (pts_buf[j] < pts_buf[r]) {
3394 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3401 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3404 if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3409 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3410 st->codecpar->video_delay, st->index);
3414 static void mov_current_sample_inc(MOVStreamContext *sc)
3416 sc->current_sample++;
3417 sc->current_index++;
3418 if (sc->index_ranges &&
3419 sc->current_index >= sc->current_index_range->end &&
3420 sc->current_index_range->end) {
3421 sc->current_index_range++;
3422 sc->current_index = sc->current_index_range->start;
3426 static void mov_current_sample_dec(MOVStreamContext *sc)
3428 sc->current_sample--;
3429 sc->current_index--;
3430 if (sc->index_ranges &&
3431 sc->current_index < sc->current_index_range->start &&
3432 sc->current_index_range > sc->index_ranges) {
3433 sc->current_index_range--;
3434 sc->current_index = sc->current_index_range->end - 1;
3438 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3442 sc->current_sample = current_sample;
3443 sc->current_index = current_sample;
3444 if (!sc->index_ranges) {
3448 for (sc->current_index_range = sc->index_ranges;
3449 sc->current_index_range->end;
3450 sc->current_index_range++) {
3451 range_size = sc->current_index_range->end - sc->current_index_range->start;
3452 if (range_size > current_sample) {
3453 sc->current_index = sc->current_index_range->start + current_sample;
3456 current_sample -= range_size;
3461 * Fix st->index_entries, so that it contains only the entries (and the entries
3462 * which are needed to decode them) that fall in the edit list time ranges.
3463 * Also fixes the timestamps of the index entries to match the timeline
3464 * specified the edit lists.
3466 static void mov_fix_index(MOVContext *mov, AVStream *st)
3468 MOVStreamContext *msc = st->priv_data;
3469 AVIndexEntry *e_old = st->index_entries;
3470 int nb_old = st->nb_index_entries;
3471 const AVIndexEntry *e_old_end = e_old + nb_old;
3472 const AVIndexEntry *current = NULL;
3473 MOVStts *ctts_data_old = msc->ctts_data;
3474 int64_t ctts_index_old = 0;
3475 int64_t ctts_sample_old = 0;
3476 int64_t ctts_count_old = msc->ctts_count;
3477 int64_t edit_list_media_time = 0;
3478 int64_t edit_list_duration = 0;
3479 int64_t frame_duration = 0;
3480 int64_t edit_list_dts_counter = 0;
3481 int64_t edit_list_dts_entry_end = 0;
3482 int64_t edit_list_start_ctts_sample = 0;
3484 int64_t curr_ctts = 0;
3485 int64_t empty_edits_sum_duration = 0;
3486 int64_t edit_list_index = 0;
3489 int64_t start_dts = 0;
3490 int64_t edit_list_start_encountered = 0;
3491 int64_t search_timestamp = 0;
3492 int64_t* frame_duration_buffer = NULL;
3493 int num_discarded_begin = 0;
3494 int first_non_zero_audio_edit = -1;
3495 int packet_skip_samples = 0;
3496 MOVIndexRange *current_index_range;
3498 int found_keyframe_after_edit = 0;
3499 int found_non_empty_edit = 0;
3501 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
3505 // allocate the index ranges array
3506 msc->index_ranges = av_malloc((msc->elst_count + 1) * sizeof(msc->index_ranges[0]));
3507 if (!msc->index_ranges) {
3508 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
3511 msc->current_index_range = msc->index_ranges;
3512 current_index_range = msc->index_ranges - 1;
3514 // Clean AVStream from traces of old index
3515 st->index_entries = NULL;
3516 st->index_entries_allocated_size = 0;
3517 st->nb_index_entries = 0;
3519 // Clean ctts fields of MOVStreamContext
3520 msc->ctts_data = NULL;
3521 msc->ctts_count = 0;
3522 msc->ctts_index = 0;
3523 msc->ctts_sample = 0;
3524 msc->ctts_allocated_size = 0;
3526 // Reinitialize min_corrected_pts so that it can be computed again.
3527 msc->min_corrected_pts = -1;
3529 // If the dts_shift is positive (in case of negative ctts values in mov),
3530 // then negate the DTS by dts_shift
3531 if (msc->dts_shift > 0) {
3532 edit_list_dts_entry_end -= msc->dts_shift;
3533 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
3536 start_dts = edit_list_dts_entry_end;
3538 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
3539 &edit_list_duration, mov->time_scale)) {
3540 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
3541 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
3543 edit_list_dts_counter = edit_list_dts_entry_end;
3544 edit_list_dts_entry_end += edit_list_duration;
3545 num_discarded_begin = 0;
3546 if (!found_non_empty_edit && edit_list_media_time == -1) {
3547 empty_edits_sum_duration += edit_list_duration;
3550 found_non_empty_edit = 1;
3552 // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
3553 // according to the edit list below.
3554 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3555 if (first_non_zero_audio_edit < 0) {
3556 first_non_zero_audio_edit = 1;
3558 first_non_zero_audio_edit = 0;
3561 if (first_non_zero_audio_edit > 0)
3562 st->skip_samples = msc->start_pad = 0;
3565 // While reordering frame index according to edit list we must handle properly
3566 // the scenario when edit list entry starts from none key frame.
3567 // We find closest previous key frame and preserve it and consequent frames in index.
3568 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
3569 search_timestamp = edit_list_media_time;
3570 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3571 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
3572 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
3573 // edit_list_media_time to cover the decoder delay.
3574 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
3577 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
3578 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3579 av_log(mov->fc, AV_LOG_WARNING,
3580 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
3581 st->index, edit_list_index, search_timestamp);
3582 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
3583 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3584 av_log(mov->fc, AV_LOG_WARNING,
3585 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
3586 st->index, edit_list_index, search_timestamp);
3589 ctts_sample_old = 0;
3592 current = e_old + index;
3593 edit_list_start_ctts_sample = ctts_sample_old;
3595 // Iterate over index and arrange it according to edit list
3596 edit_list_start_encountered = 0;
3597 found_keyframe_after_edit = 0;
3598 for (; current < e_old_end; current++, index++) {
3599 // check if frame outside edit list mark it for discard
3600 frame_duration = (current + 1 < e_old_end) ?
3601 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
3603 flags = current->flags;
3605 // frames (pts) before or after edit list
3606 curr_cts = current->timestamp + msc->dts_shift;
3609 if (ctts_data_old && ctts_index_old < ctts_count_old) {
3610 curr_ctts = ctts_data_old[ctts_index_old].duration;
3611 av_log(mov->fc, AV_LOG_DEBUG, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
3612 curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
3613 curr_cts += curr_ctts;
3615 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
3616 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3617 &msc->ctts_allocated_size,
3618 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3619 ctts_data_old[ctts_index_old].duration) == -1) {
3620 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3622 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3623 ctts_data_old[ctts_index_old].duration);
3627 ctts_sample_old = 0;
3628 edit_list_start_ctts_sample = 0;
3632 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
3633 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
3634 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
3635 first_non_zero_audio_edit > 0) {
3636 packet_skip_samples = edit_list_media_time - curr_cts;
3637 st->skip_samples += packet_skip_samples;
3639 // Shift the index entry timestamp by packet_skip_samples to be correct.
3640 edit_list_dts_counter -= packet_skip_samples;
3641 if (edit_list_start_encountered == 0) {
3642 edit_list_start_encountered = 1;
3643 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
3644 // discarded packets.
3645 if (frame_duration_buffer) {
3646 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3647 frame_duration_buffer, num_discarded_begin);
3648 av_freep(&frame_duration_buffer);
3652 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
3654 flags |= AVINDEX_DISCARD_FRAME;
3655 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
3657 if (edit_list_start_encountered == 0) {
3658 num_discarded_begin++;
3659 frame_duration_buffer = av_realloc(frame_duration_buffer,
3660 num_discarded_begin * sizeof(int64_t));
3661 if (!frame_duration_buffer) {
3662 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
3665 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
3667 // Increment skip_samples for the first non-zero audio edit list
3668 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3669 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
3670 st->skip_samples += frame_duration;
3675 if (msc->min_corrected_pts < 0) {
3676 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
3678 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
3680 if (edit_list_start_encountered == 0) {
3681 edit_list_start_encountered = 1;
3682 // Make timestamps strictly monotonically increasing by rewriting timestamps for
3683 // discarded packets.
3684 if (frame_duration_buffer) {
3685 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3686 frame_duration_buffer, num_discarded_begin);
3687 av_freep(&frame_duration_buffer);
3692 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
3693 current->min_distance, flags) == -1) {
3694 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
3698 // Update the index ranges array
3699 if (current_index_range < msc->index_ranges || index != current_index_range->end) {
3700 current_index_range++;
3701 current_index_range->start = index;
3703 current_index_range->end = index + 1;
3705 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
3706 if (edit_list_start_encountered > 0) {
3707 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
3710 // Break when found first key frame after edit entry completion
3711 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
3712 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
3713 if (ctts_data_old) {
3714 // If we have CTTS and this is the first keyframe after edit elist,
3715 // wait for one more, because there might be trailing B-frames after this I-frame
3716 // that do belong to the edit.
3717 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
3718 found_keyframe_after_edit = 1;
3721 if (ctts_sample_old != 0) {
3722 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3723 &msc->ctts_allocated_size,
3724 ctts_sample_old - edit_list_start_ctts_sample,
3725 ctts_data_old[ctts_index_old].duration) == -1) {
3726 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3727 ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
3728 ctts_data_old[ctts_index_old].duration);
3737 // If there are empty edits, then msc->min_corrected_pts might be positive
3738 // intentionally. So we subtract the sum duration of emtpy edits here.
3739 msc->min_corrected_pts -= empty_edits_sum_duration;
3741 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
3742 // dts by that amount to make the first pts zero.
3743 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
3744 if (msc->min_corrected_pts > 0) {
3745 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
3746 for (i = 0; i < st->nb_index_entries; ++i) {
3747 st->index_entries[i].timestamp -= msc->min_corrected_pts;
3751 // Start time should be equal to zero or the duration of any empty edits.
3752 st->start_time = empty_edits_sum_duration;
3754 // Update av stream length, if it ends up shorter than the track's media duration
3755 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
3756 msc->start_pad = st->skip_samples;
3758 // Free the old index and the old CTTS structures
3760 av_free(ctts_data_old);
3761 av_freep(&frame_duration_buffer);
3763 // Null terminate the index ranges array
3764 current_index_range++;
3765 current_index_range->start = 0;
3766 current_index_range->end = 0;
3767 msc->current_index = msc->index_ranges[0].start;
3770 static void mov_build_index(MOVContext *mov, AVStream *st)
3772 MOVStreamContext *sc = st->priv_data;
3773 int64_t current_offset;
3774 int64_t current_dts = 0;
3775 unsigned int stts_index = 0;
3776 unsigned int stsc_index = 0;
3777 unsigned int stss_index = 0;
3778 unsigned int stps_index = 0;
3780 uint64_t stream_size = 0;
3781 MOVStts *ctts_data_old = sc->ctts_data;
3782 unsigned int ctts_count_old = sc->ctts_count;
3784 if (sc->elst_count) {
3785 int i, edit_start_index = 0, multiple_edits = 0;
3786 int64_t empty_duration = 0; // empty duration of the first edit list entry
3787 int64_t start_time = 0; // start time of the media
3789 for (i = 0; i < sc->elst_count; i++) {
3790 const MOVElst *e = &sc->elst_data[i];
3791 if (i == 0 && e->time == -1) {
3792 /* if empty, the first entry is the start time of the stream
3793 * relative to the presentation itself */
3794 empty_duration = e->duration;
3795 edit_start_index = 1;
3796 } else if (i == edit_start_index && e->time >= 0) {
3797 start_time = e->time;
3803 if (multiple_edits && !mov->advanced_editlist)
3804 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
3805 "Use -advanced_editlist to correctly decode otherwise "
3806 "a/v desync might occur\n");
3808 /* adjust first dts according to edit list */
3809 if ((empty_duration || start_time) && mov->time_scale > 0) {
3811 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
3812 sc->time_offset = start_time - empty_duration;
3813 sc->min_corrected_pts = start_time;
3814 if (!mov->advanced_editlist)
3815 current_dts = -sc->time_offset;
3818 if (!multiple_edits && !mov->advanced_editlist &&
3819 st->codecpar->codec_id == AV_CODEC_ID_AAC && start_time > 0)
3820 sc->start_pad = start_time;
3823 /* only use old uncompressed audio chunk demuxing when stts specifies it */
3824 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3825 sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
3826 unsigned int current_sample = 0;
3827 unsigned int stts_sample = 0;
3828 unsigned int sample_size;
3829 unsigned int distance = 0;
3830 unsigned int rap_group_index = 0;
3831 unsigned int rap_group_sample = 0;
3832 int64_t last_dts = 0;
3833 int64_t dts_correction = 0;
3834 int rap_group_present = sc->rap_group_count && sc->rap_group;
3835 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
3837 current_dts -= sc->dts_shift;
3838 last_dts = current_dts;
3840 if (!sc->sample_count || st->nb_index_entries)
3842 if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
3844 if (av_reallocp_array(&st->index_entries,
3845 st->nb_index_entries + sc->sample_count,
3846 sizeof(*st->index_entries)) < 0) {
3847 st->nb_index_entries = 0;
3850 st->index_entries_allocated_size = (st->nb_index_entries + sc->sample_count) * sizeof(*st->index_entries);
3852 if (ctts_data_old) {
3853 // Expand ctts entries such that we have a 1-1 mapping with samples
3854 if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
3857 sc->ctts_allocated_size = 0;
3858 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size,
3859 sc->sample_count * sizeof(*sc->ctts_data));
3860 if (!sc->ctts_data) {
3861 av_free(ctts_data_old);
3865 memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
3867 for (i = 0; i < ctts_count_old &&
3868 sc->ctts_count < sc->sample_count; i++)
3869 for (j = 0; j < ctts_data_old[i].count &&
3870 sc->ctts_count < sc->sample_count; j++)
3871 add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
3872 &sc->ctts_allocated_size, 1,
3873 ctts_data_old[i].duration);
3874 av_free(ctts_data_old);
3877 for (i = 0; i < sc->chunk_count; i++) {
3878 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
3879 current_offset = sc->chunk_offsets[i];
3880 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3881 i + 1 == sc->stsc_data[stsc_index + 1].first)
3884 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
3885 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
3886 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
3887 sc->stsz_sample_size = sc->sample_size;
3889 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
3890 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
3891 sc->stsz_sample_size = sc->sample_size;
3894 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
3896 if (current_sample >= sc->sample_count) {
3897 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
3901 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
3903 if (stss_index + 1 < sc->keyframe_count)
3905 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
3907 if (stps_index + 1 < sc->stps_count)
3910 if (rap_group_present && rap_group_index < sc->rap_group_count) {
3911 if (sc->rap_group[rap_group_index].index > 0)
3913 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
3914 rap_group_sample = 0;
3918 if (sc->keyframe_absent
3920 && !rap_group_present
3921 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
3925 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
3926 if (sc->pseudo_stream_id == -1 ||
3927 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
3929 if (sample_size > 0x3FFFFFFF) {
3930 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
3933 e = &st->index_entries[st->nb_index_entries++];
3934 e->pos = current_offset;
3935 e->timestamp = current_dts;
3936 e->size = sample_size;
3937 e->min_distance = distance;
3938 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
3939 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
3940 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
3941 current_offset, current_dts, sample_size, distance, keyframe);
3942 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries < 100)
3943 ff_rfps_add_frame(mov->fc, st, current_dts);
3946 current_offset += sample_size;
3947 stream_size += sample_size;
3949 /* A negative sample duration is invalid based on the spec,
3950 * but some samples need it to correct the DTS. */
3951 if (sc->stts_data[stts_index].duration < 0) {
3952 av_log(mov->fc, AV_LOG_WARNING,
3953 "Invalid SampleDelta %d in STTS, at %d st:%d\n",
3954 sc->stts_data[stts_index].duration, stts_index,
3956 dts_correction += sc->stts_data[stts_index].duration - 1;
3957 sc->stts_data[stts_index].duration = 1;
3959 current_dts += sc->stts_data[stts_index].duration;
3960 if (!dts_correction || current_dts + dts_correction > last_dts) {
3961 current_dts += dts_correction;
3964 /* Avoid creating non-monotonous DTS */
3965 dts_correction += current_dts - last_dts - 1;
3966 current_dts = last_dts + 1;
3968 last_dts = current_dts;
3972 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
3978 if (st->duration > 0)
3979 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
3981 unsigned chunk_samples, total = 0;
3983 if (!sc->chunk_count)
3986 // compute total chunk count
3987 for (i = 0; i < sc->stsc_count; i++) {
3988 unsigned count, chunk_count;
3990 chunk_samples = sc->stsc_data[i].count;
3991 if (i != sc->stsc_count - 1 &&
3992 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
3993 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
3997 if (sc->samples_per_frame >= 160) { // gsm
3998 count = chunk_samples / sc->samples_per_frame;
3999 } else if (sc->samples_per_frame > 1) {
4000 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4001 count = (chunk_samples+samples-1) / samples;
4003 count = (chunk_samples+1023) / 1024;
4006 if (mov_stsc_index_valid(i, sc->stsc_count))
4007 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4009 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4010 total += chunk_count * count;
4013 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4014 if (total >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
4016 if (av_reallocp_array(&st->index_entries,
4017 st->nb_index_entries + total,
4018 sizeof(*st->index_entries)) < 0) {
4019 st->nb_index_entries = 0;
4022 st->index_entries_allocated_size = (st->nb_index_entries + total) * sizeof(*st->index_entries);
4025 for (i = 0; i < sc->chunk_count; i++) {
4026 current_offset = sc->chunk_offsets[i];
4027 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4028 i + 1 == sc->stsc_data[stsc_index + 1].first)
4030 chunk_samples = sc->stsc_data[stsc_index].count;
4032 while (chunk_samples > 0) {
4034 unsigned size, samples;
4036 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4037 avpriv_request_sample(mov->fc,
4038 "Zero bytes per frame, but %d samples per frame",
4039 sc->samples_per_frame);
4043 if (sc->samples_per_frame >= 160) { // gsm
4044 samples = sc->samples_per_frame;
4045 size = sc->bytes_per_frame;
4047 if (sc->samples_per_frame > 1) {
4048 samples = FFMIN((1024 / sc->samples_per_frame)*
4049 sc->samples_per_frame, chunk_samples);
4050 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
4052 samples = FFMIN(1024, chunk_samples);
4053 size = samples * sc->sample_size;
4057 if (st->nb_index_entries >= total) {
4058 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4061 if (size > 0x3FFFFFFF) {
4062 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4065 e = &st->index_entries[st->nb_index_entries++];
4066 e->pos = current_offset;
4067 e->timestamp = current_dts;
4069 e->min_distance = 0;
4070 e->flags = AVINDEX_KEYFRAME;
4071 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4072 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4075 current_offset += size;
4076 current_dts += samples;
4077 chunk_samples -= samples;
4082 if (!mov->ignore_editlist && mov->advanced_editlist) {
4083 // Fix index according to edit lists.
4084 mov_fix_index(mov, st);
4087 // Update start time of the stream.
4088 if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries > 0) {
4089 st->start_time = st->index_entries[0].timestamp + sc->dts_shift;
4090 if (sc->ctts_data) {
4091 st->start_time += sc->ctts_data[0].duration;
4095 mov_estimate_video_delay(mov, st);
4098 static int test_same_origin(const char *src, const char *ref) {
4108 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4109 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4111 if (strlen(src) == 0) {
4113 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4114 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4115 strlen(src_host) + 1 >= sizeof(src_host) ||
4116 strlen(ref_host) + 1 >= sizeof(ref_host)) {
4118 } else if (strcmp(src_proto, ref_proto) ||
4119 strcmp(src_auth, ref_auth) ||
4120 strcmp(src_host, ref_host) ||
4121 src_port != ref_port) {
4127 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4129 /* try relative path, we do not try the absolute because it can leak information about our
4130 system to an attacker */
4131 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4132 char filename[1025];
4133 const char *src_path;
4136 /* find a source dir */
4137 src_path = strrchr(src, '/');
4143 /* find a next level down to target */
4144 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4145 if (ref->path[l] == '/') {
4146 if (i == ref->nlvl_to - 1)
4152 /* compose filename if next level down to target was found */
4153 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4154 memcpy(filename, src, src_path - src);
4155 filename[src_path - src] = 0;
4157 for (i = 1; i < ref->nlvl_from; i++)
4158 av_strlcat(filename, "../", sizeof(filename));
4160 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4161 if (!c->use_absolute_path) {
4162 int same_origin = test_same_origin(src, filename);
4165 av_log(c->fc, AV_LOG_ERROR,
4166 "Reference with mismatching origin, %s not tried for security reasons, "
4167 "set demuxer option use_absolute_path to allow it anyway\n",
4169 return AVERROR(ENOENT);
4172 if(strstr(ref->path + l + 1, "..") ||
4173 strstr(ref->path + l + 1, ":") ||
4174 (ref->nlvl_from > 1 && same_origin < 0) ||
4175 (filename[0] == '/' && src_path == src))
4176 return AVERROR(ENOENT);
4179 if (strlen(filename) + 1 == sizeof(filename))
4180 return AVERROR(ENOENT);
4181 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4184 } else if (c->use_absolute_path) {
4185 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4186 "this is a possible security issue\n");
4187 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4190 av_log(c->fc, AV_LOG_ERROR,
4191 "Absolute path %s not tried for security reasons, "
4192 "set demuxer option use_absolute_path to allow absolute paths\n",
4196 return AVERROR(ENOENT);
4199 static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
4201 if (sc->time_scale <= 0) {
4202 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4203 sc->time_scale = c->time_scale;
4204 if (sc->time_scale <= 0)
4209 static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4212 MOVStreamContext *sc;
4215 st = avformat_new_stream(c->fc, NULL);
4216 if (!st) return AVERROR(ENOMEM);
4218 sc = av_mallocz(sizeof(MOVStreamContext));
4219 if (!sc) return AVERROR(ENOMEM);
4222 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
4223 sc->ffindex = st->index;
4224 c->trak_index = st->index;
4226 if ((ret = mov_read_default(c, pb, atom)) < 0)
4231 // Here stsc refers to a chunk not described in stco. This is technically invalid,
4232 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4233 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4235 av_freep(&sc->stsc_data);
4239 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4240 (!sc->sample_size && !sc->sample_count))) ||
4241 (!sc->chunk_count && sc->sample_count)) {
4242 av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4246 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4247 av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4249 return AVERROR_INVALIDDATA;
4252 fix_timescale(c, sc);
4254 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4256 mov_build_index(c, st);
4258 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4259 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4260 if (c->enable_drefs) {
4261 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4262 av_log(c->fc, AV_LOG_ERROR,
4263 "stream %d, error opening alias: path='%s', dir='%s', "
4264 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4265 st->index, dref->path, dref->dir, dref->filename,
4266 dref->volume, dref->nlvl_from, dref->nlvl_to);
4268 av_log(c->fc, AV_LOG_WARNING,
4269 "Skipped opening external track: "
4270 "stream %d, alias: path='%s', dir='%s', "
4271 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4272 "Set enable_drefs to allow this.\n",
4273 st->index, dref->path, dref->dir, dref->filename,
4274 dref->volume, dref->nlvl_from, dref->nlvl_to);
4278 sc->pb_is_copied = 1;
4281 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4282 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4283 sc->height && sc->width &&
4284 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4285 st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4286 ((double)st->codecpar->width * sc->height), INT_MAX);
4289 #if FF_API_R_FRAME_RATE
4290 if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4291 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
4292 sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4296 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4297 if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4298 TAG_IS_AVCI(st->codecpar->codec_tag)) {
4299 ret = ff_generate_avci_extradata(st);
4304 switch (st->codecpar->codec_id) {
4305 #if CONFIG_H261_DECODER
4306 case AV_CODEC_ID_H261:
4308 #if CONFIG_H263_DECODER
4309 case AV_CODEC_ID_H263:
4311 #if CONFIG_MPEG4_DECODER
4312 case AV_CODEC_ID_MPEG4:
4314 st->codecpar->width = 0; /* let decoder init width/height */
4315 st->codecpar->height= 0;
4319 // If the duration of the mp3 packets is not constant, then they could need a parser
4320 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4321 && sc->stts_count > 3
4322 && sc->stts_count*10 > st->nb_frames
4323 && sc->time_scale == st->codecpar->sample_rate) {
4324 st->need_parsing = AVSTREAM_PARSE_FULL;
4326 /* Do not need those anymore. */
4327 av_freep(&sc->chunk_offsets);
4328 av_freep(&sc->sample_sizes);
4329 av_freep(&sc->keyframes);
4330 av_freep(&sc->stts_data);
4331 av_freep(&sc->stps_data);
4332 av_freep(&sc->elst_data);
4333 av_freep(&sc->rap_group);
4338 static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4341 c->itunes_metadata = 1;
4342 ret = mov_read_default(c, pb, atom);
4343 c->itunes_metadata = 0;
4347 static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4356 count = avio_rb32(pb);
4357 if (count > UINT_MAX / sizeof(*c->meta_keys) - 1) {
4358 av_log(c->fc, AV_LOG_ERROR,
4359 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
4360 return AVERROR_INVALIDDATA;
4363 c->meta_keys_count = count + 1;
4364 c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
4366 return AVERROR(ENOMEM);
4368 for (i = 1; i <= count; ++i) {
4369 uint32_t key_size = avio_rb32(pb);
4370 uint32_t type = avio_rl32(pb);
4372 av_log(c->fc, AV_LOG_ERROR,
4373 "The key# %"PRIu32" in meta has invalid size:"
4374 "%"PRIu32"\n", i, key_size);
4375 return AVERROR_INVALIDDATA;
4378 if (type != MKTAG('m','d','t','a')) {
4379 avio_skip(pb, key_size);
4381 c->meta_keys[i] = av_mallocz(key_size + 1);
4382 if (!c->meta_keys[i])
4383 return AVERROR(ENOMEM);
4384 avio_read(pb, c->meta_keys[i], key_size);
4390 static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4392 int64_t end = avio_tell(pb) + atom.size;
4393 uint8_t *key = NULL, *val = NULL, *mean = NULL;
4397 MOVStreamContext *sc;
4399 if (c->fc->nb_streams < 1)
4401 st = c->fc->streams[c->fc->nb_streams-1];
4404 for (i = 0; i < 3; i++) {
4408 if (end - avio_tell(pb) <= 12)
4411 len = avio_rb32(pb);
4412 tag = avio_rl32(pb);
4413 avio_skip(pb, 4); // flags
4415 if (len < 12 || len - 12 > end - avio_tell(pb))
4419 if (tag == MKTAG('m', 'e', 'a', 'n'))
4421 else if (tag == MKTAG('n', 'a', 'm', 'e'))
4423 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
4430 *p = av_malloc(len + 1);
4432 ret = AVERROR(ENOMEM);
4435 ret = ffio_read_size(pb, *p, len);
4443 if (mean && key && val) {
4444 if (strcmp(key, "iTunSMPB") == 0) {
4445 int priming, remainder, samples;
4446 if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
4447 if(priming>0 && priming<16384)
4448 sc->start_pad = priming;
4451 if (strcmp(key, "cdec") != 0) {
4452 av_dict_set(&c->fc->metadata, key, val,
4453 AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
4457 av_log(c->fc, AV_LOG_VERBOSE,
4458 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
4461 avio_seek(pb, end, SEEK_SET);
4468 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4470 while (atom.size > 8) {
4474 tag = avio_rl32(pb);
4476 if (tag == MKTAG('h','d','l','r')) {
4477 avio_seek(pb, -8, SEEK_CUR);
4479 return mov_read_default(c, pb, atom);
4485 // return 1 when matrix is identity, 0 otherwise
4486 #define IS_MATRIX_IDENT(matrix) \
4487 ( (matrix)[0][0] == (1 << 16) && \
4488 (matrix)[1][1] == (1 << 16) && \
4489 (matrix)[2][2] == (1 << 30) && \
4490 !(matrix)[0][1] && !(matrix)[0][2] && \
4491 !(matrix)[1][0] && !(matrix)[1][2] && \
4492 !(matrix)[2][0] && !(matrix)[2][1])
4494 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4499 int display_matrix[3][3];
4500 int res_display_matrix[3][3] = { { 0 } };
4502 MOVStreamContext *sc;
4506 if (c->fc->nb_streams < 1)
4508 st = c->fc->streams[c->fc->nb_streams-1];
4511 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4512 // avoids corrupting AVStreams mapped to an earlier tkhd.
4514 return AVERROR_INVALIDDATA;
4516 version = avio_r8(pb);
4517 flags = avio_rb24(pb);
4518 st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
4524 avio_rb32(pb); /* creation time */
4525 avio_rb32(pb); /* modification time */
4527 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4528 avio_rb32(pb); /* reserved */
4530 /* highlevel (considering edits) duration in movie timebase */
4531 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4532 avio_rb32(pb); /* reserved */
4533 avio_rb32(pb); /* reserved */
4535 avio_rb16(pb); /* layer */
4536 avio_rb16(pb); /* alternate group */
4537 avio_rb16(pb); /* volume */
4538 avio_rb16(pb); /* reserved */
4540 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4541 // they're kept in fixed point format through all calculations
4542 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4543 // side data, but the scale factor is not needed to calculate aspect ratio
4544 for (i = 0; i < 3; i++) {
4545 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
4546 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
4547 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
4550 width = avio_rb32(pb); // 16.16 fixed point track width
4551 height = avio_rb32(pb); // 16.16 fixed point track height
4552 sc->width = width >> 16;
4553 sc->height = height >> 16;
4555 // apply the moov display matrix (after the tkhd one)
4556 for (i = 0; i < 3; i++) {
4557 const int sh[3] = { 16, 16, 30 };
4558 for (j = 0; j < 3; j++) {
4559 for (e = 0; e < 3; e++) {
4560 res_display_matrix[i][j] +=
4561 ((int64_t) display_matrix[i][e] *
4562 c->movie_display_matrix[e][j]) >> sh[e];
4567 // save the matrix when it is not the default identity
4568 if (!IS_MATRIX_IDENT(res_display_matrix)) {
4571 av_freep(&sc->display_matrix);
4572 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4573 if (!sc->display_matrix)
4574 return AVERROR(ENOMEM);
4576 for (i = 0; i < 3; i++)
4577 for (j = 0; j < 3; j++)
4578 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4580 #if FF_API_OLD_ROTATE_API
4581 rotate = av_display_rotation_get(sc->display_matrix);
4582 if (!isnan(rotate)) {
4583 char rotate_buf[64];
4585 if (rotate < 0) // for backward compatibility
4587 snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate);
4588 av_dict_set(&st->metadata, "rotate", rotate_buf, 0);
4593 // transform the display width/height according to the matrix
4594 // to keep the same scale, use [width height 1<<16]
4595 if (width && height && sc->display_matrix) {
4596 double disp_transform[2];
4598 for (i = 0; i < 2; i++)
4599 disp_transform[i] = hypot(sc->display_matrix[0 + i],
4600 sc->display_matrix[3 + i]);
4602 if (disp_transform[0] > 0 && disp_transform[1] > 0 &&
4603 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4604 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4605 st->sample_aspect_ratio = av_d2q(
4606 disp_transform[0] / disp_transform[1],
4612 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4614 MOVFragment *frag = &c->fragment;
4615 MOVTrackExt *trex = NULL;
4616 int flags, track_id, i;
4618 avio_r8(pb); /* version */
4619 flags = avio_rb24(pb);
4621 track_id = avio_rb32(pb);
4623 return AVERROR_INVALIDDATA;
4624 for (i = 0; i < c->trex_count; i++)
4625 if (c->trex_data[i].track_id == track_id) {
4626 trex = &c->trex_data[i];
4630 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4633 c->fragment.found_tfhd = 1;
4634 frag->track_id = track_id;
4635 set_frag_stream(&c->frag_index, track_id);
4637 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4638 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4639 frag->moof_offset : frag->implicit_offset;
4640 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4642 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4643 avio_rb32(pb) : trex->duration;
4644 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4645 avio_rb32(pb) : trex->size;
4646 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4647 avio_rb32(pb) : trex->flags;
4648 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4653 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4658 num = atom.size / 4;
4659 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4660 return AVERROR(ENOMEM);
4662 av_free(c->chapter_tracks);
4663 c->chapter_tracks = new_tracks;
4664 c->nb_chapter_tracks = num;
4666 for (i = 0; i < num && !pb->eof_reached; i++)
4667 c->chapter_tracks[i] = avio_rb32(pb);
4672 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4677 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4678 return AVERROR_INVALIDDATA;
4679 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4680 sizeof(*c->trex_data))) < 0) {
4685 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4687 trex = &c->trex_data[c->trex_count++];
4688 avio_r8(pb); /* version */
4689 avio_rb24(pb); /* flags */
4690 trex->track_id = avio_rb32(pb);
4691 trex->stsd_id = avio_rb32(pb);
4692 trex->duration = avio_rb32(pb);
4693 trex->size = avio_rb32(pb);
4694 trex->flags = avio_rb32(pb);
4698 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4700 MOVFragment *frag = &c->fragment;
4701 AVStream *st = NULL;
4702 MOVStreamContext *sc;
4704 MOVFragmentStreamInfo * frag_stream_info;
4705 int64_t base_media_decode_time;
4707 for (i = 0; i < c->fc->nb_streams; i++) {
4708 if (c->fc->streams[i]->id == frag->track_id) {
4709 st = c->fc->streams[i];
4714 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4718 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4720 version = avio_r8(pb);
4721 avio_rb24(pb); /* flags */
4723 base_media_decode_time = avio_rb64(pb);
4725 base_media_decode_time = avio_rb32(pb);
4728 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4729 if (frag_stream_info)
4730 frag_stream_info->tfdt_dts = base_media_decode_time;
4731 sc->track_end = base_media_decode_time;
4736 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4738 MOVFragment *frag = &c->fragment;
4739 AVStream *st = NULL;
4740 MOVStreamContext *sc;
4743 int64_t dts, pts = AV_NOPTS_VALUE;
4744 int data_offset = 0;
4745 unsigned entries, first_sample_flags = frag->flags;
4746 int flags, distance, i;
4747 int64_t prev_dts = AV_NOPTS_VALUE;
4748 int next_frag_index = -1, index_entry_pos;
4749 size_t requested_size;
4750 size_t old_ctts_allocated_size;
4751 AVIndexEntry *new_entries;
4752 MOVFragmentStreamInfo * frag_stream_info;
4754 if (!frag->found_tfhd) {
4755 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4756 return AVERROR_INVALIDDATA;
4759 for (i = 0; i < c->fc->nb_streams; i++) {
4760 if (c->fc->streams[i]->id == frag->track_id) {
4761 st = c->fc->streams[i];
4766 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4770 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4773 // Find the next frag_index index that has a valid index_entry for
4774 // the current track_id.
4776 // A valid index_entry means the trun for the fragment was read
4777 // and it's samples are in index_entries at the given position.
4778 // New index entries will be inserted before the index_entry found.
4779 index_entry_pos = st->nb_index_entries;
4780 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4781 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4782 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4783 next_frag_index = i;
4784 index_entry_pos = frag_stream_info->index_entry;
4788 av_assert0(index_entry_pos <= st->nb_index_entries);
4790 avio_r8(pb); /* version */
4791 flags = avio_rb24(pb);
4792 entries = avio_rb32(pb);
4793 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4795 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4796 return AVERROR_INVALIDDATA;
4797 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4798 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4800 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4801 if (frag_stream_info)
4803 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4804 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4805 pts = frag_stream_info->first_tfra_pts;
4806 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4807 ", using it for pts\n", pts);
4808 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4809 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4810 // pts = frag_stream_info->sidx_pts;
4811 dts = frag_stream_info->sidx_pts - sc->time_offset;
4812 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4813 ", using it for pts\n", pts);
4814 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4815 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4816 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4817 ", using it for dts\n", dts);
4819 dts = sc->track_end - sc->time_offset;
4820 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4821 ", using it for dts\n", dts);
4824 dts = sc->track_end - sc->time_offset;
4825 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4826 ", using it for dts\n", dts);
4828 offset = frag->base_data_offset + data_offset;
4830 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4832 // realloc space for new index entries
4833 if((uint64_t)st->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4834 entries = UINT_MAX / sizeof(AVIndexEntry) - st->nb_index_entries;
4835 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4840 requested_size = (st->nb_index_entries + entries) * sizeof(AVIndexEntry);
4841 new_entries = av_fast_realloc(st->index_entries,
4842 &st->index_entries_allocated_size,
4845 return AVERROR(ENOMEM);
4846 st->index_entries= new_entries;
4848 requested_size = (st->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4849 old_ctts_allocated_size = sc->ctts_allocated_size;
4850 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4853 return AVERROR(ENOMEM);
4854 sc->ctts_data = ctts_data;
4856 // In case there were samples without ctts entries, ensure they get
4857 // zero valued entries. This ensures clips which mix boxes with and
4858 // without ctts entries don't pickup uninitialized data.
4859 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4860 sc->ctts_allocated_size - old_ctts_allocated_size);
4862 if (index_entry_pos < st->nb_index_entries) {
4863 // Make hole in index_entries and ctts_data for new samples
4864 memmove(st->index_entries + index_entry_pos + entries,
4865 st->index_entries + index_entry_pos,
4866 sizeof(*st->index_entries) *
4867 (st->nb_index_entries - index_entry_pos));
4868 memmove(sc->ctts_data + index_entry_pos + entries,
4869 sc->ctts_data + index_entry_pos,
4870 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4871 if (index_entry_pos < sc->current_sample) {
4872 sc->current_sample += entries;
4876 st->nb_index_entries += entries;
4877 sc->ctts_count = st->nb_index_entries;
4879 // Record the index_entry position in frag_index of this fragment
4880 if (frag_stream_info)
4881 frag_stream_info->index_entry = index_entry_pos;
4883 if (index_entry_pos > 0)
4884 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4886 for (i = 0; i < entries && !pb->eof_reached; i++) {
4887 unsigned sample_size = frag->size;
4888 int sample_flags = i ? frag->flags : first_sample_flags;
4889 unsigned sample_duration = frag->duration;
4890 unsigned ctts_duration = 0;
4892 int index_entry_flags = 0;
4894 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4895 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4896 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4897 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4899 mov_update_dts_shift(sc, ctts_duration, c->fc);
4900 if (pts != AV_NOPTS_VALUE) {
4901 dts = pts - sc->dts_shift;
4902 if (flags & MOV_TRUN_SAMPLE_CTS) {
4903 dts -= ctts_duration;
4905 dts -= sc->time_offset;
4907 av_log(c->fc, AV_LOG_DEBUG,
4908 "pts %"PRId64" calculated dts %"PRId64
4909 " sc->dts_shift %d ctts.duration %d"
4910 " sc->time_offset %"PRId64
4911 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4913 sc->dts_shift, ctts_duration,
4914 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4915 pts = AV_NOPTS_VALUE;
4918 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4922 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4923 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4926 index_entry_flags |= AVINDEX_KEYFRAME;
4928 // Fragments can overlap in time. Discard overlapping frames after
4930 if (prev_dts >= dts)
4931 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4933 st->index_entries[index_entry_pos].pos = offset;
4934 st->index_entries[index_entry_pos].timestamp = dts;
4935 st->index_entries[index_entry_pos].size= sample_size;
4936 st->index_entries[index_entry_pos].min_distance= distance;
4937 st->index_entries[index_entry_pos].flags = index_entry_flags;
4939 sc->ctts_data[index_entry_pos].count = 1;
4940 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4943 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4944 "size %u, distance %d, keyframe %d\n", st->index,
4945 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4947 dts += sample_duration;
4948 offset += sample_size;
4949 sc->data_size += sample_size;
4951 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4952 1 <= INT_MAX - sc->nb_frames_for_fps
4954 sc->duration_for_fps += sample_duration;
4955 sc->nb_frames_for_fps ++;
4959 // EOF found before reading all entries. Fix the hole this would
4960 // leave in index_entries and ctts_data
4961 int gap = entries - i;
4962 memmove(st->index_entries + index_entry_pos,
4963 st->index_entries + index_entry_pos + gap,
4964 sizeof(*st->index_entries) *
4965 (st->nb_index_entries - (index_entry_pos + gap)));
4966 memmove(sc->ctts_data + index_entry_pos,
4967 sc->ctts_data + index_entry_pos + gap,
4968 sizeof(*sc->ctts_data) *
4969 (sc->ctts_count - (index_entry_pos + gap)));
4971 st->nb_index_entries -= gap;
4972 sc->ctts_count -= gap;
4973 if (index_entry_pos < sc->current_sample) {
4974 sc->current_sample -= gap;
4979 // The end of this new fragment may overlap in time with the start
4980 // of the next fragment in index_entries. Mark the samples in the next
4981 // fragment that overlap with AVINDEX_DISCARD_FRAME
4982 prev_dts = AV_NOPTS_VALUE;
4983 if (index_entry_pos > 0)
4984 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4985 for (i = index_entry_pos; i < st->nb_index_entries; i++) {
4986 if (prev_dts < st->index_entries[i].timestamp)
4988 st->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
4991 // If a hole was created to insert the new index_entries into,
4992 // the index_entry recorded for all subsequent moof must
4993 // be incremented by the number of entries inserted.
4994 fix_frag_index_entries(&c->frag_index, next_frag_index,
4995 frag->track_id, entries);
4997 if (pb->eof_reached) {
4998 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
5002 frag->implicit_offset = offset;
5004 sc->track_end = dts + sc->time_offset;
5005 if (st->duration < sc->track_end)
5006 st->duration = sc->track_end;
5011 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5013 int64_t offset = avio_tell(pb) + atom.size, pts, timestamp;
5015 unsigned i, j, track_id, item_count;
5016 AVStream *st = NULL;
5017 AVStream *ref_st = NULL;
5018 MOVStreamContext *sc, *ref_sc = NULL;
5019 AVRational timescale;
5021 version = avio_r8(pb);
5023 avpriv_request_sample(c->fc, "sidx version %u", version);
5027 avio_rb24(pb); // flags
5029 track_id = avio_rb32(pb); // Reference ID
5030 for (i = 0; i < c->fc->nb_streams; i++) {
5031 if (c->fc->streams[i]->id == track_id) {
5032 st = c->fc->streams[i];
5037 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5043 timescale = av_make_q(1, avio_rb32(pb));
5045 if (timescale.den <= 0) {
5046 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5047 return AVERROR_INVALIDDATA;
5051 pts = avio_rb32(pb);
5052 offset += avio_rb32(pb);
5054 pts = avio_rb64(pb);
5055 offset += avio_rb64(pb);
5058 avio_rb16(pb); // reserved
5060 item_count = avio_rb16(pb);
5062 for (i = 0; i < item_count; i++) {
5064 MOVFragmentStreamInfo * frag_stream_info;
5065 uint32_t size = avio_rb32(pb);
5066 uint32_t duration = avio_rb32(pb);
5067 if (size & 0x80000000) {
5068 avpriv_request_sample(c->fc, "sidx reference_type 1");
5069 return AVERROR_PATCHWELCOME;
5071 avio_rb32(pb); // sap_flags
5072 timestamp = av_rescale_q(pts, timescale, st->time_base);
5074 index = update_frag_index(c, offset);
5075 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5076 if (frag_stream_info)
5077 frag_stream_info->sidx_pts = timestamp;
5083 st->duration = sc->track_end = pts;
5087 if (offset == avio_size(pb)) {
5088 // Find first entry in fragment index that came from an sidx.
5089 // This will pretty much always be the first entry.
5090 for (i = 0; i < c->frag_index.nb_items; i++) {
5091 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5092 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5093 MOVFragmentStreamInfo * si;
5094 si = &item->stream_info[j];
5095 if (si->sidx_pts != AV_NOPTS_VALUE) {
5096 ref_st = c->fc->streams[j];
5097 ref_sc = ref_st->priv_data;
5102 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5103 st = c->fc->streams[i];
5105 if (!sc->has_sidx) {
5106 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5110 c->frag_index.complete = 1;
5116 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5117 /* like the files created with Adobe Premiere 5.0, for samples see */
5118 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5119 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5124 return 0; /* continue */
5125 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5126 avio_skip(pb, atom.size - 4);
5129 atom.type = avio_rl32(pb);
5131 if (atom.type != MKTAG('m','d','a','t')) {
5132 avio_skip(pb, atom.size);
5135 err = mov_read_mdat(c, pb, atom);
5139 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5144 uint8_t *moov_data; /* uncompressed data */
5145 long cmov_len, moov_len;
5148 avio_rb32(pb); /* dcom atom */
5149 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5150 return AVERROR_INVALIDDATA;
5151 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5152 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5153 return AVERROR_INVALIDDATA;
5155 avio_rb32(pb); /* cmvd atom */
5156 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5157 return AVERROR_INVALIDDATA;
5158 moov_len = avio_rb32(pb); /* uncompressed size */
5159 cmov_len = atom.size - 6 * 4;
5161 cmov_data = av_malloc(cmov_len);
5163 return AVERROR(ENOMEM);
5164 moov_data = av_malloc(moov_len);
5167 return AVERROR(ENOMEM);
5169 ret = ffio_read_size(pb, cmov_data, cmov_len);
5171 goto free_and_return;
5173 ret = AVERROR_INVALIDDATA;
5174 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5175 goto free_and_return;
5176 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5177 goto free_and_return;
5178 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5179 atom.type = MKTAG('m','o','o','v');
5180 atom.size = moov_len;
5181 ret = mov_read_default(c, &ctx, atom);
5187 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5188 return AVERROR(ENOSYS);
5192 /* edit list atom */
5193 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5195 MOVStreamContext *sc;
5196 int i, edit_count, version;
5197 int64_t elst_entry_size;
5199 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5201 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5203 version = avio_r8(pb); /* version */
5204 avio_rb24(pb); /* flags */
5205 edit_count = avio_rb32(pb); /* entries */
5208 elst_entry_size = version == 1 ? 20 : 12;
5209 if (atom.size != edit_count * elst_entry_size) {
5210 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5211 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5212 edit_count, atom.size + 8);
5213 return AVERROR_INVALIDDATA;
5215 edit_count = atom.size / elst_entry_size;
5216 if (edit_count * elst_entry_size != atom.size) {
5217 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.", atom.size, edit_count);
5225 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5226 av_free(sc->elst_data);
5228 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5230 return AVERROR(ENOMEM);
5232 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5233 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5234 MOVElst *e = &sc->elst_data[i];
5237 e->duration = avio_rb64(pb);
5238 e->time = avio_rb64(pb);
5241 e->duration = avio_rb32(pb); /* segment duration */
5242 e->time = (int32_t)avio_rb32(pb); /* media time */
5245 e->rate = avio_rb32(pb) / 65536.0;
5247 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5248 e->duration, e->time, e->rate);
5250 if (e->time < 0 && e->time != -1 &&
5251 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5252 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5253 c->fc->nb_streams-1, i, e->time);
5254 return AVERROR_INVALIDDATA;
5262 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5264 MOVStreamContext *sc;
5266 if (c->fc->nb_streams < 1)
5267 return AVERROR_INVALIDDATA;
5268 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5269 sc->timecode_track = avio_rb32(pb);
5273 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5278 if (c->fc->nb_streams < 1)
5280 st = c->fc->streams[c->fc->nb_streams - 1];
5282 if (atom.size < 4) {
5283 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5284 return AVERROR_INVALIDDATA;
5287 /* For now, propagate only the OBUs, if any. Once libavcodec is
5288 updated to handle isobmff style extradata this can be removed. */
5294 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5301 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5304 int version, color_range, color_primaries, color_trc, color_space;
5306 if (c->fc->nb_streams < 1)
5308 st = c->fc->streams[c->fc->nb_streams - 1];
5310 if (atom.size < 5) {
5311 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5312 return AVERROR_INVALIDDATA;
5315 version = avio_r8(pb);
5317 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5320 avio_skip(pb, 3); /* flags */
5322 avio_skip(pb, 2); /* profile + level */
5323 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5324 color_primaries = avio_r8(pb);
5325 color_trc = avio_r8(pb);
5326 color_space = avio_r8(pb);
5327 if (avio_rb16(pb)) /* codecIntializationDataSize */
5328 return AVERROR_INVALIDDATA;
5330 if (!av_color_primaries_name(color_primaries))
5331 color_primaries = AVCOL_PRI_UNSPECIFIED;
5332 if (!av_color_transfer_name(color_trc))
5333 color_trc = AVCOL_TRC_UNSPECIFIED;
5334 if (!av_color_space_name(color_space))
5335 color_space = AVCOL_SPC_UNSPECIFIED;
5337 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5338 st->codecpar->color_primaries = color_primaries;
5339 st->codecpar->color_trc = color_trc;
5340 st->codecpar->color_space = color_space;
5345 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5347 MOVStreamContext *sc;
5350 if (c->fc->nb_streams < 1)
5351 return AVERROR_INVALIDDATA;
5353 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5355 if (atom.size < 5) {
5356 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5357 return AVERROR_INVALIDDATA;
5360 version = avio_r8(pb);
5362 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5365 avio_skip(pb, 3); /* flags */
5367 sc->mastering = av_mastering_display_metadata_alloc();
5369 return AVERROR(ENOMEM);
5371 for (i = 0; i < 3; i++) {
5372 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5373 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5375 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5376 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5378 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5379 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5381 sc->mastering->has_primaries = 1;
5382 sc->mastering->has_luminance = 1;
5387 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5389 MOVStreamContext *sc;
5390 const int mapping[3] = {1, 2, 0};
5391 const int chroma_den = 50000;
5392 const int luma_den = 10000;
5395 if (c->fc->nb_streams < 1)
5396 return AVERROR_INVALIDDATA;
5398 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5400 if (atom.size < 24) {
5401 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5402 return AVERROR_INVALIDDATA;
5405 sc->mastering = av_mastering_display_metadata_alloc();
5407 return AVERROR(ENOMEM);
5409 for (i = 0; i < 3; i++) {
5410 const int j = mapping[i];
5411 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5412 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5414 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5415 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5417 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5418 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5420 sc->mastering->has_luminance = 1;
5421 sc->mastering->has_primaries = 1;
5426 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5428 MOVStreamContext *sc;
5431 if (c->fc->nb_streams < 1)
5432 return AVERROR_INVALIDDATA;
5434 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5436 if (atom.size < 5) {
5437 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5438 return AVERROR_INVALIDDATA;
5441 version = avio_r8(pb);
5443 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5446 avio_skip(pb, 3); /* flags */
5448 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5450 return AVERROR(ENOMEM);
5452 sc->coll->MaxCLL = avio_rb16(pb);
5453 sc->coll->MaxFALL = avio_rb16(pb);
5458 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5460 MOVStreamContext *sc;
5462 if (c->fc->nb_streams < 1)
5463 return AVERROR_INVALIDDATA;
5465 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5467 if (atom.size < 4) {
5468 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5469 return AVERROR_INVALIDDATA;
5472 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5474 return AVERROR(ENOMEM);
5476 sc->coll->MaxCLL = avio_rb16(pb);
5477 sc->coll->MaxFALL = avio_rb16(pb);
5482 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5485 MOVStreamContext *sc;
5486 enum AVStereo3DType type;
5489 if (c->fc->nb_streams < 1)
5492 st = c->fc->streams[c->fc->nb_streams - 1];
5495 if (atom.size < 5) {
5496 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5497 return AVERROR_INVALIDDATA;
5499 avio_skip(pb, 4); /* version + flags */
5504 type = AV_STEREO3D_2D;
5507 type = AV_STEREO3D_TOPBOTTOM;
5510 type = AV_STEREO3D_SIDEBYSIDE;
5513 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5517 sc->stereo3d = av_stereo3d_alloc();
5519 return AVERROR(ENOMEM);
5521 sc->stereo3d->type = type;
5525 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5528 MOVStreamContext *sc;
5529 int size, version, layout;
5530 int32_t yaw, pitch, roll;
5531 uint32_t l = 0, t = 0, r = 0, b = 0;
5532 uint32_t tag, padding = 0;
5533 enum AVSphericalProjection projection;
5535 if (c->fc->nb_streams < 1)
5538 st = c->fc->streams[c->fc->nb_streams - 1];
5541 if (atom.size < 8) {
5542 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5543 return AVERROR_INVALIDDATA;
5546 size = avio_rb32(pb);
5547 if (size <= 12 || size > atom.size)
5548 return AVERROR_INVALIDDATA;
5550 tag = avio_rl32(pb);
5551 if (tag != MKTAG('s','v','h','d')) {
5552 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5555 version = avio_r8(pb);
5557 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5561 avio_skip(pb, 3); /* flags */
5562 avio_skip(pb, size - 12); /* metadata_source */
5564 size = avio_rb32(pb);
5565 if (size > atom.size)
5566 return AVERROR_INVALIDDATA;
5568 tag = avio_rl32(pb);
5569 if (tag != MKTAG('p','r','o','j')) {
5570 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5574 size = avio_rb32(pb);
5575 if (size > atom.size)
5576 return AVERROR_INVALIDDATA;
5578 tag = avio_rl32(pb);
5579 if (tag != MKTAG('p','r','h','d')) {
5580 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5583 version = avio_r8(pb);
5585 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5589 avio_skip(pb, 3); /* flags */
5591 /* 16.16 fixed point */
5592 yaw = avio_rb32(pb);
5593 pitch = avio_rb32(pb);
5594 roll = avio_rb32(pb);
5596 size = avio_rb32(pb);
5597 if (size > atom.size)
5598 return AVERROR_INVALIDDATA;
5600 tag = avio_rl32(pb);
5601 version = avio_r8(pb);
5603 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5607 avio_skip(pb, 3); /* flags */
5609 case MKTAG('c','b','m','p'):
5610 layout = avio_rb32(pb);
5612 av_log(c->fc, AV_LOG_WARNING,
5613 "Unsupported cubemap layout %d\n", layout);
5616 projection = AV_SPHERICAL_CUBEMAP;
5617 padding = avio_rb32(pb);
5619 case MKTAG('e','q','u','i'):
5625 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5626 av_log(c->fc, AV_LOG_ERROR,
5627 "Invalid bounding rectangle coordinates "
5628 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5629 return AVERROR_INVALIDDATA;
5632 if (l || t || r || b)
5633 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5635 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5638 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5642 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5644 return AVERROR(ENOMEM);
5646 sc->spherical->projection = projection;
5648 sc->spherical->yaw = yaw;
5649 sc->spherical->pitch = pitch;
5650 sc->spherical->roll = roll;
5652 sc->spherical->padding = padding;
5654 sc->spherical->bound_left = l;
5655 sc->spherical->bound_top = t;
5656 sc->spherical->bound_right = r;
5657 sc->spherical->bound_bottom = b;
5662 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5665 uint8_t *buffer = av_malloc(len + 1);
5669 return AVERROR(ENOMEM);
5672 ret = ffio_read_size(pb, buffer, len);
5676 /* Check for mandatory keys and values, try to support XML as best-effort */
5677 if (!sc->spherical &&
5678 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5679 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5680 av_stristr(val, "true") &&
5681 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5682 av_stristr(val, "true") &&
5683 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5684 av_stristr(val, "equirectangular")) {
5685 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5689 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5691 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5692 enum AVStereo3DType mode;
5694 if (av_stristr(buffer, "left-right"))
5695 mode = AV_STEREO3D_SIDEBYSIDE;
5696 else if (av_stristr(buffer, "top-bottom"))
5697 mode = AV_STEREO3D_TOPBOTTOM;
5699 mode = AV_STEREO3D_2D;
5701 sc->stereo3d = av_stereo3d_alloc();
5705 sc->stereo3d->type = mode;
5709 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5711 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5712 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5714 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5715 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5717 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5725 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5728 MOVStreamContext *sc;
5731 static const uint8_t uuid_isml_manifest[] = {
5732 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5733 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5735 static const uint8_t uuid_xmp[] = {
5736 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5737 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5739 static const uint8_t uuid_spherical[] = {
5740 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5741 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5744 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5745 return AVERROR_INVALIDDATA;
5747 if (c->fc->nb_streams < 1)
5749 st = c->fc->streams[c->fc->nb_streams - 1];
5752 ret = avio_read(pb, uuid, sizeof(uuid));
5755 } else if (ret != sizeof(uuid)) {
5756 return AVERROR_INVALIDDATA;
5758 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5759 uint8_t *buffer, *ptr;
5761 size_t len = atom.size - sizeof(uuid);
5764 return AVERROR_INVALIDDATA;
5766 ret = avio_skip(pb, 4); // zeroes
5769 buffer = av_mallocz(len + 1);
5771 return AVERROR(ENOMEM);
5773 ret = avio_read(pb, buffer, len);
5777 } else if (ret != len) {
5779 return AVERROR_INVALIDDATA;
5783 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5784 ptr += sizeof("systemBitrate=\"") - 1;
5785 c->bitrates_count++;
5786 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5788 c->bitrates_count = 0;
5790 return AVERROR(ENOMEM);
5793 ret = strtol(ptr, &endptr, 10);
5794 if (ret < 0 || errno || *endptr != '"') {
5795 c->bitrates[c->bitrates_count - 1] = 0;
5797 c->bitrates[c->bitrates_count - 1] = ret;
5802 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5804 size_t len = atom.size - sizeof(uuid);
5805 if (c->export_xmp) {
5806 buffer = av_mallocz(len + 1);
5808 return AVERROR(ENOMEM);
5810 ret = avio_read(pb, buffer, len);
5814 } else if (ret != len) {
5816 return AVERROR_INVALIDDATA;
5819 av_dict_set(&c->fc->metadata, "xmp",
5820 buffer, AV_DICT_DONT_STRDUP_VAL);
5822 // skip all uuid atom, which makes it fast for long uuid-xmp file
5823 ret = avio_skip(pb, len);
5827 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5828 size_t len = atom.size - sizeof(uuid);
5829 ret = mov_parse_uuid_spherical(sc, pb, len);
5833 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5839 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5842 uint8_t content[16];
5847 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5853 && !memcmp(content, "Anevia\x1A\x1A", 8)
5854 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5855 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5861 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5863 uint32_t format = avio_rl32(pb);
5864 MOVStreamContext *sc;
5868 if (c->fc->nb_streams < 1)
5870 st = c->fc->streams[c->fc->nb_streams - 1];
5875 case MKTAG('e','n','c','v'): // encrypted video
5876 case MKTAG('e','n','c','a'): // encrypted audio
5877 id = mov_codec_id(st, format);
5878 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5879 st->codecpar->codec_id != id) {
5880 av_log(c->fc, AV_LOG_WARNING,
5881 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5882 (char*)&format, st->codecpar->codec_id);
5886 st->codecpar->codec_id = id;
5887 sc->format = format;
5891 if (format != sc->format) {
5892 av_log(c->fc, AV_LOG_WARNING,
5893 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5894 (char*)&format, (char*)&sc->format);
5903 * Gets the current encryption info and associated current stream context. If
5904 * we are parsing a track fragment, this will return the specific encryption
5905 * info for this fragment; otherwise this will return the global encryption
5906 * info for the current stream.
5908 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5910 MOVFragmentStreamInfo *frag_stream_info;
5914 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5915 if (frag_stream_info) {
5916 for (i = 0; i < c->fc->nb_streams; i++) {
5917 if (c->fc->streams[i]->id == frag_stream_info->id) {
5918 st = c->fc->streams[i];
5922 if (i == c->fc->nb_streams)
5924 *sc = st->priv_data;
5926 if (!frag_stream_info->encryption_index) {
5927 // If this stream isn't encrypted, don't create the index.
5928 if (!(*sc)->cenc.default_encrypted_sample)
5930 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5931 if (!frag_stream_info->encryption_index)
5932 return AVERROR(ENOMEM);
5934 *encryption_index = frag_stream_info->encryption_index;
5937 // No current track fragment, using stream level encryption info.
5939 if (c->fc->nb_streams < 1)
5941 st = c->fc->streams[c->fc->nb_streams - 1];
5942 *sc = st->priv_data;
5944 if (!(*sc)->cenc.encryption_index) {
5945 // If this stream isn't encrypted, don't create the index.
5946 if (!(*sc)->cenc.default_encrypted_sample)
5948 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5949 if (!(*sc)->cenc.encryption_index)
5950 return AVERROR(ENOMEM);
5953 *encryption_index = (*sc)->cenc.encryption_index;
5958 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
5961 unsigned int subsample_count;
5962 AVSubsampleEncryptionInfo *subsamples;
5964 if (!sc->cenc.default_encrypted_sample) {
5965 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
5966 return AVERROR_INVALIDDATA;
5969 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
5971 return AVERROR(ENOMEM);
5973 if (sc->cenc.per_sample_iv_size != 0) {
5974 if (avio_read(pb, (*sample)->iv, sc->cenc.per_sample_iv_size) != sc->cenc.per_sample_iv_size) {
5975 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
5976 av_encryption_info_free(*sample);
5978 return AVERROR_INVALIDDATA;
5982 if (use_subsamples) {
5983 subsample_count = avio_rb16(pb);
5984 av_free((*sample)->subsamples);
5985 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
5986 if (!(*sample)->subsamples) {
5987 av_encryption_info_free(*sample);
5989 return AVERROR(ENOMEM);
5992 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
5993 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
5994 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
5997 if (pb->eof_reached) {
5998 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
5999 av_encryption_info_free(*sample);
6001 return AVERROR_INVALIDDATA;
6003 (*sample)->subsample_count = subsample_count;
6009 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6011 AVEncryptionInfo **encrypted_samples;
6012 MOVEncryptionIndex *encryption_index;
6013 MOVStreamContext *sc;
6014 int use_subsamples, ret;
6015 unsigned int sample_count, i, alloc_size = 0;
6017 ret = get_current_encryption_info(c, &encryption_index, &sc);
6021 if (encryption_index->nb_encrypted_samples) {
6022 // This can happen if we have both saio/saiz and senc atoms.
6023 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6027 avio_r8(pb); /* version */
6028 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6030 sample_count = avio_rb32(pb);
6031 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6032 return AVERROR(ENOMEM);
6034 for (i = 0; i < sample_count; i++) {
6035 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6036 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6037 min_samples * sizeof(*encrypted_samples));
6038 if (encrypted_samples) {
6039 encryption_index->encrypted_samples = encrypted_samples;
6041 ret = mov_read_sample_encryption_info(
6042 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6044 ret = AVERROR(ENOMEM);
6046 if (pb->eof_reached) {
6047 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6048 ret = AVERROR_INVALIDDATA;
6053 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6054 av_freep(&encryption_index->encrypted_samples);
6058 encryption_index->nb_encrypted_samples = sample_count;
6063 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6065 AVEncryptionInfo **sample, **encrypted_samples;
6067 size_t sample_count, sample_info_size, i;
6069 unsigned int alloc_size = 0;
6071 if (encryption_index->nb_encrypted_samples)
6073 sample_count = encryption_index->auxiliary_info_sample_count;
6074 if (encryption_index->auxiliary_offsets_count != 1) {
6075 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6076 return AVERROR_PATCHWELCOME;
6078 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6079 return AVERROR(ENOMEM);
6081 prev_pos = avio_tell(pb);
6082 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6083 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6084 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6088 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6089 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6090 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6091 min_samples * sizeof(*encrypted_samples));
6092 if (!encrypted_samples) {
6093 ret = AVERROR(ENOMEM);
6096 encryption_index->encrypted_samples = encrypted_samples;
6098 sample = &encryption_index->encrypted_samples[i];
6099 sample_info_size = encryption_index->auxiliary_info_default_size
6100 ? encryption_index->auxiliary_info_default_size
6101 : encryption_index->auxiliary_info_sizes[i];
6103 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6107 if (pb->eof_reached) {
6108 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6109 ret = AVERROR_INVALIDDATA;
6111 encryption_index->nb_encrypted_samples = sample_count;
6115 avio_seek(pb, prev_pos, SEEK_SET);
6117 for (; i > 0; i--) {
6118 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6120 av_freep(&encryption_index->encrypted_samples);
6126 * Tries to read the given number of bytes from the stream and puts it in a
6127 * newly allocated buffer. This reads in small chunks to avoid allocating large
6128 * memory if the file contains an invalid/malicious size value.
6130 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6132 const unsigned int block_size = 1024 * 1024;
6133 uint8_t *buffer = NULL;
6134 unsigned int alloc_size = 0, offset = 0;
6135 while (offset < size) {
6136 unsigned int new_size =
6137 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6138 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6139 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6142 return AVERROR(ENOMEM);
6144 buffer = new_buffer;
6146 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6148 return AVERROR_INVALIDDATA;
6157 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6159 MOVEncryptionIndex *encryption_index;
6160 MOVStreamContext *sc;
6162 unsigned int sample_count, aux_info_type, aux_info_param;
6164 ret = get_current_encryption_info(c, &encryption_index, &sc);
6168 if (encryption_index->nb_encrypted_samples) {
6169 // This can happen if we have both saio/saiz and senc atoms.
6170 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6174 if (encryption_index->auxiliary_info_sample_count) {
6175 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6176 return AVERROR_INVALIDDATA;
6179 avio_r8(pb); /* version */
6180 if (avio_rb24(pb) & 0x01) { /* flags */
6181 aux_info_type = avio_rb32(pb);
6182 aux_info_param = avio_rb32(pb);
6183 if (sc->cenc.default_encrypted_sample) {
6184 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6185 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6188 if (aux_info_param != 0) {
6189 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6193 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6194 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6195 aux_info_type == MKBETAG('c','e','n','s') ||
6196 aux_info_type == MKBETAG('c','b','c','1') ||
6197 aux_info_type == MKBETAG('c','b','c','s')) &&
6198 aux_info_param == 0) {
6199 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6200 return AVERROR_INVALIDDATA;
6205 } else if (!sc->cenc.default_encrypted_sample) {
6206 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6210 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6211 sample_count = avio_rb32(pb);
6212 encryption_index->auxiliary_info_sample_count = sample_count;
6214 if (encryption_index->auxiliary_info_default_size == 0) {
6215 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6217 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6222 if (encryption_index->auxiliary_offsets_count) {
6223 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6229 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6231 uint64_t *auxiliary_offsets;
6232 MOVEncryptionIndex *encryption_index;
6233 MOVStreamContext *sc;
6235 unsigned int version, entry_count, aux_info_type, aux_info_param;
6236 unsigned int alloc_size = 0;
6238 ret = get_current_encryption_info(c, &encryption_index, &sc);
6242 if (encryption_index->nb_encrypted_samples) {
6243 // This can happen if we have both saio/saiz and senc atoms.
6244 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6248 if (encryption_index->auxiliary_offsets_count) {
6249 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6250 return AVERROR_INVALIDDATA;
6253 version = avio_r8(pb); /* version */
6254 if (avio_rb24(pb) & 0x01) { /* flags */
6255 aux_info_type = avio_rb32(pb);
6256 aux_info_param = avio_rb32(pb);
6257 if (sc->cenc.default_encrypted_sample) {
6258 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6259 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6262 if (aux_info_param != 0) {
6263 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6267 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6268 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6269 aux_info_type == MKBETAG('c','e','n','s') ||
6270 aux_info_type == MKBETAG('c','b','c','1') ||
6271 aux_info_type == MKBETAG('c','b','c','s')) &&
6272 aux_info_param == 0) {
6273 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6274 return AVERROR_INVALIDDATA;
6279 } else if (!sc->cenc.default_encrypted_sample) {
6280 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6284 entry_count = avio_rb32(pb);
6285 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6286 return AVERROR(ENOMEM);
6288 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6289 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6290 auxiliary_offsets = av_fast_realloc(
6291 encryption_index->auxiliary_offsets, &alloc_size,
6292 min_offsets * sizeof(*auxiliary_offsets));
6293 if (!auxiliary_offsets) {
6294 av_freep(&encryption_index->auxiliary_offsets);
6295 return AVERROR(ENOMEM);
6297 encryption_index->auxiliary_offsets = auxiliary_offsets;
6300 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6302 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6304 if (c->frag_index.current >= 0) {
6305 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6309 if (pb->eof_reached) {
6310 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6311 av_freep(&encryption_index->auxiliary_offsets);
6312 return AVERROR_INVALIDDATA;
6315 encryption_index->auxiliary_offsets_count = entry_count;
6317 if (encryption_index->auxiliary_info_sample_count) {
6318 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6324 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6326 AVEncryptionInitInfo *info, *old_init_info;
6329 uint8_t *side_data, *extra_data, *old_side_data;
6330 size_t side_data_size;
6331 int ret = 0, old_side_data_size;
6332 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6334 if (c->fc->nb_streams < 1)
6336 st = c->fc->streams[c->fc->nb_streams-1];
6338 version = avio_r8(pb); /* version */
6339 avio_rb24(pb); /* flags */
6341 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6342 /* key_id_size */ 16, /* data_size */ 0);
6344 return AVERROR(ENOMEM);
6346 if (avio_read(pb, info->system_id, 16) != 16) {
6347 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6348 ret = AVERROR_INVALIDDATA;
6353 kid_count = avio_rb32(pb);
6354 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
6355 ret = AVERROR(ENOMEM);
6359 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6360 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6361 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6362 min_kid_count * sizeof(*key_ids));
6364 ret = AVERROR(ENOMEM);
6367 info->key_ids = key_ids;
6369 info->key_ids[i] = av_mallocz(16);
6370 if (!info->key_ids[i]) {
6371 ret = AVERROR(ENOMEM);
6374 info->num_key_ids = i + 1;
6376 if (avio_read(pb, info->key_ids[i], 16) != 16) {
6377 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6378 ret = AVERROR_INVALIDDATA;
6383 if (pb->eof_reached) {
6384 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6385 ret = AVERROR_INVALIDDATA;
6390 extra_data_size = avio_rb32(pb);
6391 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6395 av_freep(&info->data); // malloc(0) may still allocate something.
6396 info->data = extra_data;
6397 info->data_size = extra_data_size;
6399 // If there is existing initialization data, append to the list.
6400 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6401 if (old_side_data) {
6402 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6403 if (old_init_info) {
6404 // Append to the end of the list.
6405 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6411 info = old_init_info;
6413 // Assume existing side-data will be valid, so the only error we could get is OOM.
6414 ret = AVERROR(ENOMEM);
6419 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6421 ret = AVERROR(ENOMEM);
6424 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6425 side_data, side_data_size);
6430 av_encryption_init_info_free(info);
6434 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6437 MOVStreamContext *sc;
6439 if (c->fc->nb_streams < 1)
6441 st = c->fc->streams[c->fc->nb_streams-1];
6444 if (sc->pseudo_stream_id != 0) {
6445 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6446 return AVERROR_PATCHWELCOME;
6450 return AVERROR_INVALIDDATA;
6452 avio_rb32(pb); /* version and flags */
6454 if (!sc->cenc.default_encrypted_sample) {
6455 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6456 if (!sc->cenc.default_encrypted_sample) {
6457 return AVERROR(ENOMEM);
6461 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6465 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6468 MOVStreamContext *sc;
6469 unsigned int version, pattern, is_protected, iv_size;
6471 if (c->fc->nb_streams < 1)
6473 st = c->fc->streams[c->fc->nb_streams-1];
6476 if (sc->pseudo_stream_id != 0) {
6477 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6478 return AVERROR_PATCHWELCOME;
6481 if (!sc->cenc.default_encrypted_sample) {
6482 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6483 if (!sc->cenc.default_encrypted_sample) {
6484 return AVERROR(ENOMEM);
6489 return AVERROR_INVALIDDATA;
6491 version = avio_r8(pb); /* version */
6492 avio_rb24(pb); /* flags */
6494 avio_r8(pb); /* reserved */
6495 pattern = avio_r8(pb);
6498 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6499 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6502 is_protected = avio_r8(pb);
6503 if (is_protected && !sc->cenc.encryption_index) {
6504 // The whole stream should be by-default encrypted.
6505 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6506 if (!sc->cenc.encryption_index)
6507 return AVERROR(ENOMEM);
6509 sc->cenc.per_sample_iv_size = avio_r8(pb);
6510 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6511 sc->cenc.per_sample_iv_size != 16) {
6512 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6513 return AVERROR_INVALIDDATA;
6515 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6516 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6517 return AVERROR_INVALIDDATA;
6520 if (is_protected && !sc->cenc.per_sample_iv_size) {
6521 iv_size = avio_r8(pb);
6522 if (iv_size != 8 && iv_size != 16) {
6523 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6524 return AVERROR_INVALIDDATA;
6527 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6528 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6529 return AVERROR_INVALIDDATA;
6536 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6539 int last, type, size, ret;
6542 if (c->fc->nb_streams < 1)
6544 st = c->fc->streams[c->fc->nb_streams-1];
6546 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6547 return AVERROR_INVALIDDATA;
6549 /* Check FlacSpecificBox version. */
6550 if (avio_r8(pb) != 0)
6551 return AVERROR_INVALIDDATA;
6553 avio_rb24(pb); /* Flags */
6555 avio_read(pb, buf, sizeof(buf));
6556 flac_parse_block_header(buf, &last, &type, &size);
6558 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6559 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6560 return AVERROR_INVALIDDATA;
6563 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6568 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6573 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6577 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6578 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6579 return AVERROR_PATCHWELCOME;
6582 if (!sc->cenc.aes_ctr) {
6583 /* initialize the cipher */
6584 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6585 if (!sc->cenc.aes_ctr) {
6586 return AVERROR(ENOMEM);
6589 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6595 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6597 if (!sample->subsample_count)
6599 /* decrypt the whole packet */
6600 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6604 for (i = 0; i < sample->subsample_count; i++)
6606 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6607 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6608 return AVERROR_INVALIDDATA;
6611 /* skip the clear bytes */
6612 input += sample->subsamples[i].bytes_of_clear_data;
6613 size -= sample->subsamples[i].bytes_of_clear_data;
6615 /* decrypt the encrypted bytes */
6616 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6617 input += sample->subsamples[i].bytes_of_protected_data;
6618 size -= sample->subsamples[i].bytes_of_protected_data;
6622 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6623 return AVERROR_INVALIDDATA;
6629 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6631 MOVFragmentStreamInfo *frag_stream_info;
6632 MOVEncryptionIndex *encryption_index;
6633 AVEncryptionInfo *encrypted_sample;
6634 int encrypted_index, ret;
6636 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6637 encrypted_index = current_index;
6638 encryption_index = NULL;
6639 if (frag_stream_info) {
6640 // Note this only supports encryption info in the first sample descriptor.
6641 if (mov->fragment.stsd_id == 1) {
6642 if (frag_stream_info->encryption_index) {
6643 encrypted_index = current_index - frag_stream_info->index_entry;
6644 encryption_index = frag_stream_info->encryption_index;
6646 encryption_index = sc->cenc.encryption_index;
6650 encryption_index = sc->cenc.encryption_index;
6653 if (encryption_index) {
6654 if (encryption_index->auxiliary_info_sample_count &&
6655 !encryption_index->nb_encrypted_samples) {
6656 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6657 return AVERROR_INVALIDDATA;
6659 if (encryption_index->auxiliary_offsets_count &&
6660 !encryption_index->nb_encrypted_samples) {
6661 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6662 return AVERROR_INVALIDDATA;
6665 if (!encryption_index->nb_encrypted_samples) {
6666 // Full-sample encryption with default settings.
6667 encrypted_sample = sc->cenc.default_encrypted_sample;
6668 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6669 // Per-sample setting override.
6670 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6672 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6673 return AVERROR_INVALIDDATA;
6676 if (mov->decryption_key) {
6677 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6680 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6682 return AVERROR(ENOMEM);
6683 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6693 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6695 const int OPUS_SEEK_PREROLL_MS = 80;
6701 if (c->fc->nb_streams < 1)
6703 st = c->fc->streams[c->fc->nb_streams-1];
6705 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6706 return AVERROR_INVALIDDATA;
6708 /* Check OpusSpecificBox version. */
6709 if (avio_r8(pb) != 0) {
6710 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6711 return AVERROR_INVALIDDATA;
6714 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6715 size = atom.size + 8;
6717 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
6720 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6721 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6722 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6723 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6725 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6726 little-endian; aside from the preceeding magic and version they're
6727 otherwise currently identical. Data after output gain at offset 16
6728 doesn't need to be bytewapped. */
6729 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6730 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6731 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6732 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6734 st->codecpar->initial_padding = pre_skip;
6735 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6736 (AVRational){1, 1000},
6737 (AVRational){1, 48000});
6742 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6745 unsigned format_info;
6746 int channel_assignment, channel_assignment1, channel_assignment2;
6749 if (c->fc->nb_streams < 1)
6751 st = c->fc->streams[c->fc->nb_streams-1];
6754 return AVERROR_INVALIDDATA;
6756 format_info = avio_rb32(pb);
6758 ratebits = (format_info >> 28) & 0xF;
6759 channel_assignment1 = (format_info >> 15) & 0x1F;
6760 channel_assignment2 = format_info & 0x1FFF;
6761 if (channel_assignment2)
6762 channel_assignment = channel_assignment2;
6764 channel_assignment = channel_assignment1;
6766 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6767 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6768 st->codecpar->channels = truehd_channels(channel_assignment);
6769 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6774 static const MOVParseTableEntry mov_default_parse_table[] = {
6775 { MKTAG('A','C','L','R'), mov_read_aclr },
6776 { MKTAG('A','P','R','G'), mov_read_avid },
6777 { MKTAG('A','A','L','P'), mov_read_avid },
6778 { MKTAG('A','R','E','S'), mov_read_ares },
6779 { MKTAG('a','v','s','s'), mov_read_avss },
6780 { MKTAG('a','v','1','C'), mov_read_av1c },
6781 { MKTAG('c','h','p','l'), mov_read_chpl },
6782 { MKTAG('c','o','6','4'), mov_read_stco },
6783 { MKTAG('c','o','l','r'), mov_read_colr },
6784 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6785 { MKTAG('d','i','n','f'), mov_read_default },
6786 { MKTAG('D','p','x','E'), mov_read_dpxe },
6787 { MKTAG('d','r','e','f'), mov_read_dref },
6788 { MKTAG('e','d','t','s'), mov_read_default },
6789 { MKTAG('e','l','s','t'), mov_read_elst },
6790 { MKTAG('e','n','d','a'), mov_read_enda },
6791 { MKTAG('f','i','e','l'), mov_read_fiel },
6792 { MKTAG('a','d','r','m'), mov_read_adrm },
6793 { MKTAG('f','t','y','p'), mov_read_ftyp },
6794 { MKTAG('g','l','b','l'), mov_read_glbl },
6795 { MKTAG('h','d','l','r'), mov_read_hdlr },
6796 { MKTAG('i','l','s','t'), mov_read_ilst },
6797 { MKTAG('j','p','2','h'), mov_read_jp2h },
6798 { MKTAG('m','d','a','t'), mov_read_mdat },
6799 { MKTAG('m','d','h','d'), mov_read_mdhd },
6800 { MKTAG('m','d','i','a'), mov_read_default },
6801 { MKTAG('m','e','t','a'), mov_read_meta },
6802 { MKTAG('m','i','n','f'), mov_read_default },
6803 { MKTAG('m','o','o','f'), mov_read_moof },
6804 { MKTAG('m','o','o','v'), mov_read_moov },
6805 { MKTAG('m','v','e','x'), mov_read_default },
6806 { MKTAG('m','v','h','d'), mov_read_mvhd },
6807 { MKTAG('S','M','I',' '), mov_read_svq3 },
6808 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6809 { MKTAG('a','v','c','C'), mov_read_glbl },
6810 { MKTAG('p','a','s','p'), mov_read_pasp },
6811 { MKTAG('s','i','d','x'), mov_read_sidx },
6812 { MKTAG('s','t','b','l'), mov_read_default },
6813 { MKTAG('s','t','c','o'), mov_read_stco },
6814 { MKTAG('s','t','p','s'), mov_read_stps },
6815 { MKTAG('s','t','r','f'), mov_read_strf },
6816 { MKTAG('s','t','s','c'), mov_read_stsc },
6817 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6818 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6819 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6820 { MKTAG('s','t','t','s'), mov_read_stts },
6821 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6822 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
6823 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6824 { MKTAG('t','f','d','t'), mov_read_tfdt },
6825 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6826 { MKTAG('t','r','a','k'), mov_read_trak },
6827 { MKTAG('t','r','a','f'), mov_read_default },
6828 { MKTAG('t','r','e','f'), mov_read_default },
6829 { MKTAG('t','m','c','d'), mov_read_tmcd },
6830 { MKTAG('c','h','a','p'), mov_read_chap },
6831 { MKTAG('t','r','e','x'), mov_read_trex },
6832 { MKTAG('t','r','u','n'), mov_read_trun },
6833 { MKTAG('u','d','t','a'), mov_read_default },
6834 { MKTAG('w','a','v','e'), mov_read_wave },
6835 { MKTAG('e','s','d','s'), mov_read_esds },
6836 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6837 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6838 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6839 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6840 { MKTAG('w','f','e','x'), mov_read_wfex },
6841 { MKTAG('c','m','o','v'), mov_read_cmov },
6842 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6843 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6844 { MKTAG('s','b','g','p'), mov_read_sbgp },
6845 { MKTAG('h','v','c','C'), mov_read_glbl },
6846 { MKTAG('u','u','i','d'), mov_read_uuid },
6847 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6848 { MKTAG('f','r','e','e'), mov_read_free },
6849 { MKTAG('-','-','-','-'), mov_read_custom },
6850 { MKTAG('s','i','n','f'), mov_read_default },
6851 { MKTAG('f','r','m','a'), mov_read_frma },
6852 { MKTAG('s','e','n','c'), mov_read_senc },
6853 { MKTAG('s','a','i','z'), mov_read_saiz },
6854 { MKTAG('s','a','i','o'), mov_read_saio },
6855 { MKTAG('p','s','s','h'), mov_read_pssh },
6856 { MKTAG('s','c','h','m'), mov_read_schm },
6857 { MKTAG('s','c','h','i'), mov_read_default },
6858 { MKTAG('t','e','n','c'), mov_read_tenc },
6859 { MKTAG('d','f','L','a'), mov_read_dfla },
6860 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6861 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6862 { MKTAG('d','O','p','s'), mov_read_dops },
6863 { MKTAG('d','m','l','p'), mov_read_dmlp },
6864 { MKTAG('S','m','D','m'), mov_read_smdm },
6865 { MKTAG('C','o','L','L'), mov_read_coll },
6866 { MKTAG('v','p','c','C'), mov_read_vpcc },
6867 { MKTAG('m','d','c','v'), mov_read_mdcv },
6868 { MKTAG('c','l','l','i'), mov_read_clli },
6872 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6874 int64_t total_size = 0;
6878 if (c->atom_depth > 10) {
6879 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6880 return AVERROR_INVALIDDATA;
6885 atom.size = INT64_MAX;
6886 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6887 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
6890 if (atom.size >= 8) {
6891 a.size = avio_rb32(pb);
6892 a.type = avio_rl32(pb);
6893 if (a.type == MKTAG('f','r','e','e') &&
6895 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT &&
6898 uint32_t *type = (uint32_t *)buf + 1;
6899 if (avio_read(pb, buf, 8) != 8)
6900 return AVERROR_INVALIDDATA;
6901 avio_seek(pb, -8, SEEK_CUR);
6902 if (*type == MKTAG('m','v','h','d') ||
6903 *type == MKTAG('c','m','o','v')) {
6904 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free atom.\n");
6905 a.type = MKTAG('m','o','o','v');
6908 if (atom.type != MKTAG('r','o','o','t') &&
6909 atom.type != MKTAG('m','o','o','v'))
6911 if (a.type == MKTAG('t','r','a','k') || a.type == MKTAG('m','d','a','t'))
6913 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
6920 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
6921 a.size = avio_rb64(pb) - 8;
6925 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
6926 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
6928 a.size = atom.size - total_size + 8;
6933 a.size = FFMIN(a.size, atom.size - total_size);
6935 for (i = 0; mov_default_parse_table[i].type; i++)
6936 if (mov_default_parse_table[i].type == a.type) {
6937 parse = mov_default_parse_table[i].parse;
6941 // container is user data
6942 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
6943 atom.type == MKTAG('i','l','s','t')))
6944 parse = mov_read_udta_string;
6946 // Supports parsing the QuickTime Metadata Keys.
6947 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
6948 if (!parse && c->found_hdlr_mdta &&
6949 atom.type == MKTAG('m','e','t','a') &&
6950 a.type == MKTAG('k','e','y','s')) {
6951 parse = mov_read_keys;
6954 if (!parse) { /* skip leaf atoms data */
6955 avio_skip(pb, a.size);
6957 int64_t start_pos = avio_tell(pb);
6959 int err = parse(c, pb, a);
6964 if (c->found_moov && c->found_mdat &&
6965 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
6966 start_pos + a.size == avio_size(pb))) {
6967 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
6968 c->next_root_atom = start_pos + a.size;
6972 left = a.size - avio_tell(pb) + start_pos;
6973 if (left > 0) /* skip garbage at atom end */
6974 avio_skip(pb, left);
6975 else if (left < 0) {
6976 av_log(c->fc, AV_LOG_WARNING,
6977 "overread end of atom '%.4s' by %"PRId64" bytes\n",
6978 (char*)&a.type, -left);
6979 avio_seek(pb, left, SEEK_CUR);
6983 total_size += a.size;
6986 if (total_size < atom.size && atom.size < 0x7ffff)
6987 avio_skip(pb, atom.size - total_size);
6993 static int mov_probe(const AVProbeData *p)
6998 int moov_offset = -1;
7000 /* check file header */
7003 /* ignore invalid offset */
7004 if ((offset + 8) > (unsigned int)p->buf_size)
7006 tag = AV_RL32(p->buf + offset + 4);
7008 /* check for obvious tags */
7009 case MKTAG('m','o','o','v'):
7010 moov_offset = offset + 4;
7011 case MKTAG('m','d','a','t'):
7012 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
7013 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
7014 case MKTAG('f','t','y','p'):
7015 if (AV_RB32(p->buf+offset) < 8 &&
7016 (AV_RB32(p->buf+offset) != 1 ||
7017 offset + 12 > (unsigned int)p->buf_size ||
7018 AV_RB64(p->buf+offset + 8) == 0)) {
7019 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7020 } else if (tag == MKTAG('f','t','y','p') &&
7021 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
7022 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
7024 score = FFMAX(score, 5);
7026 score = AVPROBE_SCORE_MAX;
7028 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7030 /* those are more common words, so rate then a bit less */
7031 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
7032 case MKTAG('w','i','d','e'):
7033 case MKTAG('f','r','e','e'):
7034 case MKTAG('j','u','n','k'):
7035 case MKTAG('p','i','c','t'):
7036 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
7037 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7039 case MKTAG(0x82,0x82,0x7f,0x7d):
7040 case MKTAG('s','k','i','p'):
7041 case MKTAG('u','u','i','d'):
7042 case MKTAG('p','r','f','l'):
7043 /* if we only find those cause probedata is too small at least rate them */
7044 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7045 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7048 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7051 if(score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
7052 /* moov atom in the header - we should make sure that this is not a
7053 * MOV-packed MPEG-PS */
7054 offset = moov_offset;
7056 while(offset < (p->buf_size - 16)){ /* Sufficient space */
7057 /* We found an actual hdlr atom */
7058 if(AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7059 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7060 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')){
7061 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7062 /* We found a media handler reference atom describing an
7063 * MPEG-PS-in-MOV, return a
7064 * low score to force expanding the probe window until
7065 * mpegps_probe finds what it needs */
7076 // must be done after parsing all trak because there's no order requirement
7077 static void mov_read_chapters(AVFormatContext *s)
7079 MOVContext *mov = s->priv_data;
7081 MOVStreamContext *sc;
7086 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7087 chapter_track = mov->chapter_tracks[j];
7089 for (i = 0; i < s->nb_streams; i++)
7090 if (s->streams[i]->id == chapter_track) {
7095 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7100 cur_pos = avio_tell(sc->pb);
7102 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7103 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7104 if (st->nb_index_entries) {
7105 // Retrieve the first frame, if possible
7107 AVIndexEntry *sample = &st->index_entries[0];
7108 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7109 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7113 if (av_get_packet(sc->pb, &pkt, sample->size) < 0)
7116 st->attached_pic = pkt;
7117 st->attached_pic.stream_index = st->index;
7118 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
7121 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7122 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7123 st->discard = AVDISCARD_ALL;
7124 for (i = 0; i < st->nb_index_entries; i++) {
7125 AVIndexEntry *sample = &st->index_entries[i];
7126 int64_t end = i+1 < st->nb_index_entries ? st->index_entries[i+1].timestamp : st->duration;
7131 if (end < sample->timestamp) {
7132 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7133 end = AV_NOPTS_VALUE;
7136 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7137 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7141 // the first two bytes are the length of the title
7142 len = avio_rb16(sc->pb);
7143 if (len > sample->size-2)
7145 title_len = 2*len + 1;
7146 if (!(title = av_mallocz(title_len)))
7149 // The samples could theoretically be in any encoding if there's an encd
7150 // atom following, but in practice are only utf-8 or utf-16, distinguished
7151 // instead by the presence of a BOM
7155 ch = avio_rb16(sc->pb);
7157 avio_get_str16be(sc->pb, len, title, title_len);
7158 else if (ch == 0xfffe)
7159 avio_get_str16le(sc->pb, len, title, title_len);
7162 if (len == 1 || len == 2)
7165 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7169 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7174 avio_seek(sc->pb, cur_pos, SEEK_SET);
7178 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7179 uint32_t value, int flags)
7182 char buf[AV_TIMECODE_STR_SIZE];
7183 AVRational rate = st->avg_frame_rate;
7184 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7187 av_dict_set(&st->metadata, "timecode",
7188 av_timecode_make_string(&tc, buf, value), 0);
7192 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7194 MOVStreamContext *sc = st->priv_data;
7195 char buf[AV_TIMECODE_STR_SIZE];
7196 int64_t cur_pos = avio_tell(sc->pb);
7197 int hh, mm, ss, ff, drop;
7199 if (!st->nb_index_entries)
7202 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7203 avio_skip(s->pb, 13);
7204 hh = avio_r8(s->pb);
7205 mm = avio_r8(s->pb);
7206 ss = avio_r8(s->pb);
7207 drop = avio_r8(s->pb);
7208 ff = avio_r8(s->pb);
7209 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7210 hh, mm, ss, drop ? ';' : ':', ff);
7211 av_dict_set(&st->metadata, "timecode", buf, 0);
7213 avio_seek(sc->pb, cur_pos, SEEK_SET);
7217 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7219 MOVStreamContext *sc = st->priv_data;
7221 int64_t cur_pos = avio_tell(sc->pb);
7224 if (!st->nb_index_entries)
7227 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7228 value = avio_rb32(s->pb);
7230 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7231 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7232 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7234 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7235 * not the case) and thus assume "frame number format" instead of QT one.
7236 * No sample with tmcd track can be found with a QT timecode at the moment,
7237 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7239 parse_timecode_in_framenum_format(s, st, value, flags);
7241 avio_seek(sc->pb, cur_pos, SEEK_SET);
7245 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7247 if (!index || !*index) return;
7248 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7249 av_encryption_info_free((*index)->encrypted_samples[i]);
7251 av_freep(&(*index)->encrypted_samples);
7252 av_freep(&(*index)->auxiliary_info_sizes);
7253 av_freep(&(*index)->auxiliary_offsets);
7257 static int mov_read_close(AVFormatContext *s)
7259 MOVContext *mov = s->priv_data;
7262 for (i = 0; i < s->nb_streams; i++) {
7263 AVStream *st = s->streams[i];
7264 MOVStreamContext *sc = st->priv_data;
7269 av_freep(&sc->ctts_data);
7270 for (j = 0; j < sc->drefs_count; j++) {
7271 av_freep(&sc->drefs[j].path);
7272 av_freep(&sc->drefs[j].dir);
7274 av_freep(&sc->drefs);
7276 sc->drefs_count = 0;
7278 if (!sc->pb_is_copied)
7279 ff_format_io_close(s, &sc->pb);
7282 av_freep(&sc->chunk_offsets);
7283 av_freep(&sc->stsc_data);
7284 av_freep(&sc->sample_sizes);
7285 av_freep(&sc->keyframes);
7286 av_freep(&sc->stts_data);
7287 av_freep(&sc->sdtp_data);
7288 av_freep(&sc->stps_data);
7289 av_freep(&sc->elst_data);
7290 av_freep(&sc->rap_group);
7291 av_freep(&sc->display_matrix);
7292 av_freep(&sc->index_ranges);
7295 for (j = 0; j < sc->stsd_count; j++)
7296 av_free(sc->extradata[j]);
7297 av_freep(&sc->extradata);
7298 av_freep(&sc->extradata_size);
7300 mov_free_encryption_index(&sc->cenc.encryption_index);
7301 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7302 av_aes_ctr_free(sc->cenc.aes_ctr);
7304 av_freep(&sc->stereo3d);
7305 av_freep(&sc->spherical);
7306 av_freep(&sc->mastering);
7307 av_freep(&sc->coll);
7310 if (mov->dv_demux) {
7311 avformat_free_context(mov->dv_fctx);
7312 mov->dv_fctx = NULL;
7315 if (mov->meta_keys) {
7316 for (i = 1; i < mov->meta_keys_count; i++) {
7317 av_freep(&mov->meta_keys[i]);
7319 av_freep(&mov->meta_keys);
7322 av_freep(&mov->trex_data);
7323 av_freep(&mov->bitrates);
7325 for (i = 0; i < mov->frag_index.nb_items; i++) {
7326 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7327 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7328 mov_free_encryption_index(&frag[j].encryption_index);
7330 av_freep(&mov->frag_index.item[i].stream_info);
7332 av_freep(&mov->frag_index.item);
7334 av_freep(&mov->aes_decrypt);
7335 av_freep(&mov->chapter_tracks);
7340 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7344 for (i = 0; i < s->nb_streams; i++) {
7345 AVStream *st = s->streams[i];
7346 MOVStreamContext *sc = st->priv_data;
7348 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7349 sc->timecode_track == tmcd_id)
7355 /* look for a tmcd track not referenced by any video track, and export it globally */
7356 static void export_orphan_timecode(AVFormatContext *s)
7360 for (i = 0; i < s->nb_streams; i++) {
7361 AVStream *st = s->streams[i];
7363 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7364 !tmcd_is_referenced(s, i + 1)) {
7365 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7367 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7374 static int read_tfra(MOVContext *mov, AVIOContext *f)
7376 int version, fieldlength, i, j;
7377 int64_t pos = avio_tell(f);
7378 uint32_t size = avio_rb32(f);
7379 unsigned track_id, item_count;
7381 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7384 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7386 version = avio_r8(f);
7388 track_id = avio_rb32(f);
7389 fieldlength = avio_rb32(f);
7390 item_count = avio_rb32(f);
7391 for (i = 0; i < item_count; i++) {
7392 int64_t time, offset;
7394 MOVFragmentStreamInfo * frag_stream_info;
7397 return AVERROR_INVALIDDATA;
7401 time = avio_rb64(f);
7402 offset = avio_rb64(f);
7404 time = avio_rb32(f);
7405 offset = avio_rb32(f);
7408 // The first sample of each stream in a fragment is always a random
7409 // access sample. So it's entry in the tfra can be used as the
7410 // initial PTS of the fragment.
7411 index = update_frag_index(mov, offset);
7412 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7413 if (frag_stream_info &&
7414 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7415 frag_stream_info->first_tfra_pts = time;
7417 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7419 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7421 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7425 avio_seek(f, pos + size, SEEK_SET);
7429 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7431 int64_t stream_size = avio_size(f);
7432 int64_t original_pos = avio_tell(f);
7436 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7440 mfra_size = avio_rb32(f);
7441 if (mfra_size < 0 || mfra_size > stream_size) {
7442 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7445 if ((seek_ret = avio_seek(f, -mfra_size, SEEK_CUR)) < 0) {
7449 if (avio_rb32(f) != mfra_size) {
7450 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7453 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7454 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7457 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7459 ret = read_tfra(c, f);
7465 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7467 av_log(c->fc, AV_LOG_ERROR,
7468 "failed to seek back after looking for mfra\n");
7474 static int mov_read_header(AVFormatContext *s)
7476 MOVContext *mov = s->priv_data;
7477 AVIOContext *pb = s->pb;
7479 MOVAtom atom = { AV_RL32("root") };
7482 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7483 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7484 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7485 return AVERROR(EINVAL);
7489 mov->trak_index = -1;
7490 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7491 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7492 atom.size = avio_size(pb);
7494 atom.size = INT64_MAX;
7496 /* check MOV header */
7498 if (mov->moov_retry)
7499 avio_seek(pb, 0, SEEK_SET);
7500 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7501 av_log(s, AV_LOG_ERROR, "error reading header\n");
7505 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7506 if (!mov->found_moov) {
7507 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7509 return AVERROR_INVALIDDATA;
7511 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7513 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7514 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7515 mov_read_chapters(s);
7516 for (i = 0; i < s->nb_streams; i++)
7517 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7518 mov_read_timecode_track(s, s->streams[i]);
7519 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7520 mov_read_rtmd_track(s, s->streams[i]);
7524 /* copy timecode metadata from tmcd tracks to the related video streams */
7525 for (i = 0; i < s->nb_streams; i++) {
7526 AVStream *st = s->streams[i];
7527 MOVStreamContext *sc = st->priv_data;
7528 if (sc->timecode_track > 0) {
7529 AVDictionaryEntry *tcr;
7530 int tmcd_st_id = -1;
7532 for (j = 0; j < s->nb_streams; j++)
7533 if (s->streams[j]->id == sc->timecode_track)
7536 if (tmcd_st_id < 0 || tmcd_st_id == i)
7538 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7540 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7543 export_orphan_timecode(s);
7545 for (i = 0; i < s->nb_streams; i++) {
7546 AVStream *st = s->streams[i];
7547 MOVStreamContext *sc = st->priv_data;
7548 fix_timescale(mov, sc);
7549 if(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7550 st->skip_samples = sc->start_pad;
7552 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7553 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7554 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7555 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7556 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7557 st->codecpar->width = sc->width;
7558 st->codecpar->height = sc->height;
7560 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7561 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7565 if (mov->handbrake_version &&
7566 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7567 st->codecpar->codec_id == AV_CODEC_ID_MP3
7569 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7570 st->need_parsing = AVSTREAM_PARSE_FULL;
7574 if (mov->trex_data) {
7575 for (i = 0; i < s->nb_streams; i++) {
7576 AVStream *st = s->streams[i];
7577 MOVStreamContext *sc = st->priv_data;
7578 if (st->duration > 0) {
7579 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7580 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7581 sc->data_size, sc->time_scale);
7583 return AVERROR_INVALIDDATA;
7585 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7590 if (mov->use_mfra_for > 0) {
7591 for (i = 0; i < s->nb_streams; i++) {
7592 AVStream *st = s->streams[i];
7593 MOVStreamContext *sc = st->priv_data;
7594 if (sc->duration_for_fps > 0) {
7595 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7596 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7597 sc->data_size, sc->time_scale);
7599 return AVERROR_INVALIDDATA;
7601 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7602 sc->duration_for_fps;
7607 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7608 if (mov->bitrates[i]) {
7609 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7613 ff_rfps_calculate(s);
7615 for (i = 0; i < s->nb_streams; i++) {
7616 AVStream *st = s->streams[i];
7617 MOVStreamContext *sc = st->priv_data;
7619 switch (st->codecpar->codec_type) {
7620 case AVMEDIA_TYPE_AUDIO:
7621 err = ff_replaygain_export(st, s->metadata);
7627 case AVMEDIA_TYPE_VIDEO:
7628 if (sc->display_matrix) {
7629 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7630 sizeof(int32_t) * 9);
7634 sc->display_matrix = NULL;
7637 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7638 (uint8_t *)sc->stereo3d,
7639 sizeof(*sc->stereo3d));
7643 sc->stereo3d = NULL;
7645 if (sc->spherical) {
7646 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7647 (uint8_t *)sc->spherical,
7648 sc->spherical_size);
7652 sc->spherical = NULL;
7654 if (sc->mastering) {
7655 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7656 (uint8_t *)sc->mastering,
7657 sizeof(*sc->mastering));
7661 sc->mastering = NULL;
7664 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7665 (uint8_t *)sc->coll,
7675 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7677 for (i = 0; i < mov->frag_index.nb_items; i++)
7678 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7679 mov->frag_index.item[i].headers_read = 1;
7684 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7686 AVIndexEntry *sample = NULL;
7687 int64_t best_dts = INT64_MAX;
7689 for (i = 0; i < s->nb_streams; i++) {
7690 AVStream *avst = s->streams[i];
7691 MOVStreamContext *msc = avst->priv_data;
7692 if (msc->pb && msc->current_sample < avst->nb_index_entries) {
7693 AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample];
7694 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7695 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7696 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7697 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7698 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb &&
7699 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7700 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7701 sample = current_sample;
7710 static int should_retry(AVIOContext *pb, int error_code) {
7711 if (error_code == AVERROR_EOF || avio_feof(pb))
7717 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7720 MOVContext *mov = s->priv_data;
7722 if (index >= 0 && index < mov->frag_index.nb_items)
7723 target = mov->frag_index.item[index].moof_offset;
7724 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7725 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7726 return AVERROR_INVALIDDATA;
7729 mov->next_root_atom = 0;
7730 if (index < 0 || index >= mov->frag_index.nb_items)
7731 index = search_frag_moof_offset(&mov->frag_index, target);
7732 if (index < mov->frag_index.nb_items) {
7733 if (index + 1 < mov->frag_index.nb_items)
7734 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7735 if (mov->frag_index.item[index].headers_read)
7737 mov->frag_index.item[index].headers_read = 1;
7740 mov->found_mdat = 0;
7742 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7745 if (avio_feof(s->pb))
7747 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7752 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7754 uint8_t *side, *extradata;
7757 /* Save the current index. */
7758 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7760 /* Notify the decoder that extradata changed. */
7761 extradata_size = sc->extradata_size[sc->last_stsd_index];
7762 extradata = sc->extradata[sc->last_stsd_index];
7763 if (extradata_size > 0 && extradata) {
7764 side = av_packet_new_side_data(pkt,
7765 AV_PKT_DATA_NEW_EXTRADATA,
7768 return AVERROR(ENOMEM);
7769 memcpy(side, extradata, extradata_size);
7775 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7777 MOVContext *mov = s->priv_data;
7778 MOVStreamContext *sc;
7779 AVIndexEntry *sample;
7780 AVStream *st = NULL;
7781 int64_t current_index;
7785 sample = mov_find_next_sample(s, &st);
7786 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7787 if (!mov->next_root_atom)
7789 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7794 /* must be done just before reading, to avoid infinite loop on sample */
7795 current_index = sc->current_index;
7796 mov_current_sample_inc(sc);
7798 if (mov->next_root_atom) {
7799 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7800 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7803 if (st->discard != AVDISCARD_ALL) {
7804 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7805 if (ret64 != sample->pos) {
7806 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7807 sc->ffindex, sample->pos);
7808 if (should_retry(sc->pb, ret64)) {
7809 mov_current_sample_dec(sc);
7811 return AVERROR_INVALIDDATA;
7814 if( st->discard == AVDISCARD_NONKEY && 0==(sample->flags & AVINDEX_KEYFRAME) ) {
7815 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7819 ret = av_get_packet(sc->pb, pkt, sample->size);
7821 if (should_retry(sc->pb, ret)) {
7822 mov_current_sample_dec(sc);
7826 if (sc->has_palette) {
7829 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7831 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7833 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7834 sc->has_palette = 0;
7837 #if CONFIG_DV_DEMUXER
7838 if (mov->dv_demux && sc->dv_audio_container) {
7839 avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7840 av_freep(&pkt->data);
7842 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7847 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7848 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7849 st->need_parsing = AVSTREAM_PARSE_FULL;
7853 pkt->stream_index = sc->ffindex;
7854 pkt->dts = sample->timestamp;
7855 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7856 pkt->flags |= AV_PKT_FLAG_DISCARD;
7858 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7859 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
7860 /* update ctts context */
7862 if (sc->ctts_index < sc->ctts_count &&
7863 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
7865 sc->ctts_sample = 0;
7868 int64_t next_dts = (sc->current_sample < st->nb_index_entries) ?
7869 st->index_entries[sc->current_sample].timestamp : st->duration;
7871 if (next_dts >= pkt->dts)
7872 pkt->duration = next_dts - pkt->dts;
7873 pkt->pts = pkt->dts;
7875 if (st->discard == AVDISCARD_ALL)
7877 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
7878 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
7879 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
7880 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
7882 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
7883 pkt->pos = sample->pos;
7885 /* Multiple stsd handling. */
7886 if (sc->stsc_data) {
7887 /* Keep track of the stsc index for the given sample, then check
7888 * if the stsd index is different from the last used one. */
7890 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
7891 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
7893 sc->stsc_sample = 0;
7894 /* Do not check indexes after a switch. */
7895 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
7896 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
7897 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
7898 ret = mov_change_extradata(sc, pkt);
7905 aax_filter(pkt->data, pkt->size, mov);
7907 ret = cenc_filter(mov, st, sc, pkt, current_index);
7915 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
7917 MOVContext *mov = s->priv_data;
7920 if (!mov->frag_index.complete)
7923 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
7926 if (!mov->frag_index.item[index].headers_read)
7927 return mov_switch_root(s, -1, index);
7928 if (index + 1 < mov->frag_index.nb_items)
7929 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7934 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
7936 MOVStreamContext *sc = st->priv_data;
7937 int sample, time_sample, ret;
7940 // Here we consider timestamp to be PTS, hence try to offset it so that we
7941 // can search over the DTS timeline.
7942 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
7944 ret = mov_seek_fragment(s, st, timestamp);
7948 sample = av_index_search_timestamp(st, timestamp, flags);
7949 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
7950 if (sample < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp)
7952 if (sample < 0) /* not sure what to do */
7953 return AVERROR_INVALIDDATA;
7954 mov_current_sample_set(sc, sample);
7955 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
7956 /* adjust ctts index */
7957 if (sc->ctts_data) {
7959 for (i = 0; i < sc->ctts_count; i++) {
7960 int next = time_sample + sc->ctts_data[i].count;
7961 if (next > sc->current_sample) {
7963 sc->ctts_sample = sc->current_sample - time_sample;
7970 /* adjust stsd index */
7971 if (sc->chunk_count) {
7973 for (i = 0; i < sc->stsc_count; i++) {
7974 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
7975 if (next > sc->current_sample) {
7977 sc->stsc_sample = sc->current_sample - time_sample;
7980 av_assert0(next == (int)next);
7988 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
7990 MOVContext *mc = s->priv_data;
7995 if (stream_index >= s->nb_streams)
7996 return AVERROR_INVALIDDATA;
7998 st = s->streams[stream_index];
7999 sample = mov_seek_stream(s, st, sample_time, flags);
8003 if (mc->seek_individually) {
8004 /* adjust seek timestamp to found sample timestamp */
8005 int64_t seek_timestamp = st->index_entries[sample].timestamp;
8007 for (i = 0; i < s->nb_streams; i++) {
8009 MOVStreamContext *sc = s->streams[i]->priv_data;
8011 st->skip_samples = (sample_time <= 0) ? sc->start_pad : 0;
8013 if (stream_index == i)
8016 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
8017 mov_seek_stream(s, st, timestamp, flags);
8020 for (i = 0; i < s->nb_streams; i++) {
8021 MOVStreamContext *sc;
8024 mov_current_sample_set(sc, 0);
8027 MOVStreamContext *sc;
8028 AVIndexEntry *entry = mov_find_next_sample(s, &st);
8030 return AVERROR_INVALIDDATA;
8032 if (sc->ffindex == stream_index && sc->current_sample == sample)
8034 mov_current_sample_inc(sc);
8040 #define OFFSET(x) offsetof(MOVContext, x)
8041 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
8042 static const AVOption mov_options[] = {
8043 {"use_absolute_path",
8044 "allow using absolute path when opening alias, this is a possible security issue",
8045 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
8047 {"seek_streams_individually",
8048 "Seek each stream individually to the closest point",
8049 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
8051 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
8053 {"advanced_editlist",
8054 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
8055 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
8057 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8060 "use mfra for fragment timestamps",
8061 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8062 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8064 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8065 FLAGS, "use_mfra_for" },
8066 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8067 FLAGS, "use_mfra_for" },
8068 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8069 FLAGS, "use_mfra_for" },
8070 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8071 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8072 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8073 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8074 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8075 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8076 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8077 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8078 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8079 .flags = AV_OPT_FLAG_DECODING_PARAM },
8080 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8081 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8082 {.i64 = 0}, 0, 1, FLAGS },
8087 static const AVClass mov_class = {
8088 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8089 .item_name = av_default_item_name,
8090 .option = mov_options,
8091 .version = LIBAVUTIL_VERSION_INT,
8094 AVInputFormat ff_mov_demuxer = {
8095 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8096 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8097 .priv_class = &mov_class,
8098 .priv_data_size = sizeof(MOVContext),
8099 .extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
8100 .read_probe = mov_probe,
8101 .read_header = mov_read_header,
8102 .read_packet = mov_read_packet,
8103 .read_close = mov_read_close,
8104 .read_seek = mov_read_seek,
8105 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,