3 * Copyright (c) 2001 Fabrice Bellard
4 * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
6 * first version by Francois Revol <revol@free.fr>
7 * seek function by Gael Chardon <gael.dev@4now.net>
9 * This file is part of FFmpeg.
11 * FFmpeg is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * FFmpeg is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with FFmpeg; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30 #include "libavutil/attributes.h"
31 #include "libavutil/channel_layout.h"
32 #include "libavutil/internal.h"
33 #include "libavutil/intreadwrite.h"
34 #include "libavutil/intfloat.h"
35 #include "libavutil/mathematics.h"
36 #include "libavutil/time_internal.h"
37 #include "libavutil/avassert.h"
38 #include "libavutil/avstring.h"
39 #include "libavutil/dict.h"
40 #include "libavutil/display.h"
41 #include "libavutil/opt.h"
42 #include "libavutil/aes.h"
43 #include "libavutil/aes_ctr.h"
44 #include "libavutil/pixdesc.h"
45 #include "libavutil/sha.h"
46 #include "libavutil/spherical.h"
47 #include "libavutil/stereo3d.h"
48 #include "libavutil/timecode.h"
49 #include "libavcodec/ac3tab.h"
50 #include "libavcodec/flac.h"
51 #include "libavcodec/mpegaudiodecheader.h"
52 #include "libavcodec/mlp_parse.h"
55 #include "avio_internal.h"
58 #include "libavcodec/get_bits.h"
61 #include "replaygain.h"
67 #include "qtpalette.h"
69 /* those functions parse an atom */
70 /* links atom IDs to parse functions */
71 typedef struct MOVParseTableEntry {
73 int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
76 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
77 static int mov_read_mfra(MOVContext *c, AVIOContext *f);
78 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
79 int count, int duration);
81 static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb,
82 unsigned len, const char *key)
86 short current, total = 0;
87 avio_rb16(pb); // unknown
88 current = avio_rb16(pb);
90 total = avio_rb16(pb);
92 snprintf(buf, sizeof(buf), "%d", current);
94 snprintf(buf, sizeof(buf), "%d/%d", current, total);
95 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
96 av_dict_set(&c->fc->metadata, key, buf, 0);
101 static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb,
102 unsigned len, const char *key)
104 /* bypass padding bytes */
109 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
110 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
115 static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb,
116 unsigned len, const char *key)
118 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
119 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
124 static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb,
125 unsigned len, const char *key)
129 avio_r8(pb); // unknown
132 if (genre < 1 || genre > ID3v1_GENRE_MAX)
134 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
135 av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
140 static const uint32_t mac_to_unicode[128] = {
141 0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
142 0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
143 0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
144 0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
145 0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
146 0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
147 0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
148 0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
149 0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
150 0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
151 0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
152 0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
153 0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
154 0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
155 0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
156 0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
159 static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len,
160 char *dst, int dstlen)
163 char *end = dst+dstlen-1;
166 for (i = 0; i < len; i++) {
167 uint8_t t, c = avio_r8(pb);
175 PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
181 static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
185 MOVStreamContext *sc;
190 case 0xd: id = AV_CODEC_ID_MJPEG; break;
191 case 0xe: id = AV_CODEC_ID_PNG; break;
192 case 0x1b: id = AV_CODEC_ID_BMP; break;
194 av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
199 st = avformat_new_stream(c->fc, NULL);
201 return AVERROR(ENOMEM);
202 sc = av_mallocz(sizeof(*sc));
204 return AVERROR(ENOMEM);
207 ret = av_get_packet(pb, &pkt, len);
211 if (pkt.size >= 8 && id != AV_CODEC_ID_BMP) {
212 if (AV_RB64(pkt.data) == 0x89504e470d0a1a0a) {
213 id = AV_CODEC_ID_PNG;
215 id = AV_CODEC_ID_MJPEG;
219 st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
221 st->attached_pic = pkt;
222 st->attached_pic.stream_index = st->index;
223 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
225 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
226 st->codecpar->codec_id = id;
232 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
234 char language[4] = { 0 };
235 char buf[200], place[100];
236 uint16_t langcode = 0;
237 double longitude, latitude, altitude;
238 const char *key = "location";
240 if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
241 av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
242 return AVERROR_INVALIDDATA;
245 avio_skip(pb, 4); // version+flags
246 langcode = avio_rb16(pb);
247 ff_mov_lang_to_iso639(langcode, language);
250 len -= avio_get_str(pb, len, place, sizeof(place));
252 av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
253 return AVERROR_INVALIDDATA;
255 avio_skip(pb, 1); // role
259 av_log(c->fc, AV_LOG_ERROR,
260 "loci too short (%u bytes left, need at least %d)\n", len, 12);
261 return AVERROR_INVALIDDATA;
263 longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
264 latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
265 altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
267 // Try to output in the same format as the ?xyz field
268 snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
270 av_strlcatf(buf, sizeof(buf), "%+f", altitude);
271 av_strlcatf(buf, sizeof(buf), "/%s", place);
273 if (*language && strcmp(language, "und")) {
275 snprintf(key2, sizeof(key2), "%s-%s", key, language);
276 av_dict_set(&c->fc->metadata, key2, buf, 0);
278 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
279 return av_dict_set(&c->fc->metadata, key, buf, 0);
282 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
288 if (c->ignore_chapters)
291 n_hmmt = avio_rb32(pb);
292 for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
293 int moment_time = avio_rb32(pb);
294 avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
299 static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
302 char key2[32], language[4] = {0};
304 const char *key = NULL;
305 uint16_t langcode = 0;
306 uint32_t data_type = 0, str_size, str_size_alloc;
307 int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
312 case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
313 case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
314 case MKTAG( 'X','M','P','_'):
315 if (c->export_xmp) { key = "xmp"; raw = 1; } break;
316 case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
317 case MKTAG( 'a','k','I','D'): key = "account_type";
318 parse = mov_metadata_int8_no_padding; break;
319 case MKTAG( 'a','p','I','D'): key = "account_id"; break;
320 case MKTAG( 'c','a','t','g'): key = "category"; break;
321 case MKTAG( 'c','p','i','l'): key = "compilation";
322 parse = mov_metadata_int8_no_padding; break;
323 case MKTAG( 'c','p','r','t'): key = "copyright"; break;
324 case MKTAG( 'd','e','s','c'): key = "description"; break;
325 case MKTAG( 'd','i','s','k'): key = "disc";
326 parse = mov_metadata_track_or_disc_number; break;
327 case MKTAG( 'e','g','i','d'): key = "episode_uid";
328 parse = mov_metadata_int8_no_padding; break;
329 case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
330 case MKTAG( 'g','n','r','e'): key = "genre";
331 parse = mov_metadata_gnre; break;
332 case MKTAG( 'h','d','v','d'): key = "hd_video";
333 parse = mov_metadata_int8_no_padding; break;
334 case MKTAG( 'H','M','M','T'):
335 return mov_metadata_hmmt(c, pb, atom.size);
336 case MKTAG( 'k','e','y','w'): key = "keywords"; break;
337 case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
338 case MKTAG( 'l','o','c','i'):
339 return mov_metadata_loci(c, pb, atom.size);
340 case MKTAG( 'm','a','n','u'): key = "make"; break;
341 case MKTAG( 'm','o','d','l'): key = "model"; break;
342 case MKTAG( 'p','c','s','t'): key = "podcast";
343 parse = mov_metadata_int8_no_padding; break;
344 case MKTAG( 'p','g','a','p'): key = "gapless_playback";
345 parse = mov_metadata_int8_no_padding; break;
346 case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
347 case MKTAG( 'r','t','n','g'): key = "rating";
348 parse = mov_metadata_int8_no_padding; break;
349 case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
350 case MKTAG( 's','o','a','l'): key = "sort_album"; break;
351 case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
352 case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
353 case MKTAG( 's','o','n','m'): key = "sort_name"; break;
354 case MKTAG( 's','o','s','n'): key = "sort_show"; break;
355 case MKTAG( 's','t','i','k'): key = "media_type";
356 parse = mov_metadata_int8_no_padding; break;
357 case MKTAG( 't','r','k','n'): key = "track";
358 parse = mov_metadata_track_or_disc_number; break;
359 case MKTAG( 't','v','e','n'): key = "episode_id"; break;
360 case MKTAG( 't','v','e','s'): key = "episode_sort";
361 parse = mov_metadata_int8_bypass_padding; break;
362 case MKTAG( 't','v','n','n'): key = "network"; break;
363 case MKTAG( 't','v','s','h'): key = "show"; break;
364 case MKTAG( 't','v','s','n'): key = "season_number";
365 parse = mov_metadata_int8_bypass_padding; break;
366 case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
367 case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
368 case MKTAG(0xa9,'a','l','b'): key = "album"; break;
369 case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
370 case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
371 case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
372 case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
373 case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
374 case MKTAG(0xa9,'d','a','y'): key = "date"; break;
375 case MKTAG(0xa9,'d','i','r'): key = "director"; break;
376 case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
377 case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
378 case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
379 case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
380 case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
381 case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
382 case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
383 case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
384 case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
385 case MKTAG(0xa9,'m','a','k'): key = "make"; break;
386 case MKTAG(0xa9,'m','o','d'): key = "model"; break;
387 case MKTAG(0xa9,'n','a','m'): key = "title"; break;
388 case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
389 case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
390 case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
391 case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
392 case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
393 case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
394 case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
395 case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
396 case MKTAG(0xa9,'t','r','k'): key = "track"; break;
397 case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
398 case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
399 case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
400 case MKTAG(0xa9,'x','y','z'): key = "location"; break;
403 if (c->itunes_metadata && atom.size > 8) {
404 int data_size = avio_rb32(pb);
405 int tag = avio_rl32(pb);
406 if (tag == MKTAG('d','a','t','a') && data_size <= atom.size) {
407 data_type = avio_rb32(pb); // type
408 avio_rb32(pb); // unknown
409 str_size = data_size - 16;
412 if (atom.type == MKTAG('c', 'o', 'v', 'r')) {
413 int ret = mov_read_covr(c, pb, data_type, str_size);
415 av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
418 atom.size -= str_size;
422 } else if (!key && c->found_hdlr_mdta && c->meta_keys) {
423 uint32_t index = AV_RB32(&atom.type);
424 if (index < c->meta_keys_count && index > 0) {
425 key = c->meta_keys[index];
427 av_log(c->fc, AV_LOG_WARNING,
428 "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
429 index, c->meta_keys_count);
433 } else if (atom.size > 4 && key && !c->itunes_metadata && !raw) {
434 str_size = avio_rb16(pb); // string length
435 if (str_size > atom.size) {
437 avio_seek(pb, -2, SEEK_CUR);
438 av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
441 langcode = avio_rb16(pb);
442 ff_mov_lang_to_iso639(langcode, language);
445 str_size = atom.size;
447 if (c->export_all && !key) {
448 snprintf(tmp_key, 5, "%.4s", (char*)&atom.type);
454 if (atom.size < 0 || str_size >= INT_MAX/2)
455 return AVERROR_INVALIDDATA;
457 // Allocates enough space if data_type is a int32 or float32 number, otherwise
458 // worst-case requirement for output string in case of utf8 coded input
459 num = (data_type >= 21 && data_type <= 23);
460 str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
461 str = av_mallocz(str_size_alloc);
463 return AVERROR(ENOMEM);
466 parse(c, pb, str_size, key);
468 if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
469 mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
470 } else if (data_type == 21) { // BE signed integer, variable size
473 val = (int8_t)avio_r8(pb);
474 else if (str_size == 2)
475 val = (int16_t)avio_rb16(pb);
476 else if (str_size == 3)
477 val = ((int32_t)(avio_rb24(pb)<<8))>>8;
478 else if (str_size == 4)
479 val = (int32_t)avio_rb32(pb);
480 if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
481 av_log(c->fc, AV_LOG_ERROR,
482 "Failed to store the number (%d) in string.\n", val);
484 return AVERROR_INVALIDDATA;
486 } else if (data_type == 22) { // BE unsigned integer, variable size
487 unsigned int val = 0;
490 else if (str_size == 2)
492 else if (str_size == 3)
494 else if (str_size == 4)
496 if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
497 av_log(c->fc, AV_LOG_ERROR,
498 "Failed to store the number (%u) in string.\n", val);
500 return AVERROR_INVALIDDATA;
502 } else if (data_type == 23 && str_size >= 4) { // BE float32
503 float val = av_int2float(avio_rb32(pb));
504 if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
505 av_log(c->fc, AV_LOG_ERROR,
506 "Failed to store the float32 number (%f) in string.\n", val);
508 return AVERROR_INVALIDDATA;
511 int ret = ffio_read_size(pb, str, str_size);
518 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
519 av_dict_set(&c->fc->metadata, key, str, 0);
520 if (*language && strcmp(language, "und")) {
521 snprintf(key2, sizeof(key2), "%s-%s", key, language);
522 av_dict_set(&c->fc->metadata, key2, str, 0);
524 if (!strcmp(key, "encoder")) {
525 int major, minor, micro;
526 if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, µ) == 3) {
527 c->handbrake_version = 1000000*major + 1000*minor + micro;
536 static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
539 int i, nb_chapters, str_len, version;
543 if (c->ignore_chapters)
546 if ((atom.size -= 5) < 0)
549 version = avio_r8(pb);
552 avio_rb32(pb); // ???
553 nb_chapters = avio_r8(pb);
555 for (i = 0; i < nb_chapters; i++) {
559 start = avio_rb64(pb);
560 str_len = avio_r8(pb);
562 if ((atom.size -= 9+str_len) < 0)
565 ret = ffio_read_size(pb, str, str_len);
569 avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
574 #define MIN_DATA_ENTRY_BOX_SIZE 12
575 static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
578 MOVStreamContext *sc;
581 if (c->fc->nb_streams < 1)
583 st = c->fc->streams[c->fc->nb_streams-1];
586 avio_rb32(pb); // version + flags
587 entries = avio_rb32(pb);
589 entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
590 entries >= UINT_MAX / sizeof(*sc->drefs))
591 return AVERROR_INVALIDDATA;
595 sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
597 return AVERROR(ENOMEM);
598 sc->drefs_count = entries;
600 for (i = 0; i < entries; i++) {
601 MOVDref *dref = &sc->drefs[i];
602 uint32_t size = avio_rb32(pb);
603 int64_t next = avio_tell(pb) + size - 4;
606 return AVERROR_INVALIDDATA;
608 dref->type = avio_rl32(pb);
609 avio_rb32(pb); // version + flags
611 if (dref->type == MKTAG('a','l','i','s') && size > 150) {
612 /* macintosh alias record */
613 uint16_t volume_len, len;
619 volume_len = avio_r8(pb);
620 volume_len = FFMIN(volume_len, 27);
621 ret = ffio_read_size(pb, dref->volume, 27);
624 dref->volume[volume_len] = 0;
625 av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
630 len = FFMIN(len, 63);
631 ret = ffio_read_size(pb, dref->filename, 63);
634 dref->filename[len] = 0;
635 av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
639 /* read next level up_from_alias/down_to_target */
640 dref->nlvl_from = avio_rb16(pb);
641 dref->nlvl_to = avio_rb16(pb);
642 av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
643 dref->nlvl_from, dref->nlvl_to);
647 for (type = 0; type != -1 && avio_tell(pb) < next; ) {
650 type = avio_rb16(pb);
652 av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
655 if (type == 2) { // absolute path
657 dref->path = av_mallocz(len+1);
659 return AVERROR(ENOMEM);
661 ret = ffio_read_size(pb, dref->path, len);
663 av_freep(&dref->path);
666 if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
668 memmove(dref->path, dref->path+volume_len, len);
671 // trim string of any ending zeros
672 for (j = len - 1; j >= 0; j--) {
673 if (dref->path[j] == 0)
678 for (j = 0; j < len; j++)
679 if (dref->path[j] == ':' || dref->path[j] == 0)
681 av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
682 } else if (type == 0) { // directory name
684 dref->dir = av_malloc(len+1);
686 return AVERROR(ENOMEM);
688 ret = ffio_read_size(pb, dref->dir, len);
690 av_freep(&dref->dir);
694 for (j = 0; j < len; j++)
695 if (dref->dir[j] == ':')
697 av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
702 av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
707 avio_seek(pb, next, SEEK_SET);
712 static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
721 avio_r8(pb); /* version */
722 avio_rb24(pb); /* flags */
725 ctype = avio_rl32(pb);
726 type = avio_rl32(pb); /* component subtype */
728 av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
729 av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
731 if (c->trak_index < 0) { // meta not inside a trak
732 if (type == MKTAG('m','d','t','a')) {
733 c->found_hdlr_mdta = 1;
738 st = c->fc->streams[c->fc->nb_streams-1];
740 if (type == MKTAG('v','i','d','e'))
741 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
742 else if (type == MKTAG('s','o','u','n'))
743 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
744 else if (type == MKTAG('m','1','a',' '))
745 st->codecpar->codec_id = AV_CODEC_ID_MP2;
746 else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
747 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
749 avio_rb32(pb); /* component manufacture */
750 avio_rb32(pb); /* component flags */
751 avio_rb32(pb); /* component flags mask */
753 title_size = atom.size - 24;
754 if (title_size > 0) {
755 if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
756 return AVERROR_INVALIDDATA;
757 title_str = av_malloc(title_size + 1); /* Add null terminator */
759 return AVERROR(ENOMEM);
761 ret = ffio_read_size(pb, title_str, title_size);
763 av_freep(&title_str);
766 title_str[title_size] = 0;
768 int off = (!c->isom && title_str[0] == title_size - 1);
769 // flag added so as to not set stream handler name if already set from mdia->hdlr
770 av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
772 av_freep(&title_str);
778 static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
780 return ff_mov_read_esds(c->fc, pb);
783 static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
786 enum AVAudioServiceType *ast;
787 int ac3info, acmod, lfeon, bsmod;
789 if (c->fc->nb_streams < 1)
791 st = c->fc->streams[c->fc->nb_streams-1];
793 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
796 return AVERROR(ENOMEM);
798 ac3info = avio_rb24(pb);
799 bsmod = (ac3info >> 14) & 0x7;
800 acmod = (ac3info >> 11) & 0x7;
801 lfeon = (ac3info >> 10) & 0x1;
802 st->codecpar->channels = ((int[]){2,1,2,3,3,4,4,5})[acmod] + lfeon;
803 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
805 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
807 if (st->codecpar->channels > 1 && bsmod == 0x7)
808 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
810 #if FF_API_LAVF_AVCTX
811 FF_DISABLE_DEPRECATION_WARNINGS
812 st->codec->audio_service_type = *ast;
813 FF_ENABLE_DEPRECATION_WARNINGS
819 static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
822 enum AVAudioServiceType *ast;
823 int eac3info, acmod, lfeon, bsmod;
825 if (c->fc->nb_streams < 1)
827 st = c->fc->streams[c->fc->nb_streams-1];
829 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
832 return AVERROR(ENOMEM);
834 /* No need to parse fields for additional independent substreams and its
835 * associated dependent substreams since libavcodec's E-AC-3 decoder
836 * does not support them yet. */
837 avio_rb16(pb); /* data_rate and num_ind_sub */
838 eac3info = avio_rb24(pb);
839 bsmod = (eac3info >> 12) & 0x1f;
840 acmod = (eac3info >> 9) & 0x7;
841 lfeon = (eac3info >> 8) & 0x1;
842 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
844 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
845 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
847 if (st->codecpar->channels > 1 && bsmod == 0x7)
848 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
850 #if FF_API_LAVF_AVCTX
851 FF_DISABLE_DEPRECATION_WARNINGS
852 st->codec->audio_service_type = *ast;
853 FF_ENABLE_DEPRECATION_WARNINGS
859 static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
861 const uint32_t ddts_size = 20;
864 uint32_t frame_duration_code = 0;
865 uint32_t channel_layout_code = 0;
868 buf = av_malloc(ddts_size + AV_INPUT_BUFFER_PADDING_SIZE);
870 return AVERROR(ENOMEM);
872 if (avio_read(pb, buf, ddts_size) < ddts_size) {
874 return AVERROR_INVALIDDATA;
877 init_get_bits(&gb, buf, 8*ddts_size);
879 if (c->fc->nb_streams < 1) {
883 st = c->fc->streams[c->fc->nb_streams-1];
885 st->codecpar->sample_rate = get_bits_long(&gb, 32);
886 if (st->codecpar->sample_rate <= 0) {
887 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
889 return AVERROR_INVALIDDATA;
891 skip_bits_long(&gb, 32); /* max bitrate */
892 st->codecpar->bit_rate = get_bits_long(&gb, 32);
893 st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
894 frame_duration_code = get_bits(&gb, 2);
895 skip_bits(&gb, 30); /* various fields */
896 channel_layout_code = get_bits(&gb, 16);
898 st->codecpar->frame_size =
899 (frame_duration_code == 0) ? 512 :
900 (frame_duration_code == 1) ? 1024 :
901 (frame_duration_code == 2) ? 2048 :
902 (frame_duration_code == 3) ? 4096 : 0;
904 if (channel_layout_code > 0xff) {
905 av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout");
907 st->codecpar->channel_layout =
908 ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
909 ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
910 ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
911 ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
912 ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
913 ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0);
915 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
921 static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
925 if (c->fc->nb_streams < 1)
927 st = c->fc->streams[c->fc->nb_streams-1];
932 /* skip version and flags */
935 ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
940 static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
945 if (c->fc->nb_streams < 1)
947 st = c->fc->streams[c->fc->nb_streams-1];
949 if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
950 av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
955 static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
957 const int num = avio_rb32(pb);
958 const int den = avio_rb32(pb);
961 if (c->fc->nb_streams < 1)
963 st = c->fc->streams[c->fc->nb_streams-1];
965 if ((st->sample_aspect_ratio.den != 1 || st->sample_aspect_ratio.num) && // default
966 (den != st->sample_aspect_ratio.den || num != st->sample_aspect_ratio.num)) {
967 av_log(c->fc, AV_LOG_WARNING,
968 "sample aspect ratio already set to %d:%d, ignoring 'pasp' atom (%d:%d)\n",
969 st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
971 } else if (den != 0) {
972 av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den,
978 /* this atom contains actual media data */
979 static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
981 if (atom.size == 0) /* wrong one (MP4) */
984 return 0; /* now go for moov */
987 #define DRM_BLOB_SIZE 56
989 static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
991 uint8_t intermediate_key[20];
992 uint8_t intermediate_iv[20];
995 uint8_t file_checksum[20];
996 uint8_t calculated_checksum[20];
1000 uint8_t *activation_bytes = c->activation_bytes;
1001 uint8_t *fixed_key = c->audible_fixed_key;
1005 sha = av_sha_alloc();
1007 return AVERROR(ENOMEM);
1008 c->aes_decrypt = av_aes_alloc();
1009 if (!c->aes_decrypt) {
1010 ret = AVERROR(ENOMEM);
1014 /* drm blob processing */
1015 avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1016 avio_read(pb, input, DRM_BLOB_SIZE);
1017 avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1018 avio_read(pb, file_checksum, 20);
1020 av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == "); // required by external tools
1021 for (i = 0; i < 20; i++)
1022 av_log(c->fc, AV_LOG_INFO, "%02x", file_checksum[i]);
1023 av_log(c->fc, AV_LOG_INFO, "\n");
1025 /* verify activation data */
1026 if (!activation_bytes) {
1027 av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1028 ret = 0; /* allow ffprobe to continue working on .aax files */
1031 if (c->activation_bytes_size != 4) {
1032 av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1033 ret = AVERROR(EINVAL);
1037 /* verify fixed key */
1038 if (c->audible_fixed_key_size != 16) {
1039 av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1040 ret = AVERROR(EINVAL);
1044 /* AAX (and AAX+) key derivation */
1045 av_sha_init(sha, 160);
1046 av_sha_update(sha, fixed_key, 16);
1047 av_sha_update(sha, activation_bytes, 4);
1048 av_sha_final(sha, intermediate_key);
1049 av_sha_init(sha, 160);
1050 av_sha_update(sha, fixed_key, 16);
1051 av_sha_update(sha, intermediate_key, 20);
1052 av_sha_update(sha, activation_bytes, 4);
1053 av_sha_final(sha, intermediate_iv);
1054 av_sha_init(sha, 160);
1055 av_sha_update(sha, intermediate_key, 16);
1056 av_sha_update(sha, intermediate_iv, 16);
1057 av_sha_final(sha, calculated_checksum);
1058 if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1059 av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1060 ret = AVERROR_INVALIDDATA;
1063 av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1064 av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1065 for (i = 0; i < 4; i++) {
1066 // file data (in output) is stored in big-endian mode
1067 if (activation_bytes[i] != output[3 - i]) { // critical error
1068 av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1069 ret = AVERROR_INVALIDDATA;
1073 memcpy(c->file_key, output + 8, 16);
1074 memcpy(input, output + 26, 16);
1075 av_sha_init(sha, 160);
1076 av_sha_update(sha, input, 16);
1077 av_sha_update(sha, c->file_key, 16);
1078 av_sha_update(sha, fixed_key, 16);
1079 av_sha_final(sha, c->file_iv);
1087 // Audible AAX (and AAX+) bytestream decryption
1088 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1091 unsigned char iv[16];
1093 memcpy(iv, c->file_iv, 16); // iv is overwritten
1094 blocks = size >> 4; // trailing bytes are not encrypted!
1095 av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1096 av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1101 /* read major brand, minor version and compatible brands and store them as metadata */
1102 static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1105 int comp_brand_size;
1106 char* comp_brands_str;
1107 uint8_t type[5] = {0};
1108 int ret = ffio_read_size(pb, type, 4);
1112 if (strcmp(type, "qt "))
1114 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1115 av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1116 minor_ver = avio_rb32(pb); /* minor version */
1117 av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1119 comp_brand_size = atom.size - 8;
1120 if (comp_brand_size < 0)
1121 return AVERROR_INVALIDDATA;
1122 comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1123 if (!comp_brands_str)
1124 return AVERROR(ENOMEM);
1126 ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1128 av_freep(&comp_brands_str);
1131 comp_brands_str[comp_brand_size] = 0;
1132 av_dict_set(&c->fc->metadata, "compatible_brands",
1133 comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1138 /* this atom should contain all header atoms */
1139 static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1143 if (c->found_moov) {
1144 av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1145 avio_skip(pb, atom.size);
1149 if ((ret = mov_read_default(c, pb, atom)) < 0)
1151 /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1152 /* so we don't parse the whole file if over a network */
1154 return 0; /* now go for mdat */
1157 static MOVFragmentStreamInfo * get_frag_stream_info(
1158 MOVFragmentIndex *frag_index,
1163 MOVFragmentIndexItem * item;
1165 if (index < 0 || index >= frag_index->nb_items)
1167 item = &frag_index->item[index];
1168 for (i = 0; i < item->nb_stream_info; i++)
1169 if (item->stream_info[i].id == id)
1170 return &item->stream_info[i];
1172 // This shouldn't happen
1176 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1179 MOVFragmentIndexItem * item;
1181 if (frag_index->current < 0 ||
1182 frag_index->current >= frag_index->nb_items)
1185 item = &frag_index->item[frag_index->current];
1186 for (i = 0; i < item->nb_stream_info; i++)
1187 if (item->stream_info[i].id == id) {
1192 // id not found. This shouldn't happen.
1196 static MOVFragmentStreamInfo * get_current_frag_stream_info(
1197 MOVFragmentIndex *frag_index)
1199 MOVFragmentIndexItem *item;
1200 if (frag_index->current < 0 ||
1201 frag_index->current >= frag_index->nb_items)
1204 item = &frag_index->item[frag_index->current];
1205 if (item->current >= 0 && item->current < item->nb_stream_info)
1206 return &item->stream_info[item->current];
1208 // This shouldn't happen
1212 static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
1215 int64_t moof_offset;
1217 // Optimize for appending new entries
1218 if (!frag_index->nb_items ||
1219 frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1220 return frag_index->nb_items;
1223 b = frag_index->nb_items;
1227 moof_offset = frag_index->item[m].moof_offset;
1228 if (moof_offset >= offset)
1230 if (moof_offset <= offset)
1236 static int64_t get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
1238 av_assert0(frag_stream_info);
1239 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1240 return frag_stream_info->sidx_pts;
1241 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1242 return frag_stream_info->first_tfra_pts;
1243 return frag_stream_info->tfdt_dts;
1246 static int64_t get_frag_time(MOVFragmentIndex *frag_index,
1247 int index, int track_id)
1249 MOVFragmentStreamInfo * frag_stream_info;
1253 if (track_id >= 0) {
1254 frag_stream_info = get_frag_stream_info(frag_index, index, track_id);
1255 return frag_stream_info->sidx_pts;
1258 for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1259 frag_stream_info = &frag_index->item[index].stream_info[i];
1260 timestamp = get_stream_info_time(frag_stream_info);
1261 if (timestamp != AV_NOPTS_VALUE)
1264 return AV_NOPTS_VALUE;
1267 static int search_frag_timestamp(MOVFragmentIndex *frag_index,
1268 AVStream *st, int64_t timestamp)
1275 // If the stream is referenced by any sidx, limit the search
1276 // to fragments that referenced this stream in the sidx
1277 MOVStreamContext *sc = st->priv_data;
1283 b = frag_index->nb_items;
1286 m0 = m = (a + b) >> 1;
1289 (frag_time = get_frag_time(frag_index, m, id)) == AV_NOPTS_VALUE)
1292 if (m < b && frag_time <= timestamp)
1301 static int update_frag_index(MOVContext *c, int64_t offset)
1304 MOVFragmentIndexItem * item;
1305 MOVFragmentStreamInfo * frag_stream_info;
1307 // If moof_offset already exists in frag_index, return index to it
1308 index = search_frag_moof_offset(&c->frag_index, offset);
1309 if (index < c->frag_index.nb_items &&
1310 c->frag_index.item[index].moof_offset == offset)
1313 // offset is not yet in frag index.
1314 // Insert new item at index (sorted by moof offset)
1315 item = av_fast_realloc(c->frag_index.item,
1316 &c->frag_index.allocated_size,
1317 (c->frag_index.nb_items + 1) *
1318 sizeof(*c->frag_index.item));
1321 c->frag_index.item = item;
1323 frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1324 sizeof(*item->stream_info));
1325 if (!frag_stream_info)
1328 for (i = 0; i < c->fc->nb_streams; i++) {
1329 // Avoid building frag index if streams lack track id.
1330 if (c->fc->streams[i]->id < 0) {
1331 av_free(frag_stream_info);
1332 return AVERROR_INVALIDDATA;
1335 frag_stream_info[i].id = c->fc->streams[i]->id;
1336 frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1337 frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1338 frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1339 frag_stream_info[i].index_entry = -1;
1340 frag_stream_info[i].encryption_index = NULL;
1343 if (index < c->frag_index.nb_items)
1344 memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1345 (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1347 item = &c->frag_index.item[index];
1348 item->headers_read = 0;
1350 item->nb_stream_info = c->fc->nb_streams;
1351 item->moof_offset = offset;
1352 item->stream_info = frag_stream_info;
1353 c->frag_index.nb_items++;
1358 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1359 int id, int entries)
1362 MOVFragmentStreamInfo * frag_stream_info;
1366 for (i = index; i < frag_index->nb_items; i++) {
1367 frag_stream_info = get_frag_stream_info(frag_index, i, id);
1368 if (frag_stream_info && frag_stream_info->index_entry >= 0)
1369 frag_stream_info->index_entry += entries;
1373 static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1375 // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1376 c->fragment.found_tfhd = 0;
1378 if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1379 c->has_looked_for_mfra = 1;
1380 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1382 av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1384 if ((ret = mov_read_mfra(c, pb)) < 0) {
1385 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1386 "read the mfra (may be a live ismv)\n");
1389 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1390 "seekable, can not look for mfra\n");
1393 c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1394 av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1395 c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1396 return mov_read_default(c, pb, atom);
1399 static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time, void *logctx)
1402 if(time >= 2082844800)
1403 time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1405 if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1406 av_log(logctx, AV_LOG_DEBUG, "creation_time is not representable\n");
1410 avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1414 static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1417 MOVStreamContext *sc;
1419 char language[4] = {0};
1421 int64_t creation_time;
1423 if (c->fc->nb_streams < 1)
1425 st = c->fc->streams[c->fc->nb_streams-1];
1428 if (sc->time_scale) {
1429 av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1430 return AVERROR_INVALIDDATA;
1433 version = avio_r8(pb);
1435 avpriv_request_sample(c->fc, "Version %d", version);
1436 return AVERROR_PATCHWELCOME;
1438 avio_rb24(pb); /* flags */
1440 creation_time = avio_rb64(pb);
1443 creation_time = avio_rb32(pb);
1444 avio_rb32(pb); /* modification time */
1446 mov_metadata_creation_time(&st->metadata, creation_time, c->fc);
1448 sc->time_scale = avio_rb32(pb);
1449 if (sc->time_scale <= 0) {
1450 av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1453 st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1455 lang = avio_rb16(pb); /* language */
1456 if (ff_mov_lang_to_iso639(lang, language))
1457 av_dict_set(&st->metadata, "language", language, 0);
1458 avio_rb16(pb); /* quality */
1463 static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1466 int64_t creation_time;
1467 int version = avio_r8(pb); /* version */
1468 avio_rb24(pb); /* flags */
1471 creation_time = avio_rb64(pb);
1474 creation_time = avio_rb32(pb);
1475 avio_rb32(pb); /* modification time */
1477 mov_metadata_creation_time(&c->fc->metadata, creation_time, c->fc);
1478 c->time_scale = avio_rb32(pb); /* time scale */
1479 if (c->time_scale <= 0) {
1480 av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1483 av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1485 c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1486 // set the AVCodecContext duration because the duration of individual tracks
1487 // may be inaccurate
1488 if (c->time_scale > 0 && !c->trex_data)
1489 c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale);
1490 avio_rb32(pb); /* preferred scale */
1492 avio_rb16(pb); /* preferred volume */
1494 avio_skip(pb, 10); /* reserved */
1496 /* movie display matrix, store it in main context and use it later on */
1497 for (i = 0; i < 3; i++) {
1498 c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1499 c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1500 c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1503 avio_rb32(pb); /* preview time */
1504 avio_rb32(pb); /* preview duration */
1505 avio_rb32(pb); /* poster time */
1506 avio_rb32(pb); /* selection time */
1507 avio_rb32(pb); /* selection duration */
1508 avio_rb32(pb); /* current time */
1509 avio_rb32(pb); /* next track ID */
1514 static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1519 if (c->fc->nb_streams < 1)
1521 st = c->fc->streams[c->fc->nb_streams-1];
1523 little_endian = avio_rb16(pb) & 0xFF;
1524 av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1525 if (little_endian == 1) {
1526 switch (st->codecpar->codec_id) {
1527 case AV_CODEC_ID_PCM_S24BE:
1528 st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE;
1530 case AV_CODEC_ID_PCM_S32BE:
1531 st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE;
1533 case AV_CODEC_ID_PCM_F32BE:
1534 st->codecpar->codec_id = AV_CODEC_ID_PCM_F32LE;
1536 case AV_CODEC_ID_PCM_F64BE:
1537 st->codecpar->codec_id = AV_CODEC_ID_PCM_F64LE;
1546 static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1549 uint8_t *icc_profile;
1550 char color_parameter_type[5] = { 0 };
1551 uint16_t color_primaries, color_trc, color_matrix;
1554 if (c->fc->nb_streams < 1)
1556 st = c->fc->streams[c->fc->nb_streams - 1];
1558 ret = ffio_read_size(pb, color_parameter_type, 4);
1561 if (strncmp(color_parameter_type, "nclx", 4) &&
1562 strncmp(color_parameter_type, "nclc", 4) &&
1563 strncmp(color_parameter_type, "prof", 4)) {
1564 av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
1565 color_parameter_type);
1569 if (!strncmp(color_parameter_type, "prof", 4)) {
1570 icc_profile = av_stream_new_side_data(st, AV_PKT_DATA_ICC_PROFILE, atom.size - 4);
1572 return AVERROR(ENOMEM);
1573 ret = ffio_read_size(pb, icc_profile, atom.size - 4);
1578 color_primaries = avio_rb16(pb);
1579 color_trc = avio_rb16(pb);
1580 color_matrix = avio_rb16(pb);
1582 av_log(c->fc, AV_LOG_TRACE,
1583 "%s: pri %d trc %d matrix %d",
1584 color_parameter_type, color_primaries, color_trc, color_matrix);
1586 if (!strncmp(color_parameter_type, "nclx", 4)) {
1587 uint8_t color_range = avio_r8(pb) >> 7;
1588 av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
1590 st->codecpar->color_range = AVCOL_RANGE_JPEG;
1592 st->codecpar->color_range = AVCOL_RANGE_MPEG;
1595 if (!av_color_primaries_name(color_primaries))
1596 color_primaries = AVCOL_PRI_UNSPECIFIED;
1597 if (!av_color_transfer_name(color_trc))
1598 color_trc = AVCOL_TRC_UNSPECIFIED;
1599 if (!av_color_space_name(color_matrix))
1600 color_matrix = AVCOL_SPC_UNSPECIFIED;
1602 st->codecpar->color_primaries = color_primaries;
1603 st->codecpar->color_trc = color_trc;
1604 st->codecpar->color_space = color_matrix;
1605 av_log(c->fc, AV_LOG_TRACE, "\n");
1610 static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1613 unsigned mov_field_order;
1614 enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
1616 if (c->fc->nb_streams < 1) // will happen with jp2 files
1618 st = c->fc->streams[c->fc->nb_streams-1];
1620 return AVERROR_INVALIDDATA;
1621 mov_field_order = avio_rb16(pb);
1622 if ((mov_field_order & 0xFF00) == 0x0100)
1623 decoded_field_order = AV_FIELD_PROGRESSIVE;
1624 else if ((mov_field_order & 0xFF00) == 0x0200) {
1625 switch (mov_field_order & 0xFF) {
1626 case 0x01: decoded_field_order = AV_FIELD_TT;
1628 case 0x06: decoded_field_order = AV_FIELD_BB;
1630 case 0x09: decoded_field_order = AV_FIELD_TB;
1632 case 0x0E: decoded_field_order = AV_FIELD_BT;
1636 if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
1637 av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
1639 st->codecpar->field_order = decoded_field_order;
1644 static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
1647 uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
1648 if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
1649 return AVERROR_INVALIDDATA;
1650 if ((err = av_reallocp(&par->extradata, size)) < 0) {
1651 par->extradata_size = 0;
1654 par->extradata_size = size - AV_INPUT_BUFFER_PADDING_SIZE;
1658 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
1659 static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1660 AVCodecParameters *par, uint8_t *buf)
1662 int64_t result = atom.size;
1665 AV_WB32(buf , atom.size + 8);
1666 AV_WL32(buf + 4, atom.type);
1667 err = ffio_read_size(pb, buf + 8, atom.size);
1669 par->extradata_size -= atom.size;
1671 } else if (err < atom.size) {
1672 av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
1673 par->extradata_size -= atom.size - err;
1676 memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1680 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
1681 static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1682 enum AVCodecID codec_id)
1685 uint64_t original_size;
1688 if (c->fc->nb_streams < 1) // will happen with jp2 files
1690 st = c->fc->streams[c->fc->nb_streams-1];
1692 if (st->codecpar->codec_id != codec_id)
1693 return 0; /* unexpected codec_id - don't mess with extradata */
1695 original_size = st->codecpar->extradata_size;
1696 err = mov_realloc_extradata(st->codecpar, atom);
1700 err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
1703 return 0; // Note: this is the original behavior to ignore truncation.
1706 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
1707 static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1709 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
1712 static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1714 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS);
1717 static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1719 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
1722 static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1724 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
1727 static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1729 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
1731 ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
1735 static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1737 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
1739 if (!ret && c->fc->nb_streams >= 1) {
1740 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1741 if (par->extradata_size >= 40) {
1742 par->height = AV_RB16(&par->extradata[36]);
1743 par->width = AV_RB16(&par->extradata[38]);
1749 static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1751 if (c->fc->nb_streams >= 1) {
1752 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1753 if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
1754 par->codec_id == AV_CODEC_ID_H264 &&
1758 cid = avio_rb16(pb);
1759 /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
1760 if (cid == 0xd4d || cid == 0xd4e)
1763 } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
1764 par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
1765 par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
1769 num = avio_rb32(pb);
1770 den = avio_rb32(pb);
1771 if (num <= 0 || den <= 0)
1773 switch (avio_rb32(pb)) {
1775 if (den >= INT_MAX / 2)
1779 c->fc->streams[c->fc->nb_streams-1]->display_aspect_ratio.num = num;
1780 c->fc->streams[c->fc->nb_streams-1]->display_aspect_ratio.den = den;
1787 return mov_read_avid(c, pb, atom);
1790 static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1794 uint64_t original_size;
1795 if (c->fc->nb_streams >= 1) {
1796 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1797 if (par->codec_id == AV_CODEC_ID_H264)
1799 if (atom.size == 16) {
1800 original_size = par->extradata_size;
1801 ret = mov_realloc_extradata(par, atom);
1803 length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
1804 if (length == atom.size) {
1805 const uint8_t range_value = par->extradata[original_size + 19];
1806 switch (range_value) {
1808 par->color_range = AVCOL_RANGE_MPEG;
1811 par->color_range = AVCOL_RANGE_JPEG;
1814 av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
1817 ff_dlog(c->fc, "color_range: %d\n", par->color_range);
1819 /* For some reason the whole atom was not added to the extradata */
1820 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
1823 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
1826 av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
1833 static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1835 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
1838 static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1843 if (c->fc->nb_streams < 1)
1845 st = c->fc->streams[c->fc->nb_streams-1];
1847 if ((uint64_t)atom.size > (1<<30))
1848 return AVERROR_INVALIDDATA;
1850 if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
1851 st->codecpar->codec_id == AV_CODEC_ID_QDMC ||
1852 st->codecpar->codec_id == AV_CODEC_ID_SPEEX) {
1853 // pass all frma atom to codec, needed at least for QDMC and QDM2
1854 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1857 } else if (atom.size > 8) { /* to read frma, esds atoms */
1858 if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
1860 ret = ffio_ensure_seekback(pb, 8);
1863 buffer = avio_rb64(pb);
1865 if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
1866 && buffer >> 32 <= atom.size
1867 && buffer >> 32 >= 8) {
1870 } else if (!st->codecpar->extradata_size) {
1871 #define ALAC_EXTRADATA_SIZE 36
1872 st->codecpar->extradata = av_mallocz(ALAC_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
1873 if (!st->codecpar->extradata)
1874 return AVERROR(ENOMEM);
1875 st->codecpar->extradata_size = ALAC_EXTRADATA_SIZE;
1876 AV_WB32(st->codecpar->extradata , ALAC_EXTRADATA_SIZE);
1877 AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
1878 AV_WB64(st->codecpar->extradata + 12, buffer);
1879 avio_read(pb, st->codecpar->extradata + 20, 16);
1880 avio_skip(pb, atom.size - 24);
1884 if ((ret = mov_read_default(c, pb, atom)) < 0)
1887 avio_skip(pb, atom.size);
1892 * This function reads atom content and puts data in extradata without tag
1893 * nor size unlike mov_read_extradata.
1895 static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1900 if (c->fc->nb_streams < 1)
1902 st = c->fc->streams[c->fc->nb_streams-1];
1904 if ((uint64_t)atom.size > (1<<30))
1905 return AVERROR_INVALIDDATA;
1907 if (atom.size >= 10) {
1908 // Broken files created by legacy versions of libavformat will
1909 // wrap a whole fiel atom inside of a glbl atom.
1910 unsigned size = avio_rb32(pb);
1911 unsigned type = avio_rl32(pb);
1912 avio_seek(pb, -8, SEEK_CUR);
1913 if (type == MKTAG('f','i','e','l') && size == atom.size)
1914 return mov_read_default(c, pb, atom);
1916 if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
1917 av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
1920 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1923 if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
1924 /* HEVC-based Dolby Vision derived from hvc1.
1925 Happens to match with an identifier
1926 previously utilized for DV. Thus, if we have
1927 the hvcC extradata box available as specified,
1928 set codec to HEVC */
1929 st->codecpar->codec_id = AV_CODEC_ID_HEVC;
1934 static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1937 uint8_t profile_level;
1940 if (c->fc->nb_streams < 1)
1942 st = c->fc->streams[c->fc->nb_streams-1];
1944 if (atom.size >= (1<<28) || atom.size < 7)
1945 return AVERROR_INVALIDDATA;
1947 profile_level = avio_r8(pb);
1948 if ((profile_level & 0xf0) != 0xc0)
1951 avio_seek(pb, 6, SEEK_CUR);
1952 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
1960 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
1961 * but can have extradata appended at the end after the 40 bytes belonging
1964 static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1969 if (c->fc->nb_streams < 1)
1971 if (atom.size <= 40)
1973 st = c->fc->streams[c->fc->nb_streams-1];
1975 if ((uint64_t)atom.size > (1<<30))
1976 return AVERROR_INVALIDDATA;
1979 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
1986 static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1989 MOVStreamContext *sc;
1990 unsigned int i, entries;
1992 if (c->trak_index < 0) {
1993 av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
1996 if (c->fc->nb_streams < 1)
1998 st = c->fc->streams[c->fc->nb_streams-1];
2001 avio_r8(pb); /* version */
2002 avio_rb24(pb); /* flags */
2004 entries = avio_rb32(pb);
2009 if (sc->chunk_offsets)
2010 av_log(c->fc, AV_LOG_WARNING, "Duplicated STCO atom\n");
2011 av_free(sc->chunk_offsets);
2012 sc->chunk_count = 0;
2013 sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2014 if (!sc->chunk_offsets)
2015 return AVERROR(ENOMEM);
2016 sc->chunk_count = entries;
2018 if (atom.type == MKTAG('s','t','c','o'))
2019 for (i = 0; i < entries && !pb->eof_reached; i++)
2020 sc->chunk_offsets[i] = avio_rb32(pb);
2021 else if (atom.type == MKTAG('c','o','6','4'))
2022 for (i = 0; i < entries && !pb->eof_reached; i++)
2023 sc->chunk_offsets[i] = avio_rb64(pb);
2025 return AVERROR_INVALIDDATA;
2027 sc->chunk_count = i;
2029 if (pb->eof_reached) {
2030 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2037 static int mov_codec_id(AVStream *st, uint32_t format)
2039 int id = ff_codec_get_id(ff_codec_movaudio_tags, format);
2042 ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2043 (format & 0xFFFF) == 'T' + ('S' << 8)))
2044 id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format) & 0xFFFF);
2046 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2047 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2048 } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2049 /* skip old ASF MPEG-4 tag */
2050 format && format != MKTAG('m','p','4','s')) {
2051 id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2053 id = ff_codec_get_id(ff_codec_bmp_tags, format);
2055 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
2056 else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2057 (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE &&
2058 st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2059 id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
2061 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
2063 id = ff_codec_get_id(ff_codec_movdata_tags, format);
2067 st->codecpar->codec_tag = format;
2072 static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
2073 AVStream *st, MOVStreamContext *sc)
2075 uint8_t codec_name[32] = { 0 };
2079 /* The first 16 bytes of the video sample description are already
2080 * read in ff_mov_read_stsd_entries() */
2081 stsd_start = avio_tell(pb) - 16;
2083 avio_rb16(pb); /* version */
2084 avio_rb16(pb); /* revision level */
2085 avio_rb32(pb); /* vendor */
2086 avio_rb32(pb); /* temporal quality */
2087 avio_rb32(pb); /* spatial quality */
2089 st->codecpar->width = avio_rb16(pb); /* width */
2090 st->codecpar->height = avio_rb16(pb); /* height */
2092 avio_rb32(pb); /* horiz resolution */
2093 avio_rb32(pb); /* vert resolution */
2094 avio_rb32(pb); /* data size, always 0 */
2095 avio_rb16(pb); /* frames per samples */
2097 len = avio_r8(pb); /* codec name, pascal string */
2100 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2102 avio_skip(pb, 31 - len);
2105 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2107 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2108 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2109 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2110 st->codecpar->width &= ~1;
2111 st->codecpar->height &= ~1;
2113 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2114 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2115 !strncmp(codec_name, "Sorenson H263", 13))
2116 st->codecpar->codec_id = AV_CODEC_ID_FLV1;
2118 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2120 avio_seek(pb, stsd_start, SEEK_SET);
2122 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2123 st->codecpar->bits_per_coded_sample &= 0x1F;
2124 sc->has_palette = 1;
2128 static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
2129 AVStream *st, MOVStreamContext *sc)
2131 int bits_per_sample, flags;
2132 uint16_t version = avio_rb16(pb);
2133 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2135 avio_rb16(pb); /* revision level */
2136 avio_rb32(pb); /* vendor */
2138 st->codecpar->channels = avio_rb16(pb); /* channel count */
2139 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2140 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", st->codecpar->channels);
2142 sc->audio_cid = avio_rb16(pb);
2143 avio_rb16(pb); /* packet size = 0 */
2145 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2147 // Read QT version 1 fields. In version 0 these do not exist.
2148 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2150 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2151 (sc->stsd_version == 0 && version > 0)) {
2153 sc->samples_per_frame = avio_rb32(pb);
2154 avio_rb32(pb); /* bytes per packet */
2155 sc->bytes_per_frame = avio_rb32(pb);
2156 avio_rb32(pb); /* bytes per sample */
2157 } else if (version == 2) {
2158 avio_rb32(pb); /* sizeof struct only */
2159 st->codecpar->sample_rate = av_int2double(avio_rb64(pb));
2160 st->codecpar->channels = avio_rb32(pb);
2161 avio_rb32(pb); /* always 0x7F000000 */
2162 st->codecpar->bits_per_coded_sample = avio_rb32(pb);
2164 flags = avio_rb32(pb); /* lpcm format specific flag */
2165 sc->bytes_per_frame = avio_rb32(pb);
2166 sc->samples_per_frame = avio_rb32(pb);
2167 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2168 st->codecpar->codec_id =
2169 ff_mov_get_lpcm_codec_id(st->codecpar->bits_per_coded_sample,
2172 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2173 /* can't correctly handle variable sized packet as audio unit */
2174 switch (st->codecpar->codec_id) {
2175 case AV_CODEC_ID_MP2:
2176 case AV_CODEC_ID_MP3:
2177 st->need_parsing = AVSTREAM_PARSE_FULL;
2183 if (sc->format == 0) {
2184 if (st->codecpar->bits_per_coded_sample == 8)
2185 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2186 else if (st->codecpar->bits_per_coded_sample == 16)
2187 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2190 switch (st->codecpar->codec_id) {
2191 case AV_CODEC_ID_PCM_S8:
2192 case AV_CODEC_ID_PCM_U8:
2193 if (st->codecpar->bits_per_coded_sample == 16)
2194 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16BE;
2196 case AV_CODEC_ID_PCM_S16LE:
2197 case AV_CODEC_ID_PCM_S16BE:
2198 if (st->codecpar->bits_per_coded_sample == 8)
2199 st->codecpar->codec_id = AV_CODEC_ID_PCM_S8;
2200 else if (st->codecpar->bits_per_coded_sample == 24)
2201 st->codecpar->codec_id =
2202 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2203 AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
2204 else if (st->codecpar->bits_per_coded_sample == 32)
2205 st->codecpar->codec_id =
2206 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2207 AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
2209 /* set values for old format before stsd version 1 appeared */
2210 case AV_CODEC_ID_MACE3:
2211 sc->samples_per_frame = 6;
2212 sc->bytes_per_frame = 2 * st->codecpar->channels;
2214 case AV_CODEC_ID_MACE6:
2215 sc->samples_per_frame = 6;
2216 sc->bytes_per_frame = 1 * st->codecpar->channels;
2218 case AV_CODEC_ID_ADPCM_IMA_QT:
2219 sc->samples_per_frame = 64;
2220 sc->bytes_per_frame = 34 * st->codecpar->channels;
2222 case AV_CODEC_ID_GSM:
2223 sc->samples_per_frame = 160;
2224 sc->bytes_per_frame = 33;
2230 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2231 if (bits_per_sample) {
2232 st->codecpar->bits_per_coded_sample = bits_per_sample;
2233 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->channels;
2237 static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
2238 AVStream *st, MOVStreamContext *sc,
2241 // ttxt stsd contains display flags, justification, background
2242 // color, fonts, and default styles, so fake an atom to read it
2243 MOVAtom fake_atom = { .size = size };
2244 // mp4s contains a regular esds atom
2245 if (st->codecpar->codec_tag != AV_RL32("mp4s"))
2246 mov_read_glbl(c, pb, fake_atom);
2247 st->codecpar->width = sc->width;
2248 st->codecpar->height = sc->height;
2251 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2256 y = (ycbcr >> 16) & 0xFF;
2257 cr = (ycbcr >> 8) & 0xFF;
2260 b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
2261 g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
2262 r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
2264 return (r << 16) | (g << 8) | b;
2267 static int mov_rewrite_dvd_sub_extradata(AVStream *st)
2269 char buf[256] = {0};
2270 uint8_t *src = st->codecpar->extradata;
2273 if (st->codecpar->extradata_size != 64)
2276 if (st->codecpar->width > 0 && st->codecpar->height > 0)
2277 snprintf(buf, sizeof(buf), "size: %dx%d\n",
2278 st->codecpar->width, st->codecpar->height);
2279 av_strlcat(buf, "palette: ", sizeof(buf));
2281 for (i = 0; i < 16; i++) {
2282 uint32_t yuv = AV_RB32(src + i * 4);
2283 uint32_t rgba = yuv_to_rgba(yuv);
2285 av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2288 if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2291 ret = ff_alloc_extradata(st->codecpar, strlen(buf));
2294 memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2299 static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
2300 AVStream *st, MOVStreamContext *sc,
2305 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2306 if ((int)size != size)
2307 return AVERROR(ENOMEM);
2309 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2313 MOVStreamContext *tmcd_ctx = st->priv_data;
2315 val = AV_RB32(st->codecpar->extradata + 4);
2316 tmcd_ctx->tmcd_flags = val;
2317 st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2318 st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2319 #if FF_API_LAVF_AVCTX
2320 FF_DISABLE_DEPRECATION_WARNINGS
2321 st->codec->time_base = av_inv_q(st->avg_frame_rate);
2322 FF_ENABLE_DEPRECATION_WARNINGS
2324 /* adjust for per frame dur in counter mode */
2325 if (tmcd_ctx->tmcd_flags & 0x0008) {
2326 int timescale = AV_RB32(st->codecpar->extradata + 8);
2327 int framedur = AV_RB32(st->codecpar->extradata + 12);
2328 st->avg_frame_rate.num *= timescale;
2329 st->avg_frame_rate.den *= framedur;
2330 #if FF_API_LAVF_AVCTX
2331 FF_DISABLE_DEPRECATION_WARNINGS
2332 st->codec->time_base.den *= timescale;
2333 st->codec->time_base.num *= framedur;
2334 FF_ENABLE_DEPRECATION_WARNINGS
2338 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2339 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2340 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2341 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2342 if (str_size > 0 && size >= (int)str_size + 26) {
2343 char *reel_name = av_malloc(str_size + 1);
2345 return AVERROR(ENOMEM);
2346 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2347 reel_name[str_size] = 0; /* Add null terminator */
2348 /* don't add reel_name if emtpy string */
2349 if (*reel_name == 0) {
2352 av_dict_set(&st->metadata, "reel_name", reel_name, AV_DICT_DONT_STRDUP_VAL);
2359 /* other codec type, just skip (rtp, mp4s ...) */
2360 avio_skip(pb, size);
2365 static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
2366 AVStream *st, MOVStreamContext *sc)
2368 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2369 !st->codecpar->sample_rate && sc->time_scale > 1)
2370 st->codecpar->sample_rate = sc->time_scale;
2372 /* special codec parameters handling */
2373 switch (st->codecpar->codec_id) {
2374 #if CONFIG_DV_DEMUXER
2375 case AV_CODEC_ID_DVAUDIO:
2376 c->dv_fctx = avformat_alloc_context();
2378 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2379 return AVERROR(ENOMEM);
2381 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2383 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2384 return AVERROR(ENOMEM);
2386 sc->dv_audio_container = 1;
2387 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
2390 /* no ifdef since parameters are always those */
2391 case AV_CODEC_ID_QCELP:
2392 st->codecpar->channels = 1;
2393 // force sample rate for qcelp when not stored in mov
2394 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2395 st->codecpar->sample_rate = 8000;
2396 // FIXME: Why is the following needed for some files?
2397 sc->samples_per_frame = 160;
2398 if (!sc->bytes_per_frame)
2399 sc->bytes_per_frame = 35;
2401 case AV_CODEC_ID_AMR_NB:
2402 st->codecpar->channels = 1;
2403 /* force sample rate for amr, stsd in 3gp does not store sample rate */
2404 st->codecpar->sample_rate = 8000;
2406 case AV_CODEC_ID_AMR_WB:
2407 st->codecpar->channels = 1;
2408 st->codecpar->sample_rate = 16000;
2410 case AV_CODEC_ID_MP2:
2411 case AV_CODEC_ID_MP3:
2412 /* force type after stsd for m1a hdlr */
2413 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2415 case AV_CODEC_ID_GSM:
2416 case AV_CODEC_ID_ADPCM_MS:
2417 case AV_CODEC_ID_ADPCM_IMA_WAV:
2418 case AV_CODEC_ID_ILBC:
2419 case AV_CODEC_ID_MACE3:
2420 case AV_CODEC_ID_MACE6:
2421 case AV_CODEC_ID_QDM2:
2422 st->codecpar->block_align = sc->bytes_per_frame;
2424 case AV_CODEC_ID_ALAC:
2425 if (st->codecpar->extradata_size == 36) {
2426 st->codecpar->channels = AV_RB8 (st->codecpar->extradata + 21);
2427 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2430 case AV_CODEC_ID_AC3:
2431 case AV_CODEC_ID_EAC3:
2432 case AV_CODEC_ID_MPEG1VIDEO:
2433 case AV_CODEC_ID_VC1:
2434 case AV_CODEC_ID_VP8:
2435 case AV_CODEC_ID_VP9:
2436 st->need_parsing = AVSTREAM_PARSE_FULL;
2444 static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
2445 int codec_tag, int format,
2448 int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2451 (codec_tag != format &&
2452 // AVID 1:1 samples with differing data format and codec tag exist
2453 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
2454 // prores is allowed to have differing data format and codec tag
2455 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
2457 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
2458 (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id
2459 : codec_tag != MKTAG('j','p','e','g')))) {
2460 /* Multiple fourcc, we skip JPEG. This is not correct, we should
2461 * export it as a separate AVStream but this needs a few changes
2462 * in the MOV demuxer, patch welcome. */
2464 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
2465 avio_skip(pb, size);
2472 int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
2475 MOVStreamContext *sc;
2476 int pseudo_stream_id;
2478 av_assert0 (c->fc->nb_streams >= 1);
2479 st = c->fc->streams[c->fc->nb_streams-1];
2482 for (pseudo_stream_id = 0;
2483 pseudo_stream_id < entries && !pb->eof_reached;
2484 pseudo_stream_id++) {
2485 //Parsing Sample description table
2487 int ret, dref_id = 1;
2488 MOVAtom a = { AV_RL32("stsd") };
2489 int64_t start_pos = avio_tell(pb);
2490 int64_t size = avio_rb32(pb); /* size */
2491 uint32_t format = avio_rl32(pb); /* data format */
2494 avio_rb32(pb); /* reserved */
2495 avio_rb16(pb); /* reserved */
2496 dref_id = avio_rb16(pb);
2497 } else if (size <= 7) {
2498 av_log(c->fc, AV_LOG_ERROR,
2499 "invalid size %"PRId64" in stsd\n", size);
2500 return AVERROR_INVALIDDATA;
2503 if (mov_skip_multiple_stsd(c, pb, st->codecpar->codec_tag, format,
2504 size - (avio_tell(pb) - start_pos))) {
2509 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
2510 sc->dref_id= dref_id;
2511 sc->format = format;
2513 id = mov_codec_id(st, format);
2515 av_log(c->fc, AV_LOG_TRACE,
2516 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
2517 av_fourcc2str(format), st->codecpar->codec_type);
2519 st->codecpar->codec_id = id;
2520 if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) {
2521 mov_parse_stsd_video(c, pb, st, sc);
2522 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
2523 mov_parse_stsd_audio(c, pb, st, sc);
2524 if (st->codecpar->sample_rate < 0) {
2525 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
2526 return AVERROR_INVALIDDATA;
2528 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
2529 mov_parse_stsd_subtitle(c, pb, st, sc,
2530 size - (avio_tell(pb) - start_pos));
2532 ret = mov_parse_stsd_data(c, pb, st, sc,
2533 size - (avio_tell(pb) - start_pos));
2537 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
2538 a.size = size - (avio_tell(pb) - start_pos);
2540 if ((ret = mov_read_default(c, pb, a)) < 0)
2542 } else if (a.size > 0)
2543 avio_skip(pb, a.size);
2545 if (sc->extradata && st->codecpar->extradata) {
2546 int extra_size = st->codecpar->extradata_size;
2548 /* Move the current stream extradata to the stream context one. */
2549 sc->extradata_size[pseudo_stream_id] = extra_size;
2550 sc->extradata[pseudo_stream_id] = av_malloc(extra_size + AV_INPUT_BUFFER_PADDING_SIZE);
2551 if (!sc->extradata[pseudo_stream_id])
2552 return AVERROR(ENOMEM);
2553 memcpy(sc->extradata[pseudo_stream_id], st->codecpar->extradata, extra_size);
2554 av_freep(&st->codecpar->extradata);
2555 st->codecpar->extradata_size = 0;
2560 if (pb->eof_reached) {
2561 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
2568 static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2571 MOVStreamContext *sc;
2574 if (c->fc->nb_streams < 1)
2576 st = c->fc->streams[c->fc->nb_streams - 1];
2579 sc->stsd_version = avio_r8(pb);
2580 avio_rb24(pb); /* flags */
2581 entries = avio_rb32(pb);
2583 /* Each entry contains a size (4 bytes) and format (4 bytes). */
2584 if (entries <= 0 || entries > atom.size / 8) {
2585 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
2586 return AVERROR_INVALIDDATA;
2589 if (sc->extradata) {
2590 av_log(c->fc, AV_LOG_ERROR,
2591 "Duplicate stsd found in this track.\n");
2592 return AVERROR_INVALIDDATA;
2595 /* Prepare space for hosting multiple extradata. */
2596 sc->extradata = av_mallocz_array(entries, sizeof(*sc->extradata));
2598 return AVERROR(ENOMEM);
2600 sc->extradata_size = av_mallocz_array(entries, sizeof(*sc->extradata_size));
2601 if (!sc->extradata_size) {
2602 ret = AVERROR(ENOMEM);
2606 ret = ff_mov_read_stsd_entries(c, pb, entries);
2610 /* Restore back the primary extradata. */
2611 av_freep(&st->codecpar->extradata);
2612 st->codecpar->extradata_size = sc->extradata_size[0];
2613 if (sc->extradata_size[0]) {
2614 st->codecpar->extradata = av_mallocz(sc->extradata_size[0] + AV_INPUT_BUFFER_PADDING_SIZE);
2615 if (!st->codecpar->extradata)
2616 return AVERROR(ENOMEM);
2617 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
2620 return mov_finalize_stsd_codec(c, pb, st, sc);
2622 if (sc->extradata) {
2624 for (j = 0; j < sc->stsd_count; j++)
2625 av_freep(&sc->extradata[j]);
2628 av_freep(&sc->extradata);
2629 av_freep(&sc->extradata_size);
2633 static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2636 MOVStreamContext *sc;
2637 unsigned int i, entries;
2639 if (c->fc->nb_streams < 1)
2641 st = c->fc->streams[c->fc->nb_streams-1];
2644 avio_r8(pb); /* version */
2645 avio_rb24(pb); /* flags */
2647 entries = avio_rb32(pb);
2648 if ((uint64_t)entries * 12 + 4 > atom.size)
2649 return AVERROR_INVALIDDATA;
2651 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
2656 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSC atom\n");
2657 av_free(sc->stsc_data);
2659 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
2661 return AVERROR(ENOMEM);
2663 for (i = 0; i < entries && !pb->eof_reached; i++) {
2664 sc->stsc_data[i].first = avio_rb32(pb);
2665 sc->stsc_data[i].count = avio_rb32(pb);
2666 sc->stsc_data[i].id = avio_rb32(pb);
2670 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
2671 int64_t first_min = i + 1;
2672 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
2673 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
2674 sc->stsc_data[i].first < first_min ||
2675 sc->stsc_data[i].count < 1 ||
2676 sc->stsc_data[i].id < 1) {
2677 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);
2678 if (i+1 >= sc->stsc_count) {
2679 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
2680 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
2681 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
2682 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
2683 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
2686 av_assert0(sc->stsc_data[i+1].first >= 2);
2687 // We replace this entry by the next valid
2688 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
2689 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
2690 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
2694 if (pb->eof_reached) {
2695 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
2702 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
2704 return index < count - 1;
2707 /* Compute the samples value for the stsc entry at the given index. */
2708 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
2712 if (mov_stsc_index_valid(index, sc->stsc_count))
2713 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
2715 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
2716 av_assert0(sc->stsc_data[index].first <= sc->chunk_count);
2717 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
2720 return sc->stsc_data[index].count * (int64_t)chunk_count;
2723 static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2726 MOVStreamContext *sc;
2727 unsigned i, entries;
2729 if (c->fc->nb_streams < 1)
2731 st = c->fc->streams[c->fc->nb_streams-1];
2734 avio_rb32(pb); // version + flags
2736 entries = avio_rb32(pb);
2738 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
2739 av_free(sc->stps_data);
2741 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
2743 return AVERROR(ENOMEM);
2745 for (i = 0; i < entries && !pb->eof_reached; i++) {
2746 sc->stps_data[i] = avio_rb32(pb);
2751 if (pb->eof_reached) {
2752 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
2759 static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2762 MOVStreamContext *sc;
2763 unsigned int i, entries;
2765 if (c->fc->nb_streams < 1)
2767 st = c->fc->streams[c->fc->nb_streams-1];
2770 avio_r8(pb); /* version */
2771 avio_rb24(pb); /* flags */
2773 entries = avio_rb32(pb);
2775 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
2779 sc->keyframe_absent = 1;
2780 if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
2781 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2785 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
2786 if (entries >= UINT_MAX / sizeof(int))
2787 return AVERROR_INVALIDDATA;
2788 av_freep(&sc->keyframes);
2789 sc->keyframe_count = 0;
2790 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
2792 return AVERROR(ENOMEM);
2794 for (i = 0; i < entries && !pb->eof_reached; i++) {
2795 sc->keyframes[i] = avio_rb32(pb);
2798 sc->keyframe_count = i;
2800 if (pb->eof_reached) {
2801 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
2808 static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2811 MOVStreamContext *sc;
2812 unsigned int i, entries, sample_size, field_size, num_bytes;
2817 if (c->fc->nb_streams < 1)
2819 st = c->fc->streams[c->fc->nb_streams-1];
2822 avio_r8(pb); /* version */
2823 avio_rb24(pb); /* flags */
2825 if (atom.type == MKTAG('s','t','s','z')) {
2826 sample_size = avio_rb32(pb);
2827 if (!sc->sample_size) /* do not overwrite value computed in stsd */
2828 sc->sample_size = sample_size;
2829 sc->stsz_sample_size = sample_size;
2833 avio_rb24(pb); /* reserved */
2834 field_size = avio_r8(pb);
2836 entries = avio_rb32(pb);
2838 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
2840 sc->sample_count = entries;
2844 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
2845 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
2846 return AVERROR_INVALIDDATA;
2851 if (entries >= (UINT_MAX - 4) / field_size)
2852 return AVERROR_INVALIDDATA;
2853 if (sc->sample_sizes)
2854 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
2855 av_free(sc->sample_sizes);
2856 sc->sample_count = 0;
2857 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
2858 if (!sc->sample_sizes)
2859 return AVERROR(ENOMEM);
2861 num_bytes = (entries*field_size+4)>>3;
2863 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
2865 av_freep(&sc->sample_sizes);
2866 return AVERROR(ENOMEM);
2869 ret = ffio_read_size(pb, buf, num_bytes);
2871 av_freep(&sc->sample_sizes);
2873 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
2877 init_get_bits(&gb, buf, 8*num_bytes);
2879 for (i = 0; i < entries && !pb->eof_reached; i++) {
2880 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
2881 sc->data_size += sc->sample_sizes[i];
2884 sc->sample_count = i;
2888 if (pb->eof_reached) {
2889 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSZ atom\n");
2896 static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2899 MOVStreamContext *sc;
2900 unsigned int i, entries, alloc_size = 0;
2902 int64_t total_sample_count=0;
2904 if (c->fc->nb_streams < 1)
2906 st = c->fc->streams[c->fc->nb_streams-1];
2909 avio_r8(pb); /* version */
2910 avio_rb24(pb); /* flags */
2911 entries = avio_rb32(pb);
2913 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
2914 c->fc->nb_streams-1, entries);
2917 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
2918 av_freep(&sc->stts_data);
2920 if (entries >= INT_MAX / sizeof(*sc->stts_data))
2921 return AVERROR(ENOMEM);
2923 for (i = 0; i < entries && !pb->eof_reached; i++) {
2924 int sample_duration;
2925 unsigned int sample_count;
2926 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
2927 MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
2928 min_entries * sizeof(*sc->stts_data));
2930 av_freep(&sc->stts_data);
2932 return AVERROR(ENOMEM);
2934 sc->stts_count = min_entries;
2935 sc->stts_data = stts_data;
2937 sample_count=avio_rb32(pb);
2938 sample_duration = avio_rb32(pb);
2940 sc->stts_data[i].count= sample_count;
2941 sc->stts_data[i].duration= sample_duration;
2943 av_log(c->fc, AV_LOG_TRACE, "sample_count=%d, sample_duration=%d\n",
2944 sample_count, sample_duration);
2946 duration+=(int64_t)sample_duration*(uint64_t)sample_count;
2947 total_sample_count+=sample_count;
2953 duration <= INT64_MAX - sc->duration_for_fps &&
2954 total_sample_count <= INT_MAX - sc->nb_frames_for_fps
2956 sc->duration_for_fps += duration;
2957 sc->nb_frames_for_fps += total_sample_count;
2960 if (pb->eof_reached) {
2961 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
2965 st->nb_frames= total_sample_count;
2967 st->duration= FFMIN(st->duration, duration);
2968 sc->track_end = duration;
2972 static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2975 MOVStreamContext *sc;
2978 if (c->fc->nb_streams < 1)
2980 st = c->fc->streams[c->fc->nb_streams - 1];
2983 avio_r8(pb); /* version */
2984 avio_rb24(pb); /* flags */
2985 entries = atom.size - 4;
2987 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
2988 c->fc->nb_streams - 1, entries);
2991 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
2992 av_freep(&sc->sdtp_data);
2995 sc->sdtp_data = av_mallocz(entries);
2997 return AVERROR(ENOMEM);
2999 for (i = 0; i < entries && !pb->eof_reached; i++)
3000 sc->sdtp_data[i] = avio_r8(pb);
3006 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3009 if (duration == INT_MIN) {
3010 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3013 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3017 static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3020 MOVStreamContext *sc;
3021 unsigned int i, entries, ctts_count = 0;
3023 if (c->fc->nb_streams < 1)
3025 st = c->fc->streams[c->fc->nb_streams-1];
3028 avio_r8(pb); /* version */
3029 avio_rb24(pb); /* flags */
3030 entries = avio_rb32(pb);
3032 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3036 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3037 return AVERROR_INVALIDDATA;
3038 av_freep(&sc->ctts_data);
3039 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3041 return AVERROR(ENOMEM);
3043 for (i = 0; i < entries && !pb->eof_reached; i++) {
3044 int count =avio_rb32(pb);
3045 int duration =avio_rb32(pb);
3048 av_log(c->fc, AV_LOG_TRACE,
3049 "ignoring CTTS entry with count=%d duration=%d\n",
3054 add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3057 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3060 if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3061 av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3062 av_freep(&sc->ctts_data);
3068 mov_update_dts_shift(sc, duration, c->fc);
3071 sc->ctts_count = ctts_count;
3073 if (pb->eof_reached) {
3074 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3078 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3083 static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3086 MOVStreamContext *sc;
3087 unsigned int i, entries;
3089 uint32_t grouping_type;
3091 if (c->fc->nb_streams < 1)
3093 st = c->fc->streams[c->fc->nb_streams-1];
3096 version = avio_r8(pb); /* version */
3097 avio_rb24(pb); /* flags */
3098 grouping_type = avio_rl32(pb);
3099 if (grouping_type != MKTAG( 'r','a','p',' '))
3100 return 0; /* only support 'rap ' grouping */
3102 avio_rb32(pb); /* grouping_type_parameter */
3104 entries = avio_rb32(pb);
3108 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP atom\n");
3109 av_free(sc->rap_group);
3110 sc->rap_group_count = 0;
3111 sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group));
3113 return AVERROR(ENOMEM);
3115 for (i = 0; i < entries && !pb->eof_reached; i++) {
3116 sc->rap_group[i].count = avio_rb32(pb); /* sample_count */
3117 sc->rap_group[i].index = avio_rb32(pb); /* group_description_index */
3120 sc->rap_group_count = i;
3122 if (pb->eof_reached) {
3123 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3131 * Get ith edit list entry (media time, duration).
3133 static int get_edit_list_entry(MOVContext *mov,
3134 const MOVStreamContext *msc,
3135 unsigned int edit_list_index,
3136 int64_t *edit_list_media_time,
3137 int64_t *edit_list_duration,
3138 int64_t global_timescale)
3140 if (edit_list_index == msc->elst_count) {
3143 *edit_list_media_time = msc->elst_data[edit_list_index].time;
3144 *edit_list_duration = msc->elst_data[edit_list_index].duration;
3146 /* duration is in global timescale units;convert to msc timescale */
3147 if (global_timescale == 0) {
3148 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3151 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3157 * Find the closest previous frame to the timestamp_pts, in e_old index
3158 * entries. Searching for just any frame / just key frames can be controlled by
3159 * last argument 'flag'.
3160 * Note that if ctts_data is not NULL, we will always search for a key frame
3161 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3162 * return the first frame of the video.
3164 * Here the timestamp_pts is considered to be a presentation timestamp and
3165 * the timestamp of index entries are considered to be decoding timestamps.
3167 * Returns 0 if successful in finding a frame, else returns -1.
3168 * Places the found index corresponding output arg.
3170 * If ctts_old is not NULL, then refines the searched entry by searching
3171 * backwards from the found timestamp, to find the frame with correct PTS.
3173 * Places the found ctts_index and ctts_sample in corresponding output args.
3175 static int find_prev_closest_index(AVStream *st,
3176 AVIndexEntry *e_old,
3180 int64_t timestamp_pts,
3183 int64_t* ctts_index,
3184 int64_t* ctts_sample)
3186 MOVStreamContext *msc = st->priv_data;
3187 AVIndexEntry *e_keep = st->index_entries;
3188 int nb_keep = st->nb_index_entries;
3190 int64_t index_ctts_count;
3194 // If dts_shift > 0, then all the index timestamps will have to be offset by
3195 // at least dts_shift amount to obtain PTS.
3196 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3197 if (msc->dts_shift > 0) {
3198 timestamp_pts -= msc->dts_shift;
3201 st->index_entries = e_old;
3202 st->nb_index_entries = nb_old;
3203 *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3205 // Keep going backwards in the index entries until the timestamp is the same.
3207 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3209 if ((flag & AVSEEK_FLAG_ANY) ||
3210 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3216 // If we have CTTS then refine the search, by searching backwards over PTS
3217 // computed by adding corresponding CTTS durations to index timestamps.
3218 if (ctts_data && *index >= 0) {
3219 av_assert0(ctts_index);
3220 av_assert0(ctts_sample);
3221 // Find out the ctts_index for the found frame.
3224 for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3225 if (*ctts_index < ctts_count) {
3227 if (ctts_data[*ctts_index].count == *ctts_sample) {
3234 while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3235 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3236 // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3237 // compensated by dts_shift above.
3238 if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3239 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3244 if (*ctts_sample == 0) {
3246 if (*ctts_index >= 0)
3247 *ctts_sample = ctts_data[*ctts_index].count - 1;
3254 /* restore AVStream state*/
3255 st->index_entries = e_keep;
3256 st->nb_index_entries = nb_keep;
3257 return *index >= 0 ? 0 : -1;
3261 * Add index entry with the given values, to the end of st->index_entries.
3262 * Returns the new size st->index_entries if successful, else returns -1.
3264 * This function is similar to ff_add_index_entry in libavformat/utils.c
3265 * except that here we are always unconditionally adding an index entry to
3266 * the end, instead of searching the entries list and skipping the add if
3267 * there is an existing entry with the same timestamp.
3268 * This is needed because the mov_fix_index calls this func with the same
3269 * unincremented timestamp for successive discarded frames.
3271 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3272 int size, int distance, int flags)
3274 AVIndexEntry *entries, *ie;
3276 const size_t min_size_needed = (st->nb_index_entries + 1) * sizeof(AVIndexEntry);
3278 // Double the allocation each time, to lower memory fragmentation.
3279 // Another difference from ff_add_index_entry function.
3280 const size_t requested_size =
3281 min_size_needed > st->index_entries_allocated_size ?
3282 FFMAX(min_size_needed, 2 * st->index_entries_allocated_size) :
3285 if((unsigned)st->nb_index_entries + 1 >= UINT_MAX / sizeof(AVIndexEntry))
3288 entries = av_fast_realloc(st->index_entries,
3289 &st->index_entries_allocated_size,
3294 st->index_entries= entries;
3296 index= st->nb_index_entries++;
3297 ie= &entries[index];
3300 ie->timestamp = timestamp;
3301 ie->min_distance= distance;
3308 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3309 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3311 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3312 int64_t* frame_duration_buffer,
3313 int frame_duration_buffer_size) {
3315 av_assert0(end_index >= 0 && end_index <= st->nb_index_entries);
3316 for (i = 0; i < frame_duration_buffer_size; i++) {
3317 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3318 st->index_entries[end_index - 1 - i].timestamp = end_ts;
3323 * Append a new ctts entry to ctts_data.
3324 * Returns the new ctts_count if successful, else returns -1.
3326 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3327 int count, int duration)
3329 MOVStts *ctts_buf_new;
3330 const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVStts);
3331 const size_t requested_size =
3332 min_size_needed > *allocated_size ?
3333 FFMAX(min_size_needed, 2 * (*allocated_size)) :
3336 if((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
3339 ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3344 *ctts_data = ctts_buf_new;
3346 ctts_buf_new[*ctts_count].count = count;
3347 ctts_buf_new[*ctts_count].duration = duration;
3349 *ctts_count = (*ctts_count) + 1;
3353 #define MAX_REORDER_DELAY 16
3354 static void mov_estimate_video_delay(MOVContext *c, AVStream* st) {
3355 MOVStreamContext *msc = st->priv_data;
3358 int ctts_sample = 0;
3359 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3361 int j, r, num_swaps;
3363 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3364 pts_buf[j] = INT64_MIN;
3366 if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3367 st->codecpar->codec_id == AV_CODEC_ID_H264) {
3368 st->codecpar->video_delay = 0;
3369 for(ind = 0; ind < st->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3370 // Point j to the last elem of the buffer and insert the current pts there.
3372 buf_start = (buf_start + 1);
3373 if (buf_start == MAX_REORDER_DELAY + 1)
3376 pts_buf[j] = st->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3378 // The timestamps that are already in the sorted buffer, and are greater than the
3379 // current pts, are exactly the timestamps that need to be buffered to output PTS
3380 // in correct sorted order.
3381 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3382 // can be computed as the maximum no. of swaps any particular timestamp needs to
3383 // go through, to keep this buffer in sorted order.
3385 while (j != buf_start) {
3387 if (r < 0) r = MAX_REORDER_DELAY;
3388 if (pts_buf[j] < pts_buf[r]) {
3389 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3396 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3399 if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3404 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3405 st->codecpar->video_delay, st->index);
3409 static void mov_current_sample_inc(MOVStreamContext *sc)
3411 sc->current_sample++;
3412 sc->current_index++;
3413 if (sc->index_ranges &&
3414 sc->current_index >= sc->current_index_range->end &&
3415 sc->current_index_range->end) {
3416 sc->current_index_range++;
3417 sc->current_index = sc->current_index_range->start;
3421 static void mov_current_sample_dec(MOVStreamContext *sc)
3423 sc->current_sample--;
3424 sc->current_index--;
3425 if (sc->index_ranges &&
3426 sc->current_index < sc->current_index_range->start &&
3427 sc->current_index_range > sc->index_ranges) {
3428 sc->current_index_range--;
3429 sc->current_index = sc->current_index_range->end - 1;
3433 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3437 sc->current_sample = current_sample;
3438 sc->current_index = current_sample;
3439 if (!sc->index_ranges) {
3443 for (sc->current_index_range = sc->index_ranges;
3444 sc->current_index_range->end;
3445 sc->current_index_range++) {
3446 range_size = sc->current_index_range->end - sc->current_index_range->start;
3447 if (range_size > current_sample) {
3448 sc->current_index = sc->current_index_range->start + current_sample;
3451 current_sample -= range_size;
3456 * Fix st->index_entries, so that it contains only the entries (and the entries
3457 * which are needed to decode them) that fall in the edit list time ranges.
3458 * Also fixes the timestamps of the index entries to match the timeline
3459 * specified the edit lists.
3461 static void mov_fix_index(MOVContext *mov, AVStream *st)
3463 MOVStreamContext *msc = st->priv_data;
3464 AVIndexEntry *e_old = st->index_entries;
3465 int nb_old = st->nb_index_entries;
3466 const AVIndexEntry *e_old_end = e_old + nb_old;
3467 const AVIndexEntry *current = NULL;
3468 MOVStts *ctts_data_old = msc->ctts_data;
3469 int64_t ctts_index_old = 0;
3470 int64_t ctts_sample_old = 0;
3471 int64_t ctts_count_old = msc->ctts_count;
3472 int64_t edit_list_media_time = 0;
3473 int64_t edit_list_duration = 0;
3474 int64_t frame_duration = 0;
3475 int64_t edit_list_dts_counter = 0;
3476 int64_t edit_list_dts_entry_end = 0;
3477 int64_t edit_list_start_ctts_sample = 0;
3479 int64_t curr_ctts = 0;
3480 int64_t empty_edits_sum_duration = 0;
3481 int64_t edit_list_index = 0;
3484 int64_t start_dts = 0;
3485 int64_t edit_list_start_encountered = 0;
3486 int64_t search_timestamp = 0;
3487 int64_t* frame_duration_buffer = NULL;
3488 int num_discarded_begin = 0;
3489 int first_non_zero_audio_edit = -1;
3490 int packet_skip_samples = 0;
3491 MOVIndexRange *current_index_range;
3493 int found_keyframe_after_edit = 0;
3494 int found_non_empty_edit = 0;
3496 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
3500 // allocate the index ranges array
3501 msc->index_ranges = av_malloc((msc->elst_count + 1) * sizeof(msc->index_ranges[0]));
3502 if (!msc->index_ranges) {
3503 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
3506 msc->current_index_range = msc->index_ranges;
3507 current_index_range = msc->index_ranges - 1;
3509 // Clean AVStream from traces of old index
3510 st->index_entries = NULL;
3511 st->index_entries_allocated_size = 0;
3512 st->nb_index_entries = 0;
3514 // Clean ctts fields of MOVStreamContext
3515 msc->ctts_data = NULL;
3516 msc->ctts_count = 0;
3517 msc->ctts_index = 0;
3518 msc->ctts_sample = 0;
3519 msc->ctts_allocated_size = 0;
3521 // Reinitialize min_corrected_pts so that it can be computed again.
3522 msc->min_corrected_pts = -1;
3524 // If the dts_shift is positive (in case of negative ctts values in mov),
3525 // then negate the DTS by dts_shift
3526 if (msc->dts_shift > 0) {
3527 edit_list_dts_entry_end -= msc->dts_shift;
3528 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
3531 start_dts = edit_list_dts_entry_end;
3533 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
3534 &edit_list_duration, mov->time_scale)) {
3535 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
3536 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
3538 edit_list_dts_counter = edit_list_dts_entry_end;
3539 edit_list_dts_entry_end += edit_list_duration;
3540 num_discarded_begin = 0;
3541 if (!found_non_empty_edit && edit_list_media_time == -1) {
3542 empty_edits_sum_duration += edit_list_duration;
3545 found_non_empty_edit = 1;
3547 // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
3548 // according to the edit list below.
3549 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3550 if (first_non_zero_audio_edit < 0) {
3551 first_non_zero_audio_edit = 1;
3553 first_non_zero_audio_edit = 0;
3556 if (first_non_zero_audio_edit > 0)
3557 st->skip_samples = msc->start_pad = 0;
3560 // While reordering frame index according to edit list we must handle properly
3561 // the scenario when edit list entry starts from none key frame.
3562 // We find closest previous key frame and preserve it and consequent frames in index.
3563 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
3564 search_timestamp = edit_list_media_time;
3565 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3566 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
3567 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
3568 // edit_list_media_time to cover the decoder delay.
3569 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
3572 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
3573 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3574 av_log(mov->fc, AV_LOG_WARNING,
3575 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
3576 st->index, edit_list_index, search_timestamp);
3577 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
3578 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3579 av_log(mov->fc, AV_LOG_WARNING,
3580 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
3581 st->index, edit_list_index, search_timestamp);
3584 ctts_sample_old = 0;
3587 current = e_old + index;
3588 edit_list_start_ctts_sample = ctts_sample_old;
3590 // Iterate over index and arrange it according to edit list
3591 edit_list_start_encountered = 0;
3592 found_keyframe_after_edit = 0;
3593 for (; current < e_old_end; current++, index++) {
3594 // check if frame outside edit list mark it for discard
3595 frame_duration = (current + 1 < e_old_end) ?
3596 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
3598 flags = current->flags;
3600 // frames (pts) before or after edit list
3601 curr_cts = current->timestamp + msc->dts_shift;
3604 if (ctts_data_old && ctts_index_old < ctts_count_old) {
3605 curr_ctts = ctts_data_old[ctts_index_old].duration;
3606 av_log(mov->fc, AV_LOG_DEBUG, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
3607 curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
3608 curr_cts += curr_ctts;
3610 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
3611 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3612 &msc->ctts_allocated_size,
3613 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3614 ctts_data_old[ctts_index_old].duration) == -1) {
3615 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3617 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3618 ctts_data_old[ctts_index_old].duration);
3622 ctts_sample_old = 0;
3623 edit_list_start_ctts_sample = 0;
3627 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
3628 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
3629 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
3630 first_non_zero_audio_edit > 0) {
3631 packet_skip_samples = edit_list_media_time - curr_cts;
3632 st->skip_samples += packet_skip_samples;
3634 // Shift the index entry timestamp by packet_skip_samples to be correct.
3635 edit_list_dts_counter -= packet_skip_samples;
3636 if (edit_list_start_encountered == 0) {
3637 edit_list_start_encountered = 1;
3638 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
3639 // discarded packets.
3640 if (frame_duration_buffer) {
3641 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3642 frame_duration_buffer, num_discarded_begin);
3643 av_freep(&frame_duration_buffer);
3647 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
3649 flags |= AVINDEX_DISCARD_FRAME;
3650 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
3652 if (edit_list_start_encountered == 0) {
3653 num_discarded_begin++;
3654 frame_duration_buffer = av_realloc(frame_duration_buffer,
3655 num_discarded_begin * sizeof(int64_t));
3656 if (!frame_duration_buffer) {
3657 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
3660 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
3662 // Increment skip_samples for the first non-zero audio edit list
3663 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3664 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
3665 st->skip_samples += frame_duration;
3670 if (msc->min_corrected_pts < 0) {
3671 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
3673 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
3675 if (edit_list_start_encountered == 0) {
3676 edit_list_start_encountered = 1;
3677 // Make timestamps strictly monotonically increasing by rewriting timestamps for
3678 // discarded packets.
3679 if (frame_duration_buffer) {
3680 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3681 frame_duration_buffer, num_discarded_begin);
3682 av_freep(&frame_duration_buffer);
3687 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
3688 current->min_distance, flags) == -1) {
3689 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
3693 // Update the index ranges array
3694 if (current_index_range < msc->index_ranges || index != current_index_range->end) {
3695 current_index_range++;
3696 current_index_range->start = index;
3698 current_index_range->end = index + 1;
3700 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
3701 if (edit_list_start_encountered > 0) {
3702 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
3705 // Break when found first key frame after edit entry completion
3706 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
3707 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
3708 if (ctts_data_old) {
3709 // If we have CTTS and this is the first keyframe after edit elist,
3710 // wait for one more, because there might be trailing B-frames after this I-frame
3711 // that do belong to the edit.
3712 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
3713 found_keyframe_after_edit = 1;
3716 if (ctts_sample_old != 0) {
3717 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3718 &msc->ctts_allocated_size,
3719 ctts_sample_old - edit_list_start_ctts_sample,
3720 ctts_data_old[ctts_index_old].duration) == -1) {
3721 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3722 ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
3723 ctts_data_old[ctts_index_old].duration);
3732 // If there are empty edits, then msc->min_corrected_pts might be positive
3733 // intentionally. So we subtract the sum duration of emtpy edits here.
3734 msc->min_corrected_pts -= empty_edits_sum_duration;
3736 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
3737 // dts by that amount to make the first pts zero.
3738 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
3739 if (msc->min_corrected_pts > 0) {
3740 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
3741 for (i = 0; i < st->nb_index_entries; ++i) {
3742 st->index_entries[i].timestamp -= msc->min_corrected_pts;
3746 // Start time should be equal to zero or the duration of any empty edits.
3747 st->start_time = empty_edits_sum_duration;
3749 // Update av stream length, if it ends up shorter than the track's media duration
3750 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
3751 msc->start_pad = st->skip_samples;
3753 // Free the old index and the old CTTS structures
3755 av_free(ctts_data_old);
3756 av_freep(&frame_duration_buffer);
3758 // Null terminate the index ranges array
3759 current_index_range++;
3760 current_index_range->start = 0;
3761 current_index_range->end = 0;
3762 msc->current_index = msc->index_ranges[0].start;
3765 static void mov_build_index(MOVContext *mov, AVStream *st)
3767 MOVStreamContext *sc = st->priv_data;
3768 int64_t current_offset;
3769 int64_t current_dts = 0;
3770 unsigned int stts_index = 0;
3771 unsigned int stsc_index = 0;
3772 unsigned int stss_index = 0;
3773 unsigned int stps_index = 0;
3775 uint64_t stream_size = 0;
3776 MOVStts *ctts_data_old = sc->ctts_data;
3777 unsigned int ctts_count_old = sc->ctts_count;
3779 if (sc->elst_count) {
3780 int i, edit_start_index = 0, multiple_edits = 0;
3781 int64_t empty_duration = 0; // empty duration of the first edit list entry
3782 int64_t start_time = 0; // start time of the media
3784 for (i = 0; i < sc->elst_count; i++) {
3785 const MOVElst *e = &sc->elst_data[i];
3786 if (i == 0 && e->time == -1) {
3787 /* if empty, the first entry is the start time of the stream
3788 * relative to the presentation itself */
3789 empty_duration = e->duration;
3790 edit_start_index = 1;
3791 } else if (i == edit_start_index && e->time >= 0) {
3792 start_time = e->time;
3798 if (multiple_edits && !mov->advanced_editlist)
3799 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
3800 "Use -advanced_editlist to correctly decode otherwise "
3801 "a/v desync might occur\n");
3803 /* adjust first dts according to edit list */
3804 if ((empty_duration || start_time) && mov->time_scale > 0) {
3806 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
3807 sc->time_offset = start_time - empty_duration;
3808 sc->min_corrected_pts = start_time;
3809 if (!mov->advanced_editlist)
3810 current_dts = -sc->time_offset;
3813 if (!multiple_edits && !mov->advanced_editlist &&
3814 st->codecpar->codec_id == AV_CODEC_ID_AAC && start_time > 0)
3815 sc->start_pad = start_time;
3818 /* only use old uncompressed audio chunk demuxing when stts specifies it */
3819 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3820 sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
3821 unsigned int current_sample = 0;
3822 unsigned int stts_sample = 0;
3823 unsigned int sample_size;
3824 unsigned int distance = 0;
3825 unsigned int rap_group_index = 0;
3826 unsigned int rap_group_sample = 0;
3827 int64_t last_dts = 0;
3828 int64_t dts_correction = 0;
3829 int rap_group_present = sc->rap_group_count && sc->rap_group;
3830 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
3832 current_dts -= sc->dts_shift;
3833 last_dts = current_dts;
3835 if (!sc->sample_count || st->nb_index_entries)
3837 if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
3839 if (av_reallocp_array(&st->index_entries,
3840 st->nb_index_entries + sc->sample_count,
3841 sizeof(*st->index_entries)) < 0) {
3842 st->nb_index_entries = 0;
3845 st->index_entries_allocated_size = (st->nb_index_entries + sc->sample_count) * sizeof(*st->index_entries);
3847 if (ctts_data_old) {
3848 // Expand ctts entries such that we have a 1-1 mapping with samples
3849 if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
3852 sc->ctts_allocated_size = 0;
3853 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size,
3854 sc->sample_count * sizeof(*sc->ctts_data));
3855 if (!sc->ctts_data) {
3856 av_free(ctts_data_old);
3860 memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
3862 for (i = 0; i < ctts_count_old &&
3863 sc->ctts_count < sc->sample_count; i++)
3864 for (j = 0; j < ctts_data_old[i].count &&
3865 sc->ctts_count < sc->sample_count; j++)
3866 add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
3867 &sc->ctts_allocated_size, 1,
3868 ctts_data_old[i].duration);
3869 av_free(ctts_data_old);
3872 for (i = 0; i < sc->chunk_count; i++) {
3873 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
3874 current_offset = sc->chunk_offsets[i];
3875 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3876 i + 1 == sc->stsc_data[stsc_index + 1].first)
3879 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
3880 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
3881 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
3882 sc->stsz_sample_size = sc->sample_size;
3884 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
3885 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
3886 sc->stsz_sample_size = sc->sample_size;
3889 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
3891 if (current_sample >= sc->sample_count) {
3892 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
3896 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
3898 if (stss_index + 1 < sc->keyframe_count)
3900 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
3902 if (stps_index + 1 < sc->stps_count)
3905 if (rap_group_present && rap_group_index < sc->rap_group_count) {
3906 if (sc->rap_group[rap_group_index].index > 0)
3908 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
3909 rap_group_sample = 0;
3913 if (sc->keyframe_absent
3915 && !rap_group_present
3916 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
3920 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
3921 if (sc->pseudo_stream_id == -1 ||
3922 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
3924 if (sample_size > 0x3FFFFFFF) {
3925 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
3928 e = &st->index_entries[st->nb_index_entries++];
3929 e->pos = current_offset;
3930 e->timestamp = current_dts;
3931 e->size = sample_size;
3932 e->min_distance = distance;
3933 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
3934 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
3935 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
3936 current_offset, current_dts, sample_size, distance, keyframe);
3937 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries < 100)
3938 ff_rfps_add_frame(mov->fc, st, current_dts);
3941 current_offset += sample_size;
3942 stream_size += sample_size;
3944 /* A negative sample duration is invalid based on the spec,
3945 * but some samples need it to correct the DTS. */
3946 if (sc->stts_data[stts_index].duration < 0) {
3947 av_log(mov->fc, AV_LOG_WARNING,
3948 "Invalid SampleDelta %d in STTS, at %d st:%d\n",
3949 sc->stts_data[stts_index].duration, stts_index,
3951 dts_correction += sc->stts_data[stts_index].duration - 1;
3952 sc->stts_data[stts_index].duration = 1;
3954 current_dts += sc->stts_data[stts_index].duration;
3955 if (!dts_correction || current_dts + dts_correction > last_dts) {
3956 current_dts += dts_correction;
3959 /* Avoid creating non-monotonous DTS */
3960 dts_correction += current_dts - last_dts - 1;
3961 current_dts = last_dts + 1;
3963 last_dts = current_dts;
3967 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
3973 if (st->duration > 0)
3974 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
3976 unsigned chunk_samples, total = 0;
3978 if (!sc->chunk_count)
3981 // compute total chunk count
3982 for (i = 0; i < sc->stsc_count; i++) {
3983 unsigned count, chunk_count;
3985 chunk_samples = sc->stsc_data[i].count;
3986 if (i != sc->stsc_count - 1 &&
3987 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
3988 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
3992 if (sc->samples_per_frame >= 160) { // gsm
3993 count = chunk_samples / sc->samples_per_frame;
3994 } else if (sc->samples_per_frame > 1) {
3995 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
3996 count = (chunk_samples+samples-1) / samples;
3998 count = (chunk_samples+1023) / 1024;
4001 if (mov_stsc_index_valid(i, sc->stsc_count))
4002 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4004 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4005 total += chunk_count * count;
4008 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4009 if (total >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
4011 if (av_reallocp_array(&st->index_entries,
4012 st->nb_index_entries + total,
4013 sizeof(*st->index_entries)) < 0) {
4014 st->nb_index_entries = 0;
4017 st->index_entries_allocated_size = (st->nb_index_entries + total) * sizeof(*st->index_entries);
4020 for (i = 0; i < sc->chunk_count; i++) {
4021 current_offset = sc->chunk_offsets[i];
4022 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4023 i + 1 == sc->stsc_data[stsc_index + 1].first)
4025 chunk_samples = sc->stsc_data[stsc_index].count;
4027 while (chunk_samples > 0) {
4029 unsigned size, samples;
4031 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4032 avpriv_request_sample(mov->fc,
4033 "Zero bytes per frame, but %d samples per frame",
4034 sc->samples_per_frame);
4038 if (sc->samples_per_frame >= 160) { // gsm
4039 samples = sc->samples_per_frame;
4040 size = sc->bytes_per_frame;
4042 if (sc->samples_per_frame > 1) {
4043 samples = FFMIN((1024 / sc->samples_per_frame)*
4044 sc->samples_per_frame, chunk_samples);
4045 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
4047 samples = FFMIN(1024, chunk_samples);
4048 size = samples * sc->sample_size;
4052 if (st->nb_index_entries >= total) {
4053 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4056 if (size > 0x3FFFFFFF) {
4057 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4060 e = &st->index_entries[st->nb_index_entries++];
4061 e->pos = current_offset;
4062 e->timestamp = current_dts;
4064 e->min_distance = 0;
4065 e->flags = AVINDEX_KEYFRAME;
4066 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4067 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4070 current_offset += size;
4071 current_dts += samples;
4072 chunk_samples -= samples;
4077 if (!mov->ignore_editlist && mov->advanced_editlist) {
4078 // Fix index according to edit lists.
4079 mov_fix_index(mov, st);
4082 // Update start time of the stream.
4083 if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries > 0) {
4084 st->start_time = st->index_entries[0].timestamp + sc->dts_shift;
4085 if (sc->ctts_data) {
4086 st->start_time += sc->ctts_data[0].duration;
4090 mov_estimate_video_delay(mov, st);
4093 static int test_same_origin(const char *src, const char *ref) {
4103 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4104 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4106 if (strlen(src) == 0) {
4108 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4109 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4110 strlen(src_host) + 1 >= sizeof(src_host) ||
4111 strlen(ref_host) + 1 >= sizeof(ref_host)) {
4113 } else if (strcmp(src_proto, ref_proto) ||
4114 strcmp(src_auth, ref_auth) ||
4115 strcmp(src_host, ref_host) ||
4116 src_port != ref_port) {
4122 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4124 /* try relative path, we do not try the absolute because it can leak information about our
4125 system to an attacker */
4126 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4127 char filename[1025];
4128 const char *src_path;
4131 /* find a source dir */
4132 src_path = strrchr(src, '/');
4138 /* find a next level down to target */
4139 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4140 if (ref->path[l] == '/') {
4141 if (i == ref->nlvl_to - 1)
4147 /* compose filename if next level down to target was found */
4148 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4149 memcpy(filename, src, src_path - src);
4150 filename[src_path - src] = 0;
4152 for (i = 1; i < ref->nlvl_from; i++)
4153 av_strlcat(filename, "../", sizeof(filename));
4155 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4156 if (!c->use_absolute_path) {
4157 int same_origin = test_same_origin(src, filename);
4160 av_log(c->fc, AV_LOG_ERROR,
4161 "Reference with mismatching origin, %s not tried for security reasons, "
4162 "set demuxer option use_absolute_path to allow it anyway\n",
4164 return AVERROR(ENOENT);
4167 if(strstr(ref->path + l + 1, "..") ||
4168 strstr(ref->path + l + 1, ":") ||
4169 (ref->nlvl_from > 1 && same_origin < 0) ||
4170 (filename[0] == '/' && src_path == src))
4171 return AVERROR(ENOENT);
4174 if (strlen(filename) + 1 == sizeof(filename))
4175 return AVERROR(ENOENT);
4176 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4179 } else if (c->use_absolute_path) {
4180 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4181 "this is a possible security issue\n");
4182 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4185 av_log(c->fc, AV_LOG_ERROR,
4186 "Absolute path %s not tried for security reasons, "
4187 "set demuxer option use_absolute_path to allow absolute paths\n",
4191 return AVERROR(ENOENT);
4194 static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
4196 if (sc->time_scale <= 0) {
4197 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4198 sc->time_scale = c->time_scale;
4199 if (sc->time_scale <= 0)
4204 static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4207 MOVStreamContext *sc;
4210 st = avformat_new_stream(c->fc, NULL);
4211 if (!st) return AVERROR(ENOMEM);
4213 sc = av_mallocz(sizeof(MOVStreamContext));
4214 if (!sc) return AVERROR(ENOMEM);
4217 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
4218 sc->ffindex = st->index;
4219 c->trak_index = st->index;
4221 if ((ret = mov_read_default(c, pb, atom)) < 0)
4226 // Here stsc refers to a chunk not described in stco. This is technically invalid,
4227 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4228 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4230 av_freep(&sc->stsc_data);
4234 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4235 (!sc->sample_size && !sc->sample_count))) ||
4236 (!sc->chunk_count && sc->sample_count)) {
4237 av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4241 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4242 av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4244 return AVERROR_INVALIDDATA;
4247 fix_timescale(c, sc);
4249 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4251 mov_build_index(c, st);
4253 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4254 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4255 if (c->enable_drefs) {
4256 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4257 av_log(c->fc, AV_LOG_ERROR,
4258 "stream %d, error opening alias: path='%s', dir='%s', "
4259 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4260 st->index, dref->path, dref->dir, dref->filename,
4261 dref->volume, dref->nlvl_from, dref->nlvl_to);
4263 av_log(c->fc, AV_LOG_WARNING,
4264 "Skipped opening external track: "
4265 "stream %d, alias: path='%s', dir='%s', "
4266 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4267 "Set enable_drefs to allow this.\n",
4268 st->index, dref->path, dref->dir, dref->filename,
4269 dref->volume, dref->nlvl_from, dref->nlvl_to);
4273 sc->pb_is_copied = 1;
4276 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4277 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4278 sc->height && sc->width &&
4279 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4280 st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4281 ((double)st->codecpar->width * sc->height), INT_MAX);
4284 #if FF_API_R_FRAME_RATE
4285 if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4286 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
4287 sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4291 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4292 if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4293 TAG_IS_AVCI(st->codecpar->codec_tag)) {
4294 ret = ff_generate_avci_extradata(st);
4299 switch (st->codecpar->codec_id) {
4300 #if CONFIG_H261_DECODER
4301 case AV_CODEC_ID_H261:
4303 #if CONFIG_H263_DECODER
4304 case AV_CODEC_ID_H263:
4306 #if CONFIG_MPEG4_DECODER
4307 case AV_CODEC_ID_MPEG4:
4309 st->codecpar->width = 0; /* let decoder init width/height */
4310 st->codecpar->height= 0;
4314 // If the duration of the mp3 packets is not constant, then they could need a parser
4315 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4316 && sc->stts_count > 3
4317 && sc->stts_count*10 > st->nb_frames
4318 && sc->time_scale == st->codecpar->sample_rate) {
4319 st->need_parsing = AVSTREAM_PARSE_FULL;
4321 /* Do not need those anymore. */
4322 av_freep(&sc->chunk_offsets);
4323 av_freep(&sc->sample_sizes);
4324 av_freep(&sc->keyframes);
4325 av_freep(&sc->stts_data);
4326 av_freep(&sc->stps_data);
4327 av_freep(&sc->elst_data);
4328 av_freep(&sc->rap_group);
4333 static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4336 c->itunes_metadata = 1;
4337 ret = mov_read_default(c, pb, atom);
4338 c->itunes_metadata = 0;
4342 static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4351 count = avio_rb32(pb);
4352 if (count > UINT_MAX / sizeof(*c->meta_keys) - 1) {
4353 av_log(c->fc, AV_LOG_ERROR,
4354 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
4355 return AVERROR_INVALIDDATA;
4358 c->meta_keys_count = count + 1;
4359 c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
4361 return AVERROR(ENOMEM);
4363 for (i = 1; i <= count; ++i) {
4364 uint32_t key_size = avio_rb32(pb);
4365 uint32_t type = avio_rl32(pb);
4367 av_log(c->fc, AV_LOG_ERROR,
4368 "The key# %"PRIu32" in meta has invalid size:"
4369 "%"PRIu32"\n", i, key_size);
4370 return AVERROR_INVALIDDATA;
4373 if (type != MKTAG('m','d','t','a')) {
4374 avio_skip(pb, key_size);
4376 c->meta_keys[i] = av_mallocz(key_size + 1);
4377 if (!c->meta_keys[i])
4378 return AVERROR(ENOMEM);
4379 avio_read(pb, c->meta_keys[i], key_size);
4385 static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4387 int64_t end = avio_tell(pb) + atom.size;
4388 uint8_t *key = NULL, *val = NULL, *mean = NULL;
4392 MOVStreamContext *sc;
4394 if (c->fc->nb_streams < 1)
4396 st = c->fc->streams[c->fc->nb_streams-1];
4399 for (i = 0; i < 3; i++) {
4403 if (end - avio_tell(pb) <= 12)
4406 len = avio_rb32(pb);
4407 tag = avio_rl32(pb);
4408 avio_skip(pb, 4); // flags
4410 if (len < 12 || len - 12 > end - avio_tell(pb))
4414 if (tag == MKTAG('m', 'e', 'a', 'n'))
4416 else if (tag == MKTAG('n', 'a', 'm', 'e'))
4418 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
4425 *p = av_malloc(len + 1);
4427 ret = AVERROR(ENOMEM);
4430 ret = ffio_read_size(pb, *p, len);
4438 if (mean && key && val) {
4439 if (strcmp(key, "iTunSMPB") == 0) {
4440 int priming, remainder, samples;
4441 if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
4442 if(priming>0 && priming<16384)
4443 sc->start_pad = priming;
4446 if (strcmp(key, "cdec") != 0) {
4447 av_dict_set(&c->fc->metadata, key, val,
4448 AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
4452 av_log(c->fc, AV_LOG_VERBOSE,
4453 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
4456 avio_seek(pb, end, SEEK_SET);
4463 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4465 while (atom.size > 8) {
4469 tag = avio_rl32(pb);
4471 if (tag == MKTAG('h','d','l','r')) {
4472 avio_seek(pb, -8, SEEK_CUR);
4474 return mov_read_default(c, pb, atom);
4480 // return 1 when matrix is identity, 0 otherwise
4481 #define IS_MATRIX_IDENT(matrix) \
4482 ( (matrix)[0][0] == (1 << 16) && \
4483 (matrix)[1][1] == (1 << 16) && \
4484 (matrix)[2][2] == (1 << 30) && \
4485 !(matrix)[0][1] && !(matrix)[0][2] && \
4486 !(matrix)[1][0] && !(matrix)[1][2] && \
4487 !(matrix)[2][0] && !(matrix)[2][1])
4489 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4494 int display_matrix[3][3];
4495 int res_display_matrix[3][3] = { { 0 } };
4497 MOVStreamContext *sc;
4501 if (c->fc->nb_streams < 1)
4503 st = c->fc->streams[c->fc->nb_streams-1];
4506 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4507 // avoids corrupting AVStreams mapped to an earlier tkhd.
4509 return AVERROR_INVALIDDATA;
4511 version = avio_r8(pb);
4512 flags = avio_rb24(pb);
4513 st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
4519 avio_rb32(pb); /* creation time */
4520 avio_rb32(pb); /* modification time */
4522 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4523 avio_rb32(pb); /* reserved */
4525 /* highlevel (considering edits) duration in movie timebase */
4526 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4527 avio_rb32(pb); /* reserved */
4528 avio_rb32(pb); /* reserved */
4530 avio_rb16(pb); /* layer */
4531 avio_rb16(pb); /* alternate group */
4532 avio_rb16(pb); /* volume */
4533 avio_rb16(pb); /* reserved */
4535 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4536 // they're kept in fixed point format through all calculations
4537 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4538 // side data, but the scale factor is not needed to calculate aspect ratio
4539 for (i = 0; i < 3; i++) {
4540 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
4541 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
4542 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
4545 width = avio_rb32(pb); // 16.16 fixed point track width
4546 height = avio_rb32(pb); // 16.16 fixed point track height
4547 sc->width = width >> 16;
4548 sc->height = height >> 16;
4550 // apply the moov display matrix (after the tkhd one)
4551 for (i = 0; i < 3; i++) {
4552 const int sh[3] = { 16, 16, 30 };
4553 for (j = 0; j < 3; j++) {
4554 for (e = 0; e < 3; e++) {
4555 res_display_matrix[i][j] +=
4556 ((int64_t) display_matrix[i][e] *
4557 c->movie_display_matrix[e][j]) >> sh[e];
4562 // save the matrix when it is not the default identity
4563 if (!IS_MATRIX_IDENT(res_display_matrix)) {
4566 av_freep(&sc->display_matrix);
4567 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4568 if (!sc->display_matrix)
4569 return AVERROR(ENOMEM);
4571 for (i = 0; i < 3; i++)
4572 for (j = 0; j < 3; j++)
4573 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4575 #if FF_API_OLD_ROTATE_API
4576 rotate = av_display_rotation_get(sc->display_matrix);
4577 if (!isnan(rotate)) {
4578 char rotate_buf[64];
4580 if (rotate < 0) // for backward compatibility
4582 snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate);
4583 av_dict_set(&st->metadata, "rotate", rotate_buf, 0);
4588 // transform the display width/height according to the matrix
4589 // to keep the same scale, use [width height 1<<16]
4590 if (width && height && sc->display_matrix) {
4591 double disp_transform[2];
4593 for (i = 0; i < 2; i++)
4594 disp_transform[i] = hypot(sc->display_matrix[0 + i],
4595 sc->display_matrix[3 + i]);
4597 if (disp_transform[0] > 0 && disp_transform[1] > 0 &&
4598 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4599 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4600 st->sample_aspect_ratio = av_d2q(
4601 disp_transform[0] / disp_transform[1],
4607 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4609 MOVFragment *frag = &c->fragment;
4610 MOVTrackExt *trex = NULL;
4611 int flags, track_id, i;
4613 avio_r8(pb); /* version */
4614 flags = avio_rb24(pb);
4616 track_id = avio_rb32(pb);
4618 return AVERROR_INVALIDDATA;
4619 for (i = 0; i < c->trex_count; i++)
4620 if (c->trex_data[i].track_id == track_id) {
4621 trex = &c->trex_data[i];
4625 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4628 c->fragment.found_tfhd = 1;
4629 frag->track_id = track_id;
4630 set_frag_stream(&c->frag_index, track_id);
4632 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4633 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4634 frag->moof_offset : frag->implicit_offset;
4635 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4637 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4638 avio_rb32(pb) : trex->duration;
4639 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4640 avio_rb32(pb) : trex->size;
4641 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4642 avio_rb32(pb) : trex->flags;
4643 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4648 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4653 num = atom.size / 4;
4654 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4655 return AVERROR(ENOMEM);
4657 av_free(c->chapter_tracks);
4658 c->chapter_tracks = new_tracks;
4659 c->nb_chapter_tracks = num;
4661 for (i = 0; i < num && !pb->eof_reached; i++)
4662 c->chapter_tracks[i] = avio_rb32(pb);
4667 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4672 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4673 return AVERROR_INVALIDDATA;
4674 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4675 sizeof(*c->trex_data))) < 0) {
4680 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4682 trex = &c->trex_data[c->trex_count++];
4683 avio_r8(pb); /* version */
4684 avio_rb24(pb); /* flags */
4685 trex->track_id = avio_rb32(pb);
4686 trex->stsd_id = avio_rb32(pb);
4687 trex->duration = avio_rb32(pb);
4688 trex->size = avio_rb32(pb);
4689 trex->flags = avio_rb32(pb);
4693 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4695 MOVFragment *frag = &c->fragment;
4696 AVStream *st = NULL;
4697 MOVStreamContext *sc;
4699 MOVFragmentStreamInfo * frag_stream_info;
4700 int64_t base_media_decode_time;
4702 for (i = 0; i < c->fc->nb_streams; i++) {
4703 if (c->fc->streams[i]->id == frag->track_id) {
4704 st = c->fc->streams[i];
4709 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4713 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4715 version = avio_r8(pb);
4716 avio_rb24(pb); /* flags */
4718 base_media_decode_time = avio_rb64(pb);
4720 base_media_decode_time = avio_rb32(pb);
4723 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4724 if (frag_stream_info)
4725 frag_stream_info->tfdt_dts = base_media_decode_time;
4726 sc->track_end = base_media_decode_time;
4731 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4733 MOVFragment *frag = &c->fragment;
4734 AVStream *st = NULL;
4735 MOVStreamContext *sc;
4738 int64_t dts, pts = AV_NOPTS_VALUE;
4739 int data_offset = 0;
4740 unsigned entries, first_sample_flags = frag->flags;
4741 int flags, distance, i;
4742 int64_t prev_dts = AV_NOPTS_VALUE;
4743 int next_frag_index = -1, index_entry_pos;
4744 size_t requested_size;
4745 size_t old_ctts_allocated_size;
4746 AVIndexEntry *new_entries;
4747 MOVFragmentStreamInfo * frag_stream_info;
4749 if (!frag->found_tfhd) {
4750 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4751 return AVERROR_INVALIDDATA;
4754 for (i = 0; i < c->fc->nb_streams; i++) {
4755 if (c->fc->streams[i]->id == frag->track_id) {
4756 st = c->fc->streams[i];
4761 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4765 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4768 // Find the next frag_index index that has a valid index_entry for
4769 // the current track_id.
4771 // A valid index_entry means the trun for the fragment was read
4772 // and it's samples are in index_entries at the given position.
4773 // New index entries will be inserted before the index_entry found.
4774 index_entry_pos = st->nb_index_entries;
4775 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4776 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4777 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4778 next_frag_index = i;
4779 index_entry_pos = frag_stream_info->index_entry;
4783 av_assert0(index_entry_pos <= st->nb_index_entries);
4785 avio_r8(pb); /* version */
4786 flags = avio_rb24(pb);
4787 entries = avio_rb32(pb);
4788 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4790 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4791 return AVERROR_INVALIDDATA;
4792 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4793 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4795 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4796 if (frag_stream_info)
4798 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4799 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4800 pts = frag_stream_info->first_tfra_pts;
4801 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4802 ", using it for pts\n", pts);
4803 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4804 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4805 // pts = frag_stream_info->sidx_pts;
4806 dts = frag_stream_info->sidx_pts - sc->time_offset;
4807 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4808 ", using it for pts\n", pts);
4809 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4810 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4811 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4812 ", using it for dts\n", dts);
4814 dts = sc->track_end - sc->time_offset;
4815 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4816 ", using it for dts\n", dts);
4819 dts = sc->track_end - sc->time_offset;
4820 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4821 ", using it for dts\n", dts);
4823 offset = frag->base_data_offset + data_offset;
4825 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4827 // realloc space for new index entries
4828 if((uint64_t)st->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4829 entries = UINT_MAX / sizeof(AVIndexEntry) - st->nb_index_entries;
4830 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4835 requested_size = (st->nb_index_entries + entries) * sizeof(AVIndexEntry);
4836 new_entries = av_fast_realloc(st->index_entries,
4837 &st->index_entries_allocated_size,
4840 return AVERROR(ENOMEM);
4841 st->index_entries= new_entries;
4843 requested_size = (st->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4844 old_ctts_allocated_size = sc->ctts_allocated_size;
4845 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4848 return AVERROR(ENOMEM);
4849 sc->ctts_data = ctts_data;
4851 // In case there were samples without ctts entries, ensure they get
4852 // zero valued entries. This ensures clips which mix boxes with and
4853 // without ctts entries don't pickup uninitialized data.
4854 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4855 sc->ctts_allocated_size - old_ctts_allocated_size);
4857 if (index_entry_pos < st->nb_index_entries) {
4858 // Make hole in index_entries and ctts_data for new samples
4859 memmove(st->index_entries + index_entry_pos + entries,
4860 st->index_entries + index_entry_pos,
4861 sizeof(*st->index_entries) *
4862 (st->nb_index_entries - index_entry_pos));
4863 memmove(sc->ctts_data + index_entry_pos + entries,
4864 sc->ctts_data + index_entry_pos,
4865 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4866 if (index_entry_pos < sc->current_sample) {
4867 sc->current_sample += entries;
4871 st->nb_index_entries += entries;
4872 sc->ctts_count = st->nb_index_entries;
4874 // Record the index_entry position in frag_index of this fragment
4875 if (frag_stream_info)
4876 frag_stream_info->index_entry = index_entry_pos;
4878 if (index_entry_pos > 0)
4879 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4881 for (i = 0; i < entries && !pb->eof_reached; i++) {
4882 unsigned sample_size = frag->size;
4883 int sample_flags = i ? frag->flags : first_sample_flags;
4884 unsigned sample_duration = frag->duration;
4885 unsigned ctts_duration = 0;
4887 int index_entry_flags = 0;
4889 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4890 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4891 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4892 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4894 mov_update_dts_shift(sc, ctts_duration, c->fc);
4895 if (pts != AV_NOPTS_VALUE) {
4896 dts = pts - sc->dts_shift;
4897 if (flags & MOV_TRUN_SAMPLE_CTS) {
4898 dts -= ctts_duration;
4900 dts -= sc->time_offset;
4902 av_log(c->fc, AV_LOG_DEBUG,
4903 "pts %"PRId64" calculated dts %"PRId64
4904 " sc->dts_shift %d ctts.duration %d"
4905 " sc->time_offset %"PRId64
4906 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4908 sc->dts_shift, ctts_duration,
4909 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4910 pts = AV_NOPTS_VALUE;
4913 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4917 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4918 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4921 index_entry_flags |= AVINDEX_KEYFRAME;
4923 // Fragments can overlap in time. Discard overlapping frames after
4925 if (prev_dts >= dts)
4926 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4928 st->index_entries[index_entry_pos].pos = offset;
4929 st->index_entries[index_entry_pos].timestamp = dts;
4930 st->index_entries[index_entry_pos].size= sample_size;
4931 st->index_entries[index_entry_pos].min_distance= distance;
4932 st->index_entries[index_entry_pos].flags = index_entry_flags;
4934 sc->ctts_data[index_entry_pos].count = 1;
4935 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4938 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4939 "size %u, distance %d, keyframe %d\n", st->index,
4940 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4942 dts += sample_duration;
4943 offset += sample_size;
4944 sc->data_size += sample_size;
4946 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4947 1 <= INT_MAX - sc->nb_frames_for_fps
4949 sc->duration_for_fps += sample_duration;
4950 sc->nb_frames_for_fps ++;
4954 // EOF found before reading all entries. Fix the hole this would
4955 // leave in index_entries and ctts_data
4956 int gap = entries - i;
4957 memmove(st->index_entries + index_entry_pos,
4958 st->index_entries + index_entry_pos + gap,
4959 sizeof(*st->index_entries) *
4960 (st->nb_index_entries - (index_entry_pos + gap)));
4961 memmove(sc->ctts_data + index_entry_pos,
4962 sc->ctts_data + index_entry_pos + gap,
4963 sizeof(*sc->ctts_data) *
4964 (sc->ctts_count - (index_entry_pos + gap)));
4966 st->nb_index_entries -= gap;
4967 sc->ctts_count -= gap;
4968 if (index_entry_pos < sc->current_sample) {
4969 sc->current_sample -= gap;
4974 // The end of this new fragment may overlap in time with the start
4975 // of the next fragment in index_entries. Mark the samples in the next
4976 // fragment that overlap with AVINDEX_DISCARD_FRAME
4977 prev_dts = AV_NOPTS_VALUE;
4978 if (index_entry_pos > 0)
4979 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4980 for (i = index_entry_pos; i < st->nb_index_entries; i++) {
4981 if (prev_dts < st->index_entries[i].timestamp)
4983 st->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
4986 // If a hole was created to insert the new index_entries into,
4987 // the index_entry recorded for all subsequent moof must
4988 // be incremented by the number of entries inserted.
4989 fix_frag_index_entries(&c->frag_index, next_frag_index,
4990 frag->track_id, entries);
4992 if (pb->eof_reached) {
4993 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
4997 frag->implicit_offset = offset;
4999 sc->track_end = dts + sc->time_offset;
5000 if (st->duration < sc->track_end)
5001 st->duration = sc->track_end;
5006 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5008 int64_t offset = avio_tell(pb) + atom.size, pts, timestamp;
5010 unsigned i, j, track_id, item_count;
5011 AVStream *st = NULL;
5012 AVStream *ref_st = NULL;
5013 MOVStreamContext *sc, *ref_sc = NULL;
5014 AVRational timescale;
5016 version = avio_r8(pb);
5018 avpriv_request_sample(c->fc, "sidx version %u", version);
5022 avio_rb24(pb); // flags
5024 track_id = avio_rb32(pb); // Reference ID
5025 for (i = 0; i < c->fc->nb_streams; i++) {
5026 if (c->fc->streams[i]->id == track_id) {
5027 st = c->fc->streams[i];
5032 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5038 timescale = av_make_q(1, avio_rb32(pb));
5040 if (timescale.den <= 0) {
5041 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5042 return AVERROR_INVALIDDATA;
5046 pts = avio_rb32(pb);
5047 offset += avio_rb32(pb);
5049 pts = avio_rb64(pb);
5050 offset += avio_rb64(pb);
5053 avio_rb16(pb); // reserved
5055 item_count = avio_rb16(pb);
5057 for (i = 0; i < item_count; i++) {
5059 MOVFragmentStreamInfo * frag_stream_info;
5060 uint32_t size = avio_rb32(pb);
5061 uint32_t duration = avio_rb32(pb);
5062 if (size & 0x80000000) {
5063 avpriv_request_sample(c->fc, "sidx reference_type 1");
5064 return AVERROR_PATCHWELCOME;
5066 avio_rb32(pb); // sap_flags
5067 timestamp = av_rescale_q(pts, timescale, st->time_base);
5069 index = update_frag_index(c, offset);
5070 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5071 if (frag_stream_info)
5072 frag_stream_info->sidx_pts = timestamp;
5078 st->duration = sc->track_end = pts;
5082 if (offset == avio_size(pb)) {
5083 // Find first entry in fragment index that came from an sidx.
5084 // This will pretty much always be the first entry.
5085 for (i = 0; i < c->frag_index.nb_items; i++) {
5086 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5087 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5088 MOVFragmentStreamInfo * si;
5089 si = &item->stream_info[j];
5090 if (si->sidx_pts != AV_NOPTS_VALUE) {
5091 ref_st = c->fc->streams[j];
5092 ref_sc = ref_st->priv_data;
5097 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5098 st = c->fc->streams[i];
5100 if (!sc->has_sidx) {
5101 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5105 c->frag_index.complete = 1;
5111 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5112 /* like the files created with Adobe Premiere 5.0, for samples see */
5113 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5114 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5119 return 0; /* continue */
5120 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5121 avio_skip(pb, atom.size - 4);
5124 atom.type = avio_rl32(pb);
5126 if (atom.type != MKTAG('m','d','a','t')) {
5127 avio_skip(pb, atom.size);
5130 err = mov_read_mdat(c, pb, atom);
5134 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5139 uint8_t *moov_data; /* uncompressed data */
5140 long cmov_len, moov_len;
5143 avio_rb32(pb); /* dcom atom */
5144 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5145 return AVERROR_INVALIDDATA;
5146 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5147 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5148 return AVERROR_INVALIDDATA;
5150 avio_rb32(pb); /* cmvd atom */
5151 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5152 return AVERROR_INVALIDDATA;
5153 moov_len = avio_rb32(pb); /* uncompressed size */
5154 cmov_len = atom.size - 6 * 4;
5156 cmov_data = av_malloc(cmov_len);
5158 return AVERROR(ENOMEM);
5159 moov_data = av_malloc(moov_len);
5162 return AVERROR(ENOMEM);
5164 ret = ffio_read_size(pb, cmov_data, cmov_len);
5166 goto free_and_return;
5168 ret = AVERROR_INVALIDDATA;
5169 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5170 goto free_and_return;
5171 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5172 goto free_and_return;
5173 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5174 atom.type = MKTAG('m','o','o','v');
5175 atom.size = moov_len;
5176 ret = mov_read_default(c, &ctx, atom);
5182 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5183 return AVERROR(ENOSYS);
5187 /* edit list atom */
5188 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5190 MOVStreamContext *sc;
5191 int i, edit_count, version;
5192 int64_t elst_entry_size;
5194 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5196 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5198 version = avio_r8(pb); /* version */
5199 avio_rb24(pb); /* flags */
5200 edit_count = avio_rb32(pb); /* entries */
5203 elst_entry_size = version == 1 ? 20 : 12;
5204 if (atom.size != edit_count * elst_entry_size) {
5205 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5206 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5207 edit_count, atom.size + 8);
5208 return AVERROR_INVALIDDATA;
5210 edit_count = atom.size / elst_entry_size;
5211 if (edit_count * elst_entry_size != atom.size) {
5212 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.", atom.size, edit_count);
5220 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5221 av_free(sc->elst_data);
5223 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5225 return AVERROR(ENOMEM);
5227 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5228 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5229 MOVElst *e = &sc->elst_data[i];
5232 e->duration = avio_rb64(pb);
5233 e->time = avio_rb64(pb);
5236 e->duration = avio_rb32(pb); /* segment duration */
5237 e->time = (int32_t)avio_rb32(pb); /* media time */
5240 e->rate = avio_rb32(pb) / 65536.0;
5242 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5243 e->duration, e->time, e->rate);
5245 if (e->time < 0 && e->time != -1 &&
5246 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5247 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5248 c->fc->nb_streams-1, i, e->time);
5249 return AVERROR_INVALIDDATA;
5257 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5259 MOVStreamContext *sc;
5261 if (c->fc->nb_streams < 1)
5262 return AVERROR_INVALIDDATA;
5263 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5264 sc->timecode_track = avio_rb32(pb);
5268 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5273 if (c->fc->nb_streams < 1)
5275 st = c->fc->streams[c->fc->nb_streams - 1];
5277 if (atom.size < 4) {
5278 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5279 return AVERROR_INVALIDDATA;
5282 /* For now, propagate only the OBUs, if any. Once libavcodec is
5283 updated to handle isobmff style extradata this can be removed. */
5289 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5296 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5299 int version, color_range, color_primaries, color_trc, color_space;
5301 if (c->fc->nb_streams < 1)
5303 st = c->fc->streams[c->fc->nb_streams - 1];
5305 if (atom.size < 5) {
5306 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5307 return AVERROR_INVALIDDATA;
5310 version = avio_r8(pb);
5312 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5315 avio_skip(pb, 3); /* flags */
5317 avio_skip(pb, 2); /* profile + level */
5318 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5319 color_primaries = avio_r8(pb);
5320 color_trc = avio_r8(pb);
5321 color_space = avio_r8(pb);
5322 if (avio_rb16(pb)) /* codecIntializationDataSize */
5323 return AVERROR_INVALIDDATA;
5325 if (!av_color_primaries_name(color_primaries))
5326 color_primaries = AVCOL_PRI_UNSPECIFIED;
5327 if (!av_color_transfer_name(color_trc))
5328 color_trc = AVCOL_TRC_UNSPECIFIED;
5329 if (!av_color_space_name(color_space))
5330 color_space = AVCOL_SPC_UNSPECIFIED;
5332 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5333 st->codecpar->color_primaries = color_primaries;
5334 st->codecpar->color_trc = color_trc;
5335 st->codecpar->color_space = color_space;
5340 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5342 MOVStreamContext *sc;
5345 if (c->fc->nb_streams < 1)
5346 return AVERROR_INVALIDDATA;
5348 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5350 if (atom.size < 5) {
5351 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5352 return AVERROR_INVALIDDATA;
5355 version = avio_r8(pb);
5357 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5360 avio_skip(pb, 3); /* flags */
5362 sc->mastering = av_mastering_display_metadata_alloc();
5364 return AVERROR(ENOMEM);
5366 for (i = 0; i < 3; i++) {
5367 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5368 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5370 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5371 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5373 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5374 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5376 sc->mastering->has_primaries = 1;
5377 sc->mastering->has_luminance = 1;
5382 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5384 MOVStreamContext *sc;
5385 const int mapping[3] = {1, 2, 0};
5386 const int chroma_den = 50000;
5387 const int luma_den = 10000;
5390 if (c->fc->nb_streams < 1)
5391 return AVERROR_INVALIDDATA;
5393 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5395 if (atom.size < 24) {
5396 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5397 return AVERROR_INVALIDDATA;
5400 sc->mastering = av_mastering_display_metadata_alloc();
5402 return AVERROR(ENOMEM);
5404 for (i = 0; i < 3; i++) {
5405 const int j = mapping[i];
5406 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5407 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5409 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5410 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5412 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5413 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5415 sc->mastering->has_luminance = 1;
5416 sc->mastering->has_primaries = 1;
5421 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5423 MOVStreamContext *sc;
5426 if (c->fc->nb_streams < 1)
5427 return AVERROR_INVALIDDATA;
5429 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5431 if (atom.size < 5) {
5432 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5433 return AVERROR_INVALIDDATA;
5436 version = avio_r8(pb);
5438 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5441 avio_skip(pb, 3); /* flags */
5443 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5445 return AVERROR(ENOMEM);
5447 sc->coll->MaxCLL = avio_rb16(pb);
5448 sc->coll->MaxFALL = avio_rb16(pb);
5453 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5455 MOVStreamContext *sc;
5457 if (c->fc->nb_streams < 1)
5458 return AVERROR_INVALIDDATA;
5460 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5462 if (atom.size < 4) {
5463 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5464 return AVERROR_INVALIDDATA;
5467 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5469 return AVERROR(ENOMEM);
5471 sc->coll->MaxCLL = avio_rb16(pb);
5472 sc->coll->MaxFALL = avio_rb16(pb);
5477 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5480 MOVStreamContext *sc;
5481 enum AVStereo3DType type;
5484 if (c->fc->nb_streams < 1)
5487 st = c->fc->streams[c->fc->nb_streams - 1];
5490 if (atom.size < 5) {
5491 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5492 return AVERROR_INVALIDDATA;
5494 avio_skip(pb, 4); /* version + flags */
5499 type = AV_STEREO3D_2D;
5502 type = AV_STEREO3D_TOPBOTTOM;
5505 type = AV_STEREO3D_SIDEBYSIDE;
5508 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5512 sc->stereo3d = av_stereo3d_alloc();
5514 return AVERROR(ENOMEM);
5516 sc->stereo3d->type = type;
5520 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5523 MOVStreamContext *sc;
5524 int size, version, layout;
5525 int32_t yaw, pitch, roll;
5526 uint32_t l = 0, t = 0, r = 0, b = 0;
5527 uint32_t tag, padding = 0;
5528 enum AVSphericalProjection projection;
5530 if (c->fc->nb_streams < 1)
5533 st = c->fc->streams[c->fc->nb_streams - 1];
5536 if (atom.size < 8) {
5537 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5538 return AVERROR_INVALIDDATA;
5541 size = avio_rb32(pb);
5542 if (size <= 12 || size > atom.size)
5543 return AVERROR_INVALIDDATA;
5545 tag = avio_rl32(pb);
5546 if (tag != MKTAG('s','v','h','d')) {
5547 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5550 version = avio_r8(pb);
5552 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5556 avio_skip(pb, 3); /* flags */
5557 avio_skip(pb, size - 12); /* metadata_source */
5559 size = avio_rb32(pb);
5560 if (size > atom.size)
5561 return AVERROR_INVALIDDATA;
5563 tag = avio_rl32(pb);
5564 if (tag != MKTAG('p','r','o','j')) {
5565 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
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','h','d')) {
5575 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5578 version = avio_r8(pb);
5580 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5584 avio_skip(pb, 3); /* flags */
5586 /* 16.16 fixed point */
5587 yaw = avio_rb32(pb);
5588 pitch = avio_rb32(pb);
5589 roll = avio_rb32(pb);
5591 size = avio_rb32(pb);
5592 if (size > atom.size)
5593 return AVERROR_INVALIDDATA;
5595 tag = avio_rl32(pb);
5596 version = avio_r8(pb);
5598 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5602 avio_skip(pb, 3); /* flags */
5604 case MKTAG('c','b','m','p'):
5605 layout = avio_rb32(pb);
5607 av_log(c->fc, AV_LOG_WARNING,
5608 "Unsupported cubemap layout %d\n", layout);
5611 projection = AV_SPHERICAL_CUBEMAP;
5612 padding = avio_rb32(pb);
5614 case MKTAG('e','q','u','i'):
5620 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5621 av_log(c->fc, AV_LOG_ERROR,
5622 "Invalid bounding rectangle coordinates "
5623 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5624 return AVERROR_INVALIDDATA;
5627 if (l || t || r || b)
5628 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5630 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5633 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5637 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5639 return AVERROR(ENOMEM);
5641 sc->spherical->projection = projection;
5643 sc->spherical->yaw = yaw;
5644 sc->spherical->pitch = pitch;
5645 sc->spherical->roll = roll;
5647 sc->spherical->padding = padding;
5649 sc->spherical->bound_left = l;
5650 sc->spherical->bound_top = t;
5651 sc->spherical->bound_right = r;
5652 sc->spherical->bound_bottom = b;
5657 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5660 uint8_t *buffer = av_malloc(len + 1);
5664 return AVERROR(ENOMEM);
5667 ret = ffio_read_size(pb, buffer, len);
5671 /* Check for mandatory keys and values, try to support XML as best-effort */
5672 if (!sc->spherical &&
5673 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5674 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5675 av_stristr(val, "true") &&
5676 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5677 av_stristr(val, "true") &&
5678 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5679 av_stristr(val, "equirectangular")) {
5680 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5684 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5686 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5687 enum AVStereo3DType mode;
5689 if (av_stristr(buffer, "left-right"))
5690 mode = AV_STEREO3D_SIDEBYSIDE;
5691 else if (av_stristr(buffer, "top-bottom"))
5692 mode = AV_STEREO3D_TOPBOTTOM;
5694 mode = AV_STEREO3D_2D;
5696 sc->stereo3d = av_stereo3d_alloc();
5700 sc->stereo3d->type = mode;
5704 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5706 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5707 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5709 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5710 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5712 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5720 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5723 MOVStreamContext *sc;
5726 static const uint8_t uuid_isml_manifest[] = {
5727 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5728 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5730 static const uint8_t uuid_xmp[] = {
5731 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5732 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5734 static const uint8_t uuid_spherical[] = {
5735 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5736 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5739 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5740 return AVERROR_INVALIDDATA;
5742 if (c->fc->nb_streams < 1)
5744 st = c->fc->streams[c->fc->nb_streams - 1];
5747 ret = avio_read(pb, uuid, sizeof(uuid));
5750 } else if (ret != sizeof(uuid)) {
5751 return AVERROR_INVALIDDATA;
5753 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5754 uint8_t *buffer, *ptr;
5756 size_t len = atom.size - sizeof(uuid);
5759 return AVERROR_INVALIDDATA;
5761 ret = avio_skip(pb, 4); // zeroes
5764 buffer = av_mallocz(len + 1);
5766 return AVERROR(ENOMEM);
5768 ret = avio_read(pb, buffer, len);
5772 } else if (ret != len) {
5774 return AVERROR_INVALIDDATA;
5778 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5779 ptr += sizeof("systemBitrate=\"") - 1;
5780 c->bitrates_count++;
5781 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5783 c->bitrates_count = 0;
5785 return AVERROR(ENOMEM);
5788 ret = strtol(ptr, &endptr, 10);
5789 if (ret < 0 || errno || *endptr != '"') {
5790 c->bitrates[c->bitrates_count - 1] = 0;
5792 c->bitrates[c->bitrates_count - 1] = ret;
5797 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5799 size_t len = atom.size - sizeof(uuid);
5800 if (c->export_xmp) {
5801 buffer = av_mallocz(len + 1);
5803 return AVERROR(ENOMEM);
5805 ret = avio_read(pb, buffer, len);
5809 } else if (ret != len) {
5811 return AVERROR_INVALIDDATA;
5814 av_dict_set(&c->fc->metadata, "xmp",
5815 buffer, AV_DICT_DONT_STRDUP_VAL);
5817 // skip all uuid atom, which makes it fast for long uuid-xmp file
5818 ret = avio_skip(pb, len);
5822 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5823 size_t len = atom.size - sizeof(uuid);
5824 ret = mov_parse_uuid_spherical(sc, pb, len);
5828 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5834 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5837 uint8_t content[16];
5842 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5848 && !memcmp(content, "Anevia\x1A\x1A", 8)
5849 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5850 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5856 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5858 uint32_t format = avio_rl32(pb);
5859 MOVStreamContext *sc;
5863 if (c->fc->nb_streams < 1)
5865 st = c->fc->streams[c->fc->nb_streams - 1];
5870 case MKTAG('e','n','c','v'): // encrypted video
5871 case MKTAG('e','n','c','a'): // encrypted audio
5872 id = mov_codec_id(st, format);
5873 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5874 st->codecpar->codec_id != id) {
5875 av_log(c->fc, AV_LOG_WARNING,
5876 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5877 (char*)&format, st->codecpar->codec_id);
5881 st->codecpar->codec_id = id;
5882 sc->format = format;
5886 if (format != sc->format) {
5887 av_log(c->fc, AV_LOG_WARNING,
5888 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5889 (char*)&format, (char*)&sc->format);
5898 * Gets the current encryption info and associated current stream context. If
5899 * we are parsing a track fragment, this will return the specific encryption
5900 * info for this fragment; otherwise this will return the global encryption
5901 * info for the current stream.
5903 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5905 MOVFragmentStreamInfo *frag_stream_info;
5909 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5910 if (frag_stream_info) {
5911 for (i = 0; i < c->fc->nb_streams; i++) {
5912 if (c->fc->streams[i]->id == frag_stream_info->id) {
5913 st = c->fc->streams[i];
5917 if (i == c->fc->nb_streams)
5919 *sc = st->priv_data;
5921 if (!frag_stream_info->encryption_index) {
5922 // If this stream isn't encrypted, don't create the index.
5923 if (!(*sc)->cenc.default_encrypted_sample)
5925 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5926 if (!frag_stream_info->encryption_index)
5927 return AVERROR(ENOMEM);
5929 *encryption_index = frag_stream_info->encryption_index;
5932 // No current track fragment, using stream level encryption info.
5934 if (c->fc->nb_streams < 1)
5936 st = c->fc->streams[c->fc->nb_streams - 1];
5937 *sc = st->priv_data;
5939 if (!(*sc)->cenc.encryption_index) {
5940 // If this stream isn't encrypted, don't create the index.
5941 if (!(*sc)->cenc.default_encrypted_sample)
5943 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5944 if (!(*sc)->cenc.encryption_index)
5945 return AVERROR(ENOMEM);
5948 *encryption_index = (*sc)->cenc.encryption_index;
5953 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
5956 unsigned int subsample_count;
5957 AVSubsampleEncryptionInfo *subsamples;
5959 if (!sc->cenc.default_encrypted_sample) {
5960 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
5961 return AVERROR_INVALIDDATA;
5964 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
5966 return AVERROR(ENOMEM);
5968 if (sc->cenc.per_sample_iv_size != 0) {
5969 if (avio_read(pb, (*sample)->iv, sc->cenc.per_sample_iv_size) != sc->cenc.per_sample_iv_size) {
5970 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
5971 av_encryption_info_free(*sample);
5973 return AVERROR_INVALIDDATA;
5977 if (use_subsamples) {
5978 subsample_count = avio_rb16(pb);
5979 av_free((*sample)->subsamples);
5980 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
5981 if (!(*sample)->subsamples) {
5982 av_encryption_info_free(*sample);
5984 return AVERROR(ENOMEM);
5987 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
5988 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
5989 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
5992 if (pb->eof_reached) {
5993 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
5994 av_encryption_info_free(*sample);
5996 return AVERROR_INVALIDDATA;
5998 (*sample)->subsample_count = subsample_count;
6004 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6006 AVEncryptionInfo **encrypted_samples;
6007 MOVEncryptionIndex *encryption_index;
6008 MOVStreamContext *sc;
6009 int use_subsamples, ret;
6010 unsigned int sample_count, i, alloc_size = 0;
6012 ret = get_current_encryption_info(c, &encryption_index, &sc);
6016 if (encryption_index->nb_encrypted_samples) {
6017 // This can happen if we have both saio/saiz and senc atoms.
6018 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6022 avio_r8(pb); /* version */
6023 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6025 sample_count = avio_rb32(pb);
6026 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6027 return AVERROR(ENOMEM);
6029 for (i = 0; i < sample_count; i++) {
6030 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6031 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6032 min_samples * sizeof(*encrypted_samples));
6033 if (encrypted_samples) {
6034 encryption_index->encrypted_samples = encrypted_samples;
6036 ret = mov_read_sample_encryption_info(
6037 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6039 ret = AVERROR(ENOMEM);
6041 if (pb->eof_reached) {
6042 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6043 ret = AVERROR_INVALIDDATA;
6048 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6049 av_freep(&encryption_index->encrypted_samples);
6053 encryption_index->nb_encrypted_samples = sample_count;
6058 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6060 AVEncryptionInfo **sample, **encrypted_samples;
6062 size_t sample_count, sample_info_size, i;
6064 unsigned int alloc_size = 0;
6066 if (encryption_index->nb_encrypted_samples)
6068 sample_count = encryption_index->auxiliary_info_sample_count;
6069 if (encryption_index->auxiliary_offsets_count != 1) {
6070 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6071 return AVERROR_PATCHWELCOME;
6073 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6074 return AVERROR(ENOMEM);
6076 prev_pos = avio_tell(pb);
6077 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6078 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6079 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6083 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6084 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6085 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6086 min_samples * sizeof(*encrypted_samples));
6087 if (!encrypted_samples) {
6088 ret = AVERROR(ENOMEM);
6091 encryption_index->encrypted_samples = encrypted_samples;
6093 sample = &encryption_index->encrypted_samples[i];
6094 sample_info_size = encryption_index->auxiliary_info_default_size
6095 ? encryption_index->auxiliary_info_default_size
6096 : encryption_index->auxiliary_info_sizes[i];
6098 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6102 if (pb->eof_reached) {
6103 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6104 ret = AVERROR_INVALIDDATA;
6106 encryption_index->nb_encrypted_samples = sample_count;
6110 avio_seek(pb, prev_pos, SEEK_SET);
6112 for (; i > 0; i--) {
6113 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6115 av_freep(&encryption_index->encrypted_samples);
6121 * Tries to read the given number of bytes from the stream and puts it in a
6122 * newly allocated buffer. This reads in small chunks to avoid allocating large
6123 * memory if the file contains an invalid/malicious size value.
6125 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6127 const unsigned int block_size = 1024 * 1024;
6128 uint8_t *buffer = NULL;
6129 unsigned int alloc_size = 0, offset = 0;
6130 while (offset < size) {
6131 unsigned int new_size =
6132 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6133 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6134 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6137 return AVERROR(ENOMEM);
6139 buffer = new_buffer;
6141 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6143 return AVERROR_INVALIDDATA;
6152 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6154 MOVEncryptionIndex *encryption_index;
6155 MOVStreamContext *sc;
6157 unsigned int sample_count, aux_info_type, aux_info_param;
6159 ret = get_current_encryption_info(c, &encryption_index, &sc);
6163 if (encryption_index->nb_encrypted_samples) {
6164 // This can happen if we have both saio/saiz and senc atoms.
6165 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6169 if (encryption_index->auxiliary_info_sample_count) {
6170 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6171 return AVERROR_INVALIDDATA;
6174 avio_r8(pb); /* version */
6175 if (avio_rb24(pb) & 0x01) { /* flags */
6176 aux_info_type = avio_rb32(pb);
6177 aux_info_param = avio_rb32(pb);
6178 if (sc->cenc.default_encrypted_sample) {
6179 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6180 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6183 if (aux_info_param != 0) {
6184 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6188 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6189 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6190 aux_info_type == MKBETAG('c','e','n','s') ||
6191 aux_info_type == MKBETAG('c','b','c','1') ||
6192 aux_info_type == MKBETAG('c','b','c','s')) &&
6193 aux_info_param == 0) {
6194 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6195 return AVERROR_INVALIDDATA;
6200 } else if (!sc->cenc.default_encrypted_sample) {
6201 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6205 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6206 sample_count = avio_rb32(pb);
6207 encryption_index->auxiliary_info_sample_count = sample_count;
6209 if (encryption_index->auxiliary_info_default_size == 0) {
6210 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6212 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6217 if (encryption_index->auxiliary_offsets_count) {
6218 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6224 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6226 uint64_t *auxiliary_offsets;
6227 MOVEncryptionIndex *encryption_index;
6228 MOVStreamContext *sc;
6230 unsigned int version, entry_count, aux_info_type, aux_info_param;
6231 unsigned int alloc_size = 0;
6233 ret = get_current_encryption_info(c, &encryption_index, &sc);
6237 if (encryption_index->nb_encrypted_samples) {
6238 // This can happen if we have both saio/saiz and senc atoms.
6239 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6243 if (encryption_index->auxiliary_offsets_count) {
6244 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6245 return AVERROR_INVALIDDATA;
6248 version = avio_r8(pb); /* version */
6249 if (avio_rb24(pb) & 0x01) { /* flags */
6250 aux_info_type = avio_rb32(pb);
6251 aux_info_param = avio_rb32(pb);
6252 if (sc->cenc.default_encrypted_sample) {
6253 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6254 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6257 if (aux_info_param != 0) {
6258 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6262 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6263 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6264 aux_info_type == MKBETAG('c','e','n','s') ||
6265 aux_info_type == MKBETAG('c','b','c','1') ||
6266 aux_info_type == MKBETAG('c','b','c','s')) &&
6267 aux_info_param == 0) {
6268 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6269 return AVERROR_INVALIDDATA;
6274 } else if (!sc->cenc.default_encrypted_sample) {
6275 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6279 entry_count = avio_rb32(pb);
6280 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6281 return AVERROR(ENOMEM);
6283 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6284 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6285 auxiliary_offsets = av_fast_realloc(
6286 encryption_index->auxiliary_offsets, &alloc_size,
6287 min_offsets * sizeof(*auxiliary_offsets));
6288 if (!auxiliary_offsets) {
6289 av_freep(&encryption_index->auxiliary_offsets);
6290 return AVERROR(ENOMEM);
6292 encryption_index->auxiliary_offsets = auxiliary_offsets;
6295 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6297 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6299 if (c->frag_index.current >= 0) {
6300 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6304 if (pb->eof_reached) {
6305 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6306 av_freep(&encryption_index->auxiliary_offsets);
6307 return AVERROR_INVALIDDATA;
6310 encryption_index->auxiliary_offsets_count = entry_count;
6312 if (encryption_index->auxiliary_info_sample_count) {
6313 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6319 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6321 AVEncryptionInitInfo *info, *old_init_info;
6324 uint8_t *side_data, *extra_data, *old_side_data;
6325 size_t side_data_size;
6326 int ret = 0, old_side_data_size;
6327 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6329 if (c->fc->nb_streams < 1)
6331 st = c->fc->streams[c->fc->nb_streams-1];
6333 version = avio_r8(pb); /* version */
6334 avio_rb24(pb); /* flags */
6336 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6337 /* key_id_size */ 16, /* data_size */ 0);
6339 return AVERROR(ENOMEM);
6341 if (avio_read(pb, info->system_id, 16) != 16) {
6342 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6343 ret = AVERROR_INVALIDDATA;
6348 kid_count = avio_rb32(pb);
6349 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
6350 ret = AVERROR(ENOMEM);
6354 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6355 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6356 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6357 min_kid_count * sizeof(*key_ids));
6359 ret = AVERROR(ENOMEM);
6362 info->key_ids = key_ids;
6364 info->key_ids[i] = av_mallocz(16);
6365 if (!info->key_ids[i]) {
6366 ret = AVERROR(ENOMEM);
6369 info->num_key_ids = i + 1;
6371 if (avio_read(pb, info->key_ids[i], 16) != 16) {
6372 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6373 ret = AVERROR_INVALIDDATA;
6378 if (pb->eof_reached) {
6379 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6380 ret = AVERROR_INVALIDDATA;
6385 extra_data_size = avio_rb32(pb);
6386 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6390 av_freep(&info->data); // malloc(0) may still allocate something.
6391 info->data = extra_data;
6392 info->data_size = extra_data_size;
6394 // If there is existing initialization data, append to the list.
6395 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6396 if (old_side_data) {
6397 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6398 if (old_init_info) {
6399 // Append to the end of the list.
6400 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6406 info = old_init_info;
6408 // Assume existing side-data will be valid, so the only error we could get is OOM.
6409 ret = AVERROR(ENOMEM);
6414 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6416 ret = AVERROR(ENOMEM);
6419 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6420 side_data, side_data_size);
6425 av_encryption_init_info_free(info);
6429 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6432 MOVStreamContext *sc;
6434 if (c->fc->nb_streams < 1)
6436 st = c->fc->streams[c->fc->nb_streams-1];
6439 if (sc->pseudo_stream_id != 0) {
6440 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6441 return AVERROR_PATCHWELCOME;
6445 return AVERROR_INVALIDDATA;
6447 avio_rb32(pb); /* version and flags */
6449 if (!sc->cenc.default_encrypted_sample) {
6450 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6451 if (!sc->cenc.default_encrypted_sample) {
6452 return AVERROR(ENOMEM);
6456 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6460 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6463 MOVStreamContext *sc;
6464 unsigned int version, pattern, is_protected, iv_size;
6466 if (c->fc->nb_streams < 1)
6468 st = c->fc->streams[c->fc->nb_streams-1];
6471 if (sc->pseudo_stream_id != 0) {
6472 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6473 return AVERROR_PATCHWELCOME;
6476 if (!sc->cenc.default_encrypted_sample) {
6477 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6478 if (!sc->cenc.default_encrypted_sample) {
6479 return AVERROR(ENOMEM);
6484 return AVERROR_INVALIDDATA;
6486 version = avio_r8(pb); /* version */
6487 avio_rb24(pb); /* flags */
6489 avio_r8(pb); /* reserved */
6490 pattern = avio_r8(pb);
6493 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6494 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6497 is_protected = avio_r8(pb);
6498 if (is_protected && !sc->cenc.encryption_index) {
6499 // The whole stream should be by-default encrypted.
6500 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6501 if (!sc->cenc.encryption_index)
6502 return AVERROR(ENOMEM);
6504 sc->cenc.per_sample_iv_size = avio_r8(pb);
6505 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6506 sc->cenc.per_sample_iv_size != 16) {
6507 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6508 return AVERROR_INVALIDDATA;
6510 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6511 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6512 return AVERROR_INVALIDDATA;
6515 if (is_protected && !sc->cenc.per_sample_iv_size) {
6516 iv_size = avio_r8(pb);
6517 if (iv_size != 8 && iv_size != 16) {
6518 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6519 return AVERROR_INVALIDDATA;
6522 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6523 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6524 return AVERROR_INVALIDDATA;
6531 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6534 int last, type, size, ret;
6537 if (c->fc->nb_streams < 1)
6539 st = c->fc->streams[c->fc->nb_streams-1];
6541 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6542 return AVERROR_INVALIDDATA;
6544 /* Check FlacSpecificBox version. */
6545 if (avio_r8(pb) != 0)
6546 return AVERROR_INVALIDDATA;
6548 avio_rb24(pb); /* Flags */
6550 avio_read(pb, buf, sizeof(buf));
6551 flac_parse_block_header(buf, &last, &type, &size);
6553 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6554 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6555 return AVERROR_INVALIDDATA;
6558 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6563 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6568 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6572 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6573 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6574 return AVERROR_PATCHWELCOME;
6577 if (!sc->cenc.aes_ctr) {
6578 /* initialize the cipher */
6579 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6580 if (!sc->cenc.aes_ctr) {
6581 return AVERROR(ENOMEM);
6584 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6590 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6592 if (!sample->subsample_count)
6594 /* decrypt the whole packet */
6595 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6599 for (i = 0; i < sample->subsample_count; i++)
6601 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6602 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6603 return AVERROR_INVALIDDATA;
6606 /* skip the clear bytes */
6607 input += sample->subsamples[i].bytes_of_clear_data;
6608 size -= sample->subsamples[i].bytes_of_clear_data;
6610 /* decrypt the encrypted bytes */
6611 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6612 input += sample->subsamples[i].bytes_of_protected_data;
6613 size -= sample->subsamples[i].bytes_of_protected_data;
6617 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6618 return AVERROR_INVALIDDATA;
6624 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6626 MOVFragmentStreamInfo *frag_stream_info;
6627 MOVEncryptionIndex *encryption_index;
6628 AVEncryptionInfo *encrypted_sample;
6629 int encrypted_index, ret;
6631 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6632 encrypted_index = current_index;
6633 encryption_index = NULL;
6634 if (frag_stream_info) {
6635 // Note this only supports encryption info in the first sample descriptor.
6636 if (mov->fragment.stsd_id == 1) {
6637 if (frag_stream_info->encryption_index) {
6638 encrypted_index = current_index - frag_stream_info->index_entry;
6639 encryption_index = frag_stream_info->encryption_index;
6641 encryption_index = sc->cenc.encryption_index;
6645 encryption_index = sc->cenc.encryption_index;
6648 if (encryption_index) {
6649 if (encryption_index->auxiliary_info_sample_count &&
6650 !encryption_index->nb_encrypted_samples) {
6651 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6652 return AVERROR_INVALIDDATA;
6654 if (encryption_index->auxiliary_offsets_count &&
6655 !encryption_index->nb_encrypted_samples) {
6656 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6657 return AVERROR_INVALIDDATA;
6660 if (!encryption_index->nb_encrypted_samples) {
6661 // Full-sample encryption with default settings.
6662 encrypted_sample = sc->cenc.default_encrypted_sample;
6663 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6664 // Per-sample setting override.
6665 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6667 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6668 return AVERROR_INVALIDDATA;
6671 if (mov->decryption_key) {
6672 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6675 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6677 return AVERROR(ENOMEM);
6678 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6688 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6690 const int OPUS_SEEK_PREROLL_MS = 80;
6696 if (c->fc->nb_streams < 1)
6698 st = c->fc->streams[c->fc->nb_streams-1];
6700 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6701 return AVERROR_INVALIDDATA;
6703 /* Check OpusSpecificBox version. */
6704 if (avio_r8(pb) != 0) {
6705 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6706 return AVERROR_INVALIDDATA;
6709 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6710 size = atom.size + 8;
6712 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
6715 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6716 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6717 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6718 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6720 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6721 little-endian; aside from the preceeding magic and version they're
6722 otherwise currently identical. Data after output gain at offset 16
6723 doesn't need to be bytewapped. */
6724 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6725 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6726 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6727 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6729 st->codecpar->initial_padding = pre_skip;
6730 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6731 (AVRational){1, 1000},
6732 (AVRational){1, 48000});
6737 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6740 unsigned format_info;
6741 int channel_assignment, channel_assignment1, channel_assignment2;
6744 if (c->fc->nb_streams < 1)
6746 st = c->fc->streams[c->fc->nb_streams-1];
6749 return AVERROR_INVALIDDATA;
6751 format_info = avio_rb32(pb);
6753 ratebits = (format_info >> 28) & 0xF;
6754 channel_assignment1 = (format_info >> 15) & 0x1F;
6755 channel_assignment2 = format_info & 0x1FFF;
6756 if (channel_assignment2)
6757 channel_assignment = channel_assignment2;
6759 channel_assignment = channel_assignment1;
6761 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6762 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6763 st->codecpar->channels = truehd_channels(channel_assignment);
6764 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6769 static const MOVParseTableEntry mov_default_parse_table[] = {
6770 { MKTAG('A','C','L','R'), mov_read_aclr },
6771 { MKTAG('A','P','R','G'), mov_read_avid },
6772 { MKTAG('A','A','L','P'), mov_read_avid },
6773 { MKTAG('A','R','E','S'), mov_read_ares },
6774 { MKTAG('a','v','s','s'), mov_read_avss },
6775 { MKTAG('a','v','1','C'), mov_read_av1c },
6776 { MKTAG('c','h','p','l'), mov_read_chpl },
6777 { MKTAG('c','o','6','4'), mov_read_stco },
6778 { MKTAG('c','o','l','r'), mov_read_colr },
6779 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6780 { MKTAG('d','i','n','f'), mov_read_default },
6781 { MKTAG('D','p','x','E'), mov_read_dpxe },
6782 { MKTAG('d','r','e','f'), mov_read_dref },
6783 { MKTAG('e','d','t','s'), mov_read_default },
6784 { MKTAG('e','l','s','t'), mov_read_elst },
6785 { MKTAG('e','n','d','a'), mov_read_enda },
6786 { MKTAG('f','i','e','l'), mov_read_fiel },
6787 { MKTAG('a','d','r','m'), mov_read_adrm },
6788 { MKTAG('f','t','y','p'), mov_read_ftyp },
6789 { MKTAG('g','l','b','l'), mov_read_glbl },
6790 { MKTAG('h','d','l','r'), mov_read_hdlr },
6791 { MKTAG('i','l','s','t'), mov_read_ilst },
6792 { MKTAG('j','p','2','h'), mov_read_jp2h },
6793 { MKTAG('m','d','a','t'), mov_read_mdat },
6794 { MKTAG('m','d','h','d'), mov_read_mdhd },
6795 { MKTAG('m','d','i','a'), mov_read_default },
6796 { MKTAG('m','e','t','a'), mov_read_meta },
6797 { MKTAG('m','i','n','f'), mov_read_default },
6798 { MKTAG('m','o','o','f'), mov_read_moof },
6799 { MKTAG('m','o','o','v'), mov_read_moov },
6800 { MKTAG('m','v','e','x'), mov_read_default },
6801 { MKTAG('m','v','h','d'), mov_read_mvhd },
6802 { MKTAG('S','M','I',' '), mov_read_svq3 },
6803 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6804 { MKTAG('a','v','c','C'), mov_read_glbl },
6805 { MKTAG('p','a','s','p'), mov_read_pasp },
6806 { MKTAG('s','i','d','x'), mov_read_sidx },
6807 { MKTAG('s','t','b','l'), mov_read_default },
6808 { MKTAG('s','t','c','o'), mov_read_stco },
6809 { MKTAG('s','t','p','s'), mov_read_stps },
6810 { MKTAG('s','t','r','f'), mov_read_strf },
6811 { MKTAG('s','t','s','c'), mov_read_stsc },
6812 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6813 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6814 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6815 { MKTAG('s','t','t','s'), mov_read_stts },
6816 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6817 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
6818 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6819 { MKTAG('t','f','d','t'), mov_read_tfdt },
6820 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6821 { MKTAG('t','r','a','k'), mov_read_trak },
6822 { MKTAG('t','r','a','f'), mov_read_default },
6823 { MKTAG('t','r','e','f'), mov_read_default },
6824 { MKTAG('t','m','c','d'), mov_read_tmcd },
6825 { MKTAG('c','h','a','p'), mov_read_chap },
6826 { MKTAG('t','r','e','x'), mov_read_trex },
6827 { MKTAG('t','r','u','n'), mov_read_trun },
6828 { MKTAG('u','d','t','a'), mov_read_default },
6829 { MKTAG('w','a','v','e'), mov_read_wave },
6830 { MKTAG('e','s','d','s'), mov_read_esds },
6831 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6832 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6833 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6834 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6835 { MKTAG('w','f','e','x'), mov_read_wfex },
6836 { MKTAG('c','m','o','v'), mov_read_cmov },
6837 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6838 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6839 { MKTAG('s','b','g','p'), mov_read_sbgp },
6840 { MKTAG('h','v','c','C'), mov_read_glbl },
6841 { MKTAG('u','u','i','d'), mov_read_uuid },
6842 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6843 { MKTAG('f','r','e','e'), mov_read_free },
6844 { MKTAG('-','-','-','-'), mov_read_custom },
6845 { MKTAG('s','i','n','f'), mov_read_default },
6846 { MKTAG('f','r','m','a'), mov_read_frma },
6847 { MKTAG('s','e','n','c'), mov_read_senc },
6848 { MKTAG('s','a','i','z'), mov_read_saiz },
6849 { MKTAG('s','a','i','o'), mov_read_saio },
6850 { MKTAG('p','s','s','h'), mov_read_pssh },
6851 { MKTAG('s','c','h','m'), mov_read_schm },
6852 { MKTAG('s','c','h','i'), mov_read_default },
6853 { MKTAG('t','e','n','c'), mov_read_tenc },
6854 { MKTAG('d','f','L','a'), mov_read_dfla },
6855 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6856 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6857 { MKTAG('d','O','p','s'), mov_read_dops },
6858 { MKTAG('d','m','l','p'), mov_read_dmlp },
6859 { MKTAG('S','m','D','m'), mov_read_smdm },
6860 { MKTAG('C','o','L','L'), mov_read_coll },
6861 { MKTAG('v','p','c','C'), mov_read_vpcc },
6862 { MKTAG('m','d','c','v'), mov_read_mdcv },
6863 { MKTAG('c','l','l','i'), mov_read_clli },
6867 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6869 int64_t total_size = 0;
6873 if (c->atom_depth > 10) {
6874 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6875 return AVERROR_INVALIDDATA;
6880 atom.size = INT64_MAX;
6881 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6882 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
6885 if (atom.size >= 8) {
6886 a.size = avio_rb32(pb);
6887 a.type = avio_rl32(pb);
6888 if (a.type == MKTAG('f','r','e','e') &&
6890 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT &&
6893 uint32_t *type = (uint32_t *)buf + 1;
6894 if (avio_read(pb, buf, 8) != 8)
6895 return AVERROR_INVALIDDATA;
6896 avio_seek(pb, -8, SEEK_CUR);
6897 if (*type == MKTAG('m','v','h','d') ||
6898 *type == MKTAG('c','m','o','v')) {
6899 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free atom.\n");
6900 a.type = MKTAG('m','o','o','v');
6903 if (atom.type != MKTAG('r','o','o','t') &&
6904 atom.type != MKTAG('m','o','o','v'))
6906 if (a.type == MKTAG('t','r','a','k') || a.type == MKTAG('m','d','a','t'))
6908 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
6915 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
6916 a.size = avio_rb64(pb) - 8;
6920 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
6921 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
6923 a.size = atom.size - total_size + 8;
6928 a.size = FFMIN(a.size, atom.size - total_size);
6930 for (i = 0; mov_default_parse_table[i].type; i++)
6931 if (mov_default_parse_table[i].type == a.type) {
6932 parse = mov_default_parse_table[i].parse;
6936 // container is user data
6937 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
6938 atom.type == MKTAG('i','l','s','t')))
6939 parse = mov_read_udta_string;
6941 // Supports parsing the QuickTime Metadata Keys.
6942 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
6943 if (!parse && c->found_hdlr_mdta &&
6944 atom.type == MKTAG('m','e','t','a') &&
6945 a.type == MKTAG('k','e','y','s')) {
6946 parse = mov_read_keys;
6949 if (!parse) { /* skip leaf atoms data */
6950 avio_skip(pb, a.size);
6952 int64_t start_pos = avio_tell(pb);
6954 int err = parse(c, pb, a);
6959 if (c->found_moov && c->found_mdat &&
6960 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
6961 start_pos + a.size == avio_size(pb))) {
6962 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
6963 c->next_root_atom = start_pos + a.size;
6967 left = a.size - avio_tell(pb) + start_pos;
6968 if (left > 0) /* skip garbage at atom end */
6969 avio_skip(pb, left);
6970 else if (left < 0) {
6971 av_log(c->fc, AV_LOG_WARNING,
6972 "overread end of atom '%.4s' by %"PRId64" bytes\n",
6973 (char*)&a.type, -left);
6974 avio_seek(pb, left, SEEK_CUR);
6978 total_size += a.size;
6981 if (total_size < atom.size && atom.size < 0x7ffff)
6982 avio_skip(pb, atom.size - total_size);
6988 static int mov_probe(const AVProbeData *p)
6993 int moov_offset = -1;
6995 /* check file header */
6998 /* ignore invalid offset */
6999 if ((offset + 8) > (unsigned int)p->buf_size)
7001 tag = AV_RL32(p->buf + offset + 4);
7003 /* check for obvious tags */
7004 case MKTAG('m','o','o','v'):
7005 moov_offset = offset + 4;
7006 case MKTAG('m','d','a','t'):
7007 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
7008 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
7009 case MKTAG('f','t','y','p'):
7010 if (AV_RB32(p->buf+offset) < 8 &&
7011 (AV_RB32(p->buf+offset) != 1 ||
7012 offset + 12 > (unsigned int)p->buf_size ||
7013 AV_RB64(p->buf+offset + 8) == 0)) {
7014 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7015 } else if (tag == MKTAG('f','t','y','p') &&
7016 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
7017 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
7019 score = FFMAX(score, 5);
7021 score = AVPROBE_SCORE_MAX;
7023 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7025 /* those are more common words, so rate then a bit less */
7026 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
7027 case MKTAG('w','i','d','e'):
7028 case MKTAG('f','r','e','e'):
7029 case MKTAG('j','u','n','k'):
7030 case MKTAG('p','i','c','t'):
7031 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
7032 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7034 case MKTAG(0x82,0x82,0x7f,0x7d):
7035 case MKTAG('s','k','i','p'):
7036 case MKTAG('u','u','i','d'):
7037 case MKTAG('p','r','f','l'):
7038 /* if we only find those cause probedata is too small at least rate them */
7039 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7040 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7043 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7046 if(score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
7047 /* moov atom in the header - we should make sure that this is not a
7048 * MOV-packed MPEG-PS */
7049 offset = moov_offset;
7051 while(offset < (p->buf_size - 16)){ /* Sufficient space */
7052 /* We found an actual hdlr atom */
7053 if(AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7054 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7055 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')){
7056 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7057 /* We found a media handler reference atom describing an
7058 * MPEG-PS-in-MOV, return a
7059 * low score to force expanding the probe window until
7060 * mpegps_probe finds what it needs */
7071 // must be done after parsing all trak because there's no order requirement
7072 static void mov_read_chapters(AVFormatContext *s)
7074 MOVContext *mov = s->priv_data;
7076 MOVStreamContext *sc;
7081 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7082 chapter_track = mov->chapter_tracks[j];
7084 for (i = 0; i < s->nb_streams; i++)
7085 if (s->streams[i]->id == chapter_track) {
7090 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7095 cur_pos = avio_tell(sc->pb);
7097 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7098 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7099 if (st->nb_index_entries) {
7100 // Retrieve the first frame, if possible
7102 AVIndexEntry *sample = &st->index_entries[0];
7103 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7104 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7108 if (av_get_packet(sc->pb, &pkt, sample->size) < 0)
7111 st->attached_pic = pkt;
7112 st->attached_pic.stream_index = st->index;
7113 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
7116 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7117 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7118 st->discard = AVDISCARD_ALL;
7119 for (i = 0; i < st->nb_index_entries; i++) {
7120 AVIndexEntry *sample = &st->index_entries[i];
7121 int64_t end = i+1 < st->nb_index_entries ? st->index_entries[i+1].timestamp : st->duration;
7126 if (end < sample->timestamp) {
7127 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7128 end = AV_NOPTS_VALUE;
7131 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7132 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7136 // the first two bytes are the length of the title
7137 len = avio_rb16(sc->pb);
7138 if (len > sample->size-2)
7140 title_len = 2*len + 1;
7141 if (!(title = av_mallocz(title_len)))
7144 // The samples could theoretically be in any encoding if there's an encd
7145 // atom following, but in practice are only utf-8 or utf-16, distinguished
7146 // instead by the presence of a BOM
7150 ch = avio_rb16(sc->pb);
7152 avio_get_str16be(sc->pb, len, title, title_len);
7153 else if (ch == 0xfffe)
7154 avio_get_str16le(sc->pb, len, title, title_len);
7157 if (len == 1 || len == 2)
7160 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7164 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7169 avio_seek(sc->pb, cur_pos, SEEK_SET);
7173 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7174 uint32_t value, int flags)
7177 char buf[AV_TIMECODE_STR_SIZE];
7178 AVRational rate = st->avg_frame_rate;
7179 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7182 av_dict_set(&st->metadata, "timecode",
7183 av_timecode_make_string(&tc, buf, value), 0);
7187 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7189 MOVStreamContext *sc = st->priv_data;
7190 char buf[AV_TIMECODE_STR_SIZE];
7191 int64_t cur_pos = avio_tell(sc->pb);
7192 int hh, mm, ss, ff, drop;
7194 if (!st->nb_index_entries)
7197 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7198 avio_skip(s->pb, 13);
7199 hh = avio_r8(s->pb);
7200 mm = avio_r8(s->pb);
7201 ss = avio_r8(s->pb);
7202 drop = avio_r8(s->pb);
7203 ff = avio_r8(s->pb);
7204 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7205 hh, mm, ss, drop ? ';' : ':', ff);
7206 av_dict_set(&st->metadata, "timecode", buf, 0);
7208 avio_seek(sc->pb, cur_pos, SEEK_SET);
7212 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7214 MOVStreamContext *sc = st->priv_data;
7216 int64_t cur_pos = avio_tell(sc->pb);
7219 if (!st->nb_index_entries)
7222 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7223 value = avio_rb32(s->pb);
7225 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7226 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7227 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7229 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7230 * not the case) and thus assume "frame number format" instead of QT one.
7231 * No sample with tmcd track can be found with a QT timecode at the moment,
7232 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7234 parse_timecode_in_framenum_format(s, st, value, flags);
7236 avio_seek(sc->pb, cur_pos, SEEK_SET);
7240 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7242 if (!index || !*index) return;
7243 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7244 av_encryption_info_free((*index)->encrypted_samples[i]);
7246 av_freep(&(*index)->encrypted_samples);
7247 av_freep(&(*index)->auxiliary_info_sizes);
7248 av_freep(&(*index)->auxiliary_offsets);
7252 static int mov_read_close(AVFormatContext *s)
7254 MOVContext *mov = s->priv_data;
7257 for (i = 0; i < s->nb_streams; i++) {
7258 AVStream *st = s->streams[i];
7259 MOVStreamContext *sc = st->priv_data;
7264 av_freep(&sc->ctts_data);
7265 for (j = 0; j < sc->drefs_count; j++) {
7266 av_freep(&sc->drefs[j].path);
7267 av_freep(&sc->drefs[j].dir);
7269 av_freep(&sc->drefs);
7271 sc->drefs_count = 0;
7273 if (!sc->pb_is_copied)
7274 ff_format_io_close(s, &sc->pb);
7277 av_freep(&sc->chunk_offsets);
7278 av_freep(&sc->stsc_data);
7279 av_freep(&sc->sample_sizes);
7280 av_freep(&sc->keyframes);
7281 av_freep(&sc->stts_data);
7282 av_freep(&sc->sdtp_data);
7283 av_freep(&sc->stps_data);
7284 av_freep(&sc->elst_data);
7285 av_freep(&sc->rap_group);
7286 av_freep(&sc->display_matrix);
7287 av_freep(&sc->index_ranges);
7290 for (j = 0; j < sc->stsd_count; j++)
7291 av_free(sc->extradata[j]);
7292 av_freep(&sc->extradata);
7293 av_freep(&sc->extradata_size);
7295 mov_free_encryption_index(&sc->cenc.encryption_index);
7296 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7297 av_aes_ctr_free(sc->cenc.aes_ctr);
7299 av_freep(&sc->stereo3d);
7300 av_freep(&sc->spherical);
7301 av_freep(&sc->mastering);
7302 av_freep(&sc->coll);
7305 if (mov->dv_demux) {
7306 avformat_free_context(mov->dv_fctx);
7307 mov->dv_fctx = NULL;
7310 if (mov->meta_keys) {
7311 for (i = 1; i < mov->meta_keys_count; i++) {
7312 av_freep(&mov->meta_keys[i]);
7314 av_freep(&mov->meta_keys);
7317 av_freep(&mov->trex_data);
7318 av_freep(&mov->bitrates);
7320 for (i = 0; i < mov->frag_index.nb_items; i++) {
7321 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7322 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7323 mov_free_encryption_index(&frag[j].encryption_index);
7325 av_freep(&mov->frag_index.item[i].stream_info);
7327 av_freep(&mov->frag_index.item);
7329 av_freep(&mov->aes_decrypt);
7330 av_freep(&mov->chapter_tracks);
7335 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7339 for (i = 0; i < s->nb_streams; i++) {
7340 AVStream *st = s->streams[i];
7341 MOVStreamContext *sc = st->priv_data;
7343 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7344 sc->timecode_track == tmcd_id)
7350 /* look for a tmcd track not referenced by any video track, and export it globally */
7351 static void export_orphan_timecode(AVFormatContext *s)
7355 for (i = 0; i < s->nb_streams; i++) {
7356 AVStream *st = s->streams[i];
7358 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7359 !tmcd_is_referenced(s, i + 1)) {
7360 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7362 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7369 static int read_tfra(MOVContext *mov, AVIOContext *f)
7371 int version, fieldlength, i, j;
7372 int64_t pos = avio_tell(f);
7373 uint32_t size = avio_rb32(f);
7374 unsigned track_id, item_count;
7376 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7379 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7381 version = avio_r8(f);
7383 track_id = avio_rb32(f);
7384 fieldlength = avio_rb32(f);
7385 item_count = avio_rb32(f);
7386 for (i = 0; i < item_count; i++) {
7387 int64_t time, offset;
7389 MOVFragmentStreamInfo * frag_stream_info;
7392 return AVERROR_INVALIDDATA;
7396 time = avio_rb64(f);
7397 offset = avio_rb64(f);
7399 time = avio_rb32(f);
7400 offset = avio_rb32(f);
7403 // The first sample of each stream in a fragment is always a random
7404 // access sample. So it's entry in the tfra can be used as the
7405 // initial PTS of the fragment.
7406 index = update_frag_index(mov, offset);
7407 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7408 if (frag_stream_info &&
7409 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7410 frag_stream_info->first_tfra_pts = time;
7412 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7414 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7416 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7420 avio_seek(f, pos + size, SEEK_SET);
7424 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7426 int64_t stream_size = avio_size(f);
7427 int64_t original_pos = avio_tell(f);
7431 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7435 mfra_size = avio_rb32(f);
7436 if (mfra_size < 0 || mfra_size > stream_size) {
7437 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7440 if ((seek_ret = avio_seek(f, -mfra_size, SEEK_CUR)) < 0) {
7444 if (avio_rb32(f) != mfra_size) {
7445 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7448 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7449 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7452 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7454 ret = read_tfra(c, f);
7460 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7462 av_log(c->fc, AV_LOG_ERROR,
7463 "failed to seek back after looking for mfra\n");
7469 static int mov_read_header(AVFormatContext *s)
7471 MOVContext *mov = s->priv_data;
7472 AVIOContext *pb = s->pb;
7474 MOVAtom atom = { AV_RL32("root") };
7477 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7478 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7479 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7480 return AVERROR(EINVAL);
7484 mov->trak_index = -1;
7485 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7486 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7487 atom.size = avio_size(pb);
7489 atom.size = INT64_MAX;
7491 /* check MOV header */
7493 if (mov->moov_retry)
7494 avio_seek(pb, 0, SEEK_SET);
7495 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7496 av_log(s, AV_LOG_ERROR, "error reading header\n");
7500 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7501 if (!mov->found_moov) {
7502 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7504 return AVERROR_INVALIDDATA;
7506 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7508 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7509 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7510 mov_read_chapters(s);
7511 for (i = 0; i < s->nb_streams; i++)
7512 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7513 mov_read_timecode_track(s, s->streams[i]);
7514 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7515 mov_read_rtmd_track(s, s->streams[i]);
7519 /* copy timecode metadata from tmcd tracks to the related video streams */
7520 for (i = 0; i < s->nb_streams; i++) {
7521 AVStream *st = s->streams[i];
7522 MOVStreamContext *sc = st->priv_data;
7523 if (sc->timecode_track > 0) {
7524 AVDictionaryEntry *tcr;
7525 int tmcd_st_id = -1;
7527 for (j = 0; j < s->nb_streams; j++)
7528 if (s->streams[j]->id == sc->timecode_track)
7531 if (tmcd_st_id < 0 || tmcd_st_id == i)
7533 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7535 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7538 export_orphan_timecode(s);
7540 for (i = 0; i < s->nb_streams; i++) {
7541 AVStream *st = s->streams[i];
7542 MOVStreamContext *sc = st->priv_data;
7543 fix_timescale(mov, sc);
7544 if(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7545 st->skip_samples = sc->start_pad;
7547 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7548 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7549 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7550 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7551 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7552 st->codecpar->width = sc->width;
7553 st->codecpar->height = sc->height;
7555 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7556 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7560 if (mov->handbrake_version &&
7561 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7562 st->codecpar->codec_id == AV_CODEC_ID_MP3
7564 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7565 st->need_parsing = AVSTREAM_PARSE_FULL;
7569 if (mov->trex_data) {
7570 for (i = 0; i < s->nb_streams; i++) {
7571 AVStream *st = s->streams[i];
7572 MOVStreamContext *sc = st->priv_data;
7573 if (st->duration > 0) {
7574 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7575 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7576 sc->data_size, sc->time_scale);
7578 return AVERROR_INVALIDDATA;
7580 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7585 if (mov->use_mfra_for > 0) {
7586 for (i = 0; i < s->nb_streams; i++) {
7587 AVStream *st = s->streams[i];
7588 MOVStreamContext *sc = st->priv_data;
7589 if (sc->duration_for_fps > 0) {
7590 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7591 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7592 sc->data_size, sc->time_scale);
7594 return AVERROR_INVALIDDATA;
7596 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7597 sc->duration_for_fps;
7602 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7603 if (mov->bitrates[i]) {
7604 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7608 ff_rfps_calculate(s);
7610 for (i = 0; i < s->nb_streams; i++) {
7611 AVStream *st = s->streams[i];
7612 MOVStreamContext *sc = st->priv_data;
7614 switch (st->codecpar->codec_type) {
7615 case AVMEDIA_TYPE_AUDIO:
7616 err = ff_replaygain_export(st, s->metadata);
7622 case AVMEDIA_TYPE_VIDEO:
7623 if (sc->display_matrix) {
7624 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7625 sizeof(int32_t) * 9);
7629 sc->display_matrix = NULL;
7632 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7633 (uint8_t *)sc->stereo3d,
7634 sizeof(*sc->stereo3d));
7638 sc->stereo3d = NULL;
7640 if (sc->spherical) {
7641 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7642 (uint8_t *)sc->spherical,
7643 sc->spherical_size);
7647 sc->spherical = NULL;
7649 if (sc->mastering) {
7650 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7651 (uint8_t *)sc->mastering,
7652 sizeof(*sc->mastering));
7656 sc->mastering = NULL;
7659 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7660 (uint8_t *)sc->coll,
7670 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7672 for (i = 0; i < mov->frag_index.nb_items; i++)
7673 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7674 mov->frag_index.item[i].headers_read = 1;
7679 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7681 AVIndexEntry *sample = NULL;
7682 int64_t best_dts = INT64_MAX;
7684 for (i = 0; i < s->nb_streams; i++) {
7685 AVStream *avst = s->streams[i];
7686 MOVStreamContext *msc = avst->priv_data;
7687 if (msc->pb && msc->current_sample < avst->nb_index_entries) {
7688 AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample];
7689 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7690 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7691 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7692 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7693 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb &&
7694 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7695 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7696 sample = current_sample;
7705 static int should_retry(AVIOContext *pb, int error_code) {
7706 if (error_code == AVERROR_EOF || avio_feof(pb))
7712 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7715 MOVContext *mov = s->priv_data;
7717 if (index >= 0 && index < mov->frag_index.nb_items)
7718 target = mov->frag_index.item[index].moof_offset;
7719 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7720 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7721 return AVERROR_INVALIDDATA;
7724 mov->next_root_atom = 0;
7725 if (index < 0 || index >= mov->frag_index.nb_items)
7726 index = search_frag_moof_offset(&mov->frag_index, target);
7727 if (index < mov->frag_index.nb_items) {
7728 if (index + 1 < mov->frag_index.nb_items)
7729 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7730 if (mov->frag_index.item[index].headers_read)
7732 mov->frag_index.item[index].headers_read = 1;
7735 mov->found_mdat = 0;
7737 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7740 if (avio_feof(s->pb))
7742 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7747 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7749 uint8_t *side, *extradata;
7752 /* Save the current index. */
7753 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7755 /* Notify the decoder that extradata changed. */
7756 extradata_size = sc->extradata_size[sc->last_stsd_index];
7757 extradata = sc->extradata[sc->last_stsd_index];
7758 if (extradata_size > 0 && extradata) {
7759 side = av_packet_new_side_data(pkt,
7760 AV_PKT_DATA_NEW_EXTRADATA,
7763 return AVERROR(ENOMEM);
7764 memcpy(side, extradata, extradata_size);
7770 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7772 MOVContext *mov = s->priv_data;
7773 MOVStreamContext *sc;
7774 AVIndexEntry *sample;
7775 AVStream *st = NULL;
7776 int64_t current_index;
7780 sample = mov_find_next_sample(s, &st);
7781 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7782 if (!mov->next_root_atom)
7784 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7789 /* must be done just before reading, to avoid infinite loop on sample */
7790 current_index = sc->current_index;
7791 mov_current_sample_inc(sc);
7793 if (mov->next_root_atom) {
7794 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7795 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7798 if (st->discard != AVDISCARD_ALL) {
7799 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7800 if (ret64 != sample->pos) {
7801 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7802 sc->ffindex, sample->pos);
7803 if (should_retry(sc->pb, ret64)) {
7804 mov_current_sample_dec(sc);
7806 return AVERROR_INVALIDDATA;
7809 if( st->discard == AVDISCARD_NONKEY && 0==(sample->flags & AVINDEX_KEYFRAME) ) {
7810 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7814 ret = av_get_packet(sc->pb, pkt, sample->size);
7816 if (should_retry(sc->pb, ret)) {
7817 mov_current_sample_dec(sc);
7821 if (sc->has_palette) {
7824 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7826 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7828 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7829 sc->has_palette = 0;
7832 #if CONFIG_DV_DEMUXER
7833 if (mov->dv_demux && sc->dv_audio_container) {
7834 avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7835 av_freep(&pkt->data);
7837 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7842 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7843 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7844 st->need_parsing = AVSTREAM_PARSE_FULL;
7848 pkt->stream_index = sc->ffindex;
7849 pkt->dts = sample->timestamp;
7850 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7851 pkt->flags |= AV_PKT_FLAG_DISCARD;
7853 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7854 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
7855 /* update ctts context */
7857 if (sc->ctts_index < sc->ctts_count &&
7858 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
7860 sc->ctts_sample = 0;
7863 int64_t next_dts = (sc->current_sample < st->nb_index_entries) ?
7864 st->index_entries[sc->current_sample].timestamp : st->duration;
7866 if (next_dts >= pkt->dts)
7867 pkt->duration = next_dts - pkt->dts;
7868 pkt->pts = pkt->dts;
7870 if (st->discard == AVDISCARD_ALL)
7872 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
7873 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
7874 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
7875 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
7877 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
7878 pkt->pos = sample->pos;
7880 /* Multiple stsd handling. */
7881 if (sc->stsc_data) {
7882 /* Keep track of the stsc index for the given sample, then check
7883 * if the stsd index is different from the last used one. */
7885 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
7886 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
7888 sc->stsc_sample = 0;
7889 /* Do not check indexes after a switch. */
7890 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
7891 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
7892 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
7893 ret = mov_change_extradata(sc, pkt);
7900 aax_filter(pkt->data, pkt->size, mov);
7902 ret = cenc_filter(mov, st, sc, pkt, current_index);
7910 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
7912 MOVContext *mov = s->priv_data;
7915 if (!mov->frag_index.complete)
7918 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
7921 if (!mov->frag_index.item[index].headers_read)
7922 return mov_switch_root(s, -1, index);
7923 if (index + 1 < mov->frag_index.nb_items)
7924 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7929 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
7931 MOVStreamContext *sc = st->priv_data;
7932 int sample, time_sample, ret;
7935 // Here we consider timestamp to be PTS, hence try to offset it so that we
7936 // can search over the DTS timeline.
7937 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
7939 ret = mov_seek_fragment(s, st, timestamp);
7943 sample = av_index_search_timestamp(st, timestamp, flags);
7944 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
7945 if (sample < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp)
7947 if (sample < 0) /* not sure what to do */
7948 return AVERROR_INVALIDDATA;
7949 mov_current_sample_set(sc, sample);
7950 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
7951 /* adjust ctts index */
7952 if (sc->ctts_data) {
7954 for (i = 0; i < sc->ctts_count; i++) {
7955 int next = time_sample + sc->ctts_data[i].count;
7956 if (next > sc->current_sample) {
7958 sc->ctts_sample = sc->current_sample - time_sample;
7965 /* adjust stsd index */
7966 if (sc->chunk_count) {
7968 for (i = 0; i < sc->stsc_count; i++) {
7969 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
7970 if (next > sc->current_sample) {
7972 sc->stsc_sample = sc->current_sample - time_sample;
7975 av_assert0(next == (int)next);
7983 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
7985 MOVContext *mc = s->priv_data;
7990 if (stream_index >= s->nb_streams)
7991 return AVERROR_INVALIDDATA;
7993 st = s->streams[stream_index];
7994 sample = mov_seek_stream(s, st, sample_time, flags);
7998 if (mc->seek_individually) {
7999 /* adjust seek timestamp to found sample timestamp */
8000 int64_t seek_timestamp = st->index_entries[sample].timestamp;
8002 for (i = 0; i < s->nb_streams; i++) {
8004 MOVStreamContext *sc = s->streams[i]->priv_data;
8006 st->skip_samples = (sample_time <= 0) ? sc->start_pad : 0;
8008 if (stream_index == i)
8011 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
8012 mov_seek_stream(s, st, timestamp, flags);
8015 for (i = 0; i < s->nb_streams; i++) {
8016 MOVStreamContext *sc;
8019 mov_current_sample_set(sc, 0);
8022 MOVStreamContext *sc;
8023 AVIndexEntry *entry = mov_find_next_sample(s, &st);
8025 return AVERROR_INVALIDDATA;
8027 if (sc->ffindex == stream_index && sc->current_sample == sample)
8029 mov_current_sample_inc(sc);
8035 #define OFFSET(x) offsetof(MOVContext, x)
8036 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
8037 static const AVOption mov_options[] = {
8038 {"use_absolute_path",
8039 "allow using absolute path when opening alias, this is a possible security issue",
8040 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
8042 {"seek_streams_individually",
8043 "Seek each stream individually to the closest point",
8044 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
8046 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
8048 {"advanced_editlist",
8049 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
8050 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
8052 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8055 "use mfra for fragment timestamps",
8056 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8057 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8059 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8060 FLAGS, "use_mfra_for" },
8061 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8062 FLAGS, "use_mfra_for" },
8063 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8064 FLAGS, "use_mfra_for" },
8065 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8066 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8067 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8068 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8069 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8070 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8071 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8072 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8073 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8074 .flags = AV_OPT_FLAG_DECODING_PARAM },
8075 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8076 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8077 {.i64 = 0}, 0, 1, FLAGS },
8082 static const AVClass mov_class = {
8083 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8084 .item_name = av_default_item_name,
8085 .option = mov_options,
8086 .version = LIBAVUTIL_VERSION_INT,
8089 AVInputFormat ff_mov_demuxer = {
8090 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8091 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8092 .priv_class = &mov_class,
8093 .priv_data_size = sizeof(MOVContext),
8094 .extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
8095 .read_probe = mov_probe,
8096 .read_header = mov_read_header,
8097 .read_packet = mov_read_packet,
8098 .read_close = mov_read_close,
8099 .read_seek = mov_read_seek,
8100 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,