3 * Copyright (c) 2001 Fabrice Bellard
4 * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
6 * first version by Francois Revol <revol@free.fr>
7 * seek function by Gael Chardon <gael.dev@4now.net>
9 * This file is part of FFmpeg.
11 * FFmpeg is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * FFmpeg is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with FFmpeg; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30 #include "libavutil/attributes.h"
31 #include "libavutil/channel_layout.h"
32 #include "libavutil/internal.h"
33 #include "libavutil/intreadwrite.h"
34 #include "libavutil/intfloat.h"
35 #include "libavutil/mathematics.h"
36 #include "libavutil/time_internal.h"
37 #include "libavutil/avassert.h"
38 #include "libavutil/avstring.h"
39 #include "libavutil/dict.h"
40 #include "libavutil/display.h"
41 #include "libavutil/opt.h"
42 #include "libavutil/aes.h"
43 #include "libavutil/aes_ctr.h"
44 #include "libavutil/pixdesc.h"
45 #include "libavutil/sha.h"
46 #include "libavutil/spherical.h"
47 #include "libavutil/stereo3d.h"
48 #include "libavutil/timecode.h"
49 #include "libavcodec/ac3tab.h"
50 #include "libavcodec/flac.h"
51 #include "libavcodec/mpegaudiodecheader.h"
52 #include "libavcodec/mlp_parse.h"
55 #include "avio_internal.h"
58 #include "libavcodec/get_bits.h"
61 #include "replaygain.h"
67 #include "qtpalette.h"
69 /* those functions parse an atom */
70 /* links atom IDs to parse functions */
71 typedef struct MOVParseTableEntry {
73 int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
76 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
77 static int mov_read_mfra(MOVContext *c, AVIOContext *f);
78 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
79 int count, int duration);
81 static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb,
82 unsigned len, const char *key)
86 short current, total = 0;
87 avio_rb16(pb); // unknown
88 current = avio_rb16(pb);
90 total = avio_rb16(pb);
92 snprintf(buf, sizeof(buf), "%d", current);
94 snprintf(buf, sizeof(buf), "%d/%d", current, total);
95 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
96 av_dict_set(&c->fc->metadata, key, buf, 0);
101 static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb,
102 unsigned len, const char *key)
104 /* bypass padding bytes */
109 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
110 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
115 static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb,
116 unsigned len, const char *key)
118 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
119 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
124 static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb,
125 unsigned len, const char *key)
129 avio_r8(pb); // unknown
132 if (genre < 1 || genre > ID3v1_GENRE_MAX)
134 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
135 av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
140 static const uint32_t mac_to_unicode[128] = {
141 0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
142 0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
143 0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
144 0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
145 0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
146 0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
147 0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
148 0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
149 0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
150 0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
151 0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
152 0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
153 0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
154 0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
155 0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
156 0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
159 static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len,
160 char *dst, int dstlen)
163 char *end = dst+dstlen-1;
166 for (i = 0; i < len; i++) {
167 uint8_t t, c = avio_r8(pb);
175 PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
181 static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
185 MOVStreamContext *sc;
190 case 0xd: id = AV_CODEC_ID_MJPEG; break;
191 case 0xe: id = AV_CODEC_ID_PNG; break;
192 case 0x1b: id = AV_CODEC_ID_BMP; break;
194 av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
199 st = avformat_new_stream(c->fc, NULL);
201 return AVERROR(ENOMEM);
202 sc = av_mallocz(sizeof(*sc));
204 return AVERROR(ENOMEM);
207 ret = av_get_packet(pb, &pkt, len);
211 if (pkt.size >= 8 && id != AV_CODEC_ID_BMP) {
212 if (AV_RB64(pkt.data) == 0x89504e470d0a1a0a) {
213 id = AV_CODEC_ID_PNG;
215 id = AV_CODEC_ID_MJPEG;
219 st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
221 st->attached_pic = pkt;
222 st->attached_pic.stream_index = st->index;
223 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
225 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
226 st->codecpar->codec_id = id;
232 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
234 char language[4] = { 0 };
235 char buf[200], place[100];
236 uint16_t langcode = 0;
237 double longitude, latitude, altitude;
238 const char *key = "location";
240 if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
241 av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
242 return AVERROR_INVALIDDATA;
245 avio_skip(pb, 4); // version+flags
246 langcode = avio_rb16(pb);
247 ff_mov_lang_to_iso639(langcode, language);
250 len -= avio_get_str(pb, len, place, sizeof(place));
252 av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
253 return AVERROR_INVALIDDATA;
255 avio_skip(pb, 1); // role
259 av_log(c->fc, AV_LOG_ERROR,
260 "loci too short (%u bytes left, need at least %d)\n", len, 12);
261 return AVERROR_INVALIDDATA;
263 longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
264 latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
265 altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
267 // Try to output in the same format as the ?xyz field
268 snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
270 av_strlcatf(buf, sizeof(buf), "%+f", altitude);
271 av_strlcatf(buf, sizeof(buf), "/%s", place);
273 if (*language && strcmp(language, "und")) {
275 snprintf(key2, sizeof(key2), "%s-%s", key, language);
276 av_dict_set(&c->fc->metadata, key2, buf, 0);
278 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
279 return av_dict_set(&c->fc->metadata, key, buf, 0);
282 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
288 if (c->ignore_chapters)
291 n_hmmt = avio_rb32(pb);
292 for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
293 int moment_time = avio_rb32(pb);
294 avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
299 static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
302 char key2[32], language[4] = {0};
304 const char *key = NULL;
305 uint16_t langcode = 0;
306 uint32_t data_type = 0, str_size, str_size_alloc;
307 int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
312 case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
313 case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
314 case MKTAG( 'X','M','P','_'):
315 if (c->export_xmp) { key = "xmp"; raw = 1; } break;
316 case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
317 case MKTAG( 'a','k','I','D'): key = "account_type";
318 parse = mov_metadata_int8_no_padding; break;
319 case MKTAG( 'a','p','I','D'): key = "account_id"; break;
320 case MKTAG( 'c','a','t','g'): key = "category"; break;
321 case MKTAG( 'c','p','i','l'): key = "compilation";
322 parse = mov_metadata_int8_no_padding; break;
323 case MKTAG( 'c','p','r','t'): key = "copyright"; break;
324 case MKTAG( 'd','e','s','c'): key = "description"; break;
325 case MKTAG( 'd','i','s','k'): key = "disc";
326 parse = mov_metadata_track_or_disc_number; break;
327 case MKTAG( 'e','g','i','d'): key = "episode_uid";
328 parse = mov_metadata_int8_no_padding; break;
329 case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
330 case MKTAG( 'g','n','r','e'): key = "genre";
331 parse = mov_metadata_gnre; break;
332 case MKTAG( 'h','d','v','d'): key = "hd_video";
333 parse = mov_metadata_int8_no_padding; break;
334 case MKTAG( 'H','M','M','T'):
335 return mov_metadata_hmmt(c, pb, atom.size);
336 case MKTAG( 'k','e','y','w'): key = "keywords"; break;
337 case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
338 case MKTAG( 'l','o','c','i'):
339 return mov_metadata_loci(c, pb, atom.size);
340 case MKTAG( 'm','a','n','u'): key = "make"; break;
341 case MKTAG( 'm','o','d','l'): key = "model"; break;
342 case MKTAG( 'p','c','s','t'): key = "podcast";
343 parse = mov_metadata_int8_no_padding; break;
344 case MKTAG( 'p','g','a','p'): key = "gapless_playback";
345 parse = mov_metadata_int8_no_padding; break;
346 case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
347 case MKTAG( 'r','t','n','g'): key = "rating";
348 parse = mov_metadata_int8_no_padding; break;
349 case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
350 case MKTAG( 's','o','a','l'): key = "sort_album"; break;
351 case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
352 case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
353 case MKTAG( 's','o','n','m'): key = "sort_name"; break;
354 case MKTAG( 's','o','s','n'): key = "sort_show"; break;
355 case MKTAG( 's','t','i','k'): key = "media_type";
356 parse = mov_metadata_int8_no_padding; break;
357 case MKTAG( 't','r','k','n'): key = "track";
358 parse = mov_metadata_track_or_disc_number; break;
359 case MKTAG( 't','v','e','n'): key = "episode_id"; break;
360 case MKTAG( 't','v','e','s'): key = "episode_sort";
361 parse = mov_metadata_int8_bypass_padding; break;
362 case MKTAG( 't','v','n','n'): key = "network"; break;
363 case MKTAG( 't','v','s','h'): key = "show"; break;
364 case MKTAG( 't','v','s','n'): key = "season_number";
365 parse = mov_metadata_int8_bypass_padding; break;
366 case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
367 case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
368 case MKTAG(0xa9,'a','l','b'): key = "album"; break;
369 case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
370 case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
371 case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
372 case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
373 case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
374 case MKTAG(0xa9,'d','a','y'): key = "date"; break;
375 case MKTAG(0xa9,'d','i','r'): key = "director"; break;
376 case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
377 case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
378 case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
379 case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
380 case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
381 case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
382 case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
383 case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
384 case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
385 case MKTAG(0xa9,'m','a','k'): key = "make"; break;
386 case MKTAG(0xa9,'m','o','d'): key = "model"; break;
387 case MKTAG(0xa9,'n','a','m'): key = "title"; break;
388 case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
389 case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
390 case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
391 case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
392 case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
393 case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
394 case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
395 case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
396 case MKTAG(0xa9,'t','r','k'): key = "track"; break;
397 case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
398 case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
399 case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
400 case MKTAG(0xa9,'x','y','z'): key = "location"; break;
403 if (c->itunes_metadata && atom.size > 8) {
404 int data_size = avio_rb32(pb);
405 int tag = avio_rl32(pb);
406 if (tag == MKTAG('d','a','t','a') && data_size <= atom.size) {
407 data_type = avio_rb32(pb); // type
408 avio_rb32(pb); // unknown
409 str_size = data_size - 16;
412 if (atom.type == MKTAG('c', 'o', 'v', 'r')) {
413 int ret = mov_read_covr(c, pb, data_type, str_size);
415 av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
418 atom.size -= str_size;
422 } else if (!key && c->found_hdlr_mdta && c->meta_keys) {
423 uint32_t index = AV_RB32(&atom.type);
424 if (index < c->meta_keys_count && index > 0) {
425 key = c->meta_keys[index];
427 av_log(c->fc, AV_LOG_WARNING,
428 "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
429 index, c->meta_keys_count);
433 } else if (atom.size > 4 && key && !c->itunes_metadata && !raw) {
434 str_size = avio_rb16(pb); // string length
435 if (str_size > atom.size) {
437 avio_seek(pb, -2, SEEK_CUR);
438 av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
441 langcode = avio_rb16(pb);
442 ff_mov_lang_to_iso639(langcode, language);
445 str_size = atom.size;
447 if (c->export_all && !key) {
448 snprintf(tmp_key, 5, "%.4s", (char*)&atom.type);
454 if (atom.size < 0 || str_size >= INT_MAX/2)
455 return AVERROR_INVALIDDATA;
457 // Allocates enough space if data_type is a int32 or float32 number, otherwise
458 // worst-case requirement for output string in case of utf8 coded input
459 num = (data_type >= 21 && data_type <= 23);
460 str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
461 str = av_mallocz(str_size_alloc);
463 return AVERROR(ENOMEM);
466 parse(c, pb, str_size, key);
468 if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
469 mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
470 } else if (data_type == 21) { // BE signed integer, variable size
473 val = (int8_t)avio_r8(pb);
474 else if (str_size == 2)
475 val = (int16_t)avio_rb16(pb);
476 else if (str_size == 3)
477 val = ((int32_t)(avio_rb24(pb)<<8))>>8;
478 else if (str_size == 4)
479 val = (int32_t)avio_rb32(pb);
480 if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
481 av_log(c->fc, AV_LOG_ERROR,
482 "Failed to store the number (%d) in string.\n", val);
484 return AVERROR_INVALIDDATA;
486 } else if (data_type == 22) { // BE unsigned integer, variable size
487 unsigned int val = 0;
490 else if (str_size == 2)
492 else if (str_size == 3)
494 else if (str_size == 4)
496 if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
497 av_log(c->fc, AV_LOG_ERROR,
498 "Failed to store the number (%u) in string.\n", val);
500 return AVERROR_INVALIDDATA;
502 } else if (data_type == 23 && str_size >= 4) { // BE float32
503 float val = av_int2float(avio_rb32(pb));
504 if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
505 av_log(c->fc, AV_LOG_ERROR,
506 "Failed to store the float32 number (%f) in string.\n", val);
508 return AVERROR_INVALIDDATA;
511 int ret = ffio_read_size(pb, str, str_size);
518 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
519 av_dict_set(&c->fc->metadata, key, str, 0);
520 if (*language && strcmp(language, "und")) {
521 snprintf(key2, sizeof(key2), "%s-%s", key, language);
522 av_dict_set(&c->fc->metadata, key2, str, 0);
524 if (!strcmp(key, "encoder")) {
525 int major, minor, micro;
526 if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, µ) == 3) {
527 c->handbrake_version = 1000000*major + 1000*minor + micro;
536 static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
539 int i, nb_chapters, str_len, version;
543 if (c->ignore_chapters)
546 if ((atom.size -= 5) < 0)
549 version = avio_r8(pb);
552 avio_rb32(pb); // ???
553 nb_chapters = avio_r8(pb);
555 for (i = 0; i < nb_chapters; i++) {
559 start = avio_rb64(pb);
560 str_len = avio_r8(pb);
562 if ((atom.size -= 9+str_len) < 0)
565 ret = ffio_read_size(pb, str, str_len);
569 avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
574 #define MIN_DATA_ENTRY_BOX_SIZE 12
575 static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
578 MOVStreamContext *sc;
581 if (c->fc->nb_streams < 1)
583 st = c->fc->streams[c->fc->nb_streams-1];
586 avio_rb32(pb); // version + flags
587 entries = avio_rb32(pb);
589 entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
590 entries >= UINT_MAX / sizeof(*sc->drefs))
591 return AVERROR_INVALIDDATA;
595 sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
597 return AVERROR(ENOMEM);
598 sc->drefs_count = entries;
600 for (i = 0; i < entries; i++) {
601 MOVDref *dref = &sc->drefs[i];
602 uint32_t size = avio_rb32(pb);
603 int64_t next = avio_tell(pb) + size - 4;
606 return AVERROR_INVALIDDATA;
608 dref->type = avio_rl32(pb);
609 avio_rb32(pb); // version + flags
611 if (dref->type == MKTAG('a','l','i','s') && size > 150) {
612 /* macintosh alias record */
613 uint16_t volume_len, len;
619 volume_len = avio_r8(pb);
620 volume_len = FFMIN(volume_len, 27);
621 ret = ffio_read_size(pb, dref->volume, 27);
624 dref->volume[volume_len] = 0;
625 av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
630 len = FFMIN(len, 63);
631 ret = ffio_read_size(pb, dref->filename, 63);
634 dref->filename[len] = 0;
635 av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
639 /* read next level up_from_alias/down_to_target */
640 dref->nlvl_from = avio_rb16(pb);
641 dref->nlvl_to = avio_rb16(pb);
642 av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
643 dref->nlvl_from, dref->nlvl_to);
647 for (type = 0; type != -1 && avio_tell(pb) < next; ) {
650 type = avio_rb16(pb);
652 av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
655 if (type == 2) { // absolute path
657 dref->path = av_mallocz(len+1);
659 return AVERROR(ENOMEM);
661 ret = ffio_read_size(pb, dref->path, len);
663 av_freep(&dref->path);
666 if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
668 memmove(dref->path, dref->path+volume_len, len);
671 // trim string of any ending zeros
672 for (j = len - 1; j >= 0; j--) {
673 if (dref->path[j] == 0)
678 for (j = 0; j < len; j++)
679 if (dref->path[j] == ':' || dref->path[j] == 0)
681 av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
682 } else if (type == 0) { // directory name
684 dref->dir = av_malloc(len+1);
686 return AVERROR(ENOMEM);
688 ret = ffio_read_size(pb, dref->dir, len);
690 av_freep(&dref->dir);
694 for (j = 0; j < len; j++)
695 if (dref->dir[j] == ':')
697 av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
702 av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
707 avio_seek(pb, next, SEEK_SET);
712 static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
721 avio_r8(pb); /* version */
722 avio_rb24(pb); /* flags */
725 ctype = avio_rl32(pb);
726 type = avio_rl32(pb); /* component subtype */
728 av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
729 av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
731 if (c->trak_index < 0) { // meta not inside a trak
732 if (type == MKTAG('m','d','t','a')) {
733 c->found_hdlr_mdta = 1;
738 st = c->fc->streams[c->fc->nb_streams-1];
740 if (type == MKTAG('v','i','d','e'))
741 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
742 else if (type == MKTAG('s','o','u','n'))
743 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
744 else if (type == MKTAG('m','1','a',' '))
745 st->codecpar->codec_id = AV_CODEC_ID_MP2;
746 else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
747 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
749 avio_rb32(pb); /* component manufacture */
750 avio_rb32(pb); /* component flags */
751 avio_rb32(pb); /* component flags mask */
753 title_size = atom.size - 24;
754 if (title_size > 0) {
755 if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
756 return AVERROR_INVALIDDATA;
757 title_str = av_malloc(title_size + 1); /* Add null terminator */
759 return AVERROR(ENOMEM);
761 ret = ffio_read_size(pb, title_str, title_size);
763 av_freep(&title_str);
766 title_str[title_size] = 0;
768 int off = (!c->isom && title_str[0] == title_size - 1);
769 // flag added so as to not set stream handler name if already set from mdia->hdlr
770 av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
772 av_freep(&title_str);
778 static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
780 return ff_mov_read_esds(c->fc, pb);
783 static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
786 enum AVAudioServiceType *ast;
787 int ac3info, acmod, lfeon, bsmod;
789 if (c->fc->nb_streams < 1)
791 st = c->fc->streams[c->fc->nb_streams-1];
793 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
796 return AVERROR(ENOMEM);
798 ac3info = avio_rb24(pb);
799 bsmod = (ac3info >> 14) & 0x7;
800 acmod = (ac3info >> 11) & 0x7;
801 lfeon = (ac3info >> 10) & 0x1;
802 st->codecpar->channels = ((int[]){2,1,2,3,3,4,4,5})[acmod] + lfeon;
803 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
805 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
807 if (st->codecpar->channels > 1 && bsmod == 0x7)
808 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
810 #if FF_API_LAVF_AVCTX
811 FF_DISABLE_DEPRECATION_WARNINGS
812 st->codec->audio_service_type = *ast;
813 FF_ENABLE_DEPRECATION_WARNINGS
819 static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
822 enum AVAudioServiceType *ast;
823 int eac3info, acmod, lfeon, bsmod;
825 if (c->fc->nb_streams < 1)
827 st = c->fc->streams[c->fc->nb_streams-1];
829 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
832 return AVERROR(ENOMEM);
834 /* No need to parse fields for additional independent substreams and its
835 * associated dependent substreams since libavcodec's E-AC-3 decoder
836 * does not support them yet. */
837 avio_rb16(pb); /* data_rate and num_ind_sub */
838 eac3info = avio_rb24(pb);
839 bsmod = (eac3info >> 12) & 0x1f;
840 acmod = (eac3info >> 9) & 0x7;
841 lfeon = (eac3info >> 8) & 0x1;
842 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
844 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
845 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
847 if (st->codecpar->channels > 1 && bsmod == 0x7)
848 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
850 #if FF_API_LAVF_AVCTX
851 FF_DISABLE_DEPRECATION_WARNINGS
852 st->codec->audio_service_type = *ast;
853 FF_ENABLE_DEPRECATION_WARNINGS
859 static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
861 const uint32_t ddts_size = 20;
864 uint32_t frame_duration_code = 0;
865 uint32_t channel_layout_code = 0;
868 buf = av_malloc(ddts_size + AV_INPUT_BUFFER_PADDING_SIZE);
870 return AVERROR(ENOMEM);
872 if (avio_read(pb, buf, ddts_size) < ddts_size) {
874 return AVERROR_INVALIDDATA;
877 init_get_bits(&gb, buf, 8*ddts_size);
879 if (c->fc->nb_streams < 1) {
883 st = c->fc->streams[c->fc->nb_streams-1];
885 st->codecpar->sample_rate = get_bits_long(&gb, 32);
886 if (st->codecpar->sample_rate <= 0) {
887 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
889 return AVERROR_INVALIDDATA;
891 skip_bits_long(&gb, 32); /* max bitrate */
892 st->codecpar->bit_rate = get_bits_long(&gb, 32);
893 st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
894 frame_duration_code = get_bits(&gb, 2);
895 skip_bits(&gb, 30); /* various fields */
896 channel_layout_code = get_bits(&gb, 16);
898 st->codecpar->frame_size =
899 (frame_duration_code == 0) ? 512 :
900 (frame_duration_code == 1) ? 1024 :
901 (frame_duration_code == 2) ? 2048 :
902 (frame_duration_code == 3) ? 4096 : 0;
904 if (channel_layout_code > 0xff) {
905 av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout");
907 st->codecpar->channel_layout =
908 ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
909 ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
910 ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
911 ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
912 ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
913 ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0);
915 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
921 static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
925 if (c->fc->nb_streams < 1)
927 st = c->fc->streams[c->fc->nb_streams-1];
932 /* skip version and flags */
935 ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
940 static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
945 if (c->fc->nb_streams < 1)
947 st = c->fc->streams[c->fc->nb_streams-1];
949 if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
950 av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
955 static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
957 const int num = avio_rb32(pb);
958 const int den = avio_rb32(pb);
961 if (c->fc->nb_streams < 1)
963 st = c->fc->streams[c->fc->nb_streams-1];
965 if ((st->sample_aspect_ratio.den != 1 || st->sample_aspect_ratio.num) && // default
966 (den != st->sample_aspect_ratio.den || num != st->sample_aspect_ratio.num)) {
967 av_log(c->fc, AV_LOG_WARNING,
968 "sample aspect ratio already set to %d:%d, ignoring 'pasp' atom (%d:%d)\n",
969 st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
971 } else if (den != 0) {
972 av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den,
978 /* this atom contains actual media data */
979 static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
981 if (atom.size == 0) /* wrong one (MP4) */
984 return 0; /* now go for moov */
987 #define DRM_BLOB_SIZE 56
989 static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
991 uint8_t intermediate_key[20];
992 uint8_t intermediate_iv[20];
995 uint8_t file_checksum[20];
996 uint8_t calculated_checksum[20];
1000 uint8_t *activation_bytes = c->activation_bytes;
1001 uint8_t *fixed_key = c->audible_fixed_key;
1005 sha = av_sha_alloc();
1007 return AVERROR(ENOMEM);
1008 av_free(c->aes_decrypt);
1009 c->aes_decrypt = av_aes_alloc();
1010 if (!c->aes_decrypt) {
1011 ret = AVERROR(ENOMEM);
1015 /* drm blob processing */
1016 avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1017 avio_read(pb, input, DRM_BLOB_SIZE);
1018 avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1019 avio_read(pb, file_checksum, 20);
1021 av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == "); // required by external tools
1022 for (i = 0; i < 20; i++)
1023 av_log(c->fc, AV_LOG_INFO, "%02x", file_checksum[i]);
1024 av_log(c->fc, AV_LOG_INFO, "\n");
1026 /* verify activation data */
1027 if (!activation_bytes) {
1028 av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1029 ret = 0; /* allow ffprobe to continue working on .aax files */
1032 if (c->activation_bytes_size != 4) {
1033 av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1034 ret = AVERROR(EINVAL);
1038 /* verify fixed key */
1039 if (c->audible_fixed_key_size != 16) {
1040 av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1041 ret = AVERROR(EINVAL);
1045 /* AAX (and AAX+) key derivation */
1046 av_sha_init(sha, 160);
1047 av_sha_update(sha, fixed_key, 16);
1048 av_sha_update(sha, activation_bytes, 4);
1049 av_sha_final(sha, intermediate_key);
1050 av_sha_init(sha, 160);
1051 av_sha_update(sha, fixed_key, 16);
1052 av_sha_update(sha, intermediate_key, 20);
1053 av_sha_update(sha, activation_bytes, 4);
1054 av_sha_final(sha, intermediate_iv);
1055 av_sha_init(sha, 160);
1056 av_sha_update(sha, intermediate_key, 16);
1057 av_sha_update(sha, intermediate_iv, 16);
1058 av_sha_final(sha, calculated_checksum);
1059 if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1060 av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1061 ret = AVERROR_INVALIDDATA;
1064 av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1065 av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1066 for (i = 0; i < 4; i++) {
1067 // file data (in output) is stored in big-endian mode
1068 if (activation_bytes[i] != output[3 - i]) { // critical error
1069 av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1070 ret = AVERROR_INVALIDDATA;
1074 memcpy(c->file_key, output + 8, 16);
1075 memcpy(input, output + 26, 16);
1076 av_sha_init(sha, 160);
1077 av_sha_update(sha, input, 16);
1078 av_sha_update(sha, c->file_key, 16);
1079 av_sha_update(sha, fixed_key, 16);
1080 av_sha_final(sha, c->file_iv);
1088 // Audible AAX (and AAX+) bytestream decryption
1089 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1092 unsigned char iv[16];
1094 memcpy(iv, c->file_iv, 16); // iv is overwritten
1095 blocks = size >> 4; // trailing bytes are not encrypted!
1096 av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1097 av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1102 /* read major brand, minor version and compatible brands and store them as metadata */
1103 static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1106 int comp_brand_size;
1107 char* comp_brands_str;
1108 uint8_t type[5] = {0};
1109 int ret = ffio_read_size(pb, type, 4);
1113 if (strcmp(type, "qt "))
1115 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1116 av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1117 minor_ver = avio_rb32(pb); /* minor version */
1118 av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1120 comp_brand_size = atom.size - 8;
1121 if (comp_brand_size < 0)
1122 return AVERROR_INVALIDDATA;
1123 comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1124 if (!comp_brands_str)
1125 return AVERROR(ENOMEM);
1127 ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1129 av_freep(&comp_brands_str);
1132 comp_brands_str[comp_brand_size] = 0;
1133 av_dict_set(&c->fc->metadata, "compatible_brands",
1134 comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1139 /* this atom should contain all header atoms */
1140 static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1144 if (c->found_moov) {
1145 av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1146 avio_skip(pb, atom.size);
1150 if ((ret = mov_read_default(c, pb, atom)) < 0)
1152 /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1153 /* so we don't parse the whole file if over a network */
1155 return 0; /* now go for mdat */
1158 static MOVFragmentStreamInfo * get_frag_stream_info(
1159 MOVFragmentIndex *frag_index,
1164 MOVFragmentIndexItem * item;
1166 if (index < 0 || index >= frag_index->nb_items)
1168 item = &frag_index->item[index];
1169 for (i = 0; i < item->nb_stream_info; i++)
1170 if (item->stream_info[i].id == id)
1171 return &item->stream_info[i];
1173 // This shouldn't happen
1177 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1180 MOVFragmentIndexItem * item;
1182 if (frag_index->current < 0 ||
1183 frag_index->current >= frag_index->nb_items)
1186 item = &frag_index->item[frag_index->current];
1187 for (i = 0; i < item->nb_stream_info; i++)
1188 if (item->stream_info[i].id == id) {
1193 // id not found. This shouldn't happen.
1197 static MOVFragmentStreamInfo * get_current_frag_stream_info(
1198 MOVFragmentIndex *frag_index)
1200 MOVFragmentIndexItem *item;
1201 if (frag_index->current < 0 ||
1202 frag_index->current >= frag_index->nb_items)
1205 item = &frag_index->item[frag_index->current];
1206 if (item->current >= 0 && item->current < item->nb_stream_info)
1207 return &item->stream_info[item->current];
1209 // This shouldn't happen
1213 static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
1216 int64_t moof_offset;
1218 // Optimize for appending new entries
1219 if (!frag_index->nb_items ||
1220 frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1221 return frag_index->nb_items;
1224 b = frag_index->nb_items;
1228 moof_offset = frag_index->item[m].moof_offset;
1229 if (moof_offset >= offset)
1231 if (moof_offset <= offset)
1237 static int64_t get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
1239 av_assert0(frag_stream_info);
1240 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1241 return frag_stream_info->sidx_pts;
1242 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1243 return frag_stream_info->first_tfra_pts;
1244 return frag_stream_info->tfdt_dts;
1247 static int64_t get_frag_time(MOVFragmentIndex *frag_index,
1248 int index, int track_id)
1250 MOVFragmentStreamInfo * frag_stream_info;
1254 if (track_id >= 0) {
1255 frag_stream_info = get_frag_stream_info(frag_index, index, track_id);
1256 return frag_stream_info->sidx_pts;
1259 for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1260 frag_stream_info = &frag_index->item[index].stream_info[i];
1261 timestamp = get_stream_info_time(frag_stream_info);
1262 if (timestamp != AV_NOPTS_VALUE)
1265 return AV_NOPTS_VALUE;
1268 static int search_frag_timestamp(MOVFragmentIndex *frag_index,
1269 AVStream *st, int64_t timestamp)
1276 // If the stream is referenced by any sidx, limit the search
1277 // to fragments that referenced this stream in the sidx
1278 MOVStreamContext *sc = st->priv_data;
1284 b = frag_index->nb_items;
1287 m0 = m = (a + b) >> 1;
1290 (frag_time = get_frag_time(frag_index, m, id)) == AV_NOPTS_VALUE)
1293 if (m < b && frag_time <= timestamp)
1302 static int update_frag_index(MOVContext *c, int64_t offset)
1305 MOVFragmentIndexItem * item;
1306 MOVFragmentStreamInfo * frag_stream_info;
1308 // If moof_offset already exists in frag_index, return index to it
1309 index = search_frag_moof_offset(&c->frag_index, offset);
1310 if (index < c->frag_index.nb_items &&
1311 c->frag_index.item[index].moof_offset == offset)
1314 // offset is not yet in frag index.
1315 // Insert new item at index (sorted by moof offset)
1316 item = av_fast_realloc(c->frag_index.item,
1317 &c->frag_index.allocated_size,
1318 (c->frag_index.nb_items + 1) *
1319 sizeof(*c->frag_index.item));
1322 c->frag_index.item = item;
1324 frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1325 sizeof(*item->stream_info));
1326 if (!frag_stream_info)
1329 for (i = 0; i < c->fc->nb_streams; i++) {
1330 // Avoid building frag index if streams lack track id.
1331 if (c->fc->streams[i]->id < 0) {
1332 av_free(frag_stream_info);
1333 return AVERROR_INVALIDDATA;
1336 frag_stream_info[i].id = c->fc->streams[i]->id;
1337 frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1338 frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1339 frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1340 frag_stream_info[i].index_entry = -1;
1341 frag_stream_info[i].encryption_index = NULL;
1344 if (index < c->frag_index.nb_items)
1345 memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1346 (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1348 item = &c->frag_index.item[index];
1349 item->headers_read = 0;
1351 item->nb_stream_info = c->fc->nb_streams;
1352 item->moof_offset = offset;
1353 item->stream_info = frag_stream_info;
1354 c->frag_index.nb_items++;
1359 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1360 int id, int entries)
1363 MOVFragmentStreamInfo * frag_stream_info;
1367 for (i = index; i < frag_index->nb_items; i++) {
1368 frag_stream_info = get_frag_stream_info(frag_index, i, id);
1369 if (frag_stream_info && frag_stream_info->index_entry >= 0)
1370 frag_stream_info->index_entry += entries;
1374 static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1376 // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1377 c->fragment.found_tfhd = 0;
1379 if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1380 c->has_looked_for_mfra = 1;
1381 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1383 av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1385 if ((ret = mov_read_mfra(c, pb)) < 0) {
1386 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1387 "read the mfra (may be a live ismv)\n");
1390 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1391 "seekable, can not look for mfra\n");
1394 c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1395 av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1396 c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1397 return mov_read_default(c, pb, atom);
1400 static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time, void *logctx)
1403 if(time >= 2082844800)
1404 time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1406 if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1407 av_log(logctx, AV_LOG_DEBUG, "creation_time is not representable\n");
1411 avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1415 static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1418 MOVStreamContext *sc;
1420 char language[4] = {0};
1422 int64_t creation_time;
1424 if (c->fc->nb_streams < 1)
1426 st = c->fc->streams[c->fc->nb_streams-1];
1429 if (sc->time_scale) {
1430 av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1431 return AVERROR_INVALIDDATA;
1434 version = avio_r8(pb);
1436 avpriv_request_sample(c->fc, "Version %d", version);
1437 return AVERROR_PATCHWELCOME;
1439 avio_rb24(pb); /* flags */
1441 creation_time = avio_rb64(pb);
1444 creation_time = avio_rb32(pb);
1445 avio_rb32(pb); /* modification time */
1447 mov_metadata_creation_time(&st->metadata, creation_time, c->fc);
1449 sc->time_scale = avio_rb32(pb);
1450 if (sc->time_scale <= 0) {
1451 av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1454 st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1456 lang = avio_rb16(pb); /* language */
1457 if (ff_mov_lang_to_iso639(lang, language))
1458 av_dict_set(&st->metadata, "language", language, 0);
1459 avio_rb16(pb); /* quality */
1464 static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1467 int64_t creation_time;
1468 int version = avio_r8(pb); /* version */
1469 avio_rb24(pb); /* flags */
1472 creation_time = avio_rb64(pb);
1475 creation_time = avio_rb32(pb);
1476 avio_rb32(pb); /* modification time */
1478 mov_metadata_creation_time(&c->fc->metadata, creation_time, c->fc);
1479 c->time_scale = avio_rb32(pb); /* time scale */
1480 if (c->time_scale <= 0) {
1481 av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1484 av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1486 c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1487 // set the AVCodecContext duration because the duration of individual tracks
1488 // may be inaccurate
1489 if (c->time_scale > 0 && !c->trex_data)
1490 c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale);
1491 avio_rb32(pb); /* preferred scale */
1493 avio_rb16(pb); /* preferred volume */
1495 avio_skip(pb, 10); /* reserved */
1497 /* movie display matrix, store it in main context and use it later on */
1498 for (i = 0; i < 3; i++) {
1499 c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1500 c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1501 c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1504 avio_rb32(pb); /* preview time */
1505 avio_rb32(pb); /* preview duration */
1506 avio_rb32(pb); /* poster time */
1507 avio_rb32(pb); /* selection time */
1508 avio_rb32(pb); /* selection duration */
1509 avio_rb32(pb); /* current time */
1510 avio_rb32(pb); /* next track ID */
1515 static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1520 if (c->fc->nb_streams < 1)
1522 st = c->fc->streams[c->fc->nb_streams-1];
1524 little_endian = avio_rb16(pb) & 0xFF;
1525 av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1526 if (little_endian == 1) {
1527 switch (st->codecpar->codec_id) {
1528 case AV_CODEC_ID_PCM_S24BE:
1529 st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE;
1531 case AV_CODEC_ID_PCM_S32BE:
1532 st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE;
1534 case AV_CODEC_ID_PCM_F32BE:
1535 st->codecpar->codec_id = AV_CODEC_ID_PCM_F32LE;
1537 case AV_CODEC_ID_PCM_F64BE:
1538 st->codecpar->codec_id = AV_CODEC_ID_PCM_F64LE;
1547 static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1550 uint8_t *icc_profile;
1551 char color_parameter_type[5] = { 0 };
1552 uint16_t color_primaries, color_trc, color_matrix;
1555 if (c->fc->nb_streams < 1)
1557 st = c->fc->streams[c->fc->nb_streams - 1];
1559 ret = ffio_read_size(pb, color_parameter_type, 4);
1562 if (strncmp(color_parameter_type, "nclx", 4) &&
1563 strncmp(color_parameter_type, "nclc", 4) &&
1564 strncmp(color_parameter_type, "prof", 4)) {
1565 av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
1566 color_parameter_type);
1570 if (!strncmp(color_parameter_type, "prof", 4)) {
1571 icc_profile = av_stream_new_side_data(st, AV_PKT_DATA_ICC_PROFILE, atom.size - 4);
1573 return AVERROR(ENOMEM);
1574 ret = ffio_read_size(pb, icc_profile, atom.size - 4);
1579 color_primaries = avio_rb16(pb);
1580 color_trc = avio_rb16(pb);
1581 color_matrix = avio_rb16(pb);
1583 av_log(c->fc, AV_LOG_TRACE,
1584 "%s: pri %d trc %d matrix %d",
1585 color_parameter_type, color_primaries, color_trc, color_matrix);
1587 if (!strncmp(color_parameter_type, "nclx", 4)) {
1588 uint8_t color_range = avio_r8(pb) >> 7;
1589 av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
1591 st->codecpar->color_range = AVCOL_RANGE_JPEG;
1593 st->codecpar->color_range = AVCOL_RANGE_MPEG;
1596 if (!av_color_primaries_name(color_primaries))
1597 color_primaries = AVCOL_PRI_UNSPECIFIED;
1598 if (!av_color_transfer_name(color_trc))
1599 color_trc = AVCOL_TRC_UNSPECIFIED;
1600 if (!av_color_space_name(color_matrix))
1601 color_matrix = AVCOL_SPC_UNSPECIFIED;
1603 st->codecpar->color_primaries = color_primaries;
1604 st->codecpar->color_trc = color_trc;
1605 st->codecpar->color_space = color_matrix;
1606 av_log(c->fc, AV_LOG_TRACE, "\n");
1611 static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1614 unsigned mov_field_order;
1615 enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
1617 if (c->fc->nb_streams < 1) // will happen with jp2 files
1619 st = c->fc->streams[c->fc->nb_streams-1];
1621 return AVERROR_INVALIDDATA;
1622 mov_field_order = avio_rb16(pb);
1623 if ((mov_field_order & 0xFF00) == 0x0100)
1624 decoded_field_order = AV_FIELD_PROGRESSIVE;
1625 else if ((mov_field_order & 0xFF00) == 0x0200) {
1626 switch (mov_field_order & 0xFF) {
1627 case 0x01: decoded_field_order = AV_FIELD_TT;
1629 case 0x06: decoded_field_order = AV_FIELD_BB;
1631 case 0x09: decoded_field_order = AV_FIELD_TB;
1633 case 0x0E: decoded_field_order = AV_FIELD_BT;
1637 if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
1638 av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
1640 st->codecpar->field_order = decoded_field_order;
1645 static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
1648 uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
1649 if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
1650 return AVERROR_INVALIDDATA;
1651 if ((err = av_reallocp(&par->extradata, size)) < 0) {
1652 par->extradata_size = 0;
1655 par->extradata_size = size - AV_INPUT_BUFFER_PADDING_SIZE;
1659 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
1660 static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1661 AVCodecParameters *par, uint8_t *buf)
1663 int64_t result = atom.size;
1666 AV_WB32(buf , atom.size + 8);
1667 AV_WL32(buf + 4, atom.type);
1668 err = ffio_read_size(pb, buf + 8, atom.size);
1670 par->extradata_size -= atom.size;
1672 } else if (err < atom.size) {
1673 av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
1674 par->extradata_size -= atom.size - err;
1677 memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1681 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
1682 static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1683 enum AVCodecID codec_id)
1686 uint64_t original_size;
1689 if (c->fc->nb_streams < 1) // will happen with jp2 files
1691 st = c->fc->streams[c->fc->nb_streams-1];
1693 if (st->codecpar->codec_id != codec_id)
1694 return 0; /* unexpected codec_id - don't mess with extradata */
1696 original_size = st->codecpar->extradata_size;
1697 err = mov_realloc_extradata(st->codecpar, atom);
1701 err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
1704 return 0; // Note: this is the original behavior to ignore truncation.
1707 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
1708 static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1710 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
1713 static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1715 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS);
1718 static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1720 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
1723 static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1725 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
1728 static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1730 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
1732 ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
1736 static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1738 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
1740 if (!ret && c->fc->nb_streams >= 1) {
1741 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1742 if (par->extradata_size >= 40) {
1743 par->height = AV_RB16(&par->extradata[36]);
1744 par->width = AV_RB16(&par->extradata[38]);
1750 static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1752 if (c->fc->nb_streams >= 1) {
1753 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1754 if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
1755 par->codec_id == AV_CODEC_ID_H264 &&
1759 cid = avio_rb16(pb);
1760 /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
1761 if (cid == 0xd4d || cid == 0xd4e)
1764 } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
1765 par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
1766 par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
1770 num = avio_rb32(pb);
1771 den = avio_rb32(pb);
1772 if (num <= 0 || den <= 0)
1774 switch (avio_rb32(pb)) {
1776 if (den >= INT_MAX / 2)
1780 c->fc->streams[c->fc->nb_streams-1]->display_aspect_ratio.num = num;
1781 c->fc->streams[c->fc->nb_streams-1]->display_aspect_ratio.den = den;
1788 return mov_read_avid(c, pb, atom);
1791 static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1795 uint64_t original_size;
1796 if (c->fc->nb_streams >= 1) {
1797 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1798 if (par->codec_id == AV_CODEC_ID_H264)
1800 if (atom.size == 16) {
1801 original_size = par->extradata_size;
1802 ret = mov_realloc_extradata(par, atom);
1804 length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
1805 if (length == atom.size) {
1806 const uint8_t range_value = par->extradata[original_size + 19];
1807 switch (range_value) {
1809 par->color_range = AVCOL_RANGE_MPEG;
1812 par->color_range = AVCOL_RANGE_JPEG;
1815 av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
1818 ff_dlog(c->fc, "color_range: %d\n", par->color_range);
1820 /* For some reason the whole atom was not added to the extradata */
1821 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
1824 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
1827 av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
1834 static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1836 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
1839 static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1844 if (c->fc->nb_streams < 1)
1846 st = c->fc->streams[c->fc->nb_streams-1];
1848 if ((uint64_t)atom.size > (1<<30))
1849 return AVERROR_INVALIDDATA;
1851 if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
1852 st->codecpar->codec_id == AV_CODEC_ID_QDMC ||
1853 st->codecpar->codec_id == AV_CODEC_ID_SPEEX) {
1854 // pass all frma atom to codec, needed at least for QDMC and QDM2
1855 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1858 } else if (atom.size > 8) { /* to read frma, esds atoms */
1859 if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
1861 ret = ffio_ensure_seekback(pb, 8);
1864 buffer = avio_rb64(pb);
1866 if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
1867 && buffer >> 32 <= atom.size
1868 && buffer >> 32 >= 8) {
1871 } else if (!st->codecpar->extradata_size) {
1872 #define ALAC_EXTRADATA_SIZE 36
1873 st->codecpar->extradata = av_mallocz(ALAC_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
1874 if (!st->codecpar->extradata)
1875 return AVERROR(ENOMEM);
1876 st->codecpar->extradata_size = ALAC_EXTRADATA_SIZE;
1877 AV_WB32(st->codecpar->extradata , ALAC_EXTRADATA_SIZE);
1878 AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
1879 AV_WB64(st->codecpar->extradata + 12, buffer);
1880 avio_read(pb, st->codecpar->extradata + 20, 16);
1881 avio_skip(pb, atom.size - 24);
1885 if ((ret = mov_read_default(c, pb, atom)) < 0)
1888 avio_skip(pb, atom.size);
1893 * This function reads atom content and puts data in extradata without tag
1894 * nor size unlike mov_read_extradata.
1896 static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1901 if (c->fc->nb_streams < 1)
1903 st = c->fc->streams[c->fc->nb_streams-1];
1905 if ((uint64_t)atom.size > (1<<30))
1906 return AVERROR_INVALIDDATA;
1908 if (atom.size >= 10) {
1909 // Broken files created by legacy versions of libavformat will
1910 // wrap a whole fiel atom inside of a glbl atom.
1911 unsigned size = avio_rb32(pb);
1912 unsigned type = avio_rl32(pb);
1913 avio_seek(pb, -8, SEEK_CUR);
1914 if (type == MKTAG('f','i','e','l') && size == atom.size)
1915 return mov_read_default(c, pb, atom);
1917 if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
1918 av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
1921 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1924 if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
1925 /* HEVC-based Dolby Vision derived from hvc1.
1926 Happens to match with an identifier
1927 previously utilized for DV. Thus, if we have
1928 the hvcC extradata box available as specified,
1929 set codec to HEVC */
1930 st->codecpar->codec_id = AV_CODEC_ID_HEVC;
1935 static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1938 uint8_t profile_level;
1941 if (c->fc->nb_streams < 1)
1943 st = c->fc->streams[c->fc->nb_streams-1];
1945 if (atom.size >= (1<<28) || atom.size < 7)
1946 return AVERROR_INVALIDDATA;
1948 profile_level = avio_r8(pb);
1949 if ((profile_level & 0xf0) != 0xc0)
1952 avio_seek(pb, 6, SEEK_CUR);
1953 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
1961 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
1962 * but can have extradata appended at the end after the 40 bytes belonging
1965 static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1970 if (c->fc->nb_streams < 1)
1972 if (atom.size <= 40)
1974 st = c->fc->streams[c->fc->nb_streams-1];
1976 if ((uint64_t)atom.size > (1<<30))
1977 return AVERROR_INVALIDDATA;
1980 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
1987 static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1990 MOVStreamContext *sc;
1991 unsigned int i, entries;
1993 if (c->trak_index < 0) {
1994 av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
1997 if (c->fc->nb_streams < 1)
1999 st = c->fc->streams[c->fc->nb_streams-1];
2002 avio_r8(pb); /* version */
2003 avio_rb24(pb); /* flags */
2005 entries = avio_rb32(pb);
2010 if (sc->chunk_offsets)
2011 av_log(c->fc, AV_LOG_WARNING, "Duplicated STCO atom\n");
2012 av_free(sc->chunk_offsets);
2013 sc->chunk_count = 0;
2014 sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2015 if (!sc->chunk_offsets)
2016 return AVERROR(ENOMEM);
2017 sc->chunk_count = entries;
2019 if (atom.type == MKTAG('s','t','c','o'))
2020 for (i = 0; i < entries && !pb->eof_reached; i++)
2021 sc->chunk_offsets[i] = avio_rb32(pb);
2022 else if (atom.type == MKTAG('c','o','6','4'))
2023 for (i = 0; i < entries && !pb->eof_reached; i++)
2024 sc->chunk_offsets[i] = avio_rb64(pb);
2026 return AVERROR_INVALIDDATA;
2028 sc->chunk_count = i;
2030 if (pb->eof_reached) {
2031 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2038 static int mov_codec_id(AVStream *st, uint32_t format)
2040 int id = ff_codec_get_id(ff_codec_movaudio_tags, format);
2043 ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2044 (format & 0xFFFF) == 'T' + ('S' << 8)))
2045 id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format) & 0xFFFF);
2047 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2048 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2049 } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2050 /* skip old ASF MPEG-4 tag */
2051 format && format != MKTAG('m','p','4','s')) {
2052 id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2054 id = ff_codec_get_id(ff_codec_bmp_tags, format);
2056 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
2057 else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2058 (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE &&
2059 st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2060 id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
2062 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
2064 id = ff_codec_get_id(ff_codec_movdata_tags, format);
2068 st->codecpar->codec_tag = format;
2073 static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
2074 AVStream *st, MOVStreamContext *sc)
2076 uint8_t codec_name[32] = { 0 };
2080 /* The first 16 bytes of the video sample description are already
2081 * read in ff_mov_read_stsd_entries() */
2082 stsd_start = avio_tell(pb) - 16;
2084 avio_rb16(pb); /* version */
2085 avio_rb16(pb); /* revision level */
2086 avio_rb32(pb); /* vendor */
2087 avio_rb32(pb); /* temporal quality */
2088 avio_rb32(pb); /* spatial quality */
2090 st->codecpar->width = avio_rb16(pb); /* width */
2091 st->codecpar->height = avio_rb16(pb); /* height */
2093 avio_rb32(pb); /* horiz resolution */
2094 avio_rb32(pb); /* vert resolution */
2095 avio_rb32(pb); /* data size, always 0 */
2096 avio_rb16(pb); /* frames per samples */
2098 len = avio_r8(pb); /* codec name, pascal string */
2101 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2103 avio_skip(pb, 31 - len);
2106 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2108 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2109 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2110 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2111 st->codecpar->width &= ~1;
2112 st->codecpar->height &= ~1;
2114 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2115 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2116 !strncmp(codec_name, "Sorenson H263", 13))
2117 st->codecpar->codec_id = AV_CODEC_ID_FLV1;
2119 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2121 avio_seek(pb, stsd_start, SEEK_SET);
2123 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2124 st->codecpar->bits_per_coded_sample &= 0x1F;
2125 sc->has_palette = 1;
2129 static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
2130 AVStream *st, MOVStreamContext *sc)
2132 int bits_per_sample, flags;
2133 uint16_t version = avio_rb16(pb);
2134 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2136 avio_rb16(pb); /* revision level */
2137 avio_rb32(pb); /* vendor */
2139 st->codecpar->channels = avio_rb16(pb); /* channel count */
2140 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2141 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", st->codecpar->channels);
2143 sc->audio_cid = avio_rb16(pb);
2144 avio_rb16(pb); /* packet size = 0 */
2146 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2148 // Read QT version 1 fields. In version 0 these do not exist.
2149 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2151 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2152 (sc->stsd_version == 0 && version > 0)) {
2154 sc->samples_per_frame = avio_rb32(pb);
2155 avio_rb32(pb); /* bytes per packet */
2156 sc->bytes_per_frame = avio_rb32(pb);
2157 avio_rb32(pb); /* bytes per sample */
2158 } else if (version == 2) {
2159 avio_rb32(pb); /* sizeof struct only */
2160 st->codecpar->sample_rate = av_int2double(avio_rb64(pb));
2161 st->codecpar->channels = avio_rb32(pb);
2162 avio_rb32(pb); /* always 0x7F000000 */
2163 st->codecpar->bits_per_coded_sample = avio_rb32(pb);
2165 flags = avio_rb32(pb); /* lpcm format specific flag */
2166 sc->bytes_per_frame = avio_rb32(pb);
2167 sc->samples_per_frame = avio_rb32(pb);
2168 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2169 st->codecpar->codec_id =
2170 ff_mov_get_lpcm_codec_id(st->codecpar->bits_per_coded_sample,
2173 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2174 /* can't correctly handle variable sized packet as audio unit */
2175 switch (st->codecpar->codec_id) {
2176 case AV_CODEC_ID_MP2:
2177 case AV_CODEC_ID_MP3:
2178 st->need_parsing = AVSTREAM_PARSE_FULL;
2184 if (sc->format == 0) {
2185 if (st->codecpar->bits_per_coded_sample == 8)
2186 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2187 else if (st->codecpar->bits_per_coded_sample == 16)
2188 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2191 switch (st->codecpar->codec_id) {
2192 case AV_CODEC_ID_PCM_S8:
2193 case AV_CODEC_ID_PCM_U8:
2194 if (st->codecpar->bits_per_coded_sample == 16)
2195 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16BE;
2197 case AV_CODEC_ID_PCM_S16LE:
2198 case AV_CODEC_ID_PCM_S16BE:
2199 if (st->codecpar->bits_per_coded_sample == 8)
2200 st->codecpar->codec_id = AV_CODEC_ID_PCM_S8;
2201 else if (st->codecpar->bits_per_coded_sample == 24)
2202 st->codecpar->codec_id =
2203 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2204 AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
2205 else if (st->codecpar->bits_per_coded_sample == 32)
2206 st->codecpar->codec_id =
2207 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2208 AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
2210 /* set values for old format before stsd version 1 appeared */
2211 case AV_CODEC_ID_MACE3:
2212 sc->samples_per_frame = 6;
2213 sc->bytes_per_frame = 2 * st->codecpar->channels;
2215 case AV_CODEC_ID_MACE6:
2216 sc->samples_per_frame = 6;
2217 sc->bytes_per_frame = 1 * st->codecpar->channels;
2219 case AV_CODEC_ID_ADPCM_IMA_QT:
2220 sc->samples_per_frame = 64;
2221 sc->bytes_per_frame = 34 * st->codecpar->channels;
2223 case AV_CODEC_ID_GSM:
2224 sc->samples_per_frame = 160;
2225 sc->bytes_per_frame = 33;
2231 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2232 if (bits_per_sample) {
2233 st->codecpar->bits_per_coded_sample = bits_per_sample;
2234 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->channels;
2238 static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
2239 AVStream *st, MOVStreamContext *sc,
2242 // ttxt stsd contains display flags, justification, background
2243 // color, fonts, and default styles, so fake an atom to read it
2244 MOVAtom fake_atom = { .size = size };
2245 // mp4s contains a regular esds atom
2246 if (st->codecpar->codec_tag != AV_RL32("mp4s"))
2247 mov_read_glbl(c, pb, fake_atom);
2248 st->codecpar->width = sc->width;
2249 st->codecpar->height = sc->height;
2252 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2257 y = (ycbcr >> 16) & 0xFF;
2258 cr = (ycbcr >> 8) & 0xFF;
2261 b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
2262 g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
2263 r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
2265 return (r << 16) | (g << 8) | b;
2268 static int mov_rewrite_dvd_sub_extradata(AVStream *st)
2270 char buf[256] = {0};
2271 uint8_t *src = st->codecpar->extradata;
2274 if (st->codecpar->extradata_size != 64)
2277 if (st->codecpar->width > 0 && st->codecpar->height > 0)
2278 snprintf(buf, sizeof(buf), "size: %dx%d\n",
2279 st->codecpar->width, st->codecpar->height);
2280 av_strlcat(buf, "palette: ", sizeof(buf));
2282 for (i = 0; i < 16; i++) {
2283 uint32_t yuv = AV_RB32(src + i * 4);
2284 uint32_t rgba = yuv_to_rgba(yuv);
2286 av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2289 if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2292 ret = ff_alloc_extradata(st->codecpar, strlen(buf));
2295 memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2300 static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
2301 AVStream *st, MOVStreamContext *sc,
2306 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2307 if ((int)size != size)
2308 return AVERROR(ENOMEM);
2310 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2314 MOVStreamContext *tmcd_ctx = st->priv_data;
2316 val = AV_RB32(st->codecpar->extradata + 4);
2317 tmcd_ctx->tmcd_flags = val;
2318 st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2319 st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2320 #if FF_API_LAVF_AVCTX
2321 FF_DISABLE_DEPRECATION_WARNINGS
2322 st->codec->time_base = av_inv_q(st->avg_frame_rate);
2323 FF_ENABLE_DEPRECATION_WARNINGS
2325 /* adjust for per frame dur in counter mode */
2326 if (tmcd_ctx->tmcd_flags & 0x0008) {
2327 int timescale = AV_RB32(st->codecpar->extradata + 8);
2328 int framedur = AV_RB32(st->codecpar->extradata + 12);
2329 st->avg_frame_rate.num *= timescale;
2330 st->avg_frame_rate.den *= framedur;
2331 #if FF_API_LAVF_AVCTX
2332 FF_DISABLE_DEPRECATION_WARNINGS
2333 st->codec->time_base.den *= timescale;
2334 st->codec->time_base.num *= framedur;
2335 FF_ENABLE_DEPRECATION_WARNINGS
2339 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2340 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2341 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2342 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2343 if (str_size > 0 && size >= (int)str_size + 26) {
2344 char *reel_name = av_malloc(str_size + 1);
2346 return AVERROR(ENOMEM);
2347 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2348 reel_name[str_size] = 0; /* Add null terminator */
2349 /* don't add reel_name if emtpy string */
2350 if (*reel_name == 0) {
2353 av_dict_set(&st->metadata, "reel_name", reel_name, AV_DICT_DONT_STRDUP_VAL);
2360 /* other codec type, just skip (rtp, mp4s ...) */
2361 avio_skip(pb, size);
2366 static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
2367 AVStream *st, MOVStreamContext *sc)
2369 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2370 !st->codecpar->sample_rate && sc->time_scale > 1)
2371 st->codecpar->sample_rate = sc->time_scale;
2373 /* special codec parameters handling */
2374 switch (st->codecpar->codec_id) {
2375 #if CONFIG_DV_DEMUXER
2376 case AV_CODEC_ID_DVAUDIO:
2377 c->dv_fctx = avformat_alloc_context();
2379 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2380 return AVERROR(ENOMEM);
2382 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2384 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2385 return AVERROR(ENOMEM);
2387 sc->dv_audio_container = 1;
2388 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
2391 /* no ifdef since parameters are always those */
2392 case AV_CODEC_ID_QCELP:
2393 st->codecpar->channels = 1;
2394 // force sample rate for qcelp when not stored in mov
2395 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2396 st->codecpar->sample_rate = 8000;
2397 // FIXME: Why is the following needed for some files?
2398 sc->samples_per_frame = 160;
2399 if (!sc->bytes_per_frame)
2400 sc->bytes_per_frame = 35;
2402 case AV_CODEC_ID_AMR_NB:
2403 st->codecpar->channels = 1;
2404 /* force sample rate for amr, stsd in 3gp does not store sample rate */
2405 st->codecpar->sample_rate = 8000;
2407 case AV_CODEC_ID_AMR_WB:
2408 st->codecpar->channels = 1;
2409 st->codecpar->sample_rate = 16000;
2411 case AV_CODEC_ID_MP2:
2412 case AV_CODEC_ID_MP3:
2413 /* force type after stsd for m1a hdlr */
2414 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2416 case AV_CODEC_ID_GSM:
2417 case AV_CODEC_ID_ADPCM_MS:
2418 case AV_CODEC_ID_ADPCM_IMA_WAV:
2419 case AV_CODEC_ID_ILBC:
2420 case AV_CODEC_ID_MACE3:
2421 case AV_CODEC_ID_MACE6:
2422 case AV_CODEC_ID_QDM2:
2423 st->codecpar->block_align = sc->bytes_per_frame;
2425 case AV_CODEC_ID_ALAC:
2426 if (st->codecpar->extradata_size == 36) {
2427 st->codecpar->channels = AV_RB8 (st->codecpar->extradata + 21);
2428 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2431 case AV_CODEC_ID_AC3:
2432 case AV_CODEC_ID_EAC3:
2433 case AV_CODEC_ID_MPEG1VIDEO:
2434 case AV_CODEC_ID_VC1:
2435 case AV_CODEC_ID_VP8:
2436 case AV_CODEC_ID_VP9:
2437 st->need_parsing = AVSTREAM_PARSE_FULL;
2445 static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
2446 int codec_tag, int format,
2449 int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2452 (codec_tag != format &&
2453 // AVID 1:1 samples with differing data format and codec tag exist
2454 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
2455 // prores is allowed to have differing data format and codec tag
2456 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
2458 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
2459 (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id
2460 : codec_tag != MKTAG('j','p','e','g')))) {
2461 /* Multiple fourcc, we skip JPEG. This is not correct, we should
2462 * export it as a separate AVStream but this needs a few changes
2463 * in the MOV demuxer, patch welcome. */
2465 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
2466 avio_skip(pb, size);
2473 int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
2476 MOVStreamContext *sc;
2477 int pseudo_stream_id;
2479 av_assert0 (c->fc->nb_streams >= 1);
2480 st = c->fc->streams[c->fc->nb_streams-1];
2483 for (pseudo_stream_id = 0;
2484 pseudo_stream_id < entries && !pb->eof_reached;
2485 pseudo_stream_id++) {
2486 //Parsing Sample description table
2488 int ret, dref_id = 1;
2489 MOVAtom a = { AV_RL32("stsd") };
2490 int64_t start_pos = avio_tell(pb);
2491 int64_t size = avio_rb32(pb); /* size */
2492 uint32_t format = avio_rl32(pb); /* data format */
2495 avio_rb32(pb); /* reserved */
2496 avio_rb16(pb); /* reserved */
2497 dref_id = avio_rb16(pb);
2498 } else if (size <= 7) {
2499 av_log(c->fc, AV_LOG_ERROR,
2500 "invalid size %"PRId64" in stsd\n", size);
2501 return AVERROR_INVALIDDATA;
2504 if (mov_skip_multiple_stsd(c, pb, st->codecpar->codec_tag, format,
2505 size - (avio_tell(pb) - start_pos))) {
2510 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
2511 sc->dref_id= dref_id;
2512 sc->format = format;
2514 id = mov_codec_id(st, format);
2516 av_log(c->fc, AV_LOG_TRACE,
2517 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
2518 av_fourcc2str(format), st->codecpar->codec_type);
2520 st->codecpar->codec_id = id;
2521 if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) {
2522 mov_parse_stsd_video(c, pb, st, sc);
2523 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
2524 mov_parse_stsd_audio(c, pb, st, sc);
2525 if (st->codecpar->sample_rate < 0) {
2526 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
2527 return AVERROR_INVALIDDATA;
2529 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
2530 mov_parse_stsd_subtitle(c, pb, st, sc,
2531 size - (avio_tell(pb) - start_pos));
2533 ret = mov_parse_stsd_data(c, pb, st, sc,
2534 size - (avio_tell(pb) - start_pos));
2538 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
2539 a.size = size - (avio_tell(pb) - start_pos);
2541 if ((ret = mov_read_default(c, pb, a)) < 0)
2543 } else if (a.size > 0)
2544 avio_skip(pb, a.size);
2546 if (sc->extradata && st->codecpar->extradata) {
2547 int extra_size = st->codecpar->extradata_size;
2549 /* Move the current stream extradata to the stream context one. */
2550 sc->extradata_size[pseudo_stream_id] = extra_size;
2551 sc->extradata[pseudo_stream_id] = av_malloc(extra_size + AV_INPUT_BUFFER_PADDING_SIZE);
2552 if (!sc->extradata[pseudo_stream_id])
2553 return AVERROR(ENOMEM);
2554 memcpy(sc->extradata[pseudo_stream_id], st->codecpar->extradata, extra_size);
2555 av_freep(&st->codecpar->extradata);
2556 st->codecpar->extradata_size = 0;
2561 if (pb->eof_reached) {
2562 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
2569 static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2572 MOVStreamContext *sc;
2575 if (c->fc->nb_streams < 1)
2577 st = c->fc->streams[c->fc->nb_streams - 1];
2580 sc->stsd_version = avio_r8(pb);
2581 avio_rb24(pb); /* flags */
2582 entries = avio_rb32(pb);
2584 /* Each entry contains a size (4 bytes) and format (4 bytes). */
2585 if (entries <= 0 || entries > atom.size / 8) {
2586 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
2587 return AVERROR_INVALIDDATA;
2590 if (sc->extradata) {
2591 av_log(c->fc, AV_LOG_ERROR,
2592 "Duplicate stsd found in this track.\n");
2593 return AVERROR_INVALIDDATA;
2596 /* Prepare space for hosting multiple extradata. */
2597 sc->extradata = av_mallocz_array(entries, sizeof(*sc->extradata));
2599 return AVERROR(ENOMEM);
2601 sc->extradata_size = av_mallocz_array(entries, sizeof(*sc->extradata_size));
2602 if (!sc->extradata_size) {
2603 ret = AVERROR(ENOMEM);
2607 ret = ff_mov_read_stsd_entries(c, pb, entries);
2611 /* Restore back the primary extradata. */
2612 av_freep(&st->codecpar->extradata);
2613 st->codecpar->extradata_size = sc->extradata_size[0];
2614 if (sc->extradata_size[0]) {
2615 st->codecpar->extradata = av_mallocz(sc->extradata_size[0] + AV_INPUT_BUFFER_PADDING_SIZE);
2616 if (!st->codecpar->extradata)
2617 return AVERROR(ENOMEM);
2618 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
2621 return mov_finalize_stsd_codec(c, pb, st, sc);
2623 if (sc->extradata) {
2625 for (j = 0; j < sc->stsd_count; j++)
2626 av_freep(&sc->extradata[j]);
2629 av_freep(&sc->extradata);
2630 av_freep(&sc->extradata_size);
2634 static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2637 MOVStreamContext *sc;
2638 unsigned int i, entries;
2640 if (c->fc->nb_streams < 1)
2642 st = c->fc->streams[c->fc->nb_streams-1];
2645 avio_r8(pb); /* version */
2646 avio_rb24(pb); /* flags */
2648 entries = avio_rb32(pb);
2649 if ((uint64_t)entries * 12 + 4 > atom.size)
2650 return AVERROR_INVALIDDATA;
2652 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
2657 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSC atom\n");
2658 av_free(sc->stsc_data);
2660 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
2662 return AVERROR(ENOMEM);
2664 for (i = 0; i < entries && !pb->eof_reached; i++) {
2665 sc->stsc_data[i].first = avio_rb32(pb);
2666 sc->stsc_data[i].count = avio_rb32(pb);
2667 sc->stsc_data[i].id = avio_rb32(pb);
2671 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
2672 int64_t first_min = i + 1;
2673 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
2674 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
2675 sc->stsc_data[i].first < first_min ||
2676 sc->stsc_data[i].count < 1 ||
2677 sc->stsc_data[i].id < 1) {
2678 av_log(c->fc, AV_LOG_WARNING, "STSC entry %d is invalid (first=%d count=%d id=%d)\n", i, sc->stsc_data[i].first, sc->stsc_data[i].count, sc->stsc_data[i].id);
2679 if (i+1 >= sc->stsc_count) {
2680 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
2681 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
2682 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
2683 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
2684 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
2687 av_assert0(sc->stsc_data[i+1].first >= 2);
2688 // We replace this entry by the next valid
2689 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
2690 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
2691 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
2695 if (pb->eof_reached) {
2696 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
2703 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
2705 return index < count - 1;
2708 /* Compute the samples value for the stsc entry at the given index. */
2709 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
2713 if (mov_stsc_index_valid(index, sc->stsc_count))
2714 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
2716 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
2717 av_assert0(sc->stsc_data[index].first <= sc->chunk_count);
2718 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
2721 return sc->stsc_data[index].count * (int64_t)chunk_count;
2724 static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2727 MOVStreamContext *sc;
2728 unsigned i, entries;
2730 if (c->fc->nb_streams < 1)
2732 st = c->fc->streams[c->fc->nb_streams-1];
2735 avio_rb32(pb); // version + flags
2737 entries = avio_rb32(pb);
2739 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
2740 av_free(sc->stps_data);
2742 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
2744 return AVERROR(ENOMEM);
2746 for (i = 0; i < entries && !pb->eof_reached; i++) {
2747 sc->stps_data[i] = avio_rb32(pb);
2752 if (pb->eof_reached) {
2753 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
2760 static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2763 MOVStreamContext *sc;
2764 unsigned int i, entries;
2766 if (c->fc->nb_streams < 1)
2768 st = c->fc->streams[c->fc->nb_streams-1];
2771 avio_r8(pb); /* version */
2772 avio_rb24(pb); /* flags */
2774 entries = avio_rb32(pb);
2776 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
2780 sc->keyframe_absent = 1;
2781 if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
2782 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2786 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
2787 if (entries >= UINT_MAX / sizeof(int))
2788 return AVERROR_INVALIDDATA;
2789 av_freep(&sc->keyframes);
2790 sc->keyframe_count = 0;
2791 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
2793 return AVERROR(ENOMEM);
2795 for (i = 0; i < entries && !pb->eof_reached; i++) {
2796 sc->keyframes[i] = avio_rb32(pb);
2799 sc->keyframe_count = i;
2801 if (pb->eof_reached) {
2802 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
2809 static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2812 MOVStreamContext *sc;
2813 unsigned int i, entries, sample_size, field_size, num_bytes;
2818 if (c->fc->nb_streams < 1)
2820 st = c->fc->streams[c->fc->nb_streams-1];
2823 avio_r8(pb); /* version */
2824 avio_rb24(pb); /* flags */
2826 if (atom.type == MKTAG('s','t','s','z')) {
2827 sample_size = avio_rb32(pb);
2828 if (!sc->sample_size) /* do not overwrite value computed in stsd */
2829 sc->sample_size = sample_size;
2830 sc->stsz_sample_size = sample_size;
2834 avio_rb24(pb); /* reserved */
2835 field_size = avio_r8(pb);
2837 entries = avio_rb32(pb);
2839 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
2841 sc->sample_count = entries;
2845 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
2846 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
2847 return AVERROR_INVALIDDATA;
2852 if (entries >= (UINT_MAX - 4) / field_size)
2853 return AVERROR_INVALIDDATA;
2854 if (sc->sample_sizes)
2855 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
2856 av_free(sc->sample_sizes);
2857 sc->sample_count = 0;
2858 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
2859 if (!sc->sample_sizes)
2860 return AVERROR(ENOMEM);
2862 num_bytes = (entries*field_size+4)>>3;
2864 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
2866 av_freep(&sc->sample_sizes);
2867 return AVERROR(ENOMEM);
2870 ret = ffio_read_size(pb, buf, num_bytes);
2872 av_freep(&sc->sample_sizes);
2874 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
2878 init_get_bits(&gb, buf, 8*num_bytes);
2880 for (i = 0; i < entries && !pb->eof_reached; i++) {
2881 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
2882 sc->data_size += sc->sample_sizes[i];
2885 sc->sample_count = i;
2889 if (pb->eof_reached) {
2890 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSZ atom\n");
2897 static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2900 MOVStreamContext *sc;
2901 unsigned int i, entries, alloc_size = 0;
2903 int64_t total_sample_count=0;
2905 if (c->fc->nb_streams < 1)
2907 st = c->fc->streams[c->fc->nb_streams-1];
2910 avio_r8(pb); /* version */
2911 avio_rb24(pb); /* flags */
2912 entries = avio_rb32(pb);
2914 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
2915 c->fc->nb_streams-1, entries);
2918 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
2919 av_freep(&sc->stts_data);
2921 if (entries >= INT_MAX / sizeof(*sc->stts_data))
2922 return AVERROR(ENOMEM);
2924 for (i = 0; i < entries && !pb->eof_reached; i++) {
2925 int sample_duration;
2926 unsigned int sample_count;
2927 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
2928 MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
2929 min_entries * sizeof(*sc->stts_data));
2931 av_freep(&sc->stts_data);
2933 return AVERROR(ENOMEM);
2935 sc->stts_count = min_entries;
2936 sc->stts_data = stts_data;
2938 sample_count=avio_rb32(pb);
2939 sample_duration = avio_rb32(pb);
2941 sc->stts_data[i].count= sample_count;
2942 sc->stts_data[i].duration= sample_duration;
2944 av_log(c->fc, AV_LOG_TRACE, "sample_count=%d, sample_duration=%d\n",
2945 sample_count, sample_duration);
2947 duration+=(int64_t)sample_duration*(uint64_t)sample_count;
2948 total_sample_count+=sample_count;
2954 duration <= INT64_MAX - sc->duration_for_fps &&
2955 total_sample_count <= INT_MAX - sc->nb_frames_for_fps
2957 sc->duration_for_fps += duration;
2958 sc->nb_frames_for_fps += total_sample_count;
2961 if (pb->eof_reached) {
2962 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
2966 st->nb_frames= total_sample_count;
2968 st->duration= FFMIN(st->duration, duration);
2969 sc->track_end = duration;
2973 static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2976 MOVStreamContext *sc;
2979 if (c->fc->nb_streams < 1)
2981 st = c->fc->streams[c->fc->nb_streams - 1];
2984 avio_r8(pb); /* version */
2985 avio_rb24(pb); /* flags */
2986 entries = atom.size - 4;
2988 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
2989 c->fc->nb_streams - 1, entries);
2992 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
2993 av_freep(&sc->sdtp_data);
2996 sc->sdtp_data = av_mallocz(entries);
2998 return AVERROR(ENOMEM);
3000 for (i = 0; i < entries && !pb->eof_reached; i++)
3001 sc->sdtp_data[i] = avio_r8(pb);
3007 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3010 if (duration == INT_MIN) {
3011 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3014 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3018 static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3021 MOVStreamContext *sc;
3022 unsigned int i, entries, ctts_count = 0;
3024 if (c->fc->nb_streams < 1)
3026 st = c->fc->streams[c->fc->nb_streams-1];
3029 avio_r8(pb); /* version */
3030 avio_rb24(pb); /* flags */
3031 entries = avio_rb32(pb);
3033 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3037 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3038 return AVERROR_INVALIDDATA;
3039 av_freep(&sc->ctts_data);
3040 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3042 return AVERROR(ENOMEM);
3044 for (i = 0; i < entries && !pb->eof_reached; i++) {
3045 int count =avio_rb32(pb);
3046 int duration =avio_rb32(pb);
3049 av_log(c->fc, AV_LOG_TRACE,
3050 "ignoring CTTS entry with count=%d duration=%d\n",
3055 add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3058 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3061 if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3062 av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3063 av_freep(&sc->ctts_data);
3069 mov_update_dts_shift(sc, duration, c->fc);
3072 sc->ctts_count = ctts_count;
3074 if (pb->eof_reached) {
3075 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3079 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3084 static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3087 MOVStreamContext *sc;
3088 unsigned int i, entries;
3090 uint32_t grouping_type;
3092 if (c->fc->nb_streams < 1)
3094 st = c->fc->streams[c->fc->nb_streams-1];
3097 version = avio_r8(pb); /* version */
3098 avio_rb24(pb); /* flags */
3099 grouping_type = avio_rl32(pb);
3100 if (grouping_type != MKTAG( 'r','a','p',' '))
3101 return 0; /* only support 'rap ' grouping */
3103 avio_rb32(pb); /* grouping_type_parameter */
3105 entries = avio_rb32(pb);
3109 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP atom\n");
3110 av_free(sc->rap_group);
3111 sc->rap_group_count = 0;
3112 sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group));
3114 return AVERROR(ENOMEM);
3116 for (i = 0; i < entries && !pb->eof_reached; i++) {
3117 sc->rap_group[i].count = avio_rb32(pb); /* sample_count */
3118 sc->rap_group[i].index = avio_rb32(pb); /* group_description_index */
3121 sc->rap_group_count = i;
3123 if (pb->eof_reached) {
3124 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3132 * Get ith edit list entry (media time, duration).
3134 static int get_edit_list_entry(MOVContext *mov,
3135 const MOVStreamContext *msc,
3136 unsigned int edit_list_index,
3137 int64_t *edit_list_media_time,
3138 int64_t *edit_list_duration,
3139 int64_t global_timescale)
3141 if (edit_list_index == msc->elst_count) {
3144 *edit_list_media_time = msc->elst_data[edit_list_index].time;
3145 *edit_list_duration = msc->elst_data[edit_list_index].duration;
3147 /* duration is in global timescale units;convert to msc timescale */
3148 if (global_timescale == 0) {
3149 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3152 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3158 * Find the closest previous frame to the timestamp_pts, in e_old index
3159 * entries. Searching for just any frame / just key frames can be controlled by
3160 * last argument 'flag'.
3161 * Note that if ctts_data is not NULL, we will always search for a key frame
3162 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3163 * return the first frame of the video.
3165 * Here the timestamp_pts is considered to be a presentation timestamp and
3166 * the timestamp of index entries are considered to be decoding timestamps.
3168 * Returns 0 if successful in finding a frame, else returns -1.
3169 * Places the found index corresponding output arg.
3171 * If ctts_old is not NULL, then refines the searched entry by searching
3172 * backwards from the found timestamp, to find the frame with correct PTS.
3174 * Places the found ctts_index and ctts_sample in corresponding output args.
3176 static int find_prev_closest_index(AVStream *st,
3177 AVIndexEntry *e_old,
3181 int64_t timestamp_pts,
3184 int64_t* ctts_index,
3185 int64_t* ctts_sample)
3187 MOVStreamContext *msc = st->priv_data;
3188 AVIndexEntry *e_keep = st->index_entries;
3189 int nb_keep = st->nb_index_entries;
3191 int64_t index_ctts_count;
3195 // If dts_shift > 0, then all the index timestamps will have to be offset by
3196 // at least dts_shift amount to obtain PTS.
3197 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3198 if (msc->dts_shift > 0) {
3199 timestamp_pts -= msc->dts_shift;
3202 st->index_entries = e_old;
3203 st->nb_index_entries = nb_old;
3204 *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3206 // Keep going backwards in the index entries until the timestamp is the same.
3208 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3210 if ((flag & AVSEEK_FLAG_ANY) ||
3211 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3217 // If we have CTTS then refine the search, by searching backwards over PTS
3218 // computed by adding corresponding CTTS durations to index timestamps.
3219 if (ctts_data && *index >= 0) {
3220 av_assert0(ctts_index);
3221 av_assert0(ctts_sample);
3222 // Find out the ctts_index for the found frame.
3225 for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3226 if (*ctts_index < ctts_count) {
3228 if (ctts_data[*ctts_index].count == *ctts_sample) {
3235 while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3236 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3237 // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3238 // compensated by dts_shift above.
3239 if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3240 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3245 if (*ctts_sample == 0) {
3247 if (*ctts_index >= 0)
3248 *ctts_sample = ctts_data[*ctts_index].count - 1;
3255 /* restore AVStream state*/
3256 st->index_entries = e_keep;
3257 st->nb_index_entries = nb_keep;
3258 return *index >= 0 ? 0 : -1;
3262 * Add index entry with the given values, to the end of st->index_entries.
3263 * Returns the new size st->index_entries if successful, else returns -1.
3265 * This function is similar to ff_add_index_entry in libavformat/utils.c
3266 * except that here we are always unconditionally adding an index entry to
3267 * the end, instead of searching the entries list and skipping the add if
3268 * there is an existing entry with the same timestamp.
3269 * This is needed because the mov_fix_index calls this func with the same
3270 * unincremented timestamp for successive discarded frames.
3272 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3273 int size, int distance, int flags)
3275 AVIndexEntry *entries, *ie;
3277 const size_t min_size_needed = (st->nb_index_entries + 1) * sizeof(AVIndexEntry);
3279 // Double the allocation each time, to lower memory fragmentation.
3280 // Another difference from ff_add_index_entry function.
3281 const size_t requested_size =
3282 min_size_needed > st->index_entries_allocated_size ?
3283 FFMAX(min_size_needed, 2 * st->index_entries_allocated_size) :
3286 if((unsigned)st->nb_index_entries + 1 >= UINT_MAX / sizeof(AVIndexEntry))
3289 entries = av_fast_realloc(st->index_entries,
3290 &st->index_entries_allocated_size,
3295 st->index_entries= entries;
3297 index= st->nb_index_entries++;
3298 ie= &entries[index];
3301 ie->timestamp = timestamp;
3302 ie->min_distance= distance;
3309 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3310 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3312 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3313 int64_t* frame_duration_buffer,
3314 int frame_duration_buffer_size) {
3316 av_assert0(end_index >= 0 && end_index <= st->nb_index_entries);
3317 for (i = 0; i < frame_duration_buffer_size; i++) {
3318 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3319 st->index_entries[end_index - 1 - i].timestamp = end_ts;
3324 * Append a new ctts entry to ctts_data.
3325 * Returns the new ctts_count if successful, else returns -1.
3327 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3328 int count, int duration)
3330 MOVStts *ctts_buf_new;
3331 const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVStts);
3332 const size_t requested_size =
3333 min_size_needed > *allocated_size ?
3334 FFMAX(min_size_needed, 2 * (*allocated_size)) :
3337 if((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
3340 ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3345 *ctts_data = ctts_buf_new;
3347 ctts_buf_new[*ctts_count].count = count;
3348 ctts_buf_new[*ctts_count].duration = duration;
3350 *ctts_count = (*ctts_count) + 1;
3354 #define MAX_REORDER_DELAY 16
3355 static void mov_estimate_video_delay(MOVContext *c, AVStream* st) {
3356 MOVStreamContext *msc = st->priv_data;
3359 int ctts_sample = 0;
3360 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3362 int j, r, num_swaps;
3364 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3365 pts_buf[j] = INT64_MIN;
3367 if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3368 st->codecpar->codec_id == AV_CODEC_ID_H264) {
3369 st->codecpar->video_delay = 0;
3370 for(ind = 0; ind < st->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3371 // Point j to the last elem of the buffer and insert the current pts there.
3373 buf_start = (buf_start + 1);
3374 if (buf_start == MAX_REORDER_DELAY + 1)
3377 pts_buf[j] = st->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3379 // The timestamps that are already in the sorted buffer, and are greater than the
3380 // current pts, are exactly the timestamps that need to be buffered to output PTS
3381 // in correct sorted order.
3382 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3383 // can be computed as the maximum no. of swaps any particular timestamp needs to
3384 // go through, to keep this buffer in sorted order.
3386 while (j != buf_start) {
3388 if (r < 0) r = MAX_REORDER_DELAY;
3389 if (pts_buf[j] < pts_buf[r]) {
3390 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3397 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3400 if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3405 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3406 st->codecpar->video_delay, st->index);
3410 static void mov_current_sample_inc(MOVStreamContext *sc)
3412 sc->current_sample++;
3413 sc->current_index++;
3414 if (sc->index_ranges &&
3415 sc->current_index >= sc->current_index_range->end &&
3416 sc->current_index_range->end) {
3417 sc->current_index_range++;
3418 sc->current_index = sc->current_index_range->start;
3422 static void mov_current_sample_dec(MOVStreamContext *sc)
3424 sc->current_sample--;
3425 sc->current_index--;
3426 if (sc->index_ranges &&
3427 sc->current_index < sc->current_index_range->start &&
3428 sc->current_index_range > sc->index_ranges) {
3429 sc->current_index_range--;
3430 sc->current_index = sc->current_index_range->end - 1;
3434 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3438 sc->current_sample = current_sample;
3439 sc->current_index = current_sample;
3440 if (!sc->index_ranges) {
3444 for (sc->current_index_range = sc->index_ranges;
3445 sc->current_index_range->end;
3446 sc->current_index_range++) {
3447 range_size = sc->current_index_range->end - sc->current_index_range->start;
3448 if (range_size > current_sample) {
3449 sc->current_index = sc->current_index_range->start + current_sample;
3452 current_sample -= range_size;
3457 * Fix st->index_entries, so that it contains only the entries (and the entries
3458 * which are needed to decode them) that fall in the edit list time ranges.
3459 * Also fixes the timestamps of the index entries to match the timeline
3460 * specified the edit lists.
3462 static void mov_fix_index(MOVContext *mov, AVStream *st)
3464 MOVStreamContext *msc = st->priv_data;
3465 AVIndexEntry *e_old = st->index_entries;
3466 int nb_old = st->nb_index_entries;
3467 const AVIndexEntry *e_old_end = e_old + nb_old;
3468 const AVIndexEntry *current = NULL;
3469 MOVStts *ctts_data_old = msc->ctts_data;
3470 int64_t ctts_index_old = 0;
3471 int64_t ctts_sample_old = 0;
3472 int64_t ctts_count_old = msc->ctts_count;
3473 int64_t edit_list_media_time = 0;
3474 int64_t edit_list_duration = 0;
3475 int64_t frame_duration = 0;
3476 int64_t edit_list_dts_counter = 0;
3477 int64_t edit_list_dts_entry_end = 0;
3478 int64_t edit_list_start_ctts_sample = 0;
3480 int64_t curr_ctts = 0;
3481 int64_t empty_edits_sum_duration = 0;
3482 int64_t edit_list_index = 0;
3485 int64_t start_dts = 0;
3486 int64_t edit_list_start_encountered = 0;
3487 int64_t search_timestamp = 0;
3488 int64_t* frame_duration_buffer = NULL;
3489 int num_discarded_begin = 0;
3490 int first_non_zero_audio_edit = -1;
3491 int packet_skip_samples = 0;
3492 MOVIndexRange *current_index_range;
3494 int found_keyframe_after_edit = 0;
3495 int found_non_empty_edit = 0;
3497 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
3501 // allocate the index ranges array
3502 msc->index_ranges = av_malloc((msc->elst_count + 1) * sizeof(msc->index_ranges[0]));
3503 if (!msc->index_ranges) {
3504 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
3507 msc->current_index_range = msc->index_ranges;
3508 current_index_range = msc->index_ranges - 1;
3510 // Clean AVStream from traces of old index
3511 st->index_entries = NULL;
3512 st->index_entries_allocated_size = 0;
3513 st->nb_index_entries = 0;
3515 // Clean ctts fields of MOVStreamContext
3516 msc->ctts_data = NULL;
3517 msc->ctts_count = 0;
3518 msc->ctts_index = 0;
3519 msc->ctts_sample = 0;
3520 msc->ctts_allocated_size = 0;
3522 // Reinitialize min_corrected_pts so that it can be computed again.
3523 msc->min_corrected_pts = -1;
3525 // If the dts_shift is positive (in case of negative ctts values in mov),
3526 // then negate the DTS by dts_shift
3527 if (msc->dts_shift > 0) {
3528 edit_list_dts_entry_end -= msc->dts_shift;
3529 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
3532 start_dts = edit_list_dts_entry_end;
3534 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
3535 &edit_list_duration, mov->time_scale)) {
3536 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
3537 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
3539 edit_list_dts_counter = edit_list_dts_entry_end;
3540 edit_list_dts_entry_end += edit_list_duration;
3541 num_discarded_begin = 0;
3542 if (!found_non_empty_edit && edit_list_media_time == -1) {
3543 empty_edits_sum_duration += edit_list_duration;
3546 found_non_empty_edit = 1;
3548 // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
3549 // according to the edit list below.
3550 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3551 if (first_non_zero_audio_edit < 0) {
3552 first_non_zero_audio_edit = 1;
3554 first_non_zero_audio_edit = 0;
3557 if (first_non_zero_audio_edit > 0)
3558 st->skip_samples = msc->start_pad = 0;
3561 // While reordering frame index according to edit list we must handle properly
3562 // the scenario when edit list entry starts from none key frame.
3563 // We find closest previous key frame and preserve it and consequent frames in index.
3564 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
3565 search_timestamp = edit_list_media_time;
3566 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3567 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
3568 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
3569 // edit_list_media_time to cover the decoder delay.
3570 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
3573 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
3574 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3575 av_log(mov->fc, AV_LOG_WARNING,
3576 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
3577 st->index, edit_list_index, search_timestamp);
3578 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
3579 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3580 av_log(mov->fc, AV_LOG_WARNING,
3581 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
3582 st->index, edit_list_index, search_timestamp);
3585 ctts_sample_old = 0;
3588 current = e_old + index;
3589 edit_list_start_ctts_sample = ctts_sample_old;
3591 // Iterate over index and arrange it according to edit list
3592 edit_list_start_encountered = 0;
3593 found_keyframe_after_edit = 0;
3594 for (; current < e_old_end; current++, index++) {
3595 // check if frame outside edit list mark it for discard
3596 frame_duration = (current + 1 < e_old_end) ?
3597 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
3599 flags = current->flags;
3601 // frames (pts) before or after edit list
3602 curr_cts = current->timestamp + msc->dts_shift;
3605 if (ctts_data_old && ctts_index_old < ctts_count_old) {
3606 curr_ctts = ctts_data_old[ctts_index_old].duration;
3607 av_log(mov->fc, AV_LOG_DEBUG, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
3608 curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
3609 curr_cts += curr_ctts;
3611 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
3612 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3613 &msc->ctts_allocated_size,
3614 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3615 ctts_data_old[ctts_index_old].duration) == -1) {
3616 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3618 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3619 ctts_data_old[ctts_index_old].duration);
3623 ctts_sample_old = 0;
3624 edit_list_start_ctts_sample = 0;
3628 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
3629 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
3630 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
3631 first_non_zero_audio_edit > 0) {
3632 packet_skip_samples = edit_list_media_time - curr_cts;
3633 st->skip_samples += packet_skip_samples;
3635 // Shift the index entry timestamp by packet_skip_samples to be correct.
3636 edit_list_dts_counter -= packet_skip_samples;
3637 if (edit_list_start_encountered == 0) {
3638 edit_list_start_encountered = 1;
3639 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
3640 // discarded packets.
3641 if (frame_duration_buffer) {
3642 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3643 frame_duration_buffer, num_discarded_begin);
3644 av_freep(&frame_duration_buffer);
3648 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
3650 flags |= AVINDEX_DISCARD_FRAME;
3651 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
3653 if (edit_list_start_encountered == 0) {
3654 num_discarded_begin++;
3655 frame_duration_buffer = av_realloc(frame_duration_buffer,
3656 num_discarded_begin * sizeof(int64_t));
3657 if (!frame_duration_buffer) {
3658 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
3661 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
3663 // Increment skip_samples for the first non-zero audio edit list
3664 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3665 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
3666 st->skip_samples += frame_duration;
3671 if (msc->min_corrected_pts < 0) {
3672 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
3674 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
3676 if (edit_list_start_encountered == 0) {
3677 edit_list_start_encountered = 1;
3678 // Make timestamps strictly monotonically increasing by rewriting timestamps for
3679 // discarded packets.
3680 if (frame_duration_buffer) {
3681 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3682 frame_duration_buffer, num_discarded_begin);
3683 av_freep(&frame_duration_buffer);
3688 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
3689 current->min_distance, flags) == -1) {
3690 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
3694 // Update the index ranges array
3695 if (current_index_range < msc->index_ranges || index != current_index_range->end) {
3696 current_index_range++;
3697 current_index_range->start = index;
3699 current_index_range->end = index + 1;
3701 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
3702 if (edit_list_start_encountered > 0) {
3703 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
3706 // Break when found first key frame after edit entry completion
3707 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
3708 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
3709 if (ctts_data_old) {
3710 // If we have CTTS and this is the first keyframe after edit elist,
3711 // wait for one more, because there might be trailing B-frames after this I-frame
3712 // that do belong to the edit.
3713 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
3714 found_keyframe_after_edit = 1;
3717 if (ctts_sample_old != 0) {
3718 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3719 &msc->ctts_allocated_size,
3720 ctts_sample_old - edit_list_start_ctts_sample,
3721 ctts_data_old[ctts_index_old].duration) == -1) {
3722 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3723 ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
3724 ctts_data_old[ctts_index_old].duration);
3733 // If there are empty edits, then msc->min_corrected_pts might be positive
3734 // intentionally. So we subtract the sum duration of emtpy edits here.
3735 msc->min_corrected_pts -= empty_edits_sum_duration;
3737 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
3738 // dts by that amount to make the first pts zero.
3739 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
3740 if (msc->min_corrected_pts > 0) {
3741 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
3742 for (i = 0; i < st->nb_index_entries; ++i) {
3743 st->index_entries[i].timestamp -= msc->min_corrected_pts;
3747 // Start time should be equal to zero or the duration of any empty edits.
3748 st->start_time = empty_edits_sum_duration;
3750 // Update av stream length, if it ends up shorter than the track's media duration
3751 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
3752 msc->start_pad = st->skip_samples;
3754 // Free the old index and the old CTTS structures
3756 av_free(ctts_data_old);
3757 av_freep(&frame_duration_buffer);
3759 // Null terminate the index ranges array
3760 current_index_range++;
3761 current_index_range->start = 0;
3762 current_index_range->end = 0;
3763 msc->current_index = msc->index_ranges[0].start;
3766 static void mov_build_index(MOVContext *mov, AVStream *st)
3768 MOVStreamContext *sc = st->priv_data;
3769 int64_t current_offset;
3770 int64_t current_dts = 0;
3771 unsigned int stts_index = 0;
3772 unsigned int stsc_index = 0;
3773 unsigned int stss_index = 0;
3774 unsigned int stps_index = 0;
3776 uint64_t stream_size = 0;
3777 MOVStts *ctts_data_old = sc->ctts_data;
3778 unsigned int ctts_count_old = sc->ctts_count;
3780 if (sc->elst_count) {
3781 int i, edit_start_index = 0, multiple_edits = 0;
3782 int64_t empty_duration = 0; // empty duration of the first edit list entry
3783 int64_t start_time = 0; // start time of the media
3785 for (i = 0; i < sc->elst_count; i++) {
3786 const MOVElst *e = &sc->elst_data[i];
3787 if (i == 0 && e->time == -1) {
3788 /* if empty, the first entry is the start time of the stream
3789 * relative to the presentation itself */
3790 empty_duration = e->duration;
3791 edit_start_index = 1;
3792 } else if (i == edit_start_index && e->time >= 0) {
3793 start_time = e->time;
3799 if (multiple_edits && !mov->advanced_editlist)
3800 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
3801 "Use -advanced_editlist to correctly decode otherwise "
3802 "a/v desync might occur\n");
3804 /* adjust first dts according to edit list */
3805 if ((empty_duration || start_time) && mov->time_scale > 0) {
3807 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
3808 sc->time_offset = start_time - empty_duration;
3809 sc->min_corrected_pts = start_time;
3810 if (!mov->advanced_editlist)
3811 current_dts = -sc->time_offset;
3814 if (!multiple_edits && !mov->advanced_editlist &&
3815 st->codecpar->codec_id == AV_CODEC_ID_AAC && start_time > 0)
3816 sc->start_pad = start_time;
3819 /* only use old uncompressed audio chunk demuxing when stts specifies it */
3820 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3821 sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
3822 unsigned int current_sample = 0;
3823 unsigned int stts_sample = 0;
3824 unsigned int sample_size;
3825 unsigned int distance = 0;
3826 unsigned int rap_group_index = 0;
3827 unsigned int rap_group_sample = 0;
3828 int64_t last_dts = 0;
3829 int64_t dts_correction = 0;
3830 int rap_group_present = sc->rap_group_count && sc->rap_group;
3831 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
3833 current_dts -= sc->dts_shift;
3834 last_dts = current_dts;
3836 if (!sc->sample_count || st->nb_index_entries)
3838 if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
3840 if (av_reallocp_array(&st->index_entries,
3841 st->nb_index_entries + sc->sample_count,
3842 sizeof(*st->index_entries)) < 0) {
3843 st->nb_index_entries = 0;
3846 st->index_entries_allocated_size = (st->nb_index_entries + sc->sample_count) * sizeof(*st->index_entries);
3848 if (ctts_data_old) {
3849 // Expand ctts entries such that we have a 1-1 mapping with samples
3850 if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
3853 sc->ctts_allocated_size = 0;
3854 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size,
3855 sc->sample_count * sizeof(*sc->ctts_data));
3856 if (!sc->ctts_data) {
3857 av_free(ctts_data_old);
3861 memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
3863 for (i = 0; i < ctts_count_old &&
3864 sc->ctts_count < sc->sample_count; i++)
3865 for (j = 0; j < ctts_data_old[i].count &&
3866 sc->ctts_count < sc->sample_count; j++)
3867 add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
3868 &sc->ctts_allocated_size, 1,
3869 ctts_data_old[i].duration);
3870 av_free(ctts_data_old);
3873 for (i = 0; i < sc->chunk_count; i++) {
3874 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
3875 current_offset = sc->chunk_offsets[i];
3876 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3877 i + 1 == sc->stsc_data[stsc_index + 1].first)
3880 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
3881 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
3882 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
3883 sc->stsz_sample_size = sc->sample_size;
3885 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
3886 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
3887 sc->stsz_sample_size = sc->sample_size;
3890 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
3892 if (current_sample >= sc->sample_count) {
3893 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
3897 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
3899 if (stss_index + 1 < sc->keyframe_count)
3901 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
3903 if (stps_index + 1 < sc->stps_count)
3906 if (rap_group_present && rap_group_index < sc->rap_group_count) {
3907 if (sc->rap_group[rap_group_index].index > 0)
3909 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
3910 rap_group_sample = 0;
3914 if (sc->keyframe_absent
3916 && !rap_group_present
3917 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
3921 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
3922 if (sc->pseudo_stream_id == -1 ||
3923 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
3925 if (sample_size > 0x3FFFFFFF) {
3926 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
3929 e = &st->index_entries[st->nb_index_entries++];
3930 e->pos = current_offset;
3931 e->timestamp = current_dts;
3932 e->size = sample_size;
3933 e->min_distance = distance;
3934 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
3935 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
3936 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
3937 current_offset, current_dts, sample_size, distance, keyframe);
3938 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries < 100)
3939 ff_rfps_add_frame(mov->fc, st, current_dts);
3942 current_offset += sample_size;
3943 stream_size += sample_size;
3945 /* A negative sample duration is invalid based on the spec,
3946 * but some samples need it to correct the DTS. */
3947 if (sc->stts_data[stts_index].duration < 0) {
3948 av_log(mov->fc, AV_LOG_WARNING,
3949 "Invalid SampleDelta %d in STTS, at %d st:%d\n",
3950 sc->stts_data[stts_index].duration, stts_index,
3952 dts_correction += sc->stts_data[stts_index].duration - 1;
3953 sc->stts_data[stts_index].duration = 1;
3955 current_dts += sc->stts_data[stts_index].duration;
3956 if (!dts_correction || current_dts + dts_correction > last_dts) {
3957 current_dts += dts_correction;
3960 /* Avoid creating non-monotonous DTS */
3961 dts_correction += current_dts - last_dts - 1;
3962 current_dts = last_dts + 1;
3964 last_dts = current_dts;
3968 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
3974 if (st->duration > 0)
3975 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
3977 unsigned chunk_samples, total = 0;
3979 if (!sc->chunk_count)
3982 // compute total chunk count
3983 for (i = 0; i < sc->stsc_count; i++) {
3984 unsigned count, chunk_count;
3986 chunk_samples = sc->stsc_data[i].count;
3987 if (i != sc->stsc_count - 1 &&
3988 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
3989 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
3993 if (sc->samples_per_frame >= 160) { // gsm
3994 count = chunk_samples / sc->samples_per_frame;
3995 } else if (sc->samples_per_frame > 1) {
3996 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
3997 count = (chunk_samples+samples-1) / samples;
3999 count = (chunk_samples+1023) / 1024;
4002 if (mov_stsc_index_valid(i, sc->stsc_count))
4003 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4005 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4006 total += chunk_count * count;
4009 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4010 if (total >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
4012 if (av_reallocp_array(&st->index_entries,
4013 st->nb_index_entries + total,
4014 sizeof(*st->index_entries)) < 0) {
4015 st->nb_index_entries = 0;
4018 st->index_entries_allocated_size = (st->nb_index_entries + total) * sizeof(*st->index_entries);
4021 for (i = 0; i < sc->chunk_count; i++) {
4022 current_offset = sc->chunk_offsets[i];
4023 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4024 i + 1 == sc->stsc_data[stsc_index + 1].first)
4026 chunk_samples = sc->stsc_data[stsc_index].count;
4028 while (chunk_samples > 0) {
4030 unsigned size, samples;
4032 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4033 avpriv_request_sample(mov->fc,
4034 "Zero bytes per frame, but %d samples per frame",
4035 sc->samples_per_frame);
4039 if (sc->samples_per_frame >= 160) { // gsm
4040 samples = sc->samples_per_frame;
4041 size = sc->bytes_per_frame;
4043 if (sc->samples_per_frame > 1) {
4044 samples = FFMIN((1024 / sc->samples_per_frame)*
4045 sc->samples_per_frame, chunk_samples);
4046 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
4048 samples = FFMIN(1024, chunk_samples);
4049 size = samples * sc->sample_size;
4053 if (st->nb_index_entries >= total) {
4054 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4057 if (size > 0x3FFFFFFF) {
4058 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4061 e = &st->index_entries[st->nb_index_entries++];
4062 e->pos = current_offset;
4063 e->timestamp = current_dts;
4065 e->min_distance = 0;
4066 e->flags = AVINDEX_KEYFRAME;
4067 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4068 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4071 current_offset += size;
4072 current_dts += samples;
4073 chunk_samples -= samples;
4078 if (!mov->ignore_editlist && mov->advanced_editlist) {
4079 // Fix index according to edit lists.
4080 mov_fix_index(mov, st);
4083 // Update start time of the stream.
4084 if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries > 0) {
4085 st->start_time = st->index_entries[0].timestamp + sc->dts_shift;
4086 if (sc->ctts_data) {
4087 st->start_time += sc->ctts_data[0].duration;
4091 mov_estimate_video_delay(mov, st);
4094 static int test_same_origin(const char *src, const char *ref) {
4104 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4105 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4107 if (strlen(src) == 0) {
4109 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4110 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4111 strlen(src_host) + 1 >= sizeof(src_host) ||
4112 strlen(ref_host) + 1 >= sizeof(ref_host)) {
4114 } else if (strcmp(src_proto, ref_proto) ||
4115 strcmp(src_auth, ref_auth) ||
4116 strcmp(src_host, ref_host) ||
4117 src_port != ref_port) {
4123 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4125 /* try relative path, we do not try the absolute because it can leak information about our
4126 system to an attacker */
4127 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4128 char filename[1025];
4129 const char *src_path;
4132 /* find a source dir */
4133 src_path = strrchr(src, '/');
4139 /* find a next level down to target */
4140 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4141 if (ref->path[l] == '/') {
4142 if (i == ref->nlvl_to - 1)
4148 /* compose filename if next level down to target was found */
4149 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4150 memcpy(filename, src, src_path - src);
4151 filename[src_path - src] = 0;
4153 for (i = 1; i < ref->nlvl_from; i++)
4154 av_strlcat(filename, "../", sizeof(filename));
4156 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4157 if (!c->use_absolute_path) {
4158 int same_origin = test_same_origin(src, filename);
4161 av_log(c->fc, AV_LOG_ERROR,
4162 "Reference with mismatching origin, %s not tried for security reasons, "
4163 "set demuxer option use_absolute_path to allow it anyway\n",
4165 return AVERROR(ENOENT);
4168 if(strstr(ref->path + l + 1, "..") ||
4169 strstr(ref->path + l + 1, ":") ||
4170 (ref->nlvl_from > 1 && same_origin < 0) ||
4171 (filename[0] == '/' && src_path == src))
4172 return AVERROR(ENOENT);
4175 if (strlen(filename) + 1 == sizeof(filename))
4176 return AVERROR(ENOENT);
4177 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4180 } else if (c->use_absolute_path) {
4181 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4182 "this is a possible security issue\n");
4183 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4186 av_log(c->fc, AV_LOG_ERROR,
4187 "Absolute path %s not tried for security reasons, "
4188 "set demuxer option use_absolute_path to allow absolute paths\n",
4192 return AVERROR(ENOENT);
4195 static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
4197 if (sc->time_scale <= 0) {
4198 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4199 sc->time_scale = c->time_scale;
4200 if (sc->time_scale <= 0)
4205 static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4208 MOVStreamContext *sc;
4211 st = avformat_new_stream(c->fc, NULL);
4212 if (!st) return AVERROR(ENOMEM);
4214 sc = av_mallocz(sizeof(MOVStreamContext));
4215 if (!sc) return AVERROR(ENOMEM);
4218 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
4219 sc->ffindex = st->index;
4220 c->trak_index = st->index;
4222 if ((ret = mov_read_default(c, pb, atom)) < 0)
4227 // Here stsc refers to a chunk not described in stco. This is technically invalid,
4228 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4229 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4231 av_freep(&sc->stsc_data);
4235 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4236 (!sc->sample_size && !sc->sample_count))) ||
4237 (!sc->chunk_count && sc->sample_count)) {
4238 av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4242 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4243 av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4245 return AVERROR_INVALIDDATA;
4248 fix_timescale(c, sc);
4250 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4252 mov_build_index(c, st);
4254 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4255 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4256 if (c->enable_drefs) {
4257 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4258 av_log(c->fc, AV_LOG_ERROR,
4259 "stream %d, error opening alias: path='%s', dir='%s', "
4260 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4261 st->index, dref->path, dref->dir, dref->filename,
4262 dref->volume, dref->nlvl_from, dref->nlvl_to);
4264 av_log(c->fc, AV_LOG_WARNING,
4265 "Skipped opening external track: "
4266 "stream %d, alias: path='%s', dir='%s', "
4267 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4268 "Set enable_drefs to allow this.\n",
4269 st->index, dref->path, dref->dir, dref->filename,
4270 dref->volume, dref->nlvl_from, dref->nlvl_to);
4274 sc->pb_is_copied = 1;
4277 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4278 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4279 sc->height && sc->width &&
4280 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4281 st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4282 ((double)st->codecpar->width * sc->height), INT_MAX);
4285 #if FF_API_R_FRAME_RATE
4286 if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4287 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
4288 sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4292 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4293 if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4294 TAG_IS_AVCI(st->codecpar->codec_tag)) {
4295 ret = ff_generate_avci_extradata(st);
4300 switch (st->codecpar->codec_id) {
4301 #if CONFIG_H261_DECODER
4302 case AV_CODEC_ID_H261:
4304 #if CONFIG_H263_DECODER
4305 case AV_CODEC_ID_H263:
4307 #if CONFIG_MPEG4_DECODER
4308 case AV_CODEC_ID_MPEG4:
4310 st->codecpar->width = 0; /* let decoder init width/height */
4311 st->codecpar->height= 0;
4315 // If the duration of the mp3 packets is not constant, then they could need a parser
4316 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4317 && sc->stts_count > 3
4318 && sc->stts_count*10 > st->nb_frames
4319 && sc->time_scale == st->codecpar->sample_rate) {
4320 st->need_parsing = AVSTREAM_PARSE_FULL;
4322 /* Do not need those anymore. */
4323 av_freep(&sc->chunk_offsets);
4324 av_freep(&sc->sample_sizes);
4325 av_freep(&sc->keyframes);
4326 av_freep(&sc->stts_data);
4327 av_freep(&sc->stps_data);
4328 av_freep(&sc->elst_data);
4329 av_freep(&sc->rap_group);
4334 static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4337 c->itunes_metadata = 1;
4338 ret = mov_read_default(c, pb, atom);
4339 c->itunes_metadata = 0;
4343 static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4352 count = avio_rb32(pb);
4353 if (count > UINT_MAX / sizeof(*c->meta_keys) - 1) {
4354 av_log(c->fc, AV_LOG_ERROR,
4355 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
4356 return AVERROR_INVALIDDATA;
4359 c->meta_keys_count = count + 1;
4360 c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
4362 return AVERROR(ENOMEM);
4364 for (i = 1; i <= count; ++i) {
4365 uint32_t key_size = avio_rb32(pb);
4366 uint32_t type = avio_rl32(pb);
4368 av_log(c->fc, AV_LOG_ERROR,
4369 "The key# %"PRIu32" in meta has invalid size:"
4370 "%"PRIu32"\n", i, key_size);
4371 return AVERROR_INVALIDDATA;
4374 if (type != MKTAG('m','d','t','a')) {
4375 avio_skip(pb, key_size);
4377 c->meta_keys[i] = av_mallocz(key_size + 1);
4378 if (!c->meta_keys[i])
4379 return AVERROR(ENOMEM);
4380 avio_read(pb, c->meta_keys[i], key_size);
4386 static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4388 int64_t end = avio_tell(pb) + atom.size;
4389 uint8_t *key = NULL, *val = NULL, *mean = NULL;
4393 MOVStreamContext *sc;
4395 if (c->fc->nb_streams < 1)
4397 st = c->fc->streams[c->fc->nb_streams-1];
4400 for (i = 0; i < 3; i++) {
4404 if (end - avio_tell(pb) <= 12)
4407 len = avio_rb32(pb);
4408 tag = avio_rl32(pb);
4409 avio_skip(pb, 4); // flags
4411 if (len < 12 || len - 12 > end - avio_tell(pb))
4415 if (tag == MKTAG('m', 'e', 'a', 'n'))
4417 else if (tag == MKTAG('n', 'a', 'm', 'e'))
4419 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
4426 *p = av_malloc(len + 1);
4428 ret = AVERROR(ENOMEM);
4431 ret = ffio_read_size(pb, *p, len);
4439 if (mean && key && val) {
4440 if (strcmp(key, "iTunSMPB") == 0) {
4441 int priming, remainder, samples;
4442 if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
4443 if(priming>0 && priming<16384)
4444 sc->start_pad = priming;
4447 if (strcmp(key, "cdec") != 0) {
4448 av_dict_set(&c->fc->metadata, key, val,
4449 AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
4453 av_log(c->fc, AV_LOG_VERBOSE,
4454 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
4457 avio_seek(pb, end, SEEK_SET);
4464 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4466 while (atom.size > 8) {
4470 tag = avio_rl32(pb);
4472 if (tag == MKTAG('h','d','l','r')) {
4473 avio_seek(pb, -8, SEEK_CUR);
4475 return mov_read_default(c, pb, atom);
4481 // return 1 when matrix is identity, 0 otherwise
4482 #define IS_MATRIX_IDENT(matrix) \
4483 ( (matrix)[0][0] == (1 << 16) && \
4484 (matrix)[1][1] == (1 << 16) && \
4485 (matrix)[2][2] == (1 << 30) && \
4486 !(matrix)[0][1] && !(matrix)[0][2] && \
4487 !(matrix)[1][0] && !(matrix)[1][2] && \
4488 !(matrix)[2][0] && !(matrix)[2][1])
4490 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4495 int display_matrix[3][3];
4496 int res_display_matrix[3][3] = { { 0 } };
4498 MOVStreamContext *sc;
4502 if (c->fc->nb_streams < 1)
4504 st = c->fc->streams[c->fc->nb_streams-1];
4507 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4508 // avoids corrupting AVStreams mapped to an earlier tkhd.
4510 return AVERROR_INVALIDDATA;
4512 version = avio_r8(pb);
4513 flags = avio_rb24(pb);
4514 st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
4520 avio_rb32(pb); /* creation time */
4521 avio_rb32(pb); /* modification time */
4523 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4524 avio_rb32(pb); /* reserved */
4526 /* highlevel (considering edits) duration in movie timebase */
4527 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4528 avio_rb32(pb); /* reserved */
4529 avio_rb32(pb); /* reserved */
4531 avio_rb16(pb); /* layer */
4532 avio_rb16(pb); /* alternate group */
4533 avio_rb16(pb); /* volume */
4534 avio_rb16(pb); /* reserved */
4536 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4537 // they're kept in fixed point format through all calculations
4538 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4539 // side data, but the scale factor is not needed to calculate aspect ratio
4540 for (i = 0; i < 3; i++) {
4541 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
4542 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
4543 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
4546 width = avio_rb32(pb); // 16.16 fixed point track width
4547 height = avio_rb32(pb); // 16.16 fixed point track height
4548 sc->width = width >> 16;
4549 sc->height = height >> 16;
4551 // apply the moov display matrix (after the tkhd one)
4552 for (i = 0; i < 3; i++) {
4553 const int sh[3] = { 16, 16, 30 };
4554 for (j = 0; j < 3; j++) {
4555 for (e = 0; e < 3; e++) {
4556 res_display_matrix[i][j] +=
4557 ((int64_t) display_matrix[i][e] *
4558 c->movie_display_matrix[e][j]) >> sh[e];
4563 // save the matrix when it is not the default identity
4564 if (!IS_MATRIX_IDENT(res_display_matrix)) {
4567 av_freep(&sc->display_matrix);
4568 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4569 if (!sc->display_matrix)
4570 return AVERROR(ENOMEM);
4572 for (i = 0; i < 3; i++)
4573 for (j = 0; j < 3; j++)
4574 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4576 #if FF_API_OLD_ROTATE_API
4577 rotate = av_display_rotation_get(sc->display_matrix);
4578 if (!isnan(rotate)) {
4579 char rotate_buf[64];
4581 if (rotate < 0) // for backward compatibility
4583 snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate);
4584 av_dict_set(&st->metadata, "rotate", rotate_buf, 0);
4589 // transform the display width/height according to the matrix
4590 // to keep the same scale, use [width height 1<<16]
4591 if (width && height && sc->display_matrix) {
4592 double disp_transform[2];
4594 for (i = 0; i < 2; i++)
4595 disp_transform[i] = hypot(sc->display_matrix[0 + i],
4596 sc->display_matrix[3 + i]);
4598 if (disp_transform[0] > 0 && disp_transform[1] > 0 &&
4599 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4600 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4601 st->sample_aspect_ratio = av_d2q(
4602 disp_transform[0] / disp_transform[1],
4608 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4610 MOVFragment *frag = &c->fragment;
4611 MOVTrackExt *trex = NULL;
4612 int flags, track_id, i;
4614 avio_r8(pb); /* version */
4615 flags = avio_rb24(pb);
4617 track_id = avio_rb32(pb);
4619 return AVERROR_INVALIDDATA;
4620 for (i = 0; i < c->trex_count; i++)
4621 if (c->trex_data[i].track_id == track_id) {
4622 trex = &c->trex_data[i];
4626 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4629 c->fragment.found_tfhd = 1;
4630 frag->track_id = track_id;
4631 set_frag_stream(&c->frag_index, track_id);
4633 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4634 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4635 frag->moof_offset : frag->implicit_offset;
4636 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4638 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4639 avio_rb32(pb) : trex->duration;
4640 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4641 avio_rb32(pb) : trex->size;
4642 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4643 avio_rb32(pb) : trex->flags;
4644 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4649 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4654 num = atom.size / 4;
4655 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4656 return AVERROR(ENOMEM);
4658 av_free(c->chapter_tracks);
4659 c->chapter_tracks = new_tracks;
4660 c->nb_chapter_tracks = num;
4662 for (i = 0; i < num && !pb->eof_reached; i++)
4663 c->chapter_tracks[i] = avio_rb32(pb);
4668 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4673 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4674 return AVERROR_INVALIDDATA;
4675 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4676 sizeof(*c->trex_data))) < 0) {
4681 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4683 trex = &c->trex_data[c->trex_count++];
4684 avio_r8(pb); /* version */
4685 avio_rb24(pb); /* flags */
4686 trex->track_id = avio_rb32(pb);
4687 trex->stsd_id = avio_rb32(pb);
4688 trex->duration = avio_rb32(pb);
4689 trex->size = avio_rb32(pb);
4690 trex->flags = avio_rb32(pb);
4694 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4696 MOVFragment *frag = &c->fragment;
4697 AVStream *st = NULL;
4698 MOVStreamContext *sc;
4700 MOVFragmentStreamInfo * frag_stream_info;
4701 int64_t base_media_decode_time;
4703 for (i = 0; i < c->fc->nb_streams; i++) {
4704 if (c->fc->streams[i]->id == frag->track_id) {
4705 st = c->fc->streams[i];
4710 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4714 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4716 version = avio_r8(pb);
4717 avio_rb24(pb); /* flags */
4719 base_media_decode_time = avio_rb64(pb);
4721 base_media_decode_time = avio_rb32(pb);
4724 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4725 if (frag_stream_info)
4726 frag_stream_info->tfdt_dts = base_media_decode_time;
4727 sc->track_end = base_media_decode_time;
4732 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4734 MOVFragment *frag = &c->fragment;
4735 AVStream *st = NULL;
4736 MOVStreamContext *sc;
4739 int64_t dts, pts = AV_NOPTS_VALUE;
4740 int data_offset = 0;
4741 unsigned entries, first_sample_flags = frag->flags;
4742 int flags, distance, i;
4743 int64_t prev_dts = AV_NOPTS_VALUE;
4744 int next_frag_index = -1, index_entry_pos;
4745 size_t requested_size;
4746 size_t old_ctts_allocated_size;
4747 AVIndexEntry *new_entries;
4748 MOVFragmentStreamInfo * frag_stream_info;
4750 if (!frag->found_tfhd) {
4751 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4752 return AVERROR_INVALIDDATA;
4755 for (i = 0; i < c->fc->nb_streams; i++) {
4756 if (c->fc->streams[i]->id == frag->track_id) {
4757 st = c->fc->streams[i];
4762 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4766 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4769 // Find the next frag_index index that has a valid index_entry for
4770 // the current track_id.
4772 // A valid index_entry means the trun for the fragment was read
4773 // and it's samples are in index_entries at the given position.
4774 // New index entries will be inserted before the index_entry found.
4775 index_entry_pos = st->nb_index_entries;
4776 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4777 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4778 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4779 next_frag_index = i;
4780 index_entry_pos = frag_stream_info->index_entry;
4784 av_assert0(index_entry_pos <= st->nb_index_entries);
4786 avio_r8(pb); /* version */
4787 flags = avio_rb24(pb);
4788 entries = avio_rb32(pb);
4789 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4791 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4792 return AVERROR_INVALIDDATA;
4793 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4794 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4796 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4797 if (frag_stream_info)
4799 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4800 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4801 pts = frag_stream_info->first_tfra_pts;
4802 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4803 ", using it for pts\n", pts);
4804 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4805 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4806 // pts = frag_stream_info->sidx_pts;
4807 dts = frag_stream_info->sidx_pts - sc->time_offset;
4808 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4809 ", using it for pts\n", pts);
4810 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4811 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4812 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4813 ", using it for dts\n", dts);
4815 dts = sc->track_end - sc->time_offset;
4816 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4817 ", using it for dts\n", dts);
4820 dts = sc->track_end - sc->time_offset;
4821 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4822 ", using it for dts\n", dts);
4824 offset = frag->base_data_offset + data_offset;
4826 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4828 // realloc space for new index entries
4829 if((uint64_t)st->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4830 entries = UINT_MAX / sizeof(AVIndexEntry) - st->nb_index_entries;
4831 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4836 requested_size = (st->nb_index_entries + entries) * sizeof(AVIndexEntry);
4837 new_entries = av_fast_realloc(st->index_entries,
4838 &st->index_entries_allocated_size,
4841 return AVERROR(ENOMEM);
4842 st->index_entries= new_entries;
4844 requested_size = (st->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4845 old_ctts_allocated_size = sc->ctts_allocated_size;
4846 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4849 return AVERROR(ENOMEM);
4850 sc->ctts_data = ctts_data;
4852 // In case there were samples without ctts entries, ensure they get
4853 // zero valued entries. This ensures clips which mix boxes with and
4854 // without ctts entries don't pickup uninitialized data.
4855 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4856 sc->ctts_allocated_size - old_ctts_allocated_size);
4858 if (index_entry_pos < st->nb_index_entries) {
4859 // Make hole in index_entries and ctts_data for new samples
4860 memmove(st->index_entries + index_entry_pos + entries,
4861 st->index_entries + index_entry_pos,
4862 sizeof(*st->index_entries) *
4863 (st->nb_index_entries - index_entry_pos));
4864 memmove(sc->ctts_data + index_entry_pos + entries,
4865 sc->ctts_data + index_entry_pos,
4866 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4867 if (index_entry_pos < sc->current_sample) {
4868 sc->current_sample += entries;
4872 st->nb_index_entries += entries;
4873 sc->ctts_count = st->nb_index_entries;
4875 // Record the index_entry position in frag_index of this fragment
4876 if (frag_stream_info)
4877 frag_stream_info->index_entry = index_entry_pos;
4879 if (index_entry_pos > 0)
4880 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4882 for (i = 0; i < entries && !pb->eof_reached; i++) {
4883 unsigned sample_size = frag->size;
4884 int sample_flags = i ? frag->flags : first_sample_flags;
4885 unsigned sample_duration = frag->duration;
4886 unsigned ctts_duration = 0;
4888 int index_entry_flags = 0;
4890 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4891 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4892 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4893 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4895 mov_update_dts_shift(sc, ctts_duration, c->fc);
4896 if (pts != AV_NOPTS_VALUE) {
4897 dts = pts - sc->dts_shift;
4898 if (flags & MOV_TRUN_SAMPLE_CTS) {
4899 dts -= ctts_duration;
4901 dts -= sc->time_offset;
4903 av_log(c->fc, AV_LOG_DEBUG,
4904 "pts %"PRId64" calculated dts %"PRId64
4905 " sc->dts_shift %d ctts.duration %d"
4906 " sc->time_offset %"PRId64
4907 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4909 sc->dts_shift, ctts_duration,
4910 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4911 pts = AV_NOPTS_VALUE;
4914 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4918 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4919 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4922 index_entry_flags |= AVINDEX_KEYFRAME;
4924 // Fragments can overlap in time. Discard overlapping frames after
4926 if (prev_dts >= dts)
4927 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4929 st->index_entries[index_entry_pos].pos = offset;
4930 st->index_entries[index_entry_pos].timestamp = dts;
4931 st->index_entries[index_entry_pos].size= sample_size;
4932 st->index_entries[index_entry_pos].min_distance= distance;
4933 st->index_entries[index_entry_pos].flags = index_entry_flags;
4935 sc->ctts_data[index_entry_pos].count = 1;
4936 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4939 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4940 "size %u, distance %d, keyframe %d\n", st->index,
4941 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4943 dts += sample_duration;
4944 offset += sample_size;
4945 sc->data_size += sample_size;
4947 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4948 1 <= INT_MAX - sc->nb_frames_for_fps
4950 sc->duration_for_fps += sample_duration;
4951 sc->nb_frames_for_fps ++;
4955 // EOF found before reading all entries. Fix the hole this would
4956 // leave in index_entries and ctts_data
4957 int gap = entries - i;
4958 memmove(st->index_entries + index_entry_pos,
4959 st->index_entries + index_entry_pos + gap,
4960 sizeof(*st->index_entries) *
4961 (st->nb_index_entries - (index_entry_pos + gap)));
4962 memmove(sc->ctts_data + index_entry_pos,
4963 sc->ctts_data + index_entry_pos + gap,
4964 sizeof(*sc->ctts_data) *
4965 (sc->ctts_count - (index_entry_pos + gap)));
4967 st->nb_index_entries -= gap;
4968 sc->ctts_count -= gap;
4969 if (index_entry_pos < sc->current_sample) {
4970 sc->current_sample -= gap;
4975 // The end of this new fragment may overlap in time with the start
4976 // of the next fragment in index_entries. Mark the samples in the next
4977 // fragment that overlap with AVINDEX_DISCARD_FRAME
4978 prev_dts = AV_NOPTS_VALUE;
4979 if (index_entry_pos > 0)
4980 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4981 for (i = index_entry_pos; i < st->nb_index_entries; i++) {
4982 if (prev_dts < st->index_entries[i].timestamp)
4984 st->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
4987 // If a hole was created to insert the new index_entries into,
4988 // the index_entry recorded for all subsequent moof must
4989 // be incremented by the number of entries inserted.
4990 fix_frag_index_entries(&c->frag_index, next_frag_index,
4991 frag->track_id, entries);
4993 if (pb->eof_reached) {
4994 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
4998 frag->implicit_offset = offset;
5000 sc->track_end = dts + sc->time_offset;
5001 if (st->duration < sc->track_end)
5002 st->duration = sc->track_end;
5007 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5009 int64_t offset = avio_tell(pb) + atom.size, pts, timestamp;
5011 unsigned i, j, track_id, item_count;
5012 AVStream *st = NULL;
5013 AVStream *ref_st = NULL;
5014 MOVStreamContext *sc, *ref_sc = NULL;
5015 AVRational timescale;
5017 version = avio_r8(pb);
5019 avpriv_request_sample(c->fc, "sidx version %u", version);
5023 avio_rb24(pb); // flags
5025 track_id = avio_rb32(pb); // Reference ID
5026 for (i = 0; i < c->fc->nb_streams; i++) {
5027 if (c->fc->streams[i]->id == track_id) {
5028 st = c->fc->streams[i];
5033 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5039 timescale = av_make_q(1, avio_rb32(pb));
5041 if (timescale.den <= 0) {
5042 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5043 return AVERROR_INVALIDDATA;
5047 pts = avio_rb32(pb);
5048 offset += avio_rb32(pb);
5050 pts = avio_rb64(pb);
5051 offset += avio_rb64(pb);
5054 avio_rb16(pb); // reserved
5056 item_count = avio_rb16(pb);
5058 for (i = 0; i < item_count; i++) {
5060 MOVFragmentStreamInfo * frag_stream_info;
5061 uint32_t size = avio_rb32(pb);
5062 uint32_t duration = avio_rb32(pb);
5063 if (size & 0x80000000) {
5064 avpriv_request_sample(c->fc, "sidx reference_type 1");
5065 return AVERROR_PATCHWELCOME;
5067 avio_rb32(pb); // sap_flags
5068 timestamp = av_rescale_q(pts, timescale, st->time_base);
5070 index = update_frag_index(c, offset);
5071 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5072 if (frag_stream_info)
5073 frag_stream_info->sidx_pts = timestamp;
5079 st->duration = sc->track_end = pts;
5083 if (offset == avio_size(pb)) {
5084 // Find first entry in fragment index that came from an sidx.
5085 // This will pretty much always be the first entry.
5086 for (i = 0; i < c->frag_index.nb_items; i++) {
5087 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5088 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5089 MOVFragmentStreamInfo * si;
5090 si = &item->stream_info[j];
5091 if (si->sidx_pts != AV_NOPTS_VALUE) {
5092 ref_st = c->fc->streams[j];
5093 ref_sc = ref_st->priv_data;
5098 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5099 st = c->fc->streams[i];
5101 if (!sc->has_sidx) {
5102 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5106 c->frag_index.complete = 1;
5112 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5113 /* like the files created with Adobe Premiere 5.0, for samples see */
5114 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5115 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5120 return 0; /* continue */
5121 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5122 avio_skip(pb, atom.size - 4);
5125 atom.type = avio_rl32(pb);
5127 if (atom.type != MKTAG('m','d','a','t')) {
5128 avio_skip(pb, atom.size);
5131 err = mov_read_mdat(c, pb, atom);
5135 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5140 uint8_t *moov_data; /* uncompressed data */
5141 long cmov_len, moov_len;
5144 avio_rb32(pb); /* dcom atom */
5145 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5146 return AVERROR_INVALIDDATA;
5147 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5148 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5149 return AVERROR_INVALIDDATA;
5151 avio_rb32(pb); /* cmvd atom */
5152 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5153 return AVERROR_INVALIDDATA;
5154 moov_len = avio_rb32(pb); /* uncompressed size */
5155 cmov_len = atom.size - 6 * 4;
5157 cmov_data = av_malloc(cmov_len);
5159 return AVERROR(ENOMEM);
5160 moov_data = av_malloc(moov_len);
5163 return AVERROR(ENOMEM);
5165 ret = ffio_read_size(pb, cmov_data, cmov_len);
5167 goto free_and_return;
5169 ret = AVERROR_INVALIDDATA;
5170 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5171 goto free_and_return;
5172 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5173 goto free_and_return;
5174 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5175 atom.type = MKTAG('m','o','o','v');
5176 atom.size = moov_len;
5177 ret = mov_read_default(c, &ctx, atom);
5183 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5184 return AVERROR(ENOSYS);
5188 /* edit list atom */
5189 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5191 MOVStreamContext *sc;
5192 int i, edit_count, version;
5193 int64_t elst_entry_size;
5195 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5197 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5199 version = avio_r8(pb); /* version */
5200 avio_rb24(pb); /* flags */
5201 edit_count = avio_rb32(pb); /* entries */
5204 elst_entry_size = version == 1 ? 20 : 12;
5205 if (atom.size != edit_count * elst_entry_size) {
5206 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5207 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5208 edit_count, atom.size + 8);
5209 return AVERROR_INVALIDDATA;
5211 edit_count = atom.size / elst_entry_size;
5212 if (edit_count * elst_entry_size != atom.size) {
5213 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.", atom.size, edit_count);
5221 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5222 av_free(sc->elst_data);
5224 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5226 return AVERROR(ENOMEM);
5228 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5229 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5230 MOVElst *e = &sc->elst_data[i];
5233 e->duration = avio_rb64(pb);
5234 e->time = avio_rb64(pb);
5237 e->duration = avio_rb32(pb); /* segment duration */
5238 e->time = (int32_t)avio_rb32(pb); /* media time */
5241 e->rate = avio_rb32(pb) / 65536.0;
5243 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5244 e->duration, e->time, e->rate);
5246 if (e->time < 0 && e->time != -1 &&
5247 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5248 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5249 c->fc->nb_streams-1, i, e->time);
5250 return AVERROR_INVALIDDATA;
5258 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5260 MOVStreamContext *sc;
5262 if (c->fc->nb_streams < 1)
5263 return AVERROR_INVALIDDATA;
5264 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5265 sc->timecode_track = avio_rb32(pb);
5269 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5274 if (c->fc->nb_streams < 1)
5276 st = c->fc->streams[c->fc->nb_streams - 1];
5278 if (atom.size < 4) {
5279 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5280 return AVERROR_INVALIDDATA;
5283 /* For now, propagate only the OBUs, if any. Once libavcodec is
5284 updated to handle isobmff style extradata this can be removed. */
5290 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5297 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5300 int version, color_range, color_primaries, color_trc, color_space;
5302 if (c->fc->nb_streams < 1)
5304 st = c->fc->streams[c->fc->nb_streams - 1];
5306 if (atom.size < 5) {
5307 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5308 return AVERROR_INVALIDDATA;
5311 version = avio_r8(pb);
5313 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5316 avio_skip(pb, 3); /* flags */
5318 avio_skip(pb, 2); /* profile + level */
5319 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5320 color_primaries = avio_r8(pb);
5321 color_trc = avio_r8(pb);
5322 color_space = avio_r8(pb);
5323 if (avio_rb16(pb)) /* codecIntializationDataSize */
5324 return AVERROR_INVALIDDATA;
5326 if (!av_color_primaries_name(color_primaries))
5327 color_primaries = AVCOL_PRI_UNSPECIFIED;
5328 if (!av_color_transfer_name(color_trc))
5329 color_trc = AVCOL_TRC_UNSPECIFIED;
5330 if (!av_color_space_name(color_space))
5331 color_space = AVCOL_SPC_UNSPECIFIED;
5333 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5334 st->codecpar->color_primaries = color_primaries;
5335 st->codecpar->color_trc = color_trc;
5336 st->codecpar->color_space = color_space;
5341 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5343 MOVStreamContext *sc;
5346 if (c->fc->nb_streams < 1)
5347 return AVERROR_INVALIDDATA;
5349 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5351 if (atom.size < 5) {
5352 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5353 return AVERROR_INVALIDDATA;
5356 version = avio_r8(pb);
5358 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5361 avio_skip(pb, 3); /* flags */
5363 sc->mastering = av_mastering_display_metadata_alloc();
5365 return AVERROR(ENOMEM);
5367 for (i = 0; i < 3; i++) {
5368 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5369 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5371 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5372 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5374 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5375 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5377 sc->mastering->has_primaries = 1;
5378 sc->mastering->has_luminance = 1;
5383 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5385 MOVStreamContext *sc;
5386 const int mapping[3] = {1, 2, 0};
5387 const int chroma_den = 50000;
5388 const int luma_den = 10000;
5391 if (c->fc->nb_streams < 1)
5392 return AVERROR_INVALIDDATA;
5394 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5396 if (atom.size < 24) {
5397 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5398 return AVERROR_INVALIDDATA;
5401 sc->mastering = av_mastering_display_metadata_alloc();
5403 return AVERROR(ENOMEM);
5405 for (i = 0; i < 3; i++) {
5406 const int j = mapping[i];
5407 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5408 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5410 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5411 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5413 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5414 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5416 sc->mastering->has_luminance = 1;
5417 sc->mastering->has_primaries = 1;
5422 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5424 MOVStreamContext *sc;
5427 if (c->fc->nb_streams < 1)
5428 return AVERROR_INVALIDDATA;
5430 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5432 if (atom.size < 5) {
5433 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5434 return AVERROR_INVALIDDATA;
5437 version = avio_r8(pb);
5439 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5442 avio_skip(pb, 3); /* flags */
5444 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5446 return AVERROR(ENOMEM);
5448 sc->coll->MaxCLL = avio_rb16(pb);
5449 sc->coll->MaxFALL = avio_rb16(pb);
5454 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5456 MOVStreamContext *sc;
5458 if (c->fc->nb_streams < 1)
5459 return AVERROR_INVALIDDATA;
5461 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5463 if (atom.size < 4) {
5464 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5465 return AVERROR_INVALIDDATA;
5468 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5470 return AVERROR(ENOMEM);
5472 sc->coll->MaxCLL = avio_rb16(pb);
5473 sc->coll->MaxFALL = avio_rb16(pb);
5478 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5481 MOVStreamContext *sc;
5482 enum AVStereo3DType type;
5485 if (c->fc->nb_streams < 1)
5488 st = c->fc->streams[c->fc->nb_streams - 1];
5491 if (atom.size < 5) {
5492 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5493 return AVERROR_INVALIDDATA;
5495 avio_skip(pb, 4); /* version + flags */
5500 type = AV_STEREO3D_2D;
5503 type = AV_STEREO3D_TOPBOTTOM;
5506 type = AV_STEREO3D_SIDEBYSIDE;
5509 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5513 sc->stereo3d = av_stereo3d_alloc();
5515 return AVERROR(ENOMEM);
5517 sc->stereo3d->type = type;
5521 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5524 MOVStreamContext *sc;
5525 int size, version, layout;
5526 int32_t yaw, pitch, roll;
5527 uint32_t l = 0, t = 0, r = 0, b = 0;
5528 uint32_t tag, padding = 0;
5529 enum AVSphericalProjection projection;
5531 if (c->fc->nb_streams < 1)
5534 st = c->fc->streams[c->fc->nb_streams - 1];
5537 if (atom.size < 8) {
5538 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5539 return AVERROR_INVALIDDATA;
5542 size = avio_rb32(pb);
5543 if (size <= 12 || size > atom.size)
5544 return AVERROR_INVALIDDATA;
5546 tag = avio_rl32(pb);
5547 if (tag != MKTAG('s','v','h','d')) {
5548 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5551 version = avio_r8(pb);
5553 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5557 avio_skip(pb, 3); /* flags */
5558 avio_skip(pb, size - 12); /* metadata_source */
5560 size = avio_rb32(pb);
5561 if (size > atom.size)
5562 return AVERROR_INVALIDDATA;
5564 tag = avio_rl32(pb);
5565 if (tag != MKTAG('p','r','o','j')) {
5566 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5570 size = avio_rb32(pb);
5571 if (size > atom.size)
5572 return AVERROR_INVALIDDATA;
5574 tag = avio_rl32(pb);
5575 if (tag != MKTAG('p','r','h','d')) {
5576 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5579 version = avio_r8(pb);
5581 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5585 avio_skip(pb, 3); /* flags */
5587 /* 16.16 fixed point */
5588 yaw = avio_rb32(pb);
5589 pitch = avio_rb32(pb);
5590 roll = avio_rb32(pb);
5592 size = avio_rb32(pb);
5593 if (size > atom.size)
5594 return AVERROR_INVALIDDATA;
5596 tag = avio_rl32(pb);
5597 version = avio_r8(pb);
5599 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5603 avio_skip(pb, 3); /* flags */
5605 case MKTAG('c','b','m','p'):
5606 layout = avio_rb32(pb);
5608 av_log(c->fc, AV_LOG_WARNING,
5609 "Unsupported cubemap layout %d\n", layout);
5612 projection = AV_SPHERICAL_CUBEMAP;
5613 padding = avio_rb32(pb);
5615 case MKTAG('e','q','u','i'):
5621 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5622 av_log(c->fc, AV_LOG_ERROR,
5623 "Invalid bounding rectangle coordinates "
5624 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5625 return AVERROR_INVALIDDATA;
5628 if (l || t || r || b)
5629 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5631 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5634 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5638 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5640 return AVERROR(ENOMEM);
5642 sc->spherical->projection = projection;
5644 sc->spherical->yaw = yaw;
5645 sc->spherical->pitch = pitch;
5646 sc->spherical->roll = roll;
5648 sc->spherical->padding = padding;
5650 sc->spherical->bound_left = l;
5651 sc->spherical->bound_top = t;
5652 sc->spherical->bound_right = r;
5653 sc->spherical->bound_bottom = b;
5658 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5661 uint8_t *buffer = av_malloc(len + 1);
5665 return AVERROR(ENOMEM);
5668 ret = ffio_read_size(pb, buffer, len);
5672 /* Check for mandatory keys and values, try to support XML as best-effort */
5673 if (!sc->spherical &&
5674 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5675 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5676 av_stristr(val, "true") &&
5677 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5678 av_stristr(val, "true") &&
5679 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5680 av_stristr(val, "equirectangular")) {
5681 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5685 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5687 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5688 enum AVStereo3DType mode;
5690 if (av_stristr(buffer, "left-right"))
5691 mode = AV_STEREO3D_SIDEBYSIDE;
5692 else if (av_stristr(buffer, "top-bottom"))
5693 mode = AV_STEREO3D_TOPBOTTOM;
5695 mode = AV_STEREO3D_2D;
5697 sc->stereo3d = av_stereo3d_alloc();
5701 sc->stereo3d->type = mode;
5705 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5707 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5708 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5710 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5711 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5713 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5721 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5724 MOVStreamContext *sc;
5727 static const uint8_t uuid_isml_manifest[] = {
5728 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5729 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5731 static const uint8_t uuid_xmp[] = {
5732 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5733 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5735 static const uint8_t uuid_spherical[] = {
5736 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5737 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5740 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5741 return AVERROR_INVALIDDATA;
5743 if (c->fc->nb_streams < 1)
5745 st = c->fc->streams[c->fc->nb_streams - 1];
5748 ret = avio_read(pb, uuid, sizeof(uuid));
5751 } else if (ret != sizeof(uuid)) {
5752 return AVERROR_INVALIDDATA;
5754 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5755 uint8_t *buffer, *ptr;
5757 size_t len = atom.size - sizeof(uuid);
5760 return AVERROR_INVALIDDATA;
5762 ret = avio_skip(pb, 4); // zeroes
5765 buffer = av_mallocz(len + 1);
5767 return AVERROR(ENOMEM);
5769 ret = avio_read(pb, buffer, len);
5773 } else if (ret != len) {
5775 return AVERROR_INVALIDDATA;
5779 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5780 ptr += sizeof("systemBitrate=\"") - 1;
5781 c->bitrates_count++;
5782 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5784 c->bitrates_count = 0;
5786 return AVERROR(ENOMEM);
5789 ret = strtol(ptr, &endptr, 10);
5790 if (ret < 0 || errno || *endptr != '"') {
5791 c->bitrates[c->bitrates_count - 1] = 0;
5793 c->bitrates[c->bitrates_count - 1] = ret;
5798 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5800 size_t len = atom.size - sizeof(uuid);
5801 if (c->export_xmp) {
5802 buffer = av_mallocz(len + 1);
5804 return AVERROR(ENOMEM);
5806 ret = avio_read(pb, buffer, len);
5810 } else if (ret != len) {
5812 return AVERROR_INVALIDDATA;
5815 av_dict_set(&c->fc->metadata, "xmp",
5816 buffer, AV_DICT_DONT_STRDUP_VAL);
5818 // skip all uuid atom, which makes it fast for long uuid-xmp file
5819 ret = avio_skip(pb, len);
5823 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5824 size_t len = atom.size - sizeof(uuid);
5825 ret = mov_parse_uuid_spherical(sc, pb, len);
5829 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5835 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5838 uint8_t content[16];
5843 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5849 && !memcmp(content, "Anevia\x1A\x1A", 8)
5850 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5851 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5857 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5859 uint32_t format = avio_rl32(pb);
5860 MOVStreamContext *sc;
5864 if (c->fc->nb_streams < 1)
5866 st = c->fc->streams[c->fc->nb_streams - 1];
5871 case MKTAG('e','n','c','v'): // encrypted video
5872 case MKTAG('e','n','c','a'): // encrypted audio
5873 id = mov_codec_id(st, format);
5874 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5875 st->codecpar->codec_id != id) {
5876 av_log(c->fc, AV_LOG_WARNING,
5877 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5878 (char*)&format, st->codecpar->codec_id);
5882 st->codecpar->codec_id = id;
5883 sc->format = format;
5887 if (format != sc->format) {
5888 av_log(c->fc, AV_LOG_WARNING,
5889 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5890 (char*)&format, (char*)&sc->format);
5899 * Gets the current encryption info and associated current stream context. If
5900 * we are parsing a track fragment, this will return the specific encryption
5901 * info for this fragment; otherwise this will return the global encryption
5902 * info for the current stream.
5904 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5906 MOVFragmentStreamInfo *frag_stream_info;
5910 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5911 if (frag_stream_info) {
5912 for (i = 0; i < c->fc->nb_streams; i++) {
5913 if (c->fc->streams[i]->id == frag_stream_info->id) {
5914 st = c->fc->streams[i];
5918 if (i == c->fc->nb_streams)
5920 *sc = st->priv_data;
5922 if (!frag_stream_info->encryption_index) {
5923 // If this stream isn't encrypted, don't create the index.
5924 if (!(*sc)->cenc.default_encrypted_sample)
5926 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5927 if (!frag_stream_info->encryption_index)
5928 return AVERROR(ENOMEM);
5930 *encryption_index = frag_stream_info->encryption_index;
5933 // No current track fragment, using stream level encryption info.
5935 if (c->fc->nb_streams < 1)
5937 st = c->fc->streams[c->fc->nb_streams - 1];
5938 *sc = st->priv_data;
5940 if (!(*sc)->cenc.encryption_index) {
5941 // If this stream isn't encrypted, don't create the index.
5942 if (!(*sc)->cenc.default_encrypted_sample)
5944 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5945 if (!(*sc)->cenc.encryption_index)
5946 return AVERROR(ENOMEM);
5949 *encryption_index = (*sc)->cenc.encryption_index;
5954 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
5957 unsigned int subsample_count;
5958 AVSubsampleEncryptionInfo *subsamples;
5960 if (!sc->cenc.default_encrypted_sample) {
5961 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
5962 return AVERROR_INVALIDDATA;
5965 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
5967 return AVERROR(ENOMEM);
5969 if (sc->cenc.per_sample_iv_size != 0) {
5970 if (avio_read(pb, (*sample)->iv, sc->cenc.per_sample_iv_size) != sc->cenc.per_sample_iv_size) {
5971 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
5972 av_encryption_info_free(*sample);
5974 return AVERROR_INVALIDDATA;
5978 if (use_subsamples) {
5979 subsample_count = avio_rb16(pb);
5980 av_free((*sample)->subsamples);
5981 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
5982 if (!(*sample)->subsamples) {
5983 av_encryption_info_free(*sample);
5985 return AVERROR(ENOMEM);
5988 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
5989 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
5990 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
5993 if (pb->eof_reached) {
5994 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
5995 av_encryption_info_free(*sample);
5997 return AVERROR_INVALIDDATA;
5999 (*sample)->subsample_count = subsample_count;
6005 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6007 AVEncryptionInfo **encrypted_samples;
6008 MOVEncryptionIndex *encryption_index;
6009 MOVStreamContext *sc;
6010 int use_subsamples, ret;
6011 unsigned int sample_count, i, alloc_size = 0;
6013 ret = get_current_encryption_info(c, &encryption_index, &sc);
6017 if (encryption_index->nb_encrypted_samples) {
6018 // This can happen if we have both saio/saiz and senc atoms.
6019 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6023 avio_r8(pb); /* version */
6024 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6026 sample_count = avio_rb32(pb);
6027 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6028 return AVERROR(ENOMEM);
6030 for (i = 0; i < sample_count; i++) {
6031 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6032 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6033 min_samples * sizeof(*encrypted_samples));
6034 if (encrypted_samples) {
6035 encryption_index->encrypted_samples = encrypted_samples;
6037 ret = mov_read_sample_encryption_info(
6038 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6040 ret = AVERROR(ENOMEM);
6042 if (pb->eof_reached) {
6043 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6044 ret = AVERROR_INVALIDDATA;
6049 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6050 av_freep(&encryption_index->encrypted_samples);
6054 encryption_index->nb_encrypted_samples = sample_count;
6059 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6061 AVEncryptionInfo **sample, **encrypted_samples;
6063 size_t sample_count, sample_info_size, i;
6065 unsigned int alloc_size = 0;
6067 if (encryption_index->nb_encrypted_samples)
6069 sample_count = encryption_index->auxiliary_info_sample_count;
6070 if (encryption_index->auxiliary_offsets_count != 1) {
6071 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6072 return AVERROR_PATCHWELCOME;
6074 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6075 return AVERROR(ENOMEM);
6077 prev_pos = avio_tell(pb);
6078 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6079 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6080 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6084 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6085 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6086 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6087 min_samples * sizeof(*encrypted_samples));
6088 if (!encrypted_samples) {
6089 ret = AVERROR(ENOMEM);
6092 encryption_index->encrypted_samples = encrypted_samples;
6094 sample = &encryption_index->encrypted_samples[i];
6095 sample_info_size = encryption_index->auxiliary_info_default_size
6096 ? encryption_index->auxiliary_info_default_size
6097 : encryption_index->auxiliary_info_sizes[i];
6099 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6103 if (pb->eof_reached) {
6104 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6105 ret = AVERROR_INVALIDDATA;
6107 encryption_index->nb_encrypted_samples = sample_count;
6111 avio_seek(pb, prev_pos, SEEK_SET);
6113 for (; i > 0; i--) {
6114 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6116 av_freep(&encryption_index->encrypted_samples);
6122 * Tries to read the given number of bytes from the stream and puts it in a
6123 * newly allocated buffer. This reads in small chunks to avoid allocating large
6124 * memory if the file contains an invalid/malicious size value.
6126 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6128 const unsigned int block_size = 1024 * 1024;
6129 uint8_t *buffer = NULL;
6130 unsigned int alloc_size = 0, offset = 0;
6131 while (offset < size) {
6132 unsigned int new_size =
6133 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6134 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6135 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6138 return AVERROR(ENOMEM);
6140 buffer = new_buffer;
6142 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6144 return AVERROR_INVALIDDATA;
6153 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6155 MOVEncryptionIndex *encryption_index;
6156 MOVStreamContext *sc;
6158 unsigned int sample_count, aux_info_type, aux_info_param;
6160 ret = get_current_encryption_info(c, &encryption_index, &sc);
6164 if (encryption_index->nb_encrypted_samples) {
6165 // This can happen if we have both saio/saiz and senc atoms.
6166 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6170 if (encryption_index->auxiliary_info_sample_count) {
6171 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6172 return AVERROR_INVALIDDATA;
6175 avio_r8(pb); /* version */
6176 if (avio_rb24(pb) & 0x01) { /* flags */
6177 aux_info_type = avio_rb32(pb);
6178 aux_info_param = avio_rb32(pb);
6179 if (sc->cenc.default_encrypted_sample) {
6180 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6181 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6184 if (aux_info_param != 0) {
6185 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6189 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6190 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6191 aux_info_type == MKBETAG('c','e','n','s') ||
6192 aux_info_type == MKBETAG('c','b','c','1') ||
6193 aux_info_type == MKBETAG('c','b','c','s')) &&
6194 aux_info_param == 0) {
6195 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6196 return AVERROR_INVALIDDATA;
6201 } else if (!sc->cenc.default_encrypted_sample) {
6202 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6206 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6207 sample_count = avio_rb32(pb);
6208 encryption_index->auxiliary_info_sample_count = sample_count;
6210 if (encryption_index->auxiliary_info_default_size == 0) {
6211 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6213 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6218 if (encryption_index->auxiliary_offsets_count) {
6219 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6225 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6227 uint64_t *auxiliary_offsets;
6228 MOVEncryptionIndex *encryption_index;
6229 MOVStreamContext *sc;
6231 unsigned int version, entry_count, aux_info_type, aux_info_param;
6232 unsigned int alloc_size = 0;
6234 ret = get_current_encryption_info(c, &encryption_index, &sc);
6238 if (encryption_index->nb_encrypted_samples) {
6239 // This can happen if we have both saio/saiz and senc atoms.
6240 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6244 if (encryption_index->auxiliary_offsets_count) {
6245 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6246 return AVERROR_INVALIDDATA;
6249 version = avio_r8(pb); /* version */
6250 if (avio_rb24(pb) & 0x01) { /* flags */
6251 aux_info_type = avio_rb32(pb);
6252 aux_info_param = avio_rb32(pb);
6253 if (sc->cenc.default_encrypted_sample) {
6254 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6255 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6258 if (aux_info_param != 0) {
6259 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6263 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6264 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6265 aux_info_type == MKBETAG('c','e','n','s') ||
6266 aux_info_type == MKBETAG('c','b','c','1') ||
6267 aux_info_type == MKBETAG('c','b','c','s')) &&
6268 aux_info_param == 0) {
6269 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6270 return AVERROR_INVALIDDATA;
6275 } else if (!sc->cenc.default_encrypted_sample) {
6276 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6280 entry_count = avio_rb32(pb);
6281 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6282 return AVERROR(ENOMEM);
6284 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6285 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6286 auxiliary_offsets = av_fast_realloc(
6287 encryption_index->auxiliary_offsets, &alloc_size,
6288 min_offsets * sizeof(*auxiliary_offsets));
6289 if (!auxiliary_offsets) {
6290 av_freep(&encryption_index->auxiliary_offsets);
6291 return AVERROR(ENOMEM);
6293 encryption_index->auxiliary_offsets = auxiliary_offsets;
6296 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6298 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6300 if (c->frag_index.current >= 0) {
6301 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6305 if (pb->eof_reached) {
6306 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6307 av_freep(&encryption_index->auxiliary_offsets);
6308 return AVERROR_INVALIDDATA;
6311 encryption_index->auxiliary_offsets_count = entry_count;
6313 if (encryption_index->auxiliary_info_sample_count) {
6314 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6320 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6322 AVEncryptionInitInfo *info, *old_init_info;
6325 uint8_t *side_data, *extra_data, *old_side_data;
6326 size_t side_data_size;
6327 int ret = 0, old_side_data_size;
6328 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6330 if (c->fc->nb_streams < 1)
6332 st = c->fc->streams[c->fc->nb_streams-1];
6334 version = avio_r8(pb); /* version */
6335 avio_rb24(pb); /* flags */
6337 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6338 /* key_id_size */ 16, /* data_size */ 0);
6340 return AVERROR(ENOMEM);
6342 if (avio_read(pb, info->system_id, 16) != 16) {
6343 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6344 ret = AVERROR_INVALIDDATA;
6349 kid_count = avio_rb32(pb);
6350 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
6351 ret = AVERROR(ENOMEM);
6355 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6356 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6357 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6358 min_kid_count * sizeof(*key_ids));
6360 ret = AVERROR(ENOMEM);
6363 info->key_ids = key_ids;
6365 info->key_ids[i] = av_mallocz(16);
6366 if (!info->key_ids[i]) {
6367 ret = AVERROR(ENOMEM);
6370 info->num_key_ids = i + 1;
6372 if (avio_read(pb, info->key_ids[i], 16) != 16) {
6373 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6374 ret = AVERROR_INVALIDDATA;
6379 if (pb->eof_reached) {
6380 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6381 ret = AVERROR_INVALIDDATA;
6386 extra_data_size = avio_rb32(pb);
6387 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6391 av_freep(&info->data); // malloc(0) may still allocate something.
6392 info->data = extra_data;
6393 info->data_size = extra_data_size;
6395 // If there is existing initialization data, append to the list.
6396 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6397 if (old_side_data) {
6398 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6399 if (old_init_info) {
6400 // Append to the end of the list.
6401 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6407 info = old_init_info;
6409 // Assume existing side-data will be valid, so the only error we could get is OOM.
6410 ret = AVERROR(ENOMEM);
6415 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6417 ret = AVERROR(ENOMEM);
6420 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6421 side_data, side_data_size);
6426 av_encryption_init_info_free(info);
6430 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6433 MOVStreamContext *sc;
6435 if (c->fc->nb_streams < 1)
6437 st = c->fc->streams[c->fc->nb_streams-1];
6440 if (sc->pseudo_stream_id != 0) {
6441 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6442 return AVERROR_PATCHWELCOME;
6446 return AVERROR_INVALIDDATA;
6448 avio_rb32(pb); /* version and flags */
6450 if (!sc->cenc.default_encrypted_sample) {
6451 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6452 if (!sc->cenc.default_encrypted_sample) {
6453 return AVERROR(ENOMEM);
6457 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6461 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6464 MOVStreamContext *sc;
6465 unsigned int version, pattern, is_protected, iv_size;
6467 if (c->fc->nb_streams < 1)
6469 st = c->fc->streams[c->fc->nb_streams-1];
6472 if (sc->pseudo_stream_id != 0) {
6473 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6474 return AVERROR_PATCHWELCOME;
6477 if (!sc->cenc.default_encrypted_sample) {
6478 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6479 if (!sc->cenc.default_encrypted_sample) {
6480 return AVERROR(ENOMEM);
6485 return AVERROR_INVALIDDATA;
6487 version = avio_r8(pb); /* version */
6488 avio_rb24(pb); /* flags */
6490 avio_r8(pb); /* reserved */
6491 pattern = avio_r8(pb);
6494 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6495 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6498 is_protected = avio_r8(pb);
6499 if (is_protected && !sc->cenc.encryption_index) {
6500 // The whole stream should be by-default encrypted.
6501 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6502 if (!sc->cenc.encryption_index)
6503 return AVERROR(ENOMEM);
6505 sc->cenc.per_sample_iv_size = avio_r8(pb);
6506 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6507 sc->cenc.per_sample_iv_size != 16) {
6508 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6509 return AVERROR_INVALIDDATA;
6511 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6512 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6513 return AVERROR_INVALIDDATA;
6516 if (is_protected && !sc->cenc.per_sample_iv_size) {
6517 iv_size = avio_r8(pb);
6518 if (iv_size != 8 && iv_size != 16) {
6519 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6520 return AVERROR_INVALIDDATA;
6523 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6524 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6525 return AVERROR_INVALIDDATA;
6532 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6535 int last, type, size, ret;
6538 if (c->fc->nb_streams < 1)
6540 st = c->fc->streams[c->fc->nb_streams-1];
6542 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6543 return AVERROR_INVALIDDATA;
6545 /* Check FlacSpecificBox version. */
6546 if (avio_r8(pb) != 0)
6547 return AVERROR_INVALIDDATA;
6549 avio_rb24(pb); /* Flags */
6551 avio_read(pb, buf, sizeof(buf));
6552 flac_parse_block_header(buf, &last, &type, &size);
6554 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6555 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6556 return AVERROR_INVALIDDATA;
6559 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6564 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6569 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6573 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6574 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6575 return AVERROR_PATCHWELCOME;
6578 if (!sc->cenc.aes_ctr) {
6579 /* initialize the cipher */
6580 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6581 if (!sc->cenc.aes_ctr) {
6582 return AVERROR(ENOMEM);
6585 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6591 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6593 if (!sample->subsample_count)
6595 /* decrypt the whole packet */
6596 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6600 for (i = 0; i < sample->subsample_count; i++)
6602 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6603 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6604 return AVERROR_INVALIDDATA;
6607 /* skip the clear bytes */
6608 input += sample->subsamples[i].bytes_of_clear_data;
6609 size -= sample->subsamples[i].bytes_of_clear_data;
6611 /* decrypt the encrypted bytes */
6612 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6613 input += sample->subsamples[i].bytes_of_protected_data;
6614 size -= sample->subsamples[i].bytes_of_protected_data;
6618 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6619 return AVERROR_INVALIDDATA;
6625 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6627 MOVFragmentStreamInfo *frag_stream_info;
6628 MOVEncryptionIndex *encryption_index;
6629 AVEncryptionInfo *encrypted_sample;
6630 int encrypted_index, ret;
6632 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6633 encrypted_index = current_index;
6634 encryption_index = NULL;
6635 if (frag_stream_info) {
6636 // Note this only supports encryption info in the first sample descriptor.
6637 if (mov->fragment.stsd_id == 1) {
6638 if (frag_stream_info->encryption_index) {
6639 encrypted_index = current_index - frag_stream_info->index_entry;
6640 encryption_index = frag_stream_info->encryption_index;
6642 encryption_index = sc->cenc.encryption_index;
6646 encryption_index = sc->cenc.encryption_index;
6649 if (encryption_index) {
6650 if (encryption_index->auxiliary_info_sample_count &&
6651 !encryption_index->nb_encrypted_samples) {
6652 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6653 return AVERROR_INVALIDDATA;
6655 if (encryption_index->auxiliary_offsets_count &&
6656 !encryption_index->nb_encrypted_samples) {
6657 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6658 return AVERROR_INVALIDDATA;
6661 if (!encryption_index->nb_encrypted_samples) {
6662 // Full-sample encryption with default settings.
6663 encrypted_sample = sc->cenc.default_encrypted_sample;
6664 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6665 // Per-sample setting override.
6666 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6668 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6669 return AVERROR_INVALIDDATA;
6672 if (mov->decryption_key) {
6673 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6676 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6678 return AVERROR(ENOMEM);
6679 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6689 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6691 const int OPUS_SEEK_PREROLL_MS = 80;
6697 if (c->fc->nb_streams < 1)
6699 st = c->fc->streams[c->fc->nb_streams-1];
6701 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6702 return AVERROR_INVALIDDATA;
6704 /* Check OpusSpecificBox version. */
6705 if (avio_r8(pb) != 0) {
6706 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6707 return AVERROR_INVALIDDATA;
6710 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6711 size = atom.size + 8;
6713 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
6716 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6717 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6718 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6719 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6721 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6722 little-endian; aside from the preceeding magic and version they're
6723 otherwise currently identical. Data after output gain at offset 16
6724 doesn't need to be bytewapped. */
6725 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6726 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6727 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6728 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6730 st->codecpar->initial_padding = pre_skip;
6731 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6732 (AVRational){1, 1000},
6733 (AVRational){1, 48000});
6738 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6741 unsigned format_info;
6742 int channel_assignment, channel_assignment1, channel_assignment2;
6745 if (c->fc->nb_streams < 1)
6747 st = c->fc->streams[c->fc->nb_streams-1];
6750 return AVERROR_INVALIDDATA;
6752 format_info = avio_rb32(pb);
6754 ratebits = (format_info >> 28) & 0xF;
6755 channel_assignment1 = (format_info >> 15) & 0x1F;
6756 channel_assignment2 = format_info & 0x1FFF;
6757 if (channel_assignment2)
6758 channel_assignment = channel_assignment2;
6760 channel_assignment = channel_assignment1;
6762 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6763 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6764 st->codecpar->channels = truehd_channels(channel_assignment);
6765 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6770 static const MOVParseTableEntry mov_default_parse_table[] = {
6771 { MKTAG('A','C','L','R'), mov_read_aclr },
6772 { MKTAG('A','P','R','G'), mov_read_avid },
6773 { MKTAG('A','A','L','P'), mov_read_avid },
6774 { MKTAG('A','R','E','S'), mov_read_ares },
6775 { MKTAG('a','v','s','s'), mov_read_avss },
6776 { MKTAG('a','v','1','C'), mov_read_av1c },
6777 { MKTAG('c','h','p','l'), mov_read_chpl },
6778 { MKTAG('c','o','6','4'), mov_read_stco },
6779 { MKTAG('c','o','l','r'), mov_read_colr },
6780 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6781 { MKTAG('d','i','n','f'), mov_read_default },
6782 { MKTAG('D','p','x','E'), mov_read_dpxe },
6783 { MKTAG('d','r','e','f'), mov_read_dref },
6784 { MKTAG('e','d','t','s'), mov_read_default },
6785 { MKTAG('e','l','s','t'), mov_read_elst },
6786 { MKTAG('e','n','d','a'), mov_read_enda },
6787 { MKTAG('f','i','e','l'), mov_read_fiel },
6788 { MKTAG('a','d','r','m'), mov_read_adrm },
6789 { MKTAG('f','t','y','p'), mov_read_ftyp },
6790 { MKTAG('g','l','b','l'), mov_read_glbl },
6791 { MKTAG('h','d','l','r'), mov_read_hdlr },
6792 { MKTAG('i','l','s','t'), mov_read_ilst },
6793 { MKTAG('j','p','2','h'), mov_read_jp2h },
6794 { MKTAG('m','d','a','t'), mov_read_mdat },
6795 { MKTAG('m','d','h','d'), mov_read_mdhd },
6796 { MKTAG('m','d','i','a'), mov_read_default },
6797 { MKTAG('m','e','t','a'), mov_read_meta },
6798 { MKTAG('m','i','n','f'), mov_read_default },
6799 { MKTAG('m','o','o','f'), mov_read_moof },
6800 { MKTAG('m','o','o','v'), mov_read_moov },
6801 { MKTAG('m','v','e','x'), mov_read_default },
6802 { MKTAG('m','v','h','d'), mov_read_mvhd },
6803 { MKTAG('S','M','I',' '), mov_read_svq3 },
6804 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6805 { MKTAG('a','v','c','C'), mov_read_glbl },
6806 { MKTAG('p','a','s','p'), mov_read_pasp },
6807 { MKTAG('s','i','d','x'), mov_read_sidx },
6808 { MKTAG('s','t','b','l'), mov_read_default },
6809 { MKTAG('s','t','c','o'), mov_read_stco },
6810 { MKTAG('s','t','p','s'), mov_read_stps },
6811 { MKTAG('s','t','r','f'), mov_read_strf },
6812 { MKTAG('s','t','s','c'), mov_read_stsc },
6813 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6814 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6815 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6816 { MKTAG('s','t','t','s'), mov_read_stts },
6817 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6818 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
6819 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6820 { MKTAG('t','f','d','t'), mov_read_tfdt },
6821 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6822 { MKTAG('t','r','a','k'), mov_read_trak },
6823 { MKTAG('t','r','a','f'), mov_read_default },
6824 { MKTAG('t','r','e','f'), mov_read_default },
6825 { MKTAG('t','m','c','d'), mov_read_tmcd },
6826 { MKTAG('c','h','a','p'), mov_read_chap },
6827 { MKTAG('t','r','e','x'), mov_read_trex },
6828 { MKTAG('t','r','u','n'), mov_read_trun },
6829 { MKTAG('u','d','t','a'), mov_read_default },
6830 { MKTAG('w','a','v','e'), mov_read_wave },
6831 { MKTAG('e','s','d','s'), mov_read_esds },
6832 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6833 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6834 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6835 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6836 { MKTAG('w','f','e','x'), mov_read_wfex },
6837 { MKTAG('c','m','o','v'), mov_read_cmov },
6838 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6839 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6840 { MKTAG('s','b','g','p'), mov_read_sbgp },
6841 { MKTAG('h','v','c','C'), mov_read_glbl },
6842 { MKTAG('u','u','i','d'), mov_read_uuid },
6843 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6844 { MKTAG('f','r','e','e'), mov_read_free },
6845 { MKTAG('-','-','-','-'), mov_read_custom },
6846 { MKTAG('s','i','n','f'), mov_read_default },
6847 { MKTAG('f','r','m','a'), mov_read_frma },
6848 { MKTAG('s','e','n','c'), mov_read_senc },
6849 { MKTAG('s','a','i','z'), mov_read_saiz },
6850 { MKTAG('s','a','i','o'), mov_read_saio },
6851 { MKTAG('p','s','s','h'), mov_read_pssh },
6852 { MKTAG('s','c','h','m'), mov_read_schm },
6853 { MKTAG('s','c','h','i'), mov_read_default },
6854 { MKTAG('t','e','n','c'), mov_read_tenc },
6855 { MKTAG('d','f','L','a'), mov_read_dfla },
6856 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6857 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6858 { MKTAG('d','O','p','s'), mov_read_dops },
6859 { MKTAG('d','m','l','p'), mov_read_dmlp },
6860 { MKTAG('S','m','D','m'), mov_read_smdm },
6861 { MKTAG('C','o','L','L'), mov_read_coll },
6862 { MKTAG('v','p','c','C'), mov_read_vpcc },
6863 { MKTAG('m','d','c','v'), mov_read_mdcv },
6864 { MKTAG('c','l','l','i'), mov_read_clli },
6868 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6870 int64_t total_size = 0;
6874 if (c->atom_depth > 10) {
6875 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6876 return AVERROR_INVALIDDATA;
6881 atom.size = INT64_MAX;
6882 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6883 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
6886 if (atom.size >= 8) {
6887 a.size = avio_rb32(pb);
6888 a.type = avio_rl32(pb);
6889 if (a.type == MKTAG('f','r','e','e') &&
6891 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT &&
6894 uint32_t *type = (uint32_t *)buf + 1;
6895 if (avio_read(pb, buf, 8) != 8)
6896 return AVERROR_INVALIDDATA;
6897 avio_seek(pb, -8, SEEK_CUR);
6898 if (*type == MKTAG('m','v','h','d') ||
6899 *type == MKTAG('c','m','o','v')) {
6900 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free atom.\n");
6901 a.type = MKTAG('m','o','o','v');
6904 if (atom.type != MKTAG('r','o','o','t') &&
6905 atom.type != MKTAG('m','o','o','v'))
6907 if (a.type == MKTAG('t','r','a','k') || a.type == MKTAG('m','d','a','t'))
6909 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
6916 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
6917 a.size = avio_rb64(pb) - 8;
6921 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
6922 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
6924 a.size = atom.size - total_size + 8;
6929 a.size = FFMIN(a.size, atom.size - total_size);
6931 for (i = 0; mov_default_parse_table[i].type; i++)
6932 if (mov_default_parse_table[i].type == a.type) {
6933 parse = mov_default_parse_table[i].parse;
6937 // container is user data
6938 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
6939 atom.type == MKTAG('i','l','s','t')))
6940 parse = mov_read_udta_string;
6942 // Supports parsing the QuickTime Metadata Keys.
6943 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
6944 if (!parse && c->found_hdlr_mdta &&
6945 atom.type == MKTAG('m','e','t','a') &&
6946 a.type == MKTAG('k','e','y','s')) {
6947 parse = mov_read_keys;
6950 if (!parse) { /* skip leaf atoms data */
6951 avio_skip(pb, a.size);
6953 int64_t start_pos = avio_tell(pb);
6955 int err = parse(c, pb, a);
6960 if (c->found_moov && c->found_mdat &&
6961 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
6962 start_pos + a.size == avio_size(pb))) {
6963 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
6964 c->next_root_atom = start_pos + a.size;
6968 left = a.size - avio_tell(pb) + start_pos;
6969 if (left > 0) /* skip garbage at atom end */
6970 avio_skip(pb, left);
6971 else if (left < 0) {
6972 av_log(c->fc, AV_LOG_WARNING,
6973 "overread end of atom '%.4s' by %"PRId64" bytes\n",
6974 (char*)&a.type, -left);
6975 avio_seek(pb, left, SEEK_CUR);
6979 total_size += a.size;
6982 if (total_size < atom.size && atom.size < 0x7ffff)
6983 avio_skip(pb, atom.size - total_size);
6989 static int mov_probe(const AVProbeData *p)
6994 int moov_offset = -1;
6996 /* check file header */
6999 /* ignore invalid offset */
7000 if ((offset + 8) > (unsigned int)p->buf_size)
7002 tag = AV_RL32(p->buf + offset + 4);
7004 /* check for obvious tags */
7005 case MKTAG('m','o','o','v'):
7006 moov_offset = offset + 4;
7007 case MKTAG('m','d','a','t'):
7008 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
7009 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
7010 case MKTAG('f','t','y','p'):
7011 if (AV_RB32(p->buf+offset) < 8 &&
7012 (AV_RB32(p->buf+offset) != 1 ||
7013 offset + 12 > (unsigned int)p->buf_size ||
7014 AV_RB64(p->buf+offset + 8) == 0)) {
7015 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7016 } else if (tag == MKTAG('f','t','y','p') &&
7017 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
7018 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
7020 score = FFMAX(score, 5);
7022 score = AVPROBE_SCORE_MAX;
7024 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7026 /* those are more common words, so rate then a bit less */
7027 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
7028 case MKTAG('w','i','d','e'):
7029 case MKTAG('f','r','e','e'):
7030 case MKTAG('j','u','n','k'):
7031 case MKTAG('p','i','c','t'):
7032 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
7033 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7035 case MKTAG(0x82,0x82,0x7f,0x7d):
7036 case MKTAG('s','k','i','p'):
7037 case MKTAG('u','u','i','d'):
7038 case MKTAG('p','r','f','l'):
7039 /* if we only find those cause probedata is too small at least rate them */
7040 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7041 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7044 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7047 if(score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
7048 /* moov atom in the header - we should make sure that this is not a
7049 * MOV-packed MPEG-PS */
7050 offset = moov_offset;
7052 while(offset < (p->buf_size - 16)){ /* Sufficient space */
7053 /* We found an actual hdlr atom */
7054 if(AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7055 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7056 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')){
7057 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7058 /* We found a media handler reference atom describing an
7059 * MPEG-PS-in-MOV, return a
7060 * low score to force expanding the probe window until
7061 * mpegps_probe finds what it needs */
7072 // must be done after parsing all trak because there's no order requirement
7073 static void mov_read_chapters(AVFormatContext *s)
7075 MOVContext *mov = s->priv_data;
7077 MOVStreamContext *sc;
7082 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7083 chapter_track = mov->chapter_tracks[j];
7085 for (i = 0; i < s->nb_streams; i++)
7086 if (s->streams[i]->id == chapter_track) {
7091 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7096 cur_pos = avio_tell(sc->pb);
7098 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7099 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7100 if (st->nb_index_entries) {
7101 // Retrieve the first frame, if possible
7103 AVIndexEntry *sample = &st->index_entries[0];
7104 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7105 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7109 if (av_get_packet(sc->pb, &pkt, sample->size) < 0)
7112 st->attached_pic = pkt;
7113 st->attached_pic.stream_index = st->index;
7114 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
7117 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7118 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7119 st->discard = AVDISCARD_ALL;
7120 for (i = 0; i < st->nb_index_entries; i++) {
7121 AVIndexEntry *sample = &st->index_entries[i];
7122 int64_t end = i+1 < st->nb_index_entries ? st->index_entries[i+1].timestamp : st->duration;
7127 if (end < sample->timestamp) {
7128 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7129 end = AV_NOPTS_VALUE;
7132 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7133 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7137 // the first two bytes are the length of the title
7138 len = avio_rb16(sc->pb);
7139 if (len > sample->size-2)
7141 title_len = 2*len + 1;
7142 if (!(title = av_mallocz(title_len)))
7145 // The samples could theoretically be in any encoding if there's an encd
7146 // atom following, but in practice are only utf-8 or utf-16, distinguished
7147 // instead by the presence of a BOM
7151 ch = avio_rb16(sc->pb);
7153 avio_get_str16be(sc->pb, len, title, title_len);
7154 else if (ch == 0xfffe)
7155 avio_get_str16le(sc->pb, len, title, title_len);
7158 if (len == 1 || len == 2)
7161 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7165 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7170 avio_seek(sc->pb, cur_pos, SEEK_SET);
7174 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7175 uint32_t value, int flags)
7178 char buf[AV_TIMECODE_STR_SIZE];
7179 AVRational rate = st->avg_frame_rate;
7180 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7183 av_dict_set(&st->metadata, "timecode",
7184 av_timecode_make_string(&tc, buf, value), 0);
7188 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7190 MOVStreamContext *sc = st->priv_data;
7191 char buf[AV_TIMECODE_STR_SIZE];
7192 int64_t cur_pos = avio_tell(sc->pb);
7193 int hh, mm, ss, ff, drop;
7195 if (!st->nb_index_entries)
7198 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7199 avio_skip(s->pb, 13);
7200 hh = avio_r8(s->pb);
7201 mm = avio_r8(s->pb);
7202 ss = avio_r8(s->pb);
7203 drop = avio_r8(s->pb);
7204 ff = avio_r8(s->pb);
7205 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7206 hh, mm, ss, drop ? ';' : ':', ff);
7207 av_dict_set(&st->metadata, "timecode", buf, 0);
7209 avio_seek(sc->pb, cur_pos, SEEK_SET);
7213 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7215 MOVStreamContext *sc = st->priv_data;
7217 int64_t cur_pos = avio_tell(sc->pb);
7220 if (!st->nb_index_entries)
7223 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7224 value = avio_rb32(s->pb);
7226 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7227 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7228 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7230 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7231 * not the case) and thus assume "frame number format" instead of QT one.
7232 * No sample with tmcd track can be found with a QT timecode at the moment,
7233 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7235 parse_timecode_in_framenum_format(s, st, value, flags);
7237 avio_seek(sc->pb, cur_pos, SEEK_SET);
7241 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7243 if (!index || !*index) return;
7244 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7245 av_encryption_info_free((*index)->encrypted_samples[i]);
7247 av_freep(&(*index)->encrypted_samples);
7248 av_freep(&(*index)->auxiliary_info_sizes);
7249 av_freep(&(*index)->auxiliary_offsets);
7253 static int mov_read_close(AVFormatContext *s)
7255 MOVContext *mov = s->priv_data;
7258 for (i = 0; i < s->nb_streams; i++) {
7259 AVStream *st = s->streams[i];
7260 MOVStreamContext *sc = st->priv_data;
7265 av_freep(&sc->ctts_data);
7266 for (j = 0; j < sc->drefs_count; j++) {
7267 av_freep(&sc->drefs[j].path);
7268 av_freep(&sc->drefs[j].dir);
7270 av_freep(&sc->drefs);
7272 sc->drefs_count = 0;
7274 if (!sc->pb_is_copied)
7275 ff_format_io_close(s, &sc->pb);
7278 av_freep(&sc->chunk_offsets);
7279 av_freep(&sc->stsc_data);
7280 av_freep(&sc->sample_sizes);
7281 av_freep(&sc->keyframes);
7282 av_freep(&sc->stts_data);
7283 av_freep(&sc->sdtp_data);
7284 av_freep(&sc->stps_data);
7285 av_freep(&sc->elst_data);
7286 av_freep(&sc->rap_group);
7287 av_freep(&sc->display_matrix);
7288 av_freep(&sc->index_ranges);
7291 for (j = 0; j < sc->stsd_count; j++)
7292 av_free(sc->extradata[j]);
7293 av_freep(&sc->extradata);
7294 av_freep(&sc->extradata_size);
7296 mov_free_encryption_index(&sc->cenc.encryption_index);
7297 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7298 av_aes_ctr_free(sc->cenc.aes_ctr);
7300 av_freep(&sc->stereo3d);
7301 av_freep(&sc->spherical);
7302 av_freep(&sc->mastering);
7303 av_freep(&sc->coll);
7306 if (mov->dv_demux) {
7307 avformat_free_context(mov->dv_fctx);
7308 mov->dv_fctx = NULL;
7311 if (mov->meta_keys) {
7312 for (i = 1; i < mov->meta_keys_count; i++) {
7313 av_freep(&mov->meta_keys[i]);
7315 av_freep(&mov->meta_keys);
7318 av_freep(&mov->trex_data);
7319 av_freep(&mov->bitrates);
7321 for (i = 0; i < mov->frag_index.nb_items; i++) {
7322 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7323 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7324 mov_free_encryption_index(&frag[j].encryption_index);
7326 av_freep(&mov->frag_index.item[i].stream_info);
7328 av_freep(&mov->frag_index.item);
7330 av_freep(&mov->aes_decrypt);
7331 av_freep(&mov->chapter_tracks);
7336 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7340 for (i = 0; i < s->nb_streams; i++) {
7341 AVStream *st = s->streams[i];
7342 MOVStreamContext *sc = st->priv_data;
7344 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7345 sc->timecode_track == tmcd_id)
7351 /* look for a tmcd track not referenced by any video track, and export it globally */
7352 static void export_orphan_timecode(AVFormatContext *s)
7356 for (i = 0; i < s->nb_streams; i++) {
7357 AVStream *st = s->streams[i];
7359 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7360 !tmcd_is_referenced(s, i + 1)) {
7361 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7363 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7370 static int read_tfra(MOVContext *mov, AVIOContext *f)
7372 int version, fieldlength, i, j;
7373 int64_t pos = avio_tell(f);
7374 uint32_t size = avio_rb32(f);
7375 unsigned track_id, item_count;
7377 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7380 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7382 version = avio_r8(f);
7384 track_id = avio_rb32(f);
7385 fieldlength = avio_rb32(f);
7386 item_count = avio_rb32(f);
7387 for (i = 0; i < item_count; i++) {
7388 int64_t time, offset;
7390 MOVFragmentStreamInfo * frag_stream_info;
7393 return AVERROR_INVALIDDATA;
7397 time = avio_rb64(f);
7398 offset = avio_rb64(f);
7400 time = avio_rb32(f);
7401 offset = avio_rb32(f);
7404 // The first sample of each stream in a fragment is always a random
7405 // access sample. So it's entry in the tfra can be used as the
7406 // initial PTS of the fragment.
7407 index = update_frag_index(mov, offset);
7408 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7409 if (frag_stream_info &&
7410 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7411 frag_stream_info->first_tfra_pts = time;
7413 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7415 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7417 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7421 avio_seek(f, pos + size, SEEK_SET);
7425 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7427 int64_t stream_size = avio_size(f);
7428 int64_t original_pos = avio_tell(f);
7432 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7436 mfra_size = avio_rb32(f);
7437 if (mfra_size < 0 || mfra_size > stream_size) {
7438 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7441 if ((seek_ret = avio_seek(f, -mfra_size, SEEK_CUR)) < 0) {
7445 if (avio_rb32(f) != mfra_size) {
7446 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7449 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7450 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7453 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7455 ret = read_tfra(c, f);
7461 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7463 av_log(c->fc, AV_LOG_ERROR,
7464 "failed to seek back after looking for mfra\n");
7470 static int mov_read_header(AVFormatContext *s)
7472 MOVContext *mov = s->priv_data;
7473 AVIOContext *pb = s->pb;
7475 MOVAtom atom = { AV_RL32("root") };
7478 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7479 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7480 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7481 return AVERROR(EINVAL);
7485 mov->trak_index = -1;
7486 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7487 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7488 atom.size = avio_size(pb);
7490 atom.size = INT64_MAX;
7492 /* check MOV header */
7494 if (mov->moov_retry)
7495 avio_seek(pb, 0, SEEK_SET);
7496 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7497 av_log(s, AV_LOG_ERROR, "error reading header\n");
7501 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7502 if (!mov->found_moov) {
7503 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7505 return AVERROR_INVALIDDATA;
7507 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7509 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7510 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7511 mov_read_chapters(s);
7512 for (i = 0; i < s->nb_streams; i++)
7513 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7514 mov_read_timecode_track(s, s->streams[i]);
7515 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7516 mov_read_rtmd_track(s, s->streams[i]);
7520 /* copy timecode metadata from tmcd tracks to the related video streams */
7521 for (i = 0; i < s->nb_streams; i++) {
7522 AVStream *st = s->streams[i];
7523 MOVStreamContext *sc = st->priv_data;
7524 if (sc->timecode_track > 0) {
7525 AVDictionaryEntry *tcr;
7526 int tmcd_st_id = -1;
7528 for (j = 0; j < s->nb_streams; j++)
7529 if (s->streams[j]->id == sc->timecode_track)
7532 if (tmcd_st_id < 0 || tmcd_st_id == i)
7534 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7536 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7539 export_orphan_timecode(s);
7541 for (i = 0; i < s->nb_streams; i++) {
7542 AVStream *st = s->streams[i];
7543 MOVStreamContext *sc = st->priv_data;
7544 fix_timescale(mov, sc);
7545 if(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7546 st->skip_samples = sc->start_pad;
7548 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7549 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7550 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7551 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7552 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7553 st->codecpar->width = sc->width;
7554 st->codecpar->height = sc->height;
7556 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7557 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7561 if (mov->handbrake_version &&
7562 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7563 st->codecpar->codec_id == AV_CODEC_ID_MP3
7565 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7566 st->need_parsing = AVSTREAM_PARSE_FULL;
7570 if (mov->trex_data) {
7571 for (i = 0; i < s->nb_streams; i++) {
7572 AVStream *st = s->streams[i];
7573 MOVStreamContext *sc = st->priv_data;
7574 if (st->duration > 0) {
7575 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7576 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7577 sc->data_size, sc->time_scale);
7579 return AVERROR_INVALIDDATA;
7581 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7586 if (mov->use_mfra_for > 0) {
7587 for (i = 0; i < s->nb_streams; i++) {
7588 AVStream *st = s->streams[i];
7589 MOVStreamContext *sc = st->priv_data;
7590 if (sc->duration_for_fps > 0) {
7591 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7592 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7593 sc->data_size, sc->time_scale);
7595 return AVERROR_INVALIDDATA;
7597 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7598 sc->duration_for_fps;
7603 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7604 if (mov->bitrates[i]) {
7605 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7609 ff_rfps_calculate(s);
7611 for (i = 0; i < s->nb_streams; i++) {
7612 AVStream *st = s->streams[i];
7613 MOVStreamContext *sc = st->priv_data;
7615 switch (st->codecpar->codec_type) {
7616 case AVMEDIA_TYPE_AUDIO:
7617 err = ff_replaygain_export(st, s->metadata);
7623 case AVMEDIA_TYPE_VIDEO:
7624 if (sc->display_matrix) {
7625 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7626 sizeof(int32_t) * 9);
7630 sc->display_matrix = NULL;
7633 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7634 (uint8_t *)sc->stereo3d,
7635 sizeof(*sc->stereo3d));
7639 sc->stereo3d = NULL;
7641 if (sc->spherical) {
7642 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7643 (uint8_t *)sc->spherical,
7644 sc->spherical_size);
7648 sc->spherical = NULL;
7650 if (sc->mastering) {
7651 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7652 (uint8_t *)sc->mastering,
7653 sizeof(*sc->mastering));
7657 sc->mastering = NULL;
7660 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7661 (uint8_t *)sc->coll,
7671 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7673 for (i = 0; i < mov->frag_index.nb_items; i++)
7674 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7675 mov->frag_index.item[i].headers_read = 1;
7680 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7682 AVIndexEntry *sample = NULL;
7683 int64_t best_dts = INT64_MAX;
7685 for (i = 0; i < s->nb_streams; i++) {
7686 AVStream *avst = s->streams[i];
7687 MOVStreamContext *msc = avst->priv_data;
7688 if (msc->pb && msc->current_sample < avst->nb_index_entries) {
7689 AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample];
7690 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7691 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7692 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7693 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7694 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb &&
7695 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7696 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7697 sample = current_sample;
7706 static int should_retry(AVIOContext *pb, int error_code) {
7707 if (error_code == AVERROR_EOF || avio_feof(pb))
7713 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7716 MOVContext *mov = s->priv_data;
7718 if (index >= 0 && index < mov->frag_index.nb_items)
7719 target = mov->frag_index.item[index].moof_offset;
7720 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7721 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7722 return AVERROR_INVALIDDATA;
7725 mov->next_root_atom = 0;
7726 if (index < 0 || index >= mov->frag_index.nb_items)
7727 index = search_frag_moof_offset(&mov->frag_index, target);
7728 if (index < mov->frag_index.nb_items) {
7729 if (index + 1 < mov->frag_index.nb_items)
7730 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7731 if (mov->frag_index.item[index].headers_read)
7733 mov->frag_index.item[index].headers_read = 1;
7736 mov->found_mdat = 0;
7738 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7741 if (avio_feof(s->pb))
7743 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7748 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7750 uint8_t *side, *extradata;
7753 /* Save the current index. */
7754 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7756 /* Notify the decoder that extradata changed. */
7757 extradata_size = sc->extradata_size[sc->last_stsd_index];
7758 extradata = sc->extradata[sc->last_stsd_index];
7759 if (extradata_size > 0 && extradata) {
7760 side = av_packet_new_side_data(pkt,
7761 AV_PKT_DATA_NEW_EXTRADATA,
7764 return AVERROR(ENOMEM);
7765 memcpy(side, extradata, extradata_size);
7771 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7773 MOVContext *mov = s->priv_data;
7774 MOVStreamContext *sc;
7775 AVIndexEntry *sample;
7776 AVStream *st = NULL;
7777 int64_t current_index;
7781 sample = mov_find_next_sample(s, &st);
7782 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7783 if (!mov->next_root_atom)
7785 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7790 /* must be done just before reading, to avoid infinite loop on sample */
7791 current_index = sc->current_index;
7792 mov_current_sample_inc(sc);
7794 if (mov->next_root_atom) {
7795 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7796 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7799 if (st->discard != AVDISCARD_ALL) {
7800 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7801 if (ret64 != sample->pos) {
7802 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7803 sc->ffindex, sample->pos);
7804 if (should_retry(sc->pb, ret64)) {
7805 mov_current_sample_dec(sc);
7807 return AVERROR_INVALIDDATA;
7810 if( st->discard == AVDISCARD_NONKEY && 0==(sample->flags & AVINDEX_KEYFRAME) ) {
7811 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7815 ret = av_get_packet(sc->pb, pkt, sample->size);
7817 if (should_retry(sc->pb, ret)) {
7818 mov_current_sample_dec(sc);
7822 if (sc->has_palette) {
7825 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7827 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7829 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7830 sc->has_palette = 0;
7833 #if CONFIG_DV_DEMUXER
7834 if (mov->dv_demux && sc->dv_audio_container) {
7835 avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7836 av_freep(&pkt->data);
7838 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7843 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7844 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7845 st->need_parsing = AVSTREAM_PARSE_FULL;
7849 pkt->stream_index = sc->ffindex;
7850 pkt->dts = sample->timestamp;
7851 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7852 pkt->flags |= AV_PKT_FLAG_DISCARD;
7854 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7855 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
7856 /* update ctts context */
7858 if (sc->ctts_index < sc->ctts_count &&
7859 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
7861 sc->ctts_sample = 0;
7864 int64_t next_dts = (sc->current_sample < st->nb_index_entries) ?
7865 st->index_entries[sc->current_sample].timestamp : st->duration;
7867 if (next_dts >= pkt->dts)
7868 pkt->duration = next_dts - pkt->dts;
7869 pkt->pts = pkt->dts;
7871 if (st->discard == AVDISCARD_ALL)
7873 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
7874 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
7875 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
7876 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
7878 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
7879 pkt->pos = sample->pos;
7881 /* Multiple stsd handling. */
7882 if (sc->stsc_data) {
7883 /* Keep track of the stsc index for the given sample, then check
7884 * if the stsd index is different from the last used one. */
7886 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
7887 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
7889 sc->stsc_sample = 0;
7890 /* Do not check indexes after a switch. */
7891 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
7892 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
7893 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
7894 ret = mov_change_extradata(sc, pkt);
7901 aax_filter(pkt->data, pkt->size, mov);
7903 ret = cenc_filter(mov, st, sc, pkt, current_index);
7911 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
7913 MOVContext *mov = s->priv_data;
7916 if (!mov->frag_index.complete)
7919 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
7922 if (!mov->frag_index.item[index].headers_read)
7923 return mov_switch_root(s, -1, index);
7924 if (index + 1 < mov->frag_index.nb_items)
7925 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7930 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
7932 MOVStreamContext *sc = st->priv_data;
7933 int sample, time_sample, ret;
7936 // Here we consider timestamp to be PTS, hence try to offset it so that we
7937 // can search over the DTS timeline.
7938 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
7940 ret = mov_seek_fragment(s, st, timestamp);
7944 sample = av_index_search_timestamp(st, timestamp, flags);
7945 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
7946 if (sample < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp)
7948 if (sample < 0) /* not sure what to do */
7949 return AVERROR_INVALIDDATA;
7950 mov_current_sample_set(sc, sample);
7951 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
7952 /* adjust ctts index */
7953 if (sc->ctts_data) {
7955 for (i = 0; i < sc->ctts_count; i++) {
7956 int next = time_sample + sc->ctts_data[i].count;
7957 if (next > sc->current_sample) {
7959 sc->ctts_sample = sc->current_sample - time_sample;
7966 /* adjust stsd index */
7967 if (sc->chunk_count) {
7969 for (i = 0; i < sc->stsc_count; i++) {
7970 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
7971 if (next > sc->current_sample) {
7973 sc->stsc_sample = sc->current_sample - time_sample;
7976 av_assert0(next == (int)next);
7984 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
7986 MOVContext *mc = s->priv_data;
7991 if (stream_index >= s->nb_streams)
7992 return AVERROR_INVALIDDATA;
7994 st = s->streams[stream_index];
7995 sample = mov_seek_stream(s, st, sample_time, flags);
7999 if (mc->seek_individually) {
8000 /* adjust seek timestamp to found sample timestamp */
8001 int64_t seek_timestamp = st->index_entries[sample].timestamp;
8003 for (i = 0; i < s->nb_streams; i++) {
8005 MOVStreamContext *sc = s->streams[i]->priv_data;
8007 st->skip_samples = (sample_time <= 0) ? sc->start_pad : 0;
8009 if (stream_index == i)
8012 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
8013 mov_seek_stream(s, st, timestamp, flags);
8016 for (i = 0; i < s->nb_streams; i++) {
8017 MOVStreamContext *sc;
8020 mov_current_sample_set(sc, 0);
8023 MOVStreamContext *sc;
8024 AVIndexEntry *entry = mov_find_next_sample(s, &st);
8026 return AVERROR_INVALIDDATA;
8028 if (sc->ffindex == stream_index && sc->current_sample == sample)
8030 mov_current_sample_inc(sc);
8036 #define OFFSET(x) offsetof(MOVContext, x)
8037 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
8038 static const AVOption mov_options[] = {
8039 {"use_absolute_path",
8040 "allow using absolute path when opening alias, this is a possible security issue",
8041 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
8043 {"seek_streams_individually",
8044 "Seek each stream individually to the closest point",
8045 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
8047 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
8049 {"advanced_editlist",
8050 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
8051 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
8053 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8056 "use mfra for fragment timestamps",
8057 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8058 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8060 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8061 FLAGS, "use_mfra_for" },
8062 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8063 FLAGS, "use_mfra_for" },
8064 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8065 FLAGS, "use_mfra_for" },
8066 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8067 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8068 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8069 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8070 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8071 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8072 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8073 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8074 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8075 .flags = AV_OPT_FLAG_DECODING_PARAM },
8076 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8077 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8078 {.i64 = 0}, 0, 1, FLAGS },
8083 static const AVClass mov_class = {
8084 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8085 .item_name = av_default_item_name,
8086 .option = mov_options,
8087 .version = LIBAVUTIL_VERSION_INT,
8090 AVInputFormat ff_mov_demuxer = {
8091 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8092 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8093 .priv_class = &mov_class,
8094 .priv_data_size = sizeof(MOVContext),
8095 .extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
8096 .read_probe = mov_probe,
8097 .read_header = mov_read_header,
8098 .read_packet = mov_read_packet,
8099 .read_close = mov_read_close,
8100 .read_seek = mov_read_seek,
8101 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,