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->first_tfra_pts != AV_NOPTS_VALUE &&
4809 c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
4810 dts = frag_stream_info->first_tfra_pts;
4811 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4812 ", using it for dts\n", pts);
4813 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4814 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4815 // pts = frag_stream_info->sidx_pts;
4816 dts = frag_stream_info->sidx_pts - sc->time_offset;
4817 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4818 ", using it for pts\n", pts);
4819 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4820 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4821 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4822 ", 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);
4829 dts = sc->track_end - sc->time_offset;
4830 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4831 ", using it for dts\n", dts);
4833 offset = frag->base_data_offset + data_offset;
4835 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4837 // realloc space for new index entries
4838 if((uint64_t)st->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4839 entries = UINT_MAX / sizeof(AVIndexEntry) - st->nb_index_entries;
4840 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4845 requested_size = (st->nb_index_entries + entries) * sizeof(AVIndexEntry);
4846 new_entries = av_fast_realloc(st->index_entries,
4847 &st->index_entries_allocated_size,
4850 return AVERROR(ENOMEM);
4851 st->index_entries= new_entries;
4853 requested_size = (st->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4854 old_ctts_allocated_size = sc->ctts_allocated_size;
4855 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4858 return AVERROR(ENOMEM);
4859 sc->ctts_data = ctts_data;
4861 // In case there were samples without ctts entries, ensure they get
4862 // zero valued entries. This ensures clips which mix boxes with and
4863 // without ctts entries don't pickup uninitialized data.
4864 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4865 sc->ctts_allocated_size - old_ctts_allocated_size);
4867 if (index_entry_pos < st->nb_index_entries) {
4868 // Make hole in index_entries and ctts_data for new samples
4869 memmove(st->index_entries + index_entry_pos + entries,
4870 st->index_entries + index_entry_pos,
4871 sizeof(*st->index_entries) *
4872 (st->nb_index_entries - index_entry_pos));
4873 memmove(sc->ctts_data + index_entry_pos + entries,
4874 sc->ctts_data + index_entry_pos,
4875 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4876 if (index_entry_pos < sc->current_sample) {
4877 sc->current_sample += entries;
4881 st->nb_index_entries += entries;
4882 sc->ctts_count = st->nb_index_entries;
4884 // Record the index_entry position in frag_index of this fragment
4885 if (frag_stream_info)
4886 frag_stream_info->index_entry = index_entry_pos;
4888 if (index_entry_pos > 0)
4889 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4891 for (i = 0; i < entries && !pb->eof_reached; i++) {
4892 unsigned sample_size = frag->size;
4893 int sample_flags = i ? frag->flags : first_sample_flags;
4894 unsigned sample_duration = frag->duration;
4895 unsigned ctts_duration = 0;
4897 int index_entry_flags = 0;
4899 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4900 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4901 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4902 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4904 mov_update_dts_shift(sc, ctts_duration, c->fc);
4905 if (pts != AV_NOPTS_VALUE) {
4906 dts = pts - sc->dts_shift;
4907 if (flags & MOV_TRUN_SAMPLE_CTS) {
4908 dts -= ctts_duration;
4910 dts -= sc->time_offset;
4912 av_log(c->fc, AV_LOG_DEBUG,
4913 "pts %"PRId64" calculated dts %"PRId64
4914 " sc->dts_shift %d ctts.duration %d"
4915 " sc->time_offset %"PRId64
4916 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4918 sc->dts_shift, ctts_duration,
4919 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4920 pts = AV_NOPTS_VALUE;
4923 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4927 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4928 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4931 index_entry_flags |= AVINDEX_KEYFRAME;
4933 // Fragments can overlap in time. Discard overlapping frames after
4935 if (prev_dts >= dts)
4936 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4938 st->index_entries[index_entry_pos].pos = offset;
4939 st->index_entries[index_entry_pos].timestamp = dts;
4940 st->index_entries[index_entry_pos].size= sample_size;
4941 st->index_entries[index_entry_pos].min_distance= distance;
4942 st->index_entries[index_entry_pos].flags = index_entry_flags;
4944 sc->ctts_data[index_entry_pos].count = 1;
4945 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4948 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4949 "size %u, distance %d, keyframe %d\n", st->index,
4950 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4952 dts += sample_duration;
4953 offset += sample_size;
4954 sc->data_size += sample_size;
4956 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4957 1 <= INT_MAX - sc->nb_frames_for_fps
4959 sc->duration_for_fps += sample_duration;
4960 sc->nb_frames_for_fps ++;
4964 // EOF found before reading all entries. Fix the hole this would
4965 // leave in index_entries and ctts_data
4966 int gap = entries - i;
4967 memmove(st->index_entries + index_entry_pos,
4968 st->index_entries + index_entry_pos + gap,
4969 sizeof(*st->index_entries) *
4970 (st->nb_index_entries - (index_entry_pos + gap)));
4971 memmove(sc->ctts_data + index_entry_pos,
4972 sc->ctts_data + index_entry_pos + gap,
4973 sizeof(*sc->ctts_data) *
4974 (sc->ctts_count - (index_entry_pos + gap)));
4976 st->nb_index_entries -= gap;
4977 sc->ctts_count -= gap;
4978 if (index_entry_pos < sc->current_sample) {
4979 sc->current_sample -= gap;
4984 // The end of this new fragment may overlap in time with the start
4985 // of the next fragment in index_entries. Mark the samples in the next
4986 // fragment that overlap with AVINDEX_DISCARD_FRAME
4987 prev_dts = AV_NOPTS_VALUE;
4988 if (index_entry_pos > 0)
4989 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4990 for (i = index_entry_pos; i < st->nb_index_entries; i++) {
4991 if (prev_dts < st->index_entries[i].timestamp)
4993 st->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
4996 // If a hole was created to insert the new index_entries into,
4997 // the index_entry recorded for all subsequent moof must
4998 // be incremented by the number of entries inserted.
4999 fix_frag_index_entries(&c->frag_index, next_frag_index,
5000 frag->track_id, entries);
5002 if (pb->eof_reached) {
5003 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
5007 frag->implicit_offset = offset;
5009 sc->track_end = dts + sc->time_offset;
5010 if (st->duration < sc->track_end)
5011 st->duration = sc->track_end;
5016 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5018 int64_t offset = avio_tell(pb) + atom.size, pts, timestamp;
5020 unsigned i, j, track_id, item_count;
5021 AVStream *st = NULL;
5022 AVStream *ref_st = NULL;
5023 MOVStreamContext *sc, *ref_sc = NULL;
5024 AVRational timescale;
5026 version = avio_r8(pb);
5028 avpriv_request_sample(c->fc, "sidx version %u", version);
5032 avio_rb24(pb); // flags
5034 track_id = avio_rb32(pb); // Reference ID
5035 for (i = 0; i < c->fc->nb_streams; i++) {
5036 if (c->fc->streams[i]->id == track_id) {
5037 st = c->fc->streams[i];
5042 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5048 timescale = av_make_q(1, avio_rb32(pb));
5050 if (timescale.den <= 0) {
5051 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5052 return AVERROR_INVALIDDATA;
5056 pts = avio_rb32(pb);
5057 offset += avio_rb32(pb);
5059 pts = avio_rb64(pb);
5060 offset += avio_rb64(pb);
5063 avio_rb16(pb); // reserved
5065 item_count = avio_rb16(pb);
5067 for (i = 0; i < item_count; i++) {
5069 MOVFragmentStreamInfo * frag_stream_info;
5070 uint32_t size = avio_rb32(pb);
5071 uint32_t duration = avio_rb32(pb);
5072 if (size & 0x80000000) {
5073 avpriv_request_sample(c->fc, "sidx reference_type 1");
5074 return AVERROR_PATCHWELCOME;
5076 avio_rb32(pb); // sap_flags
5077 timestamp = av_rescale_q(pts, timescale, st->time_base);
5079 index = update_frag_index(c, offset);
5080 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5081 if (frag_stream_info)
5082 frag_stream_info->sidx_pts = timestamp;
5088 st->duration = sc->track_end = pts;
5092 if (offset == avio_size(pb)) {
5093 // Find first entry in fragment index that came from an sidx.
5094 // This will pretty much always be the first entry.
5095 for (i = 0; i < c->frag_index.nb_items; i++) {
5096 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5097 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5098 MOVFragmentStreamInfo * si;
5099 si = &item->stream_info[j];
5100 if (si->sidx_pts != AV_NOPTS_VALUE) {
5101 ref_st = c->fc->streams[j];
5102 ref_sc = ref_st->priv_data;
5107 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5108 st = c->fc->streams[i];
5110 if (!sc->has_sidx) {
5111 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5115 c->frag_index.complete = 1;
5121 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5122 /* like the files created with Adobe Premiere 5.0, for samples see */
5123 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5124 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5129 return 0; /* continue */
5130 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5131 avio_skip(pb, atom.size - 4);
5134 atom.type = avio_rl32(pb);
5136 if (atom.type != MKTAG('m','d','a','t')) {
5137 avio_skip(pb, atom.size);
5140 err = mov_read_mdat(c, pb, atom);
5144 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5149 uint8_t *moov_data; /* uncompressed data */
5150 long cmov_len, moov_len;
5153 avio_rb32(pb); /* dcom atom */
5154 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5155 return AVERROR_INVALIDDATA;
5156 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5157 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5158 return AVERROR_INVALIDDATA;
5160 avio_rb32(pb); /* cmvd atom */
5161 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5162 return AVERROR_INVALIDDATA;
5163 moov_len = avio_rb32(pb); /* uncompressed size */
5164 cmov_len = atom.size - 6 * 4;
5166 cmov_data = av_malloc(cmov_len);
5168 return AVERROR(ENOMEM);
5169 moov_data = av_malloc(moov_len);
5172 return AVERROR(ENOMEM);
5174 ret = ffio_read_size(pb, cmov_data, cmov_len);
5176 goto free_and_return;
5178 ret = AVERROR_INVALIDDATA;
5179 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5180 goto free_and_return;
5181 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5182 goto free_and_return;
5183 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5184 atom.type = MKTAG('m','o','o','v');
5185 atom.size = moov_len;
5186 ret = mov_read_default(c, &ctx, atom);
5192 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5193 return AVERROR(ENOSYS);
5197 /* edit list atom */
5198 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5200 MOVStreamContext *sc;
5201 int i, edit_count, version;
5202 int64_t elst_entry_size;
5204 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5206 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5208 version = avio_r8(pb); /* version */
5209 avio_rb24(pb); /* flags */
5210 edit_count = avio_rb32(pb); /* entries */
5213 elst_entry_size = version == 1 ? 20 : 12;
5214 if (atom.size != edit_count * elst_entry_size) {
5215 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5216 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5217 edit_count, atom.size + 8);
5218 return AVERROR_INVALIDDATA;
5220 edit_count = atom.size / elst_entry_size;
5221 if (edit_count * elst_entry_size != atom.size) {
5222 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.", atom.size, edit_count);
5230 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5231 av_free(sc->elst_data);
5233 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5235 return AVERROR(ENOMEM);
5237 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5238 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5239 MOVElst *e = &sc->elst_data[i];
5242 e->duration = avio_rb64(pb);
5243 e->time = avio_rb64(pb);
5246 e->duration = avio_rb32(pb); /* segment duration */
5247 e->time = (int32_t)avio_rb32(pb); /* media time */
5250 e->rate = avio_rb32(pb) / 65536.0;
5252 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5253 e->duration, e->time, e->rate);
5255 if (e->time < 0 && e->time != -1 &&
5256 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5257 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5258 c->fc->nb_streams-1, i, e->time);
5259 return AVERROR_INVALIDDATA;
5267 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5269 MOVStreamContext *sc;
5271 if (c->fc->nb_streams < 1)
5272 return AVERROR_INVALIDDATA;
5273 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5274 sc->timecode_track = avio_rb32(pb);
5278 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5283 if (c->fc->nb_streams < 1)
5285 st = c->fc->streams[c->fc->nb_streams - 1];
5287 if (atom.size < 4) {
5288 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5289 return AVERROR_INVALIDDATA;
5292 /* For now, propagate only the OBUs, if any. Once libavcodec is
5293 updated to handle isobmff style extradata this can be removed. */
5299 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5306 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5309 int version, color_range, color_primaries, color_trc, color_space;
5311 if (c->fc->nb_streams < 1)
5313 st = c->fc->streams[c->fc->nb_streams - 1];
5315 if (atom.size < 5) {
5316 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5317 return AVERROR_INVALIDDATA;
5320 version = avio_r8(pb);
5322 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5325 avio_skip(pb, 3); /* flags */
5327 avio_skip(pb, 2); /* profile + level */
5328 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5329 color_primaries = avio_r8(pb);
5330 color_trc = avio_r8(pb);
5331 color_space = avio_r8(pb);
5332 if (avio_rb16(pb)) /* codecIntializationDataSize */
5333 return AVERROR_INVALIDDATA;
5335 if (!av_color_primaries_name(color_primaries))
5336 color_primaries = AVCOL_PRI_UNSPECIFIED;
5337 if (!av_color_transfer_name(color_trc))
5338 color_trc = AVCOL_TRC_UNSPECIFIED;
5339 if (!av_color_space_name(color_space))
5340 color_space = AVCOL_SPC_UNSPECIFIED;
5342 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5343 st->codecpar->color_primaries = color_primaries;
5344 st->codecpar->color_trc = color_trc;
5345 st->codecpar->color_space = color_space;
5350 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5352 MOVStreamContext *sc;
5355 if (c->fc->nb_streams < 1)
5356 return AVERROR_INVALIDDATA;
5358 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5360 if (atom.size < 5) {
5361 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5362 return AVERROR_INVALIDDATA;
5365 version = avio_r8(pb);
5367 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5370 avio_skip(pb, 3); /* flags */
5372 sc->mastering = av_mastering_display_metadata_alloc();
5374 return AVERROR(ENOMEM);
5376 for (i = 0; i < 3; i++) {
5377 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5378 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5380 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5381 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5383 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5384 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5386 sc->mastering->has_primaries = 1;
5387 sc->mastering->has_luminance = 1;
5392 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5394 MOVStreamContext *sc;
5395 const int mapping[3] = {1, 2, 0};
5396 const int chroma_den = 50000;
5397 const int luma_den = 10000;
5400 if (c->fc->nb_streams < 1)
5401 return AVERROR_INVALIDDATA;
5403 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5405 if (atom.size < 24) {
5406 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5407 return AVERROR_INVALIDDATA;
5410 sc->mastering = av_mastering_display_metadata_alloc();
5412 return AVERROR(ENOMEM);
5414 for (i = 0; i < 3; i++) {
5415 const int j = mapping[i];
5416 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5417 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5419 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5420 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5422 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5423 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5425 sc->mastering->has_luminance = 1;
5426 sc->mastering->has_primaries = 1;
5431 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5433 MOVStreamContext *sc;
5436 if (c->fc->nb_streams < 1)
5437 return AVERROR_INVALIDDATA;
5439 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5441 if (atom.size < 5) {
5442 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5443 return AVERROR_INVALIDDATA;
5446 version = avio_r8(pb);
5448 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5451 avio_skip(pb, 3); /* flags */
5453 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5455 return AVERROR(ENOMEM);
5457 sc->coll->MaxCLL = avio_rb16(pb);
5458 sc->coll->MaxFALL = avio_rb16(pb);
5463 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5465 MOVStreamContext *sc;
5467 if (c->fc->nb_streams < 1)
5468 return AVERROR_INVALIDDATA;
5470 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5472 if (atom.size < 4) {
5473 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5474 return AVERROR_INVALIDDATA;
5477 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5479 return AVERROR(ENOMEM);
5481 sc->coll->MaxCLL = avio_rb16(pb);
5482 sc->coll->MaxFALL = avio_rb16(pb);
5487 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5490 MOVStreamContext *sc;
5491 enum AVStereo3DType type;
5494 if (c->fc->nb_streams < 1)
5497 st = c->fc->streams[c->fc->nb_streams - 1];
5500 if (atom.size < 5) {
5501 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5502 return AVERROR_INVALIDDATA;
5504 avio_skip(pb, 4); /* version + flags */
5509 type = AV_STEREO3D_2D;
5512 type = AV_STEREO3D_TOPBOTTOM;
5515 type = AV_STEREO3D_SIDEBYSIDE;
5518 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5522 sc->stereo3d = av_stereo3d_alloc();
5524 return AVERROR(ENOMEM);
5526 sc->stereo3d->type = type;
5530 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5533 MOVStreamContext *sc;
5534 int size, version, layout;
5535 int32_t yaw, pitch, roll;
5536 uint32_t l = 0, t = 0, r = 0, b = 0;
5537 uint32_t tag, padding = 0;
5538 enum AVSphericalProjection projection;
5540 if (c->fc->nb_streams < 1)
5543 st = c->fc->streams[c->fc->nb_streams - 1];
5546 if (atom.size < 8) {
5547 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5548 return AVERROR_INVALIDDATA;
5551 size = avio_rb32(pb);
5552 if (size <= 12 || size > atom.size)
5553 return AVERROR_INVALIDDATA;
5555 tag = avio_rl32(pb);
5556 if (tag != MKTAG('s','v','h','d')) {
5557 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5560 version = avio_r8(pb);
5562 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5566 avio_skip(pb, 3); /* flags */
5567 avio_skip(pb, size - 12); /* metadata_source */
5569 size = avio_rb32(pb);
5570 if (size > atom.size)
5571 return AVERROR_INVALIDDATA;
5573 tag = avio_rl32(pb);
5574 if (tag != MKTAG('p','r','o','j')) {
5575 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5579 size = avio_rb32(pb);
5580 if (size > atom.size)
5581 return AVERROR_INVALIDDATA;
5583 tag = avio_rl32(pb);
5584 if (tag != MKTAG('p','r','h','d')) {
5585 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5588 version = avio_r8(pb);
5590 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5594 avio_skip(pb, 3); /* flags */
5596 /* 16.16 fixed point */
5597 yaw = avio_rb32(pb);
5598 pitch = avio_rb32(pb);
5599 roll = avio_rb32(pb);
5601 size = avio_rb32(pb);
5602 if (size > atom.size)
5603 return AVERROR_INVALIDDATA;
5605 tag = avio_rl32(pb);
5606 version = avio_r8(pb);
5608 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5612 avio_skip(pb, 3); /* flags */
5614 case MKTAG('c','b','m','p'):
5615 layout = avio_rb32(pb);
5617 av_log(c->fc, AV_LOG_WARNING,
5618 "Unsupported cubemap layout %d\n", layout);
5621 projection = AV_SPHERICAL_CUBEMAP;
5622 padding = avio_rb32(pb);
5624 case MKTAG('e','q','u','i'):
5630 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5631 av_log(c->fc, AV_LOG_ERROR,
5632 "Invalid bounding rectangle coordinates "
5633 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5634 return AVERROR_INVALIDDATA;
5637 if (l || t || r || b)
5638 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5640 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5643 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5647 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5649 return AVERROR(ENOMEM);
5651 sc->spherical->projection = projection;
5653 sc->spherical->yaw = yaw;
5654 sc->spherical->pitch = pitch;
5655 sc->spherical->roll = roll;
5657 sc->spherical->padding = padding;
5659 sc->spherical->bound_left = l;
5660 sc->spherical->bound_top = t;
5661 sc->spherical->bound_right = r;
5662 sc->spherical->bound_bottom = b;
5667 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5670 uint8_t *buffer = av_malloc(len + 1);
5674 return AVERROR(ENOMEM);
5677 ret = ffio_read_size(pb, buffer, len);
5681 /* Check for mandatory keys and values, try to support XML as best-effort */
5682 if (!sc->spherical &&
5683 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5684 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5685 av_stristr(val, "true") &&
5686 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5687 av_stristr(val, "true") &&
5688 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5689 av_stristr(val, "equirectangular")) {
5690 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5694 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5696 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5697 enum AVStereo3DType mode;
5699 if (av_stristr(buffer, "left-right"))
5700 mode = AV_STEREO3D_SIDEBYSIDE;
5701 else if (av_stristr(buffer, "top-bottom"))
5702 mode = AV_STEREO3D_TOPBOTTOM;
5704 mode = AV_STEREO3D_2D;
5706 sc->stereo3d = av_stereo3d_alloc();
5710 sc->stereo3d->type = mode;
5714 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5716 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5717 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5719 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5720 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5722 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5730 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5733 MOVStreamContext *sc;
5736 static const uint8_t uuid_isml_manifest[] = {
5737 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5738 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5740 static const uint8_t uuid_xmp[] = {
5741 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5742 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5744 static const uint8_t uuid_spherical[] = {
5745 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5746 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5749 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5750 return AVERROR_INVALIDDATA;
5752 if (c->fc->nb_streams < 1)
5754 st = c->fc->streams[c->fc->nb_streams - 1];
5757 ret = avio_read(pb, uuid, sizeof(uuid));
5760 } else if (ret != sizeof(uuid)) {
5761 return AVERROR_INVALIDDATA;
5763 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5764 uint8_t *buffer, *ptr;
5766 size_t len = atom.size - sizeof(uuid);
5769 return AVERROR_INVALIDDATA;
5771 ret = avio_skip(pb, 4); // zeroes
5774 buffer = av_mallocz(len + 1);
5776 return AVERROR(ENOMEM);
5778 ret = avio_read(pb, buffer, len);
5782 } else if (ret != len) {
5784 return AVERROR_INVALIDDATA;
5788 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5789 ptr += sizeof("systemBitrate=\"") - 1;
5790 c->bitrates_count++;
5791 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5793 c->bitrates_count = 0;
5795 return AVERROR(ENOMEM);
5798 ret = strtol(ptr, &endptr, 10);
5799 if (ret < 0 || errno || *endptr != '"') {
5800 c->bitrates[c->bitrates_count - 1] = 0;
5802 c->bitrates[c->bitrates_count - 1] = ret;
5807 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5809 size_t len = atom.size - sizeof(uuid);
5810 if (c->export_xmp) {
5811 buffer = av_mallocz(len + 1);
5813 return AVERROR(ENOMEM);
5815 ret = avio_read(pb, buffer, len);
5819 } else if (ret != len) {
5821 return AVERROR_INVALIDDATA;
5824 av_dict_set(&c->fc->metadata, "xmp",
5825 buffer, AV_DICT_DONT_STRDUP_VAL);
5827 // skip all uuid atom, which makes it fast for long uuid-xmp file
5828 ret = avio_skip(pb, len);
5832 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5833 size_t len = atom.size - sizeof(uuid);
5834 ret = mov_parse_uuid_spherical(sc, pb, len);
5838 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5844 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5847 uint8_t content[16];
5852 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5858 && !memcmp(content, "Anevia\x1A\x1A", 8)
5859 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5860 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5866 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5868 uint32_t format = avio_rl32(pb);
5869 MOVStreamContext *sc;
5873 if (c->fc->nb_streams < 1)
5875 st = c->fc->streams[c->fc->nb_streams - 1];
5880 case MKTAG('e','n','c','v'): // encrypted video
5881 case MKTAG('e','n','c','a'): // encrypted audio
5882 id = mov_codec_id(st, format);
5883 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5884 st->codecpar->codec_id != id) {
5885 av_log(c->fc, AV_LOG_WARNING,
5886 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5887 (char*)&format, st->codecpar->codec_id);
5891 st->codecpar->codec_id = id;
5892 sc->format = format;
5896 if (format != sc->format) {
5897 av_log(c->fc, AV_LOG_WARNING,
5898 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5899 (char*)&format, (char*)&sc->format);
5908 * Gets the current encryption info and associated current stream context. If
5909 * we are parsing a track fragment, this will return the specific encryption
5910 * info for this fragment; otherwise this will return the global encryption
5911 * info for the current stream.
5913 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5915 MOVFragmentStreamInfo *frag_stream_info;
5919 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5920 if (frag_stream_info) {
5921 for (i = 0; i < c->fc->nb_streams; i++) {
5922 if (c->fc->streams[i]->id == frag_stream_info->id) {
5923 st = c->fc->streams[i];
5927 if (i == c->fc->nb_streams)
5929 *sc = st->priv_data;
5931 if (!frag_stream_info->encryption_index) {
5932 // If this stream isn't encrypted, don't create the index.
5933 if (!(*sc)->cenc.default_encrypted_sample)
5935 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5936 if (!frag_stream_info->encryption_index)
5937 return AVERROR(ENOMEM);
5939 *encryption_index = frag_stream_info->encryption_index;
5942 // No current track fragment, using stream level encryption info.
5944 if (c->fc->nb_streams < 1)
5946 st = c->fc->streams[c->fc->nb_streams - 1];
5947 *sc = st->priv_data;
5949 if (!(*sc)->cenc.encryption_index) {
5950 // If this stream isn't encrypted, don't create the index.
5951 if (!(*sc)->cenc.default_encrypted_sample)
5953 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5954 if (!(*sc)->cenc.encryption_index)
5955 return AVERROR(ENOMEM);
5958 *encryption_index = (*sc)->cenc.encryption_index;
5963 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
5966 unsigned int subsample_count;
5967 AVSubsampleEncryptionInfo *subsamples;
5969 if (!sc->cenc.default_encrypted_sample) {
5970 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
5971 return AVERROR_INVALIDDATA;
5974 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
5976 return AVERROR(ENOMEM);
5978 if (sc->cenc.per_sample_iv_size != 0) {
5979 if (avio_read(pb, (*sample)->iv, sc->cenc.per_sample_iv_size) != sc->cenc.per_sample_iv_size) {
5980 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
5981 av_encryption_info_free(*sample);
5983 return AVERROR_INVALIDDATA;
5987 if (use_subsamples) {
5988 subsample_count = avio_rb16(pb);
5989 av_free((*sample)->subsamples);
5990 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
5991 if (!(*sample)->subsamples) {
5992 av_encryption_info_free(*sample);
5994 return AVERROR(ENOMEM);
5997 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
5998 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
5999 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
6002 if (pb->eof_reached) {
6003 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
6004 av_encryption_info_free(*sample);
6006 return AVERROR_INVALIDDATA;
6008 (*sample)->subsample_count = subsample_count;
6014 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6016 AVEncryptionInfo **encrypted_samples;
6017 MOVEncryptionIndex *encryption_index;
6018 MOVStreamContext *sc;
6019 int use_subsamples, ret;
6020 unsigned int sample_count, i, alloc_size = 0;
6022 ret = get_current_encryption_info(c, &encryption_index, &sc);
6026 if (encryption_index->nb_encrypted_samples) {
6027 // This can happen if we have both saio/saiz and senc atoms.
6028 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6032 avio_r8(pb); /* version */
6033 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6035 sample_count = avio_rb32(pb);
6036 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6037 return AVERROR(ENOMEM);
6039 for (i = 0; i < sample_count; i++) {
6040 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6041 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6042 min_samples * sizeof(*encrypted_samples));
6043 if (encrypted_samples) {
6044 encryption_index->encrypted_samples = encrypted_samples;
6046 ret = mov_read_sample_encryption_info(
6047 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6049 ret = AVERROR(ENOMEM);
6051 if (pb->eof_reached) {
6052 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6053 ret = AVERROR_INVALIDDATA;
6058 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6059 av_freep(&encryption_index->encrypted_samples);
6063 encryption_index->nb_encrypted_samples = sample_count;
6068 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6070 AVEncryptionInfo **sample, **encrypted_samples;
6072 size_t sample_count, sample_info_size, i;
6074 unsigned int alloc_size = 0;
6076 if (encryption_index->nb_encrypted_samples)
6078 sample_count = encryption_index->auxiliary_info_sample_count;
6079 if (encryption_index->auxiliary_offsets_count != 1) {
6080 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6081 return AVERROR_PATCHWELCOME;
6083 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6084 return AVERROR(ENOMEM);
6086 prev_pos = avio_tell(pb);
6087 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6088 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6089 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6093 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6094 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6095 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6096 min_samples * sizeof(*encrypted_samples));
6097 if (!encrypted_samples) {
6098 ret = AVERROR(ENOMEM);
6101 encryption_index->encrypted_samples = encrypted_samples;
6103 sample = &encryption_index->encrypted_samples[i];
6104 sample_info_size = encryption_index->auxiliary_info_default_size
6105 ? encryption_index->auxiliary_info_default_size
6106 : encryption_index->auxiliary_info_sizes[i];
6108 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6112 if (pb->eof_reached) {
6113 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6114 ret = AVERROR_INVALIDDATA;
6116 encryption_index->nb_encrypted_samples = sample_count;
6120 avio_seek(pb, prev_pos, SEEK_SET);
6122 for (; i > 0; i--) {
6123 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6125 av_freep(&encryption_index->encrypted_samples);
6131 * Tries to read the given number of bytes from the stream and puts it in a
6132 * newly allocated buffer. This reads in small chunks to avoid allocating large
6133 * memory if the file contains an invalid/malicious size value.
6135 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6137 const unsigned int block_size = 1024 * 1024;
6138 uint8_t *buffer = NULL;
6139 unsigned int alloc_size = 0, offset = 0;
6140 while (offset < size) {
6141 unsigned int new_size =
6142 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6143 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6144 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6147 return AVERROR(ENOMEM);
6149 buffer = new_buffer;
6151 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6153 return AVERROR_INVALIDDATA;
6162 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6164 MOVEncryptionIndex *encryption_index;
6165 MOVStreamContext *sc;
6167 unsigned int sample_count, aux_info_type, aux_info_param;
6169 ret = get_current_encryption_info(c, &encryption_index, &sc);
6173 if (encryption_index->nb_encrypted_samples) {
6174 // This can happen if we have both saio/saiz and senc atoms.
6175 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6179 if (encryption_index->auxiliary_info_sample_count) {
6180 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6181 return AVERROR_INVALIDDATA;
6184 avio_r8(pb); /* version */
6185 if (avio_rb24(pb) & 0x01) { /* flags */
6186 aux_info_type = avio_rb32(pb);
6187 aux_info_param = avio_rb32(pb);
6188 if (sc->cenc.default_encrypted_sample) {
6189 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6190 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6193 if (aux_info_param != 0) {
6194 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6198 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6199 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6200 aux_info_type == MKBETAG('c','e','n','s') ||
6201 aux_info_type == MKBETAG('c','b','c','1') ||
6202 aux_info_type == MKBETAG('c','b','c','s')) &&
6203 aux_info_param == 0) {
6204 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6205 return AVERROR_INVALIDDATA;
6210 } else if (!sc->cenc.default_encrypted_sample) {
6211 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6215 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6216 sample_count = avio_rb32(pb);
6217 encryption_index->auxiliary_info_sample_count = sample_count;
6219 if (encryption_index->auxiliary_info_default_size == 0) {
6220 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6222 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6227 if (encryption_index->auxiliary_offsets_count) {
6228 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6234 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6236 uint64_t *auxiliary_offsets;
6237 MOVEncryptionIndex *encryption_index;
6238 MOVStreamContext *sc;
6240 unsigned int version, entry_count, aux_info_type, aux_info_param;
6241 unsigned int alloc_size = 0;
6243 ret = get_current_encryption_info(c, &encryption_index, &sc);
6247 if (encryption_index->nb_encrypted_samples) {
6248 // This can happen if we have both saio/saiz and senc atoms.
6249 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6253 if (encryption_index->auxiliary_offsets_count) {
6254 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6255 return AVERROR_INVALIDDATA;
6258 version = avio_r8(pb); /* version */
6259 if (avio_rb24(pb) & 0x01) { /* flags */
6260 aux_info_type = avio_rb32(pb);
6261 aux_info_param = avio_rb32(pb);
6262 if (sc->cenc.default_encrypted_sample) {
6263 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6264 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6267 if (aux_info_param != 0) {
6268 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6272 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6273 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6274 aux_info_type == MKBETAG('c','e','n','s') ||
6275 aux_info_type == MKBETAG('c','b','c','1') ||
6276 aux_info_type == MKBETAG('c','b','c','s')) &&
6277 aux_info_param == 0) {
6278 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6279 return AVERROR_INVALIDDATA;
6284 } else if (!sc->cenc.default_encrypted_sample) {
6285 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6289 entry_count = avio_rb32(pb);
6290 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6291 return AVERROR(ENOMEM);
6293 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6294 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6295 auxiliary_offsets = av_fast_realloc(
6296 encryption_index->auxiliary_offsets, &alloc_size,
6297 min_offsets * sizeof(*auxiliary_offsets));
6298 if (!auxiliary_offsets) {
6299 av_freep(&encryption_index->auxiliary_offsets);
6300 return AVERROR(ENOMEM);
6302 encryption_index->auxiliary_offsets = auxiliary_offsets;
6305 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6307 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6309 if (c->frag_index.current >= 0) {
6310 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6314 if (pb->eof_reached) {
6315 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6316 av_freep(&encryption_index->auxiliary_offsets);
6317 return AVERROR_INVALIDDATA;
6320 encryption_index->auxiliary_offsets_count = entry_count;
6322 if (encryption_index->auxiliary_info_sample_count) {
6323 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6329 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6331 AVEncryptionInitInfo *info, *old_init_info;
6334 uint8_t *side_data, *extra_data, *old_side_data;
6335 size_t side_data_size;
6336 int ret = 0, old_side_data_size;
6337 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6339 if (c->fc->nb_streams < 1)
6341 st = c->fc->streams[c->fc->nb_streams-1];
6343 version = avio_r8(pb); /* version */
6344 avio_rb24(pb); /* flags */
6346 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6347 /* key_id_size */ 16, /* data_size */ 0);
6349 return AVERROR(ENOMEM);
6351 if (avio_read(pb, info->system_id, 16) != 16) {
6352 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6353 ret = AVERROR_INVALIDDATA;
6358 kid_count = avio_rb32(pb);
6359 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
6360 ret = AVERROR(ENOMEM);
6364 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6365 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6366 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6367 min_kid_count * sizeof(*key_ids));
6369 ret = AVERROR(ENOMEM);
6372 info->key_ids = key_ids;
6374 info->key_ids[i] = av_mallocz(16);
6375 if (!info->key_ids[i]) {
6376 ret = AVERROR(ENOMEM);
6379 info->num_key_ids = i + 1;
6381 if (avio_read(pb, info->key_ids[i], 16) != 16) {
6382 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6383 ret = AVERROR_INVALIDDATA;
6388 if (pb->eof_reached) {
6389 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6390 ret = AVERROR_INVALIDDATA;
6395 extra_data_size = avio_rb32(pb);
6396 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6400 av_freep(&info->data); // malloc(0) may still allocate something.
6401 info->data = extra_data;
6402 info->data_size = extra_data_size;
6404 // If there is existing initialization data, append to the list.
6405 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6406 if (old_side_data) {
6407 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6408 if (old_init_info) {
6409 // Append to the end of the list.
6410 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6416 info = old_init_info;
6418 // Assume existing side-data will be valid, so the only error we could get is OOM.
6419 ret = AVERROR(ENOMEM);
6424 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6426 ret = AVERROR(ENOMEM);
6429 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6430 side_data, side_data_size);
6435 av_encryption_init_info_free(info);
6439 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6442 MOVStreamContext *sc;
6444 if (c->fc->nb_streams < 1)
6446 st = c->fc->streams[c->fc->nb_streams-1];
6449 if (sc->pseudo_stream_id != 0) {
6450 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6451 return AVERROR_PATCHWELCOME;
6455 return AVERROR_INVALIDDATA;
6457 avio_rb32(pb); /* version and flags */
6459 if (!sc->cenc.default_encrypted_sample) {
6460 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6461 if (!sc->cenc.default_encrypted_sample) {
6462 return AVERROR(ENOMEM);
6466 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6470 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6473 MOVStreamContext *sc;
6474 unsigned int version, pattern, is_protected, iv_size;
6476 if (c->fc->nb_streams < 1)
6478 st = c->fc->streams[c->fc->nb_streams-1];
6481 if (sc->pseudo_stream_id != 0) {
6482 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6483 return AVERROR_PATCHWELCOME;
6486 if (!sc->cenc.default_encrypted_sample) {
6487 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6488 if (!sc->cenc.default_encrypted_sample) {
6489 return AVERROR(ENOMEM);
6494 return AVERROR_INVALIDDATA;
6496 version = avio_r8(pb); /* version */
6497 avio_rb24(pb); /* flags */
6499 avio_r8(pb); /* reserved */
6500 pattern = avio_r8(pb);
6503 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6504 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6507 is_protected = avio_r8(pb);
6508 if (is_protected && !sc->cenc.encryption_index) {
6509 // The whole stream should be by-default encrypted.
6510 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6511 if (!sc->cenc.encryption_index)
6512 return AVERROR(ENOMEM);
6514 sc->cenc.per_sample_iv_size = avio_r8(pb);
6515 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6516 sc->cenc.per_sample_iv_size != 16) {
6517 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6518 return AVERROR_INVALIDDATA;
6520 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6521 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6522 return AVERROR_INVALIDDATA;
6525 if (is_protected && !sc->cenc.per_sample_iv_size) {
6526 iv_size = avio_r8(pb);
6527 if (iv_size != 8 && iv_size != 16) {
6528 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6529 return AVERROR_INVALIDDATA;
6532 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6533 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6534 return AVERROR_INVALIDDATA;
6541 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6544 int last, type, size, ret;
6547 if (c->fc->nb_streams < 1)
6549 st = c->fc->streams[c->fc->nb_streams-1];
6551 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6552 return AVERROR_INVALIDDATA;
6554 /* Check FlacSpecificBox version. */
6555 if (avio_r8(pb) != 0)
6556 return AVERROR_INVALIDDATA;
6558 avio_rb24(pb); /* Flags */
6560 avio_read(pb, buf, sizeof(buf));
6561 flac_parse_block_header(buf, &last, &type, &size);
6563 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6564 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6565 return AVERROR_INVALIDDATA;
6568 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6573 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6578 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6582 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6583 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6584 return AVERROR_PATCHWELCOME;
6587 if (!sc->cenc.aes_ctr) {
6588 /* initialize the cipher */
6589 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6590 if (!sc->cenc.aes_ctr) {
6591 return AVERROR(ENOMEM);
6594 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6600 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6602 if (!sample->subsample_count)
6604 /* decrypt the whole packet */
6605 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6609 for (i = 0; i < sample->subsample_count; i++)
6611 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6612 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6613 return AVERROR_INVALIDDATA;
6616 /* skip the clear bytes */
6617 input += sample->subsamples[i].bytes_of_clear_data;
6618 size -= sample->subsamples[i].bytes_of_clear_data;
6620 /* decrypt the encrypted bytes */
6621 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6622 input += sample->subsamples[i].bytes_of_protected_data;
6623 size -= sample->subsamples[i].bytes_of_protected_data;
6627 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6628 return AVERROR_INVALIDDATA;
6634 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6636 MOVFragmentStreamInfo *frag_stream_info;
6637 MOVEncryptionIndex *encryption_index;
6638 AVEncryptionInfo *encrypted_sample;
6639 int encrypted_index, ret;
6641 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6642 encrypted_index = current_index;
6643 encryption_index = NULL;
6644 if (frag_stream_info) {
6645 // Note this only supports encryption info in the first sample descriptor.
6646 if (mov->fragment.stsd_id == 1) {
6647 if (frag_stream_info->encryption_index) {
6648 encrypted_index = current_index - frag_stream_info->index_entry;
6649 encryption_index = frag_stream_info->encryption_index;
6651 encryption_index = sc->cenc.encryption_index;
6655 encryption_index = sc->cenc.encryption_index;
6658 if (encryption_index) {
6659 if (encryption_index->auxiliary_info_sample_count &&
6660 !encryption_index->nb_encrypted_samples) {
6661 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6662 return AVERROR_INVALIDDATA;
6664 if (encryption_index->auxiliary_offsets_count &&
6665 !encryption_index->nb_encrypted_samples) {
6666 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6667 return AVERROR_INVALIDDATA;
6670 if (!encryption_index->nb_encrypted_samples) {
6671 // Full-sample encryption with default settings.
6672 encrypted_sample = sc->cenc.default_encrypted_sample;
6673 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6674 // Per-sample setting override.
6675 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6677 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6678 return AVERROR_INVALIDDATA;
6681 if (mov->decryption_key) {
6682 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6685 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6687 return AVERROR(ENOMEM);
6688 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6698 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6700 const int OPUS_SEEK_PREROLL_MS = 80;
6706 if (c->fc->nb_streams < 1)
6708 st = c->fc->streams[c->fc->nb_streams-1];
6710 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6711 return AVERROR_INVALIDDATA;
6713 /* Check OpusSpecificBox version. */
6714 if (avio_r8(pb) != 0) {
6715 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6716 return AVERROR_INVALIDDATA;
6719 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6720 size = atom.size + 8;
6722 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
6725 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6726 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6727 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6728 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6730 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6731 little-endian; aside from the preceeding magic and version they're
6732 otherwise currently identical. Data after output gain at offset 16
6733 doesn't need to be bytewapped. */
6734 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6735 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6736 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6737 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6739 st->codecpar->initial_padding = pre_skip;
6740 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6741 (AVRational){1, 1000},
6742 (AVRational){1, 48000});
6747 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6750 unsigned format_info;
6751 int channel_assignment, channel_assignment1, channel_assignment2;
6754 if (c->fc->nb_streams < 1)
6756 st = c->fc->streams[c->fc->nb_streams-1];
6759 return AVERROR_INVALIDDATA;
6761 format_info = avio_rb32(pb);
6763 ratebits = (format_info >> 28) & 0xF;
6764 channel_assignment1 = (format_info >> 15) & 0x1F;
6765 channel_assignment2 = format_info & 0x1FFF;
6766 if (channel_assignment2)
6767 channel_assignment = channel_assignment2;
6769 channel_assignment = channel_assignment1;
6771 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6772 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6773 st->codecpar->channels = truehd_channels(channel_assignment);
6774 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6779 static const MOVParseTableEntry mov_default_parse_table[] = {
6780 { MKTAG('A','C','L','R'), mov_read_aclr },
6781 { MKTAG('A','P','R','G'), mov_read_avid },
6782 { MKTAG('A','A','L','P'), mov_read_avid },
6783 { MKTAG('A','R','E','S'), mov_read_ares },
6784 { MKTAG('a','v','s','s'), mov_read_avss },
6785 { MKTAG('a','v','1','C'), mov_read_av1c },
6786 { MKTAG('c','h','p','l'), mov_read_chpl },
6787 { MKTAG('c','o','6','4'), mov_read_stco },
6788 { MKTAG('c','o','l','r'), mov_read_colr },
6789 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6790 { MKTAG('d','i','n','f'), mov_read_default },
6791 { MKTAG('D','p','x','E'), mov_read_dpxe },
6792 { MKTAG('d','r','e','f'), mov_read_dref },
6793 { MKTAG('e','d','t','s'), mov_read_default },
6794 { MKTAG('e','l','s','t'), mov_read_elst },
6795 { MKTAG('e','n','d','a'), mov_read_enda },
6796 { MKTAG('f','i','e','l'), mov_read_fiel },
6797 { MKTAG('a','d','r','m'), mov_read_adrm },
6798 { MKTAG('f','t','y','p'), mov_read_ftyp },
6799 { MKTAG('g','l','b','l'), mov_read_glbl },
6800 { MKTAG('h','d','l','r'), mov_read_hdlr },
6801 { MKTAG('i','l','s','t'), mov_read_ilst },
6802 { MKTAG('j','p','2','h'), mov_read_jp2h },
6803 { MKTAG('m','d','a','t'), mov_read_mdat },
6804 { MKTAG('m','d','h','d'), mov_read_mdhd },
6805 { MKTAG('m','d','i','a'), mov_read_default },
6806 { MKTAG('m','e','t','a'), mov_read_meta },
6807 { MKTAG('m','i','n','f'), mov_read_default },
6808 { MKTAG('m','o','o','f'), mov_read_moof },
6809 { MKTAG('m','o','o','v'), mov_read_moov },
6810 { MKTAG('m','v','e','x'), mov_read_default },
6811 { MKTAG('m','v','h','d'), mov_read_mvhd },
6812 { MKTAG('S','M','I',' '), mov_read_svq3 },
6813 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6814 { MKTAG('a','v','c','C'), mov_read_glbl },
6815 { MKTAG('p','a','s','p'), mov_read_pasp },
6816 { MKTAG('s','i','d','x'), mov_read_sidx },
6817 { MKTAG('s','t','b','l'), mov_read_default },
6818 { MKTAG('s','t','c','o'), mov_read_stco },
6819 { MKTAG('s','t','p','s'), mov_read_stps },
6820 { MKTAG('s','t','r','f'), mov_read_strf },
6821 { MKTAG('s','t','s','c'), mov_read_stsc },
6822 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6823 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6824 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6825 { MKTAG('s','t','t','s'), mov_read_stts },
6826 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6827 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
6828 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6829 { MKTAG('t','f','d','t'), mov_read_tfdt },
6830 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6831 { MKTAG('t','r','a','k'), mov_read_trak },
6832 { MKTAG('t','r','a','f'), mov_read_default },
6833 { MKTAG('t','r','e','f'), mov_read_default },
6834 { MKTAG('t','m','c','d'), mov_read_tmcd },
6835 { MKTAG('c','h','a','p'), mov_read_chap },
6836 { MKTAG('t','r','e','x'), mov_read_trex },
6837 { MKTAG('t','r','u','n'), mov_read_trun },
6838 { MKTAG('u','d','t','a'), mov_read_default },
6839 { MKTAG('w','a','v','e'), mov_read_wave },
6840 { MKTAG('e','s','d','s'), mov_read_esds },
6841 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6842 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6843 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6844 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6845 { MKTAG('w','f','e','x'), mov_read_wfex },
6846 { MKTAG('c','m','o','v'), mov_read_cmov },
6847 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6848 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6849 { MKTAG('s','b','g','p'), mov_read_sbgp },
6850 { MKTAG('h','v','c','C'), mov_read_glbl },
6851 { MKTAG('u','u','i','d'), mov_read_uuid },
6852 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6853 { MKTAG('f','r','e','e'), mov_read_free },
6854 { MKTAG('-','-','-','-'), mov_read_custom },
6855 { MKTAG('s','i','n','f'), mov_read_default },
6856 { MKTAG('f','r','m','a'), mov_read_frma },
6857 { MKTAG('s','e','n','c'), mov_read_senc },
6858 { MKTAG('s','a','i','z'), mov_read_saiz },
6859 { MKTAG('s','a','i','o'), mov_read_saio },
6860 { MKTAG('p','s','s','h'), mov_read_pssh },
6861 { MKTAG('s','c','h','m'), mov_read_schm },
6862 { MKTAG('s','c','h','i'), mov_read_default },
6863 { MKTAG('t','e','n','c'), mov_read_tenc },
6864 { MKTAG('d','f','L','a'), mov_read_dfla },
6865 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6866 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6867 { MKTAG('d','O','p','s'), mov_read_dops },
6868 { MKTAG('d','m','l','p'), mov_read_dmlp },
6869 { MKTAG('S','m','D','m'), mov_read_smdm },
6870 { MKTAG('C','o','L','L'), mov_read_coll },
6871 { MKTAG('v','p','c','C'), mov_read_vpcc },
6872 { MKTAG('m','d','c','v'), mov_read_mdcv },
6873 { MKTAG('c','l','l','i'), mov_read_clli },
6877 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6879 int64_t total_size = 0;
6883 if (c->atom_depth > 10) {
6884 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6885 return AVERROR_INVALIDDATA;
6890 atom.size = INT64_MAX;
6891 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6892 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
6895 if (atom.size >= 8) {
6896 a.size = avio_rb32(pb);
6897 a.type = avio_rl32(pb);
6898 if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
6899 a.type == MKTAG('h','o','o','v')) &&
6901 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
6903 uint32_t *type = (uint32_t *)buf + 1;
6904 if (avio_read(pb, buf, 8) != 8)
6905 return AVERROR_INVALIDDATA;
6906 avio_seek(pb, -8, SEEK_CUR);
6907 if (*type == MKTAG('m','v','h','d') ||
6908 *type == MKTAG('c','m','o','v')) {
6909 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
6910 a.type = MKTAG('m','o','o','v');
6913 if (atom.type != MKTAG('r','o','o','t') &&
6914 atom.type != MKTAG('m','o','o','v'))
6916 if (a.type == MKTAG('t','r','a','k') || a.type == MKTAG('m','d','a','t'))
6918 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
6925 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
6926 a.size = avio_rb64(pb) - 8;
6930 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
6931 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
6933 a.size = atom.size - total_size + 8;
6938 a.size = FFMIN(a.size, atom.size - total_size);
6940 for (i = 0; mov_default_parse_table[i].type; i++)
6941 if (mov_default_parse_table[i].type == a.type) {
6942 parse = mov_default_parse_table[i].parse;
6946 // container is user data
6947 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
6948 atom.type == MKTAG('i','l','s','t')))
6949 parse = mov_read_udta_string;
6951 // Supports parsing the QuickTime Metadata Keys.
6952 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
6953 if (!parse && c->found_hdlr_mdta &&
6954 atom.type == MKTAG('m','e','t','a') &&
6955 a.type == MKTAG('k','e','y','s')) {
6956 parse = mov_read_keys;
6959 if (!parse) { /* skip leaf atoms data */
6960 avio_skip(pb, a.size);
6962 int64_t start_pos = avio_tell(pb);
6964 int err = parse(c, pb, a);
6969 if (c->found_moov && c->found_mdat &&
6970 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
6971 start_pos + a.size == avio_size(pb))) {
6972 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
6973 c->next_root_atom = start_pos + a.size;
6977 left = a.size - avio_tell(pb) + start_pos;
6978 if (left > 0) /* skip garbage at atom end */
6979 avio_skip(pb, left);
6980 else if (left < 0) {
6981 av_log(c->fc, AV_LOG_WARNING,
6982 "overread end of atom '%.4s' by %"PRId64" bytes\n",
6983 (char*)&a.type, -left);
6984 avio_seek(pb, left, SEEK_CUR);
6988 total_size += a.size;
6991 if (total_size < atom.size && atom.size < 0x7ffff)
6992 avio_skip(pb, atom.size - total_size);
6998 static int mov_probe(const AVProbeData *p)
7003 int moov_offset = -1;
7005 /* check file header */
7008 /* ignore invalid offset */
7009 if ((offset + 8) > (unsigned int)p->buf_size)
7011 tag = AV_RL32(p->buf + offset + 4);
7013 /* check for obvious tags */
7014 case MKTAG('m','o','o','v'):
7015 moov_offset = offset + 4;
7016 case MKTAG('m','d','a','t'):
7017 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
7018 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
7019 case MKTAG('f','t','y','p'):
7020 if (AV_RB32(p->buf+offset) < 8 &&
7021 (AV_RB32(p->buf+offset) != 1 ||
7022 offset + 12 > (unsigned int)p->buf_size ||
7023 AV_RB64(p->buf+offset + 8) == 0)) {
7024 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7025 } else if (tag == MKTAG('f','t','y','p') &&
7026 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
7027 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
7029 score = FFMAX(score, 5);
7031 score = AVPROBE_SCORE_MAX;
7033 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7035 /* those are more common words, so rate then a bit less */
7036 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
7037 case MKTAG('w','i','d','e'):
7038 case MKTAG('f','r','e','e'):
7039 case MKTAG('j','u','n','k'):
7040 case MKTAG('p','i','c','t'):
7041 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
7042 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7044 case MKTAG(0x82,0x82,0x7f,0x7d):
7045 case MKTAG('s','k','i','p'):
7046 case MKTAG('u','u','i','d'):
7047 case MKTAG('p','r','f','l'):
7048 /* if we only find those cause probedata is too small at least rate them */
7049 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7050 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7053 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7056 if(score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
7057 /* moov atom in the header - we should make sure that this is not a
7058 * MOV-packed MPEG-PS */
7059 offset = moov_offset;
7061 while(offset < (p->buf_size - 16)){ /* Sufficient space */
7062 /* We found an actual hdlr atom */
7063 if(AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7064 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7065 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')){
7066 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7067 /* We found a media handler reference atom describing an
7068 * MPEG-PS-in-MOV, return a
7069 * low score to force expanding the probe window until
7070 * mpegps_probe finds what it needs */
7081 // must be done after parsing all trak because there's no order requirement
7082 static void mov_read_chapters(AVFormatContext *s)
7084 MOVContext *mov = s->priv_data;
7086 MOVStreamContext *sc;
7091 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7092 chapter_track = mov->chapter_tracks[j];
7094 for (i = 0; i < s->nb_streams; i++)
7095 if (s->streams[i]->id == chapter_track) {
7100 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7105 cur_pos = avio_tell(sc->pb);
7107 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7108 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7109 if (st->nb_index_entries) {
7110 // Retrieve the first frame, if possible
7112 AVIndexEntry *sample = &st->index_entries[0];
7113 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7114 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7118 if (av_get_packet(sc->pb, &pkt, sample->size) < 0)
7121 st->attached_pic = pkt;
7122 st->attached_pic.stream_index = st->index;
7123 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
7126 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7127 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7128 st->discard = AVDISCARD_ALL;
7129 for (i = 0; i < st->nb_index_entries; i++) {
7130 AVIndexEntry *sample = &st->index_entries[i];
7131 int64_t end = i+1 < st->nb_index_entries ? st->index_entries[i+1].timestamp : st->duration;
7136 if (end < sample->timestamp) {
7137 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7138 end = AV_NOPTS_VALUE;
7141 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7142 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7146 // the first two bytes are the length of the title
7147 len = avio_rb16(sc->pb);
7148 if (len > sample->size-2)
7150 title_len = 2*len + 1;
7151 if (!(title = av_mallocz(title_len)))
7154 // The samples could theoretically be in any encoding if there's an encd
7155 // atom following, but in practice are only utf-8 or utf-16, distinguished
7156 // instead by the presence of a BOM
7160 ch = avio_rb16(sc->pb);
7162 avio_get_str16be(sc->pb, len, title, title_len);
7163 else if (ch == 0xfffe)
7164 avio_get_str16le(sc->pb, len, title, title_len);
7167 if (len == 1 || len == 2)
7170 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7174 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7179 avio_seek(sc->pb, cur_pos, SEEK_SET);
7183 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7184 uint32_t value, int flags)
7187 char buf[AV_TIMECODE_STR_SIZE];
7188 AVRational rate = st->avg_frame_rate;
7189 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7192 av_dict_set(&st->metadata, "timecode",
7193 av_timecode_make_string(&tc, buf, value), 0);
7197 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7199 MOVStreamContext *sc = st->priv_data;
7200 char buf[AV_TIMECODE_STR_SIZE];
7201 int64_t cur_pos = avio_tell(sc->pb);
7202 int hh, mm, ss, ff, drop;
7204 if (!st->nb_index_entries)
7207 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7208 avio_skip(s->pb, 13);
7209 hh = avio_r8(s->pb);
7210 mm = avio_r8(s->pb);
7211 ss = avio_r8(s->pb);
7212 drop = avio_r8(s->pb);
7213 ff = avio_r8(s->pb);
7214 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7215 hh, mm, ss, drop ? ';' : ':', ff);
7216 av_dict_set(&st->metadata, "timecode", buf, 0);
7218 avio_seek(sc->pb, cur_pos, SEEK_SET);
7222 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7224 MOVStreamContext *sc = st->priv_data;
7226 int64_t cur_pos = avio_tell(sc->pb);
7229 if (!st->nb_index_entries)
7232 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7233 value = avio_rb32(s->pb);
7235 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7236 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7237 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7239 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7240 * not the case) and thus assume "frame number format" instead of QT one.
7241 * No sample with tmcd track can be found with a QT timecode at the moment,
7242 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7244 parse_timecode_in_framenum_format(s, st, value, flags);
7246 avio_seek(sc->pb, cur_pos, SEEK_SET);
7250 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7252 if (!index || !*index) return;
7253 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7254 av_encryption_info_free((*index)->encrypted_samples[i]);
7256 av_freep(&(*index)->encrypted_samples);
7257 av_freep(&(*index)->auxiliary_info_sizes);
7258 av_freep(&(*index)->auxiliary_offsets);
7262 static int mov_read_close(AVFormatContext *s)
7264 MOVContext *mov = s->priv_data;
7267 for (i = 0; i < s->nb_streams; i++) {
7268 AVStream *st = s->streams[i];
7269 MOVStreamContext *sc = st->priv_data;
7274 av_freep(&sc->ctts_data);
7275 for (j = 0; j < sc->drefs_count; j++) {
7276 av_freep(&sc->drefs[j].path);
7277 av_freep(&sc->drefs[j].dir);
7279 av_freep(&sc->drefs);
7281 sc->drefs_count = 0;
7283 if (!sc->pb_is_copied)
7284 ff_format_io_close(s, &sc->pb);
7287 av_freep(&sc->chunk_offsets);
7288 av_freep(&sc->stsc_data);
7289 av_freep(&sc->sample_sizes);
7290 av_freep(&sc->keyframes);
7291 av_freep(&sc->stts_data);
7292 av_freep(&sc->sdtp_data);
7293 av_freep(&sc->stps_data);
7294 av_freep(&sc->elst_data);
7295 av_freep(&sc->rap_group);
7296 av_freep(&sc->display_matrix);
7297 av_freep(&sc->index_ranges);
7300 for (j = 0; j < sc->stsd_count; j++)
7301 av_free(sc->extradata[j]);
7302 av_freep(&sc->extradata);
7303 av_freep(&sc->extradata_size);
7305 mov_free_encryption_index(&sc->cenc.encryption_index);
7306 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7307 av_aes_ctr_free(sc->cenc.aes_ctr);
7309 av_freep(&sc->stereo3d);
7310 av_freep(&sc->spherical);
7311 av_freep(&sc->mastering);
7312 av_freep(&sc->coll);
7315 if (mov->dv_demux) {
7316 avformat_free_context(mov->dv_fctx);
7317 mov->dv_fctx = NULL;
7320 if (mov->meta_keys) {
7321 for (i = 1; i < mov->meta_keys_count; i++) {
7322 av_freep(&mov->meta_keys[i]);
7324 av_freep(&mov->meta_keys);
7327 av_freep(&mov->trex_data);
7328 av_freep(&mov->bitrates);
7330 for (i = 0; i < mov->frag_index.nb_items; i++) {
7331 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7332 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7333 mov_free_encryption_index(&frag[j].encryption_index);
7335 av_freep(&mov->frag_index.item[i].stream_info);
7337 av_freep(&mov->frag_index.item);
7339 av_freep(&mov->aes_decrypt);
7340 av_freep(&mov->chapter_tracks);
7345 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7349 for (i = 0; i < s->nb_streams; i++) {
7350 AVStream *st = s->streams[i];
7351 MOVStreamContext *sc = st->priv_data;
7353 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7354 sc->timecode_track == tmcd_id)
7360 /* look for a tmcd track not referenced by any video track, and export it globally */
7361 static void export_orphan_timecode(AVFormatContext *s)
7365 for (i = 0; i < s->nb_streams; i++) {
7366 AVStream *st = s->streams[i];
7368 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7369 !tmcd_is_referenced(s, i + 1)) {
7370 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7372 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7379 static int read_tfra(MOVContext *mov, AVIOContext *f)
7381 int version, fieldlength, i, j;
7382 int64_t pos = avio_tell(f);
7383 uint32_t size = avio_rb32(f);
7384 unsigned track_id, item_count;
7386 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7389 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7391 version = avio_r8(f);
7393 track_id = avio_rb32(f);
7394 fieldlength = avio_rb32(f);
7395 item_count = avio_rb32(f);
7396 for (i = 0; i < item_count; i++) {
7397 int64_t time, offset;
7399 MOVFragmentStreamInfo * frag_stream_info;
7402 return AVERROR_INVALIDDATA;
7406 time = avio_rb64(f);
7407 offset = avio_rb64(f);
7409 time = avio_rb32(f);
7410 offset = avio_rb32(f);
7413 // The first sample of each stream in a fragment is always a random
7414 // access sample. So it's entry in the tfra can be used as the
7415 // initial PTS of the fragment.
7416 index = update_frag_index(mov, offset);
7417 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7418 if (frag_stream_info &&
7419 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7420 frag_stream_info->first_tfra_pts = time;
7422 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7424 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7426 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7430 avio_seek(f, pos + size, SEEK_SET);
7434 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7436 int64_t stream_size = avio_size(f);
7437 int64_t original_pos = avio_tell(f);
7441 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7445 mfra_size = avio_rb32(f);
7446 if (mfra_size < 0 || mfra_size > stream_size) {
7447 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7450 if ((seek_ret = avio_seek(f, -mfra_size, SEEK_CUR)) < 0) {
7454 if (avio_rb32(f) != mfra_size) {
7455 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7458 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7459 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7462 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7464 ret = read_tfra(c, f);
7470 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7472 av_log(c->fc, AV_LOG_ERROR,
7473 "failed to seek back after looking for mfra\n");
7479 static int mov_read_header(AVFormatContext *s)
7481 MOVContext *mov = s->priv_data;
7482 AVIOContext *pb = s->pb;
7484 MOVAtom atom = { AV_RL32("root") };
7487 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7488 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7489 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7490 return AVERROR(EINVAL);
7494 mov->trak_index = -1;
7495 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7496 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7497 atom.size = avio_size(pb);
7499 atom.size = INT64_MAX;
7501 /* check MOV header */
7503 if (mov->moov_retry)
7504 avio_seek(pb, 0, SEEK_SET);
7505 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7506 av_log(s, AV_LOG_ERROR, "error reading header\n");
7510 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7511 if (!mov->found_moov) {
7512 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7514 return AVERROR_INVALIDDATA;
7516 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7518 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7519 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7520 mov_read_chapters(s);
7521 for (i = 0; i < s->nb_streams; i++)
7522 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7523 mov_read_timecode_track(s, s->streams[i]);
7524 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7525 mov_read_rtmd_track(s, s->streams[i]);
7529 /* copy timecode metadata from tmcd tracks to the related video streams */
7530 for (i = 0; i < s->nb_streams; i++) {
7531 AVStream *st = s->streams[i];
7532 MOVStreamContext *sc = st->priv_data;
7533 if (sc->timecode_track > 0) {
7534 AVDictionaryEntry *tcr;
7535 int tmcd_st_id = -1;
7537 for (j = 0; j < s->nb_streams; j++)
7538 if (s->streams[j]->id == sc->timecode_track)
7541 if (tmcd_st_id < 0 || tmcd_st_id == i)
7543 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7545 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7548 export_orphan_timecode(s);
7550 for (i = 0; i < s->nb_streams; i++) {
7551 AVStream *st = s->streams[i];
7552 MOVStreamContext *sc = st->priv_data;
7553 fix_timescale(mov, sc);
7554 if(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7555 st->skip_samples = sc->start_pad;
7557 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7558 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7559 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7560 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7561 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7562 st->codecpar->width = sc->width;
7563 st->codecpar->height = sc->height;
7565 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7566 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7570 if (mov->handbrake_version &&
7571 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7572 st->codecpar->codec_id == AV_CODEC_ID_MP3
7574 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7575 st->need_parsing = AVSTREAM_PARSE_FULL;
7579 if (mov->trex_data) {
7580 for (i = 0; i < s->nb_streams; i++) {
7581 AVStream *st = s->streams[i];
7582 MOVStreamContext *sc = st->priv_data;
7583 if (st->duration > 0) {
7584 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7585 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7586 sc->data_size, sc->time_scale);
7588 return AVERROR_INVALIDDATA;
7590 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7595 if (mov->use_mfra_for > 0) {
7596 for (i = 0; i < s->nb_streams; i++) {
7597 AVStream *st = s->streams[i];
7598 MOVStreamContext *sc = st->priv_data;
7599 if (sc->duration_for_fps > 0) {
7600 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7601 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7602 sc->data_size, sc->time_scale);
7604 return AVERROR_INVALIDDATA;
7606 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7607 sc->duration_for_fps;
7612 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7613 if (mov->bitrates[i]) {
7614 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7618 ff_rfps_calculate(s);
7620 for (i = 0; i < s->nb_streams; i++) {
7621 AVStream *st = s->streams[i];
7622 MOVStreamContext *sc = st->priv_data;
7624 switch (st->codecpar->codec_type) {
7625 case AVMEDIA_TYPE_AUDIO:
7626 err = ff_replaygain_export(st, s->metadata);
7632 case AVMEDIA_TYPE_VIDEO:
7633 if (sc->display_matrix) {
7634 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7635 sizeof(int32_t) * 9);
7639 sc->display_matrix = NULL;
7642 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7643 (uint8_t *)sc->stereo3d,
7644 sizeof(*sc->stereo3d));
7648 sc->stereo3d = NULL;
7650 if (sc->spherical) {
7651 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7652 (uint8_t *)sc->spherical,
7653 sc->spherical_size);
7657 sc->spherical = NULL;
7659 if (sc->mastering) {
7660 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7661 (uint8_t *)sc->mastering,
7662 sizeof(*sc->mastering));
7666 sc->mastering = NULL;
7669 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7670 (uint8_t *)sc->coll,
7680 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7682 for (i = 0; i < mov->frag_index.nb_items; i++)
7683 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7684 mov->frag_index.item[i].headers_read = 1;
7689 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7691 AVIndexEntry *sample = NULL;
7692 int64_t best_dts = INT64_MAX;
7694 for (i = 0; i < s->nb_streams; i++) {
7695 AVStream *avst = s->streams[i];
7696 MOVStreamContext *msc = avst->priv_data;
7697 if (msc->pb && msc->current_sample < avst->nb_index_entries) {
7698 AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample];
7699 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7700 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7701 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7702 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7703 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb &&
7704 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7705 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7706 sample = current_sample;
7715 static int should_retry(AVIOContext *pb, int error_code) {
7716 if (error_code == AVERROR_EOF || avio_feof(pb))
7722 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7725 MOVContext *mov = s->priv_data;
7727 if (index >= 0 && index < mov->frag_index.nb_items)
7728 target = mov->frag_index.item[index].moof_offset;
7729 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7730 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7731 return AVERROR_INVALIDDATA;
7734 mov->next_root_atom = 0;
7735 if (index < 0 || index >= mov->frag_index.nb_items)
7736 index = search_frag_moof_offset(&mov->frag_index, target);
7737 if (index < mov->frag_index.nb_items) {
7738 if (index + 1 < mov->frag_index.nb_items)
7739 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7740 if (mov->frag_index.item[index].headers_read)
7742 mov->frag_index.item[index].headers_read = 1;
7745 mov->found_mdat = 0;
7747 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7750 if (avio_feof(s->pb))
7752 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7757 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7759 uint8_t *side, *extradata;
7762 /* Save the current index. */
7763 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7765 /* Notify the decoder that extradata changed. */
7766 extradata_size = sc->extradata_size[sc->last_stsd_index];
7767 extradata = sc->extradata[sc->last_stsd_index];
7768 if (extradata_size > 0 && extradata) {
7769 side = av_packet_new_side_data(pkt,
7770 AV_PKT_DATA_NEW_EXTRADATA,
7773 return AVERROR(ENOMEM);
7774 memcpy(side, extradata, extradata_size);
7780 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7782 MOVContext *mov = s->priv_data;
7783 MOVStreamContext *sc;
7784 AVIndexEntry *sample;
7785 AVStream *st = NULL;
7786 int64_t current_index;
7790 sample = mov_find_next_sample(s, &st);
7791 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7792 if (!mov->next_root_atom)
7794 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7799 /* must be done just before reading, to avoid infinite loop on sample */
7800 current_index = sc->current_index;
7801 mov_current_sample_inc(sc);
7803 if (mov->next_root_atom) {
7804 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7805 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7808 if (st->discard != AVDISCARD_ALL) {
7809 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7810 if (ret64 != sample->pos) {
7811 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7812 sc->ffindex, sample->pos);
7813 if (should_retry(sc->pb, ret64)) {
7814 mov_current_sample_dec(sc);
7816 return AVERROR_INVALIDDATA;
7819 if( st->discard == AVDISCARD_NONKEY && 0==(sample->flags & AVINDEX_KEYFRAME) ) {
7820 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7824 ret = av_get_packet(sc->pb, pkt, sample->size);
7826 if (should_retry(sc->pb, ret)) {
7827 mov_current_sample_dec(sc);
7831 if (sc->has_palette) {
7834 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7836 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7838 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7839 sc->has_palette = 0;
7842 #if CONFIG_DV_DEMUXER
7843 if (mov->dv_demux && sc->dv_audio_container) {
7844 avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7845 av_freep(&pkt->data);
7847 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7852 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7853 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7854 st->need_parsing = AVSTREAM_PARSE_FULL;
7858 pkt->stream_index = sc->ffindex;
7859 pkt->dts = sample->timestamp;
7860 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7861 pkt->flags |= AV_PKT_FLAG_DISCARD;
7863 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7864 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
7865 /* update ctts context */
7867 if (sc->ctts_index < sc->ctts_count &&
7868 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
7870 sc->ctts_sample = 0;
7873 int64_t next_dts = (sc->current_sample < st->nb_index_entries) ?
7874 st->index_entries[sc->current_sample].timestamp : st->duration;
7876 if (next_dts >= pkt->dts)
7877 pkt->duration = next_dts - pkt->dts;
7878 pkt->pts = pkt->dts;
7880 if (st->discard == AVDISCARD_ALL)
7882 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
7883 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
7884 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
7885 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
7887 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
7888 pkt->pos = sample->pos;
7890 /* Multiple stsd handling. */
7891 if (sc->stsc_data) {
7892 /* Keep track of the stsc index for the given sample, then check
7893 * if the stsd index is different from the last used one. */
7895 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
7896 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
7898 sc->stsc_sample = 0;
7899 /* Do not check indexes after a switch. */
7900 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
7901 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
7902 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
7903 ret = mov_change_extradata(sc, pkt);
7910 aax_filter(pkt->data, pkt->size, mov);
7912 ret = cenc_filter(mov, st, sc, pkt, current_index);
7920 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
7922 MOVContext *mov = s->priv_data;
7925 if (!mov->frag_index.complete)
7928 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
7931 if (!mov->frag_index.item[index].headers_read)
7932 return mov_switch_root(s, -1, index);
7933 if (index + 1 < mov->frag_index.nb_items)
7934 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7939 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
7941 MOVStreamContext *sc = st->priv_data;
7942 int sample, time_sample, ret;
7945 // Here we consider timestamp to be PTS, hence try to offset it so that we
7946 // can search over the DTS timeline.
7947 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
7949 ret = mov_seek_fragment(s, st, timestamp);
7953 sample = av_index_search_timestamp(st, timestamp, flags);
7954 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
7955 if (sample < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp)
7957 if (sample < 0) /* not sure what to do */
7958 return AVERROR_INVALIDDATA;
7959 mov_current_sample_set(sc, sample);
7960 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
7961 /* adjust ctts index */
7962 if (sc->ctts_data) {
7964 for (i = 0; i < sc->ctts_count; i++) {
7965 int next = time_sample + sc->ctts_data[i].count;
7966 if (next > sc->current_sample) {
7968 sc->ctts_sample = sc->current_sample - time_sample;
7975 /* adjust stsd index */
7976 if (sc->chunk_count) {
7978 for (i = 0; i < sc->stsc_count; i++) {
7979 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
7980 if (next > sc->current_sample) {
7982 sc->stsc_sample = sc->current_sample - time_sample;
7985 av_assert0(next == (int)next);
7993 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
7995 MOVContext *mc = s->priv_data;
8000 if (stream_index >= s->nb_streams)
8001 return AVERROR_INVALIDDATA;
8003 st = s->streams[stream_index];
8004 sample = mov_seek_stream(s, st, sample_time, flags);
8008 if (mc->seek_individually) {
8009 /* adjust seek timestamp to found sample timestamp */
8010 int64_t seek_timestamp = st->index_entries[sample].timestamp;
8012 for (i = 0; i < s->nb_streams; i++) {
8014 MOVStreamContext *sc = s->streams[i]->priv_data;
8016 st->skip_samples = (sample_time <= 0) ? sc->start_pad : 0;
8018 if (stream_index == i)
8021 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
8022 mov_seek_stream(s, st, timestamp, flags);
8025 for (i = 0; i < s->nb_streams; i++) {
8026 MOVStreamContext *sc;
8029 mov_current_sample_set(sc, 0);
8032 MOVStreamContext *sc;
8033 AVIndexEntry *entry = mov_find_next_sample(s, &st);
8035 return AVERROR_INVALIDDATA;
8037 if (sc->ffindex == stream_index && sc->current_sample == sample)
8039 mov_current_sample_inc(sc);
8045 #define OFFSET(x) offsetof(MOVContext, x)
8046 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
8047 static const AVOption mov_options[] = {
8048 {"use_absolute_path",
8049 "allow using absolute path when opening alias, this is a possible security issue",
8050 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
8052 {"seek_streams_individually",
8053 "Seek each stream individually to the closest point",
8054 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
8056 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
8058 {"advanced_editlist",
8059 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
8060 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
8062 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8065 "use mfra for fragment timestamps",
8066 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8067 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8069 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8070 FLAGS, "use_mfra_for" },
8071 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8072 FLAGS, "use_mfra_for" },
8073 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8074 FLAGS, "use_mfra_for" },
8075 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8076 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8077 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8078 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8079 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8080 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8081 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8082 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8083 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8084 .flags = AV_OPT_FLAG_DECODING_PARAM },
8085 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8086 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8087 {.i64 = 0}, 0, 1, FLAGS },
8092 static const AVClass mov_class = {
8093 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8094 .item_name = av_default_item_name,
8095 .option = mov_options,
8096 .version = LIBAVUTIL_VERSION_INT,
8099 AVInputFormat ff_mov_demuxer = {
8100 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8101 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8102 .priv_class = &mov_class,
8103 .priv_data_size = sizeof(MOVContext),
8104 .extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
8105 .read_probe = mov_probe,
8106 .read_header = mov_read_header,
8107 .read_packet = mov_read_packet,
8108 .read_close = mov_read_close,
8109 .read_seek = mov_read_seek,
8110 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,