3 * Copyright (c) 2001 Fabrice Bellard
4 * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
6 * first version by Francois Revol <revol@free.fr>
7 * seek function by Gael Chardon <gael.dev@4now.net>
9 * This file is part of FFmpeg.
11 * FFmpeg is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * FFmpeg is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with FFmpeg; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30 #include "libavutil/attributes.h"
31 #include "libavutil/channel_layout.h"
32 #include "libavutil/internal.h"
33 #include "libavutil/intreadwrite.h"
34 #include "libavutil/intfloat.h"
35 #include "libavutil/mathematics.h"
36 #include "libavutil/time_internal.h"
37 #include "libavutil/avassert.h"
38 #include "libavutil/avstring.h"
39 #include "libavutil/dict.h"
40 #include "libavutil/display.h"
41 #include "libavutil/opt.h"
42 #include "libavutil/aes.h"
43 #include "libavutil/aes_ctr.h"
44 #include "libavutil/pixdesc.h"
45 #include "libavutil/sha.h"
46 #include "libavutil/spherical.h"
47 #include "libavutil/stereo3d.h"
48 #include "libavutil/timecode.h"
49 #include "libavcodec/ac3tab.h"
50 #include "libavcodec/flac.h"
51 #include "libavcodec/mpegaudiodecheader.h"
52 #include "libavcodec/mlp_parse.h"
55 #include "avio_internal.h"
58 #include "libavcodec/get_bits.h"
61 #include "replaygain.h"
67 #include "qtpalette.h"
69 /* those functions parse an atom */
70 /* links atom IDs to parse functions */
71 typedef struct MOVParseTableEntry {
73 int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
76 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
77 static int mov_read_mfra(MOVContext *c, AVIOContext *f);
78 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
79 int count, int duration);
81 static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb,
82 unsigned len, const char *key)
86 short current, total = 0;
87 avio_rb16(pb); // unknown
88 current = avio_rb16(pb);
90 total = avio_rb16(pb);
92 snprintf(buf, sizeof(buf), "%d", current);
94 snprintf(buf, sizeof(buf), "%d/%d", current, total);
95 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
96 av_dict_set(&c->fc->metadata, key, buf, 0);
101 static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb,
102 unsigned len, const char *key)
104 /* bypass padding bytes */
109 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
110 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
115 static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb,
116 unsigned len, const char *key)
118 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
119 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
124 static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb,
125 unsigned len, const char *key)
129 avio_r8(pb); // unknown
132 if (genre < 1 || genre > ID3v1_GENRE_MAX)
134 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
135 av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
140 static const uint32_t mac_to_unicode[128] = {
141 0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
142 0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
143 0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
144 0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
145 0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
146 0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
147 0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
148 0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
149 0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
150 0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
151 0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
152 0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
153 0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
154 0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
155 0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
156 0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
159 static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len,
160 char *dst, int dstlen)
163 char *end = dst+dstlen-1;
166 for (i = 0; i < len; i++) {
167 uint8_t t, c = avio_r8(pb);
175 PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
181 static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
185 MOVStreamContext *sc;
190 case 0xd: id = AV_CODEC_ID_MJPEG; break;
191 case 0xe: id = AV_CODEC_ID_PNG; break;
192 case 0x1b: id = AV_CODEC_ID_BMP; break;
194 av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
199 st = avformat_new_stream(c->fc, NULL);
201 return AVERROR(ENOMEM);
202 sc = av_mallocz(sizeof(*sc));
204 return AVERROR(ENOMEM);
207 ret = av_get_packet(pb, &pkt, len);
211 if (pkt.size >= 8 && id != AV_CODEC_ID_BMP) {
212 if (AV_RB64(pkt.data) == 0x89504e470d0a1a0a) {
213 id = AV_CODEC_ID_PNG;
215 id = AV_CODEC_ID_MJPEG;
219 st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
221 st->attached_pic = pkt;
222 st->attached_pic.stream_index = st->index;
223 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
225 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
226 st->codecpar->codec_id = id;
232 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
234 char language[4] = { 0 };
235 char buf[200], place[100];
236 uint16_t langcode = 0;
237 double longitude, latitude, altitude;
238 const char *key = "location";
240 if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
241 av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
242 return AVERROR_INVALIDDATA;
245 avio_skip(pb, 4); // version+flags
246 langcode = avio_rb16(pb);
247 ff_mov_lang_to_iso639(langcode, language);
250 len -= avio_get_str(pb, len, place, sizeof(place));
252 av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
253 return AVERROR_INVALIDDATA;
255 avio_skip(pb, 1); // role
259 av_log(c->fc, AV_LOG_ERROR,
260 "loci too short (%u bytes left, need at least %d)\n", len, 12);
261 return AVERROR_INVALIDDATA;
263 longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
264 latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
265 altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
267 // Try to output in the same format as the ?xyz field
268 snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
270 av_strlcatf(buf, sizeof(buf), "%+f", altitude);
271 av_strlcatf(buf, sizeof(buf), "/%s", place);
273 if (*language && strcmp(language, "und")) {
275 snprintf(key2, sizeof(key2), "%s-%s", key, language);
276 av_dict_set(&c->fc->metadata, key2, buf, 0);
278 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
279 return av_dict_set(&c->fc->metadata, key, buf, 0);
282 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
288 if (c->ignore_chapters)
291 n_hmmt = avio_rb32(pb);
292 for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
293 int moment_time = avio_rb32(pb);
294 avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
299 static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
302 char key2[32], language[4] = {0};
304 const char *key = NULL;
305 uint16_t langcode = 0;
306 uint32_t data_type = 0, str_size, str_size_alloc;
307 int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
312 case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
313 case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
314 case MKTAG( 'X','M','P','_'):
315 if (c->export_xmp) { key = "xmp"; raw = 1; } break;
316 case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
317 case MKTAG( 'a','k','I','D'): key = "account_type";
318 parse = mov_metadata_int8_no_padding; break;
319 case MKTAG( 'a','p','I','D'): key = "account_id"; break;
320 case MKTAG( 'c','a','t','g'): key = "category"; break;
321 case MKTAG( 'c','p','i','l'): key = "compilation";
322 parse = mov_metadata_int8_no_padding; break;
323 case MKTAG( 'c','p','r','t'): key = "copyright"; break;
324 case MKTAG( 'd','e','s','c'): key = "description"; break;
325 case MKTAG( 'd','i','s','k'): key = "disc";
326 parse = mov_metadata_track_or_disc_number; break;
327 case MKTAG( 'e','g','i','d'): key = "episode_uid";
328 parse = mov_metadata_int8_no_padding; break;
329 case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
330 case MKTAG( 'g','n','r','e'): key = "genre";
331 parse = mov_metadata_gnre; break;
332 case MKTAG( 'h','d','v','d'): key = "hd_video";
333 parse = mov_metadata_int8_no_padding; break;
334 case MKTAG( 'H','M','M','T'):
335 return mov_metadata_hmmt(c, pb, atom.size);
336 case MKTAG( 'k','e','y','w'): key = "keywords"; break;
337 case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
338 case MKTAG( 'l','o','c','i'):
339 return mov_metadata_loci(c, pb, atom.size);
340 case MKTAG( 'm','a','n','u'): key = "make"; break;
341 case MKTAG( 'm','o','d','l'): key = "model"; break;
342 case MKTAG( 'p','c','s','t'): key = "podcast";
343 parse = mov_metadata_int8_no_padding; break;
344 case MKTAG( 'p','g','a','p'): key = "gapless_playback";
345 parse = mov_metadata_int8_no_padding; break;
346 case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
347 case MKTAG( 'r','t','n','g'): key = "rating";
348 parse = mov_metadata_int8_no_padding; break;
349 case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
350 case MKTAG( 's','o','a','l'): key = "sort_album"; break;
351 case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
352 case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
353 case MKTAG( 's','o','n','m'): key = "sort_name"; break;
354 case MKTAG( 's','o','s','n'): key = "sort_show"; break;
355 case MKTAG( 's','t','i','k'): key = "media_type";
356 parse = mov_metadata_int8_no_padding; break;
357 case MKTAG( 't','r','k','n'): key = "track";
358 parse = mov_metadata_track_or_disc_number; break;
359 case MKTAG( 't','v','e','n'): key = "episode_id"; break;
360 case MKTAG( 't','v','e','s'): key = "episode_sort";
361 parse = mov_metadata_int8_bypass_padding; break;
362 case MKTAG( 't','v','n','n'): key = "network"; break;
363 case MKTAG( 't','v','s','h'): key = "show"; break;
364 case MKTAG( 't','v','s','n'): key = "season_number";
365 parse = mov_metadata_int8_bypass_padding; break;
366 case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
367 case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
368 case MKTAG(0xa9,'a','l','b'): key = "album"; break;
369 case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
370 case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
371 case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
372 case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
373 case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
374 case MKTAG(0xa9,'d','a','y'): key = "date"; break;
375 case MKTAG(0xa9,'d','i','r'): key = "director"; break;
376 case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
377 case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
378 case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
379 case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
380 case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
381 case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
382 case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
383 case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
384 case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
385 case MKTAG(0xa9,'m','a','k'): key = "make"; break;
386 case MKTAG(0xa9,'m','o','d'): key = "model"; break;
387 case MKTAG(0xa9,'n','a','m'): key = "title"; break;
388 case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
389 case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
390 case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
391 case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
392 case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
393 case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
394 case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
395 case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
396 case MKTAG(0xa9,'t','r','k'): key = "track"; break;
397 case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
398 case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
399 case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
400 case MKTAG(0xa9,'x','y','z'): key = "location"; break;
403 if (c->itunes_metadata && atom.size > 8) {
404 int data_size = avio_rb32(pb);
405 int tag = avio_rl32(pb);
406 if (tag == MKTAG('d','a','t','a') && data_size <= atom.size) {
407 data_type = avio_rb32(pb); // type
408 avio_rb32(pb); // unknown
409 str_size = data_size - 16;
412 if (atom.type == MKTAG('c', 'o', 'v', 'r')) {
413 int ret = mov_read_covr(c, pb, data_type, str_size);
415 av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
418 atom.size -= str_size;
422 } else if (!key && c->found_hdlr_mdta && c->meta_keys) {
423 uint32_t index = AV_RB32(&atom.type);
424 if (index < c->meta_keys_count && index > 0) {
425 key = c->meta_keys[index];
427 av_log(c->fc, AV_LOG_WARNING,
428 "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
429 index, c->meta_keys_count);
433 } else if (atom.size > 4 && key && !c->itunes_metadata && !raw) {
434 str_size = avio_rb16(pb); // string length
435 if (str_size > atom.size) {
437 avio_seek(pb, -2, SEEK_CUR);
438 av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
441 langcode = avio_rb16(pb);
442 ff_mov_lang_to_iso639(langcode, language);
445 str_size = atom.size;
447 if (c->export_all && !key) {
448 snprintf(tmp_key, 5, "%.4s", (char*)&atom.type);
454 if (atom.size < 0 || str_size >= INT_MAX/2)
455 return AVERROR_INVALIDDATA;
457 // Allocates enough space if data_type is a int32 or float32 number, otherwise
458 // worst-case requirement for output string in case of utf8 coded input
459 num = (data_type >= 21 && data_type <= 23);
460 str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
461 str = av_mallocz(str_size_alloc);
463 return AVERROR(ENOMEM);
466 parse(c, pb, str_size, key);
468 if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
469 mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
470 } else if (data_type == 21) { // BE signed integer, variable size
473 val = (int8_t)avio_r8(pb);
474 else if (str_size == 2)
475 val = (int16_t)avio_rb16(pb);
476 else if (str_size == 3)
477 val = ((int32_t)(avio_rb24(pb)<<8))>>8;
478 else if (str_size == 4)
479 val = (int32_t)avio_rb32(pb);
480 if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
481 av_log(c->fc, AV_LOG_ERROR,
482 "Failed to store the number (%d) in string.\n", val);
484 return AVERROR_INVALIDDATA;
486 } else if (data_type == 22) { // BE unsigned integer, variable size
487 unsigned int val = 0;
490 else if (str_size == 2)
492 else if (str_size == 3)
494 else if (str_size == 4)
496 if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
497 av_log(c->fc, AV_LOG_ERROR,
498 "Failed to store the number (%u) in string.\n", val);
500 return AVERROR_INVALIDDATA;
502 } else if (data_type == 23 && str_size >= 4) { // BE float32
503 float val = av_int2float(avio_rb32(pb));
504 if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
505 av_log(c->fc, AV_LOG_ERROR,
506 "Failed to store the float32 number (%f) in string.\n", val);
508 return AVERROR_INVALIDDATA;
511 int ret = ffio_read_size(pb, str, str_size);
518 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
519 av_dict_set(&c->fc->metadata, key, str, 0);
520 if (*language && strcmp(language, "und")) {
521 snprintf(key2, sizeof(key2), "%s-%s", key, language);
522 av_dict_set(&c->fc->metadata, key2, str, 0);
524 if (!strcmp(key, "encoder")) {
525 int major, minor, micro;
526 if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, µ) == 3) {
527 c->handbrake_version = 1000000*major + 1000*minor + micro;
536 static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
539 int i, nb_chapters, str_len, version;
543 if (c->ignore_chapters)
546 if ((atom.size -= 5) < 0)
549 version = avio_r8(pb);
552 avio_rb32(pb); // ???
553 nb_chapters = avio_r8(pb);
555 for (i = 0; i < nb_chapters; i++) {
559 start = avio_rb64(pb);
560 str_len = avio_r8(pb);
562 if ((atom.size -= 9+str_len) < 0)
565 ret = ffio_read_size(pb, str, str_len);
569 avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
574 #define MIN_DATA_ENTRY_BOX_SIZE 12
575 static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
578 MOVStreamContext *sc;
581 if (c->fc->nb_streams < 1)
583 st = c->fc->streams[c->fc->nb_streams-1];
586 avio_rb32(pb); // version + flags
587 entries = avio_rb32(pb);
589 entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
590 entries >= UINT_MAX / sizeof(*sc->drefs))
591 return AVERROR_INVALIDDATA;
595 sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
597 return AVERROR(ENOMEM);
598 sc->drefs_count = entries;
600 for (i = 0; i < entries; i++) {
601 MOVDref *dref = &sc->drefs[i];
602 uint32_t size = avio_rb32(pb);
603 int64_t next = avio_tell(pb) + size - 4;
606 return AVERROR_INVALIDDATA;
608 dref->type = avio_rl32(pb);
609 avio_rb32(pb); // version + flags
611 if (dref->type == MKTAG('a','l','i','s') && size > 150) {
612 /* macintosh alias record */
613 uint16_t volume_len, len;
619 volume_len = avio_r8(pb);
620 volume_len = FFMIN(volume_len, 27);
621 ret = ffio_read_size(pb, dref->volume, 27);
624 dref->volume[volume_len] = 0;
625 av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
630 len = FFMIN(len, 63);
631 ret = ffio_read_size(pb, dref->filename, 63);
634 dref->filename[len] = 0;
635 av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
639 /* read next level up_from_alias/down_to_target */
640 dref->nlvl_from = avio_rb16(pb);
641 dref->nlvl_to = avio_rb16(pb);
642 av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
643 dref->nlvl_from, dref->nlvl_to);
647 for (type = 0; type != -1 && avio_tell(pb) < next; ) {
650 type = avio_rb16(pb);
652 av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
655 if (type == 2) { // absolute path
657 dref->path = av_mallocz(len+1);
659 return AVERROR(ENOMEM);
661 ret = ffio_read_size(pb, dref->path, len);
663 av_freep(&dref->path);
666 if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
668 memmove(dref->path, dref->path+volume_len, len);
671 // trim string of any ending zeros
672 for (j = len - 1; j >= 0; j--) {
673 if (dref->path[j] == 0)
678 for (j = 0; j < len; j++)
679 if (dref->path[j] == ':' || dref->path[j] == 0)
681 av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
682 } else if (type == 0) { // directory name
684 dref->dir = av_malloc(len+1);
686 return AVERROR(ENOMEM);
688 ret = ffio_read_size(pb, dref->dir, len);
690 av_freep(&dref->dir);
694 for (j = 0; j < len; j++)
695 if (dref->dir[j] == ':')
697 av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
702 av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
707 avio_seek(pb, next, SEEK_SET);
712 static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
721 avio_r8(pb); /* version */
722 avio_rb24(pb); /* flags */
725 ctype = avio_rl32(pb);
726 type = avio_rl32(pb); /* component subtype */
728 av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
729 av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
731 if (c->trak_index < 0) { // meta not inside a trak
732 if (type == MKTAG('m','d','t','a')) {
733 c->found_hdlr_mdta = 1;
738 st = c->fc->streams[c->fc->nb_streams-1];
740 if (type == MKTAG('v','i','d','e'))
741 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
742 else if (type == MKTAG('s','o','u','n'))
743 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
744 else if (type == MKTAG('m','1','a',' '))
745 st->codecpar->codec_id = AV_CODEC_ID_MP2;
746 else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
747 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
749 avio_rb32(pb); /* component manufacture */
750 avio_rb32(pb); /* component flags */
751 avio_rb32(pb); /* component flags mask */
753 title_size = atom.size - 24;
754 if (title_size > 0) {
755 if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
756 return AVERROR_INVALIDDATA;
757 title_str = av_malloc(title_size + 1); /* Add null terminator */
759 return AVERROR(ENOMEM);
761 ret = ffio_read_size(pb, title_str, title_size);
763 av_freep(&title_str);
766 title_str[title_size] = 0;
768 int off = (!c->isom && title_str[0] == title_size - 1);
769 // flag added so as to not set stream handler name if already set from mdia->hdlr
770 av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
772 av_freep(&title_str);
778 static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
780 return ff_mov_read_esds(c->fc, pb);
783 static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
786 enum AVAudioServiceType *ast;
787 int ac3info, acmod, lfeon, bsmod;
789 if (c->fc->nb_streams < 1)
791 st = c->fc->streams[c->fc->nb_streams-1];
793 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
796 return AVERROR(ENOMEM);
798 ac3info = avio_rb24(pb);
799 bsmod = (ac3info >> 14) & 0x7;
800 acmod = (ac3info >> 11) & 0x7;
801 lfeon = (ac3info >> 10) & 0x1;
802 st->codecpar->channels = ((int[]){2,1,2,3,3,4,4,5})[acmod] + lfeon;
803 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
805 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
807 if (st->codecpar->channels > 1 && bsmod == 0x7)
808 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
810 #if FF_API_LAVF_AVCTX
811 FF_DISABLE_DEPRECATION_WARNINGS
812 st->codec->audio_service_type = *ast;
813 FF_ENABLE_DEPRECATION_WARNINGS
819 static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
822 enum AVAudioServiceType *ast;
823 int eac3info, acmod, lfeon, bsmod;
825 if (c->fc->nb_streams < 1)
827 st = c->fc->streams[c->fc->nb_streams-1];
829 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
832 return AVERROR(ENOMEM);
834 /* No need to parse fields for additional independent substreams and its
835 * associated dependent substreams since libavcodec's E-AC-3 decoder
836 * does not support them yet. */
837 avio_rb16(pb); /* data_rate and num_ind_sub */
838 eac3info = avio_rb24(pb);
839 bsmod = (eac3info >> 12) & 0x1f;
840 acmod = (eac3info >> 9) & 0x7;
841 lfeon = (eac3info >> 8) & 0x1;
842 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
844 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
845 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
847 if (st->codecpar->channels > 1 && bsmod == 0x7)
848 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
850 #if FF_API_LAVF_AVCTX
851 FF_DISABLE_DEPRECATION_WARNINGS
852 st->codec->audio_service_type = *ast;
853 FF_ENABLE_DEPRECATION_WARNINGS
859 static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
861 const uint32_t ddts_size = 20;
864 uint32_t frame_duration_code = 0;
865 uint32_t channel_layout_code = 0;
868 buf = av_malloc(ddts_size + AV_INPUT_BUFFER_PADDING_SIZE);
870 return AVERROR(ENOMEM);
872 if (avio_read(pb, buf, ddts_size) < ddts_size) {
874 return AVERROR_INVALIDDATA;
877 init_get_bits(&gb, buf, 8*ddts_size);
879 if (c->fc->nb_streams < 1) {
883 st = c->fc->streams[c->fc->nb_streams-1];
885 st->codecpar->sample_rate = get_bits_long(&gb, 32);
886 if (st->codecpar->sample_rate <= 0) {
887 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
889 return AVERROR_INVALIDDATA;
891 skip_bits_long(&gb, 32); /* max bitrate */
892 st->codecpar->bit_rate = get_bits_long(&gb, 32);
893 st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
894 frame_duration_code = get_bits(&gb, 2);
895 skip_bits(&gb, 30); /* various fields */
896 channel_layout_code = get_bits(&gb, 16);
898 st->codecpar->frame_size =
899 (frame_duration_code == 0) ? 512 :
900 (frame_duration_code == 1) ? 1024 :
901 (frame_duration_code == 2) ? 2048 :
902 (frame_duration_code == 3) ? 4096 : 0;
904 if (channel_layout_code > 0xff) {
905 av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout");
907 st->codecpar->channel_layout =
908 ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
909 ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
910 ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
911 ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
912 ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
913 ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0);
915 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
921 static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
925 if (c->fc->nb_streams < 1)
927 st = c->fc->streams[c->fc->nb_streams-1];
932 /* skip version and flags */
935 ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
940 static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
945 if (c->fc->nb_streams < 1)
947 st = c->fc->streams[c->fc->nb_streams-1];
949 if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
950 av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
955 static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
957 const int num = avio_rb32(pb);
958 const int den = avio_rb32(pb);
961 if (c->fc->nb_streams < 1)
963 st = c->fc->streams[c->fc->nb_streams-1];
965 if ((st->sample_aspect_ratio.den != 1 || st->sample_aspect_ratio.num) && // default
966 (den != st->sample_aspect_ratio.den || num != st->sample_aspect_ratio.num)) {
967 av_log(c->fc, AV_LOG_WARNING,
968 "sample aspect ratio already set to %d:%d, ignoring 'pasp' atom (%d:%d)\n",
969 st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
971 } else if (den != 0) {
972 av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den,
978 /* this atom contains actual media data */
979 static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
981 if (atom.size == 0) /* wrong one (MP4) */
984 return 0; /* now go for moov */
987 #define DRM_BLOB_SIZE 56
989 static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
991 uint8_t intermediate_key[20];
992 uint8_t intermediate_iv[20];
995 uint8_t file_checksum[20];
996 uint8_t calculated_checksum[20];
1000 uint8_t *activation_bytes = c->activation_bytes;
1001 uint8_t *fixed_key = c->audible_fixed_key;
1005 sha = av_sha_alloc();
1007 return AVERROR(ENOMEM);
1008 c->aes_decrypt = av_aes_alloc();
1009 if (!c->aes_decrypt) {
1010 ret = AVERROR(ENOMEM);
1014 /* drm blob processing */
1015 avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1016 avio_read(pb, input, DRM_BLOB_SIZE);
1017 avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1018 avio_read(pb, file_checksum, 20);
1020 av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == "); // required by external tools
1021 for (i = 0; i < 20; i++)
1022 av_log(c->fc, AV_LOG_INFO, "%02x", file_checksum[i]);
1023 av_log(c->fc, AV_LOG_INFO, "\n");
1025 /* verify activation data */
1026 if (!activation_bytes) {
1027 av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1028 ret = 0; /* allow ffprobe to continue working on .aax files */
1031 if (c->activation_bytes_size != 4) {
1032 av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1033 ret = AVERROR(EINVAL);
1037 /* verify fixed key */
1038 if (c->audible_fixed_key_size != 16) {
1039 av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1040 ret = AVERROR(EINVAL);
1044 /* AAX (and AAX+) key derivation */
1045 av_sha_init(sha, 160);
1046 av_sha_update(sha, fixed_key, 16);
1047 av_sha_update(sha, activation_bytes, 4);
1048 av_sha_final(sha, intermediate_key);
1049 av_sha_init(sha, 160);
1050 av_sha_update(sha, fixed_key, 16);
1051 av_sha_update(sha, intermediate_key, 20);
1052 av_sha_update(sha, activation_bytes, 4);
1053 av_sha_final(sha, intermediate_iv);
1054 av_sha_init(sha, 160);
1055 av_sha_update(sha, intermediate_key, 16);
1056 av_sha_update(sha, intermediate_iv, 16);
1057 av_sha_final(sha, calculated_checksum);
1058 if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1059 av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1060 ret = AVERROR_INVALIDDATA;
1063 av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1064 av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1065 for (i = 0; i < 4; i++) {
1066 // file data (in output) is stored in big-endian mode
1067 if (activation_bytes[i] != output[3 - i]) { // critical error
1068 av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1069 ret = AVERROR_INVALIDDATA;
1073 memcpy(c->file_key, output + 8, 16);
1074 memcpy(input, output + 26, 16);
1075 av_sha_init(sha, 160);
1076 av_sha_update(sha, input, 16);
1077 av_sha_update(sha, c->file_key, 16);
1078 av_sha_update(sha, fixed_key, 16);
1079 av_sha_final(sha, c->file_iv);
1087 // Audible AAX (and AAX+) bytestream decryption
1088 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1091 unsigned char iv[16];
1093 memcpy(iv, c->file_iv, 16); // iv is overwritten
1094 blocks = size >> 4; // trailing bytes are not encrypted!
1095 av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1096 av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1101 /* read major brand, minor version and compatible brands and store them as metadata */
1102 static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1105 int comp_brand_size;
1106 char* comp_brands_str;
1107 uint8_t type[5] = {0};
1108 int ret = ffio_read_size(pb, type, 4);
1112 if (strcmp(type, "qt "))
1114 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1115 av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1116 minor_ver = avio_rb32(pb); /* minor version */
1117 av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1119 comp_brand_size = atom.size - 8;
1120 if (comp_brand_size < 0)
1121 return AVERROR_INVALIDDATA;
1122 comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1123 if (!comp_brands_str)
1124 return AVERROR(ENOMEM);
1126 ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1128 av_freep(&comp_brands_str);
1131 comp_brands_str[comp_brand_size] = 0;
1132 av_dict_set(&c->fc->metadata, "compatible_brands", comp_brands_str, 0);
1133 av_freep(&comp_brands_str);
1138 /* this atom should contain all header atoms */
1139 static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1143 if (c->found_moov) {
1144 av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1145 avio_skip(pb, atom.size);
1149 if ((ret = mov_read_default(c, pb, atom)) < 0)
1151 /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1152 /* so we don't parse the whole file if over a network */
1154 return 0; /* now go for mdat */
1157 static MOVFragmentStreamInfo * get_frag_stream_info(
1158 MOVFragmentIndex *frag_index,
1163 MOVFragmentIndexItem * item;
1165 if (index < 0 || index >= frag_index->nb_items)
1167 item = &frag_index->item[index];
1168 for (i = 0; i < item->nb_stream_info; i++)
1169 if (item->stream_info[i].id == id)
1170 return &item->stream_info[i];
1172 // This shouldn't happen
1176 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1179 MOVFragmentIndexItem * item;
1181 if (frag_index->current < 0 ||
1182 frag_index->current >= frag_index->nb_items)
1185 item = &frag_index->item[frag_index->current];
1186 for (i = 0; i < item->nb_stream_info; i++)
1187 if (item->stream_info[i].id == id) {
1192 // id not found. This shouldn't happen.
1196 static MOVFragmentStreamInfo * get_current_frag_stream_info(
1197 MOVFragmentIndex *frag_index)
1199 MOVFragmentIndexItem *item;
1200 if (frag_index->current < 0 ||
1201 frag_index->current >= frag_index->nb_items)
1204 item = &frag_index->item[frag_index->current];
1205 if (item->current >= 0 && item->current < item->nb_stream_info)
1206 return &item->stream_info[item->current];
1208 // This shouldn't happen
1212 static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
1215 int64_t moof_offset;
1217 // Optimize for appending new entries
1218 if (!frag_index->nb_items ||
1219 frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1220 return frag_index->nb_items;
1223 b = frag_index->nb_items;
1227 moof_offset = frag_index->item[m].moof_offset;
1228 if (moof_offset >= offset)
1230 if (moof_offset <= offset)
1236 static int64_t get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
1238 av_assert0(frag_stream_info);
1239 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1240 return frag_stream_info->sidx_pts;
1241 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1242 return frag_stream_info->first_tfra_pts;
1243 return frag_stream_info->tfdt_dts;
1246 static int64_t get_frag_time(MOVFragmentIndex *frag_index,
1247 int index, int track_id)
1249 MOVFragmentStreamInfo * frag_stream_info;
1253 if (track_id >= 0) {
1254 frag_stream_info = get_frag_stream_info(frag_index, index, track_id);
1255 return frag_stream_info->sidx_pts;
1258 for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1259 frag_stream_info = &frag_index->item[index].stream_info[i];
1260 timestamp = get_stream_info_time(frag_stream_info);
1261 if (timestamp != AV_NOPTS_VALUE)
1264 return AV_NOPTS_VALUE;
1267 static int search_frag_timestamp(MOVFragmentIndex *frag_index,
1268 AVStream *st, int64_t timestamp)
1275 // If the stream is referenced by any sidx, limit the search
1276 // to fragments that referenced this stream in the sidx
1277 MOVStreamContext *sc = st->priv_data;
1283 b = frag_index->nb_items;
1286 m0 = m = (a + b) >> 1;
1289 (frag_time = get_frag_time(frag_index, m, id)) == AV_NOPTS_VALUE)
1292 if (m < b && frag_time <= timestamp)
1301 static int update_frag_index(MOVContext *c, int64_t offset)
1304 MOVFragmentIndexItem * item;
1305 MOVFragmentStreamInfo * frag_stream_info;
1307 // If moof_offset already exists in frag_index, return index to it
1308 index = search_frag_moof_offset(&c->frag_index, offset);
1309 if (index < c->frag_index.nb_items &&
1310 c->frag_index.item[index].moof_offset == offset)
1313 // offset is not yet in frag index.
1314 // Insert new item at index (sorted by moof offset)
1315 item = av_fast_realloc(c->frag_index.item,
1316 &c->frag_index.allocated_size,
1317 (c->frag_index.nb_items + 1) *
1318 sizeof(*c->frag_index.item));
1321 c->frag_index.item = item;
1323 frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1324 sizeof(*item->stream_info));
1325 if (!frag_stream_info)
1328 for (i = 0; i < c->fc->nb_streams; i++) {
1329 // Avoid building frag index if streams lack track id.
1330 if (c->fc->streams[i]->id < 0)
1331 return AVERROR_INVALIDDATA;
1333 frag_stream_info[i].id = c->fc->streams[i]->id;
1334 frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1335 frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1336 frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1337 frag_stream_info[i].index_entry = -1;
1338 frag_stream_info[i].encryption_index = NULL;
1341 if (index < c->frag_index.nb_items)
1342 memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1343 (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1345 item = &c->frag_index.item[index];
1346 item->headers_read = 0;
1348 item->nb_stream_info = c->fc->nb_streams;
1349 item->moof_offset = offset;
1350 item->stream_info = frag_stream_info;
1351 c->frag_index.nb_items++;
1356 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1357 int id, int entries)
1360 MOVFragmentStreamInfo * frag_stream_info;
1364 for (i = index; i < frag_index->nb_items; i++) {
1365 frag_stream_info = get_frag_stream_info(frag_index, i, id);
1366 if (frag_stream_info && frag_stream_info->index_entry >= 0)
1367 frag_stream_info->index_entry += entries;
1371 static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1373 // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1374 c->fragment.found_tfhd = 0;
1376 if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1377 c->has_looked_for_mfra = 1;
1378 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1380 av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1382 if ((ret = mov_read_mfra(c, pb)) < 0) {
1383 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1384 "read the mfra (may be a live ismv)\n");
1387 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1388 "seekable, can not look for mfra\n");
1391 c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1392 av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1393 c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1394 return mov_read_default(c, pb, atom);
1397 static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time, void *logctx)
1400 if(time >= 2082844800)
1401 time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1403 if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1404 av_log(logctx, AV_LOG_DEBUG, "creation_time is not representable\n");
1408 avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1412 static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1415 MOVStreamContext *sc;
1417 char language[4] = {0};
1419 int64_t creation_time;
1421 if (c->fc->nb_streams < 1)
1423 st = c->fc->streams[c->fc->nb_streams-1];
1426 if (sc->time_scale) {
1427 av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1428 return AVERROR_INVALIDDATA;
1431 version = avio_r8(pb);
1433 avpriv_request_sample(c->fc, "Version %d", version);
1434 return AVERROR_PATCHWELCOME;
1436 avio_rb24(pb); /* flags */
1438 creation_time = avio_rb64(pb);
1441 creation_time = avio_rb32(pb);
1442 avio_rb32(pb); /* modification time */
1444 mov_metadata_creation_time(&st->metadata, creation_time, c->fc);
1446 sc->time_scale = avio_rb32(pb);
1447 if (sc->time_scale <= 0) {
1448 av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1451 st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1453 lang = avio_rb16(pb); /* language */
1454 if (ff_mov_lang_to_iso639(lang, language))
1455 av_dict_set(&st->metadata, "language", language, 0);
1456 avio_rb16(pb); /* quality */
1461 static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1464 int64_t creation_time;
1465 int version = avio_r8(pb); /* version */
1466 avio_rb24(pb); /* flags */
1469 creation_time = avio_rb64(pb);
1472 creation_time = avio_rb32(pb);
1473 avio_rb32(pb); /* modification time */
1475 mov_metadata_creation_time(&c->fc->metadata, creation_time, c->fc);
1476 c->time_scale = avio_rb32(pb); /* time scale */
1477 if (c->time_scale <= 0) {
1478 av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1481 av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1483 c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1484 // set the AVCodecContext duration because the duration of individual tracks
1485 // may be inaccurate
1486 if (c->time_scale > 0 && !c->trex_data)
1487 c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale);
1488 avio_rb32(pb); /* preferred scale */
1490 avio_rb16(pb); /* preferred volume */
1492 avio_skip(pb, 10); /* reserved */
1494 /* movie display matrix, store it in main context and use it later on */
1495 for (i = 0; i < 3; i++) {
1496 c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1497 c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1498 c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1501 avio_rb32(pb); /* preview time */
1502 avio_rb32(pb); /* preview duration */
1503 avio_rb32(pb); /* poster time */
1504 avio_rb32(pb); /* selection time */
1505 avio_rb32(pb); /* selection duration */
1506 avio_rb32(pb); /* current time */
1507 avio_rb32(pb); /* next track ID */
1512 static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1517 if (c->fc->nb_streams < 1)
1519 st = c->fc->streams[c->fc->nb_streams-1];
1521 little_endian = avio_rb16(pb) & 0xFF;
1522 av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1523 if (little_endian == 1) {
1524 switch (st->codecpar->codec_id) {
1525 case AV_CODEC_ID_PCM_S24BE:
1526 st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE;
1528 case AV_CODEC_ID_PCM_S32BE:
1529 st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE;
1531 case AV_CODEC_ID_PCM_F32BE:
1532 st->codecpar->codec_id = AV_CODEC_ID_PCM_F32LE;
1534 case AV_CODEC_ID_PCM_F64BE:
1535 st->codecpar->codec_id = AV_CODEC_ID_PCM_F64LE;
1544 static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1547 char color_parameter_type[5] = { 0 };
1548 uint16_t color_primaries, color_trc, color_matrix;
1551 if (c->fc->nb_streams < 1)
1553 st = c->fc->streams[c->fc->nb_streams - 1];
1555 ret = ffio_read_size(pb, color_parameter_type, 4);
1558 if (strncmp(color_parameter_type, "nclx", 4) &&
1559 strncmp(color_parameter_type, "nclc", 4)) {
1560 av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
1561 color_parameter_type);
1565 color_primaries = avio_rb16(pb);
1566 color_trc = avio_rb16(pb);
1567 color_matrix = avio_rb16(pb);
1569 av_log(c->fc, AV_LOG_TRACE,
1570 "%s: pri %d trc %d matrix %d",
1571 color_parameter_type, color_primaries, color_trc, color_matrix);
1573 if (!strncmp(color_parameter_type, "nclx", 4)) {
1574 uint8_t color_range = avio_r8(pb) >> 7;
1575 av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
1577 st->codecpar->color_range = AVCOL_RANGE_JPEG;
1579 st->codecpar->color_range = AVCOL_RANGE_MPEG;
1582 if (!av_color_primaries_name(color_primaries))
1583 color_primaries = AVCOL_PRI_UNSPECIFIED;
1584 if (!av_color_transfer_name(color_trc))
1585 color_trc = AVCOL_TRC_UNSPECIFIED;
1586 if (!av_color_space_name(color_matrix))
1587 color_matrix = AVCOL_SPC_UNSPECIFIED;
1589 st->codecpar->color_primaries = color_primaries;
1590 st->codecpar->color_trc = color_trc;
1591 st->codecpar->color_space = color_matrix;
1592 av_log(c->fc, AV_LOG_TRACE, "\n");
1597 static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1600 unsigned mov_field_order;
1601 enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
1603 if (c->fc->nb_streams < 1) // will happen with jp2 files
1605 st = c->fc->streams[c->fc->nb_streams-1];
1607 return AVERROR_INVALIDDATA;
1608 mov_field_order = avio_rb16(pb);
1609 if ((mov_field_order & 0xFF00) == 0x0100)
1610 decoded_field_order = AV_FIELD_PROGRESSIVE;
1611 else if ((mov_field_order & 0xFF00) == 0x0200) {
1612 switch (mov_field_order & 0xFF) {
1613 case 0x01: decoded_field_order = AV_FIELD_TT;
1615 case 0x06: decoded_field_order = AV_FIELD_BB;
1617 case 0x09: decoded_field_order = AV_FIELD_TB;
1619 case 0x0E: decoded_field_order = AV_FIELD_BT;
1623 if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
1624 av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
1626 st->codecpar->field_order = decoded_field_order;
1631 static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
1634 uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
1635 if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
1636 return AVERROR_INVALIDDATA;
1637 if ((err = av_reallocp(&par->extradata, size)) < 0) {
1638 par->extradata_size = 0;
1641 par->extradata_size = size - AV_INPUT_BUFFER_PADDING_SIZE;
1645 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
1646 static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1647 AVCodecParameters *par, uint8_t *buf)
1649 int64_t result = atom.size;
1652 AV_WB32(buf , atom.size + 8);
1653 AV_WL32(buf + 4, atom.type);
1654 err = ffio_read_size(pb, buf + 8, atom.size);
1656 par->extradata_size -= atom.size;
1658 } else if (err < atom.size) {
1659 av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
1660 par->extradata_size -= atom.size - err;
1663 memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1667 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
1668 static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1669 enum AVCodecID codec_id)
1672 uint64_t original_size;
1675 if (c->fc->nb_streams < 1) // will happen with jp2 files
1677 st = c->fc->streams[c->fc->nb_streams-1];
1679 if (st->codecpar->codec_id != codec_id)
1680 return 0; /* unexpected codec_id - don't mess with extradata */
1682 original_size = st->codecpar->extradata_size;
1683 err = mov_realloc_extradata(st->codecpar, atom);
1687 err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
1690 return 0; // Note: this is the original behavior to ignore truncation.
1693 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
1694 static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1696 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
1699 static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1701 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS);
1704 static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1706 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
1709 static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1711 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
1714 static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1716 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
1718 ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
1722 static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1724 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
1726 if (!ret && c->fc->nb_streams >= 1) {
1727 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1728 if (par->extradata_size >= 40) {
1729 par->height = AV_RB16(&par->extradata[36]);
1730 par->width = AV_RB16(&par->extradata[38]);
1736 static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1738 if (c->fc->nb_streams >= 1) {
1739 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1740 if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
1741 par->codec_id == AV_CODEC_ID_H264 &&
1745 cid = avio_rb16(pb);
1746 /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
1747 if (cid == 0xd4d || cid == 0xd4e)
1750 } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
1751 par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
1752 par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
1756 num = avio_rb32(pb);
1757 den = avio_rb32(pb);
1758 if (num <= 0 || den <= 0)
1760 switch (avio_rb32(pb)) {
1762 if (den >= INT_MAX / 2)
1766 c->fc->streams[c->fc->nb_streams-1]->display_aspect_ratio.num = num;
1767 c->fc->streams[c->fc->nb_streams-1]->display_aspect_ratio.den = den;
1774 return mov_read_avid(c, pb, atom);
1777 static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1781 uint64_t original_size;
1782 if (c->fc->nb_streams >= 1) {
1783 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1784 if (par->codec_id == AV_CODEC_ID_H264)
1786 if (atom.size == 16) {
1787 original_size = par->extradata_size;
1788 ret = mov_realloc_extradata(par, atom);
1790 length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
1791 if (length == atom.size) {
1792 const uint8_t range_value = par->extradata[original_size + 19];
1793 switch (range_value) {
1795 par->color_range = AVCOL_RANGE_MPEG;
1798 par->color_range = AVCOL_RANGE_JPEG;
1801 av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
1804 ff_dlog(c->fc, "color_range: %d\n", par->color_range);
1806 /* For some reason the whole atom was not added to the extradata */
1807 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
1810 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
1813 av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
1820 static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1822 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
1825 static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1830 if (c->fc->nb_streams < 1)
1832 st = c->fc->streams[c->fc->nb_streams-1];
1834 if ((uint64_t)atom.size > (1<<30))
1835 return AVERROR_INVALIDDATA;
1837 if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
1838 st->codecpar->codec_id == AV_CODEC_ID_QDMC ||
1839 st->codecpar->codec_id == AV_CODEC_ID_SPEEX) {
1840 // pass all frma atom to codec, needed at least for QDMC and QDM2
1841 av_freep(&st->codecpar->extradata);
1842 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1845 } else if (atom.size > 8) { /* to read frma, esds atoms */
1846 if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
1848 ret = ffio_ensure_seekback(pb, 8);
1851 buffer = avio_rb64(pb);
1853 if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
1854 && buffer >> 32 <= atom.size
1855 && buffer >> 32 >= 8) {
1858 } else if (!st->codecpar->extradata_size) {
1859 #define ALAC_EXTRADATA_SIZE 36
1860 st->codecpar->extradata = av_mallocz(ALAC_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
1861 if (!st->codecpar->extradata)
1862 return AVERROR(ENOMEM);
1863 st->codecpar->extradata_size = ALAC_EXTRADATA_SIZE;
1864 AV_WB32(st->codecpar->extradata , ALAC_EXTRADATA_SIZE);
1865 AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
1866 AV_WB64(st->codecpar->extradata + 12, buffer);
1867 avio_read(pb, st->codecpar->extradata + 20, 16);
1868 avio_skip(pb, atom.size - 24);
1872 if ((ret = mov_read_default(c, pb, atom)) < 0)
1875 avio_skip(pb, atom.size);
1880 * This function reads atom content and puts data in extradata without tag
1881 * nor size unlike mov_read_extradata.
1883 static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1888 if (c->fc->nb_streams < 1)
1890 st = c->fc->streams[c->fc->nb_streams-1];
1892 if ((uint64_t)atom.size > (1<<30))
1893 return AVERROR_INVALIDDATA;
1895 if (atom.size >= 10) {
1896 // Broken files created by legacy versions of libavformat will
1897 // wrap a whole fiel atom inside of a glbl atom.
1898 unsigned size = avio_rb32(pb);
1899 unsigned type = avio_rl32(pb);
1900 avio_seek(pb, -8, SEEK_CUR);
1901 if (type == MKTAG('f','i','e','l') && size == atom.size)
1902 return mov_read_default(c, pb, atom);
1904 if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
1905 av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
1908 av_freep(&st->codecpar->extradata);
1909 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1912 if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
1913 /* HEVC-based Dolby Vision derived from hvc1.
1914 Happens to match with an identifier
1915 previously utilized for DV. Thus, if we have
1916 the hvcC extradata box available as specified,
1917 set codec to HEVC */
1918 st->codecpar->codec_id = AV_CODEC_ID_HEVC;
1923 static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1926 uint8_t profile_level;
1929 if (c->fc->nb_streams < 1)
1931 st = c->fc->streams[c->fc->nb_streams-1];
1933 if (atom.size >= (1<<28) || atom.size < 7)
1934 return AVERROR_INVALIDDATA;
1936 profile_level = avio_r8(pb);
1937 if ((profile_level & 0xf0) != 0xc0)
1940 avio_seek(pb, 6, SEEK_CUR);
1941 av_freep(&st->codecpar->extradata);
1942 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
1950 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
1951 * but can have extradata appended at the end after the 40 bytes belonging
1954 static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1959 if (c->fc->nb_streams < 1)
1961 if (atom.size <= 40)
1963 st = c->fc->streams[c->fc->nb_streams-1];
1965 if ((uint64_t)atom.size > (1<<30))
1966 return AVERROR_INVALIDDATA;
1969 av_freep(&st->codecpar->extradata);
1970 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
1977 static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1980 MOVStreamContext *sc;
1981 unsigned int i, entries;
1983 if (c->fc->nb_streams < 1)
1985 st = c->fc->streams[c->fc->nb_streams-1];
1988 avio_r8(pb); /* version */
1989 avio_rb24(pb); /* flags */
1991 entries = avio_rb32(pb);
1996 if (sc->chunk_offsets)
1997 av_log(c->fc, AV_LOG_WARNING, "Duplicated STCO atom\n");
1998 av_free(sc->chunk_offsets);
1999 sc->chunk_count = 0;
2000 sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2001 if (!sc->chunk_offsets)
2002 return AVERROR(ENOMEM);
2003 sc->chunk_count = entries;
2005 if (atom.type == MKTAG('s','t','c','o'))
2006 for (i = 0; i < entries && !pb->eof_reached; i++)
2007 sc->chunk_offsets[i] = avio_rb32(pb);
2008 else if (atom.type == MKTAG('c','o','6','4'))
2009 for (i = 0; i < entries && !pb->eof_reached; i++)
2010 sc->chunk_offsets[i] = avio_rb64(pb);
2012 return AVERROR_INVALIDDATA;
2014 sc->chunk_count = i;
2016 if (pb->eof_reached) {
2017 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2024 static int mov_codec_id(AVStream *st, uint32_t format)
2026 int id = ff_codec_get_id(ff_codec_movaudio_tags, format);
2029 ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2030 (format & 0xFFFF) == 'T' + ('S' << 8)))
2031 id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format) & 0xFFFF);
2033 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2034 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2035 } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2036 /* skip old ASF MPEG-4 tag */
2037 format && format != MKTAG('m','p','4','s')) {
2038 id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2040 id = ff_codec_get_id(ff_codec_bmp_tags, format);
2042 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
2043 else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2044 (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE &&
2045 st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2046 id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
2048 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
2050 id = ff_codec_get_id(ff_codec_movdata_tags, format);
2054 st->codecpar->codec_tag = format;
2059 static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
2060 AVStream *st, MOVStreamContext *sc)
2062 uint8_t codec_name[32] = { 0 };
2066 /* The first 16 bytes of the video sample description are already
2067 * read in ff_mov_read_stsd_entries() */
2068 stsd_start = avio_tell(pb) - 16;
2070 avio_rb16(pb); /* version */
2071 avio_rb16(pb); /* revision level */
2072 avio_rb32(pb); /* vendor */
2073 avio_rb32(pb); /* temporal quality */
2074 avio_rb32(pb); /* spatial quality */
2076 st->codecpar->width = avio_rb16(pb); /* width */
2077 st->codecpar->height = avio_rb16(pb); /* height */
2079 avio_rb32(pb); /* horiz resolution */
2080 avio_rb32(pb); /* vert resolution */
2081 avio_rb32(pb); /* data size, always 0 */
2082 avio_rb16(pb); /* frames per samples */
2084 len = avio_r8(pb); /* codec name, pascal string */
2087 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2089 avio_skip(pb, 31 - len);
2092 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2094 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2095 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2096 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2097 st->codecpar->width &= ~1;
2098 st->codecpar->height &= ~1;
2100 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2101 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2102 !strncmp(codec_name, "Sorenson H263", 13))
2103 st->codecpar->codec_id = AV_CODEC_ID_FLV1;
2105 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2107 avio_seek(pb, stsd_start, SEEK_SET);
2109 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2110 st->codecpar->bits_per_coded_sample &= 0x1F;
2111 sc->has_palette = 1;
2115 static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
2116 AVStream *st, MOVStreamContext *sc)
2118 int bits_per_sample, flags;
2119 uint16_t version = avio_rb16(pb);
2120 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2122 avio_rb16(pb); /* revision level */
2123 avio_rb32(pb); /* vendor */
2125 st->codecpar->channels = avio_rb16(pb); /* channel count */
2126 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2127 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", st->codecpar->channels);
2129 sc->audio_cid = avio_rb16(pb);
2130 avio_rb16(pb); /* packet size = 0 */
2132 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2134 // Read QT version 1 fields. In version 0 these do not exist.
2135 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2137 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2138 (sc->stsd_version == 0 && version > 0)) {
2140 sc->samples_per_frame = avio_rb32(pb);
2141 avio_rb32(pb); /* bytes per packet */
2142 sc->bytes_per_frame = avio_rb32(pb);
2143 avio_rb32(pb); /* bytes per sample */
2144 } else if (version == 2) {
2145 avio_rb32(pb); /* sizeof struct only */
2146 st->codecpar->sample_rate = av_int2double(avio_rb64(pb));
2147 st->codecpar->channels = avio_rb32(pb);
2148 avio_rb32(pb); /* always 0x7F000000 */
2149 st->codecpar->bits_per_coded_sample = avio_rb32(pb);
2151 flags = avio_rb32(pb); /* lpcm format specific flag */
2152 sc->bytes_per_frame = avio_rb32(pb);
2153 sc->samples_per_frame = avio_rb32(pb);
2154 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2155 st->codecpar->codec_id =
2156 ff_mov_get_lpcm_codec_id(st->codecpar->bits_per_coded_sample,
2159 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2160 /* can't correctly handle variable sized packet as audio unit */
2161 switch (st->codecpar->codec_id) {
2162 case AV_CODEC_ID_MP2:
2163 case AV_CODEC_ID_MP3:
2164 st->need_parsing = AVSTREAM_PARSE_FULL;
2170 if (sc->format == 0) {
2171 if (st->codecpar->bits_per_coded_sample == 8)
2172 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2173 else if (st->codecpar->bits_per_coded_sample == 16)
2174 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2177 switch (st->codecpar->codec_id) {
2178 case AV_CODEC_ID_PCM_S8:
2179 case AV_CODEC_ID_PCM_U8:
2180 if (st->codecpar->bits_per_coded_sample == 16)
2181 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16BE;
2183 case AV_CODEC_ID_PCM_S16LE:
2184 case AV_CODEC_ID_PCM_S16BE:
2185 if (st->codecpar->bits_per_coded_sample == 8)
2186 st->codecpar->codec_id = AV_CODEC_ID_PCM_S8;
2187 else if (st->codecpar->bits_per_coded_sample == 24)
2188 st->codecpar->codec_id =
2189 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2190 AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
2191 else if (st->codecpar->bits_per_coded_sample == 32)
2192 st->codecpar->codec_id =
2193 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2194 AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
2196 /* set values for old format before stsd version 1 appeared */
2197 case AV_CODEC_ID_MACE3:
2198 sc->samples_per_frame = 6;
2199 sc->bytes_per_frame = 2 * st->codecpar->channels;
2201 case AV_CODEC_ID_MACE6:
2202 sc->samples_per_frame = 6;
2203 sc->bytes_per_frame = 1 * st->codecpar->channels;
2205 case AV_CODEC_ID_ADPCM_IMA_QT:
2206 sc->samples_per_frame = 64;
2207 sc->bytes_per_frame = 34 * st->codecpar->channels;
2209 case AV_CODEC_ID_GSM:
2210 sc->samples_per_frame = 160;
2211 sc->bytes_per_frame = 33;
2217 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2218 if (bits_per_sample) {
2219 st->codecpar->bits_per_coded_sample = bits_per_sample;
2220 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->channels;
2224 static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
2225 AVStream *st, MOVStreamContext *sc,
2228 // ttxt stsd contains display flags, justification, background
2229 // color, fonts, and default styles, so fake an atom to read it
2230 MOVAtom fake_atom = { .size = size };
2231 // mp4s contains a regular esds atom
2232 if (st->codecpar->codec_tag != AV_RL32("mp4s"))
2233 mov_read_glbl(c, pb, fake_atom);
2234 st->codecpar->width = sc->width;
2235 st->codecpar->height = sc->height;
2238 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2243 y = (ycbcr >> 16) & 0xFF;
2244 cr = (ycbcr >> 8) & 0xFF;
2247 b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
2248 g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
2249 r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
2251 return (r << 16) | (g << 8) | b;
2254 static int mov_rewrite_dvd_sub_extradata(AVStream *st)
2256 char buf[256] = {0};
2257 uint8_t *src = st->codecpar->extradata;
2260 if (st->codecpar->extradata_size != 64)
2263 if (st->codecpar->width > 0 && st->codecpar->height > 0)
2264 snprintf(buf, sizeof(buf), "size: %dx%d\n",
2265 st->codecpar->width, st->codecpar->height);
2266 av_strlcat(buf, "palette: ", sizeof(buf));
2268 for (i = 0; i < 16; i++) {
2269 uint32_t yuv = AV_RB32(src + i * 4);
2270 uint32_t rgba = yuv_to_rgba(yuv);
2272 av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2275 if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2278 ret = ff_alloc_extradata(st->codecpar, strlen(buf));
2281 memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2286 static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
2287 AVStream *st, MOVStreamContext *sc,
2292 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2293 if ((int)size != size)
2294 return AVERROR(ENOMEM);
2296 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2300 MOVStreamContext *tmcd_ctx = st->priv_data;
2302 val = AV_RB32(st->codecpar->extradata + 4);
2303 tmcd_ctx->tmcd_flags = val;
2304 st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2305 st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2306 #if FF_API_LAVF_AVCTX
2307 FF_DISABLE_DEPRECATION_WARNINGS
2308 st->codec->time_base = av_inv_q(st->avg_frame_rate);
2309 FF_ENABLE_DEPRECATION_WARNINGS
2311 /* adjust for per frame dur in counter mode */
2312 if (tmcd_ctx->tmcd_flags & 0x0008) {
2313 int timescale = AV_RB32(st->codecpar->extradata + 8);
2314 int framedur = AV_RB32(st->codecpar->extradata + 12);
2315 st->avg_frame_rate.num *= timescale;
2316 st->avg_frame_rate.den *= framedur;
2317 #if FF_API_LAVF_AVCTX
2318 FF_DISABLE_DEPRECATION_WARNINGS
2319 st->codec->time_base.den *= timescale;
2320 st->codec->time_base.num *= framedur;
2321 FF_ENABLE_DEPRECATION_WARNINGS
2325 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2326 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2327 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2328 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2329 if (str_size > 0 && size >= (int)str_size + 26) {
2330 char *reel_name = av_malloc(str_size + 1);
2332 return AVERROR(ENOMEM);
2333 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2334 reel_name[str_size] = 0; /* Add null terminator */
2335 /* don't add reel_name if emtpy string */
2336 if (*reel_name == 0) {
2339 av_dict_set(&st->metadata, "reel_name", reel_name, AV_DICT_DONT_STRDUP_VAL);
2346 /* other codec type, just skip (rtp, mp4s ...) */
2347 avio_skip(pb, size);
2352 static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
2353 AVStream *st, MOVStreamContext *sc)
2355 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2356 !st->codecpar->sample_rate && sc->time_scale > 1)
2357 st->codecpar->sample_rate = sc->time_scale;
2359 /* special codec parameters handling */
2360 switch (st->codecpar->codec_id) {
2361 #if CONFIG_DV_DEMUXER
2362 case AV_CODEC_ID_DVAUDIO:
2363 c->dv_fctx = avformat_alloc_context();
2365 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2366 return AVERROR(ENOMEM);
2368 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2370 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2371 return AVERROR(ENOMEM);
2373 sc->dv_audio_container = 1;
2374 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
2377 /* no ifdef since parameters are always those */
2378 case AV_CODEC_ID_QCELP:
2379 st->codecpar->channels = 1;
2380 // force sample rate for qcelp when not stored in mov
2381 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2382 st->codecpar->sample_rate = 8000;
2383 // FIXME: Why is the following needed for some files?
2384 sc->samples_per_frame = 160;
2385 if (!sc->bytes_per_frame)
2386 sc->bytes_per_frame = 35;
2388 case AV_CODEC_ID_AMR_NB:
2389 st->codecpar->channels = 1;
2390 /* force sample rate for amr, stsd in 3gp does not store sample rate */
2391 st->codecpar->sample_rate = 8000;
2393 case AV_CODEC_ID_AMR_WB:
2394 st->codecpar->channels = 1;
2395 st->codecpar->sample_rate = 16000;
2397 case AV_CODEC_ID_MP2:
2398 case AV_CODEC_ID_MP3:
2399 /* force type after stsd for m1a hdlr */
2400 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2402 case AV_CODEC_ID_GSM:
2403 case AV_CODEC_ID_ADPCM_MS:
2404 case AV_CODEC_ID_ADPCM_IMA_WAV:
2405 case AV_CODEC_ID_ILBC:
2406 case AV_CODEC_ID_MACE3:
2407 case AV_CODEC_ID_MACE6:
2408 case AV_CODEC_ID_QDM2:
2409 st->codecpar->block_align = sc->bytes_per_frame;
2411 case AV_CODEC_ID_ALAC:
2412 if (st->codecpar->extradata_size == 36) {
2413 st->codecpar->channels = AV_RB8 (st->codecpar->extradata + 21);
2414 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2417 case AV_CODEC_ID_AC3:
2418 case AV_CODEC_ID_EAC3:
2419 case AV_CODEC_ID_MPEG1VIDEO:
2420 case AV_CODEC_ID_VC1:
2421 case AV_CODEC_ID_VP8:
2422 case AV_CODEC_ID_VP9:
2423 st->need_parsing = AVSTREAM_PARSE_FULL;
2431 static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
2432 int codec_tag, int format,
2435 int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2438 (codec_tag != format &&
2439 // AVID 1:1 samples with differing data format and codec tag exist
2440 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
2441 // prores is allowed to have differing data format and codec tag
2442 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
2444 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
2445 (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id
2446 : codec_tag != MKTAG('j','p','e','g')))) {
2447 /* Multiple fourcc, we skip JPEG. This is not correct, we should
2448 * export it as a separate AVStream but this needs a few changes
2449 * in the MOV demuxer, patch welcome. */
2451 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
2452 avio_skip(pb, size);
2459 int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
2462 MOVStreamContext *sc;
2463 int pseudo_stream_id;
2465 av_assert0 (c->fc->nb_streams >= 1);
2466 st = c->fc->streams[c->fc->nb_streams-1];
2469 for (pseudo_stream_id = 0;
2470 pseudo_stream_id < entries && !pb->eof_reached;
2471 pseudo_stream_id++) {
2472 //Parsing Sample description table
2474 int ret, dref_id = 1;
2475 MOVAtom a = { AV_RL32("stsd") };
2476 int64_t start_pos = avio_tell(pb);
2477 int64_t size = avio_rb32(pb); /* size */
2478 uint32_t format = avio_rl32(pb); /* data format */
2481 avio_rb32(pb); /* reserved */
2482 avio_rb16(pb); /* reserved */
2483 dref_id = avio_rb16(pb);
2484 } else if (size <= 7) {
2485 av_log(c->fc, AV_LOG_ERROR,
2486 "invalid size %"PRId64" in stsd\n", size);
2487 return AVERROR_INVALIDDATA;
2490 if (mov_skip_multiple_stsd(c, pb, st->codecpar->codec_tag, format,
2491 size - (avio_tell(pb) - start_pos))) {
2496 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
2497 sc->dref_id= dref_id;
2498 sc->format = format;
2500 id = mov_codec_id(st, format);
2502 av_log(c->fc, AV_LOG_TRACE,
2503 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
2504 av_fourcc2str(format), st->codecpar->codec_type);
2506 st->codecpar->codec_id = id;
2507 if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) {
2508 mov_parse_stsd_video(c, pb, st, sc);
2509 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
2510 mov_parse_stsd_audio(c, pb, st, sc);
2511 if (st->codecpar->sample_rate < 0) {
2512 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
2513 return AVERROR_INVALIDDATA;
2515 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
2516 mov_parse_stsd_subtitle(c, pb, st, sc,
2517 size - (avio_tell(pb) - start_pos));
2519 ret = mov_parse_stsd_data(c, pb, st, sc,
2520 size - (avio_tell(pb) - start_pos));
2524 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
2525 a.size = size - (avio_tell(pb) - start_pos);
2527 if ((ret = mov_read_default(c, pb, a)) < 0)
2529 } else if (a.size > 0)
2530 avio_skip(pb, a.size);
2532 if (sc->extradata && st->codecpar->extradata) {
2533 int extra_size = st->codecpar->extradata_size;
2535 /* Move the current stream extradata to the stream context one. */
2536 sc->extradata_size[pseudo_stream_id] = extra_size;
2537 sc->extradata[pseudo_stream_id] = av_malloc(extra_size + AV_INPUT_BUFFER_PADDING_SIZE);
2538 if (!sc->extradata[pseudo_stream_id])
2539 return AVERROR(ENOMEM);
2540 memcpy(sc->extradata[pseudo_stream_id], st->codecpar->extradata, extra_size);
2541 av_freep(&st->codecpar->extradata);
2542 st->codecpar->extradata_size = 0;
2547 if (pb->eof_reached) {
2548 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
2555 static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2558 MOVStreamContext *sc;
2561 if (c->fc->nb_streams < 1)
2563 st = c->fc->streams[c->fc->nb_streams - 1];
2566 sc->stsd_version = avio_r8(pb);
2567 avio_rb24(pb); /* flags */
2568 entries = avio_rb32(pb);
2570 /* Each entry contains a size (4 bytes) and format (4 bytes). */
2571 if (entries <= 0 || entries > atom.size / 8) {
2572 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
2573 return AVERROR_INVALIDDATA;
2576 if (sc->extradata) {
2577 av_log(c->fc, AV_LOG_ERROR,
2578 "Duplicate stsd found in this track.\n");
2579 return AVERROR_INVALIDDATA;
2582 /* Prepare space for hosting multiple extradata. */
2583 sc->extradata = av_mallocz_array(entries, sizeof(*sc->extradata));
2585 return AVERROR(ENOMEM);
2587 sc->extradata_size = av_mallocz_array(entries, sizeof(*sc->extradata_size));
2588 if (!sc->extradata_size) {
2589 ret = AVERROR(ENOMEM);
2593 ret = ff_mov_read_stsd_entries(c, pb, entries);
2597 /* Restore back the primary extradata. */
2598 av_freep(&st->codecpar->extradata);
2599 st->codecpar->extradata_size = sc->extradata_size[0];
2600 if (sc->extradata_size[0]) {
2601 st->codecpar->extradata = av_mallocz(sc->extradata_size[0] + AV_INPUT_BUFFER_PADDING_SIZE);
2602 if (!st->codecpar->extradata)
2603 return AVERROR(ENOMEM);
2604 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
2607 return mov_finalize_stsd_codec(c, pb, st, sc);
2609 if (sc->extradata) {
2611 for (j = 0; j < sc->stsd_count; j++)
2612 av_freep(&sc->extradata[j]);
2615 av_freep(&sc->extradata);
2616 av_freep(&sc->extradata_size);
2620 static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2623 MOVStreamContext *sc;
2624 unsigned int i, entries;
2626 if (c->fc->nb_streams < 1)
2628 st = c->fc->streams[c->fc->nb_streams-1];
2631 avio_r8(pb); /* version */
2632 avio_rb24(pb); /* flags */
2634 entries = avio_rb32(pb);
2635 if ((uint64_t)entries * 12 + 4 > atom.size)
2636 return AVERROR_INVALIDDATA;
2638 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
2643 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSC atom\n");
2644 av_free(sc->stsc_data);
2646 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
2648 return AVERROR(ENOMEM);
2650 for (i = 0; i < entries && !pb->eof_reached; i++) {
2651 sc->stsc_data[i].first = avio_rb32(pb);
2652 sc->stsc_data[i].count = avio_rb32(pb);
2653 sc->stsc_data[i].id = avio_rb32(pb);
2657 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
2658 int64_t first_min = i + 1;
2659 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
2660 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
2661 sc->stsc_data[i].first < first_min ||
2662 sc->stsc_data[i].count < 1 ||
2663 sc->stsc_data[i].id < 1) {
2664 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);
2665 if (i+1 >= sc->stsc_count) {
2666 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
2667 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
2668 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
2669 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
2670 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
2673 av_assert0(sc->stsc_data[i+1].first >= 2);
2674 // We replace this entry by the next valid
2675 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
2676 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
2677 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
2681 if (pb->eof_reached) {
2682 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
2689 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
2691 return index < count - 1;
2694 /* Compute the samples value for the stsc entry at the given index. */
2695 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
2699 if (mov_stsc_index_valid(index, sc->stsc_count))
2700 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
2702 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
2703 av_assert0(sc->stsc_data[index].first <= sc->chunk_count);
2704 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
2707 return sc->stsc_data[index].count * (int64_t)chunk_count;
2710 static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2713 MOVStreamContext *sc;
2714 unsigned i, entries;
2716 if (c->fc->nb_streams < 1)
2718 st = c->fc->streams[c->fc->nb_streams-1];
2721 avio_rb32(pb); // version + flags
2723 entries = avio_rb32(pb);
2725 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
2726 av_free(sc->stps_data);
2728 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
2730 return AVERROR(ENOMEM);
2732 for (i = 0; i < entries && !pb->eof_reached; i++) {
2733 sc->stps_data[i] = avio_rb32(pb);
2738 if (pb->eof_reached) {
2739 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
2746 static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2749 MOVStreamContext *sc;
2750 unsigned int i, entries;
2752 if (c->fc->nb_streams < 1)
2754 st = c->fc->streams[c->fc->nb_streams-1];
2757 avio_r8(pb); /* version */
2758 avio_rb24(pb); /* flags */
2760 entries = avio_rb32(pb);
2762 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
2766 sc->keyframe_absent = 1;
2767 if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
2768 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2772 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
2773 if (entries >= UINT_MAX / sizeof(int))
2774 return AVERROR_INVALIDDATA;
2775 av_freep(&sc->keyframes);
2776 sc->keyframe_count = 0;
2777 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
2779 return AVERROR(ENOMEM);
2781 for (i = 0; i < entries && !pb->eof_reached; i++) {
2782 sc->keyframes[i] = avio_rb32(pb);
2785 sc->keyframe_count = i;
2787 if (pb->eof_reached) {
2788 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
2795 static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2798 MOVStreamContext *sc;
2799 unsigned int i, entries, sample_size, field_size, num_bytes;
2804 if (c->fc->nb_streams < 1)
2806 st = c->fc->streams[c->fc->nb_streams-1];
2809 avio_r8(pb); /* version */
2810 avio_rb24(pb); /* flags */
2812 if (atom.type == MKTAG('s','t','s','z')) {
2813 sample_size = avio_rb32(pb);
2814 if (!sc->sample_size) /* do not overwrite value computed in stsd */
2815 sc->sample_size = sample_size;
2816 sc->stsz_sample_size = sample_size;
2820 avio_rb24(pb); /* reserved */
2821 field_size = avio_r8(pb);
2823 entries = avio_rb32(pb);
2825 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
2827 sc->sample_count = entries;
2831 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
2832 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
2833 return AVERROR_INVALIDDATA;
2838 if (entries >= (UINT_MAX - 4) / field_size)
2839 return AVERROR_INVALIDDATA;
2840 if (sc->sample_sizes)
2841 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
2842 av_free(sc->sample_sizes);
2843 sc->sample_count = 0;
2844 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
2845 if (!sc->sample_sizes)
2846 return AVERROR(ENOMEM);
2848 num_bytes = (entries*field_size+4)>>3;
2850 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
2852 av_freep(&sc->sample_sizes);
2853 return AVERROR(ENOMEM);
2856 ret = ffio_read_size(pb, buf, num_bytes);
2858 av_freep(&sc->sample_sizes);
2860 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
2864 init_get_bits(&gb, buf, 8*num_bytes);
2866 for (i = 0; i < entries && !pb->eof_reached; i++) {
2867 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
2868 sc->data_size += sc->sample_sizes[i];
2871 sc->sample_count = i;
2875 if (pb->eof_reached) {
2876 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSZ atom\n");
2883 static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2886 MOVStreamContext *sc;
2887 unsigned int i, entries, alloc_size = 0;
2889 int64_t total_sample_count=0;
2891 if (c->fc->nb_streams < 1)
2893 st = c->fc->streams[c->fc->nb_streams-1];
2896 avio_r8(pb); /* version */
2897 avio_rb24(pb); /* flags */
2898 entries = avio_rb32(pb);
2900 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
2901 c->fc->nb_streams-1, entries);
2904 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
2905 av_freep(&sc->stts_data);
2907 if (entries >= INT_MAX / sizeof(*sc->stts_data))
2908 return AVERROR(ENOMEM);
2910 for (i = 0; i < entries && !pb->eof_reached; i++) {
2911 int sample_duration;
2912 unsigned int sample_count;
2913 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
2914 MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
2915 min_entries * sizeof(*sc->stts_data));
2917 av_freep(&sc->stts_data);
2919 return AVERROR(ENOMEM);
2921 sc->stts_count = min_entries;
2922 sc->stts_data = stts_data;
2924 sample_count=avio_rb32(pb);
2925 sample_duration = avio_rb32(pb);
2927 sc->stts_data[i].count= sample_count;
2928 sc->stts_data[i].duration= sample_duration;
2930 av_log(c->fc, AV_LOG_TRACE, "sample_count=%d, sample_duration=%d\n",
2931 sample_count, sample_duration);
2933 duration+=(int64_t)sample_duration*(uint64_t)sample_count;
2934 total_sample_count+=sample_count;
2940 duration <= INT64_MAX - sc->duration_for_fps &&
2941 total_sample_count <= INT_MAX - sc->nb_frames_for_fps
2943 sc->duration_for_fps += duration;
2944 sc->nb_frames_for_fps += total_sample_count;
2947 if (pb->eof_reached) {
2948 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
2952 st->nb_frames= total_sample_count;
2954 st->duration= FFMIN(st->duration, duration);
2955 sc->track_end = duration;
2959 static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2962 MOVStreamContext *sc;
2965 if (c->fc->nb_streams < 1)
2967 st = c->fc->streams[c->fc->nb_streams - 1];
2970 avio_r8(pb); /* version */
2971 avio_rb24(pb); /* flags */
2972 entries = atom.size - 4;
2974 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
2975 c->fc->nb_streams - 1, entries);
2978 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
2979 av_freep(&sc->sdtp_data);
2982 sc->sdtp_data = av_mallocz(entries);
2984 return AVERROR(ENOMEM);
2986 for (i = 0; i < entries && !pb->eof_reached; i++)
2987 sc->sdtp_data[i] = avio_r8(pb);
2993 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
2996 if (duration == INT_MIN) {
2997 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3000 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3004 static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3007 MOVStreamContext *sc;
3008 unsigned int i, entries, ctts_count = 0;
3010 if (c->fc->nb_streams < 1)
3012 st = c->fc->streams[c->fc->nb_streams-1];
3015 avio_r8(pb); /* version */
3016 avio_rb24(pb); /* flags */
3017 entries = avio_rb32(pb);
3019 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3023 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3024 return AVERROR_INVALIDDATA;
3025 av_freep(&sc->ctts_data);
3026 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3028 return AVERROR(ENOMEM);
3030 for (i = 0; i < entries && !pb->eof_reached; i++) {
3031 int count =avio_rb32(pb);
3032 int duration =avio_rb32(pb);
3035 av_log(c->fc, AV_LOG_TRACE,
3036 "ignoring CTTS entry with count=%d duration=%d\n",
3041 add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3044 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3047 if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3048 av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3049 av_freep(&sc->ctts_data);
3055 mov_update_dts_shift(sc, duration, c->fc);
3058 sc->ctts_count = ctts_count;
3060 if (pb->eof_reached) {
3061 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3065 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3070 static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3073 MOVStreamContext *sc;
3074 unsigned int i, entries;
3076 uint32_t grouping_type;
3078 if (c->fc->nb_streams < 1)
3080 st = c->fc->streams[c->fc->nb_streams-1];
3083 version = avio_r8(pb); /* version */
3084 avio_rb24(pb); /* flags */
3085 grouping_type = avio_rl32(pb);
3086 if (grouping_type != MKTAG( 'r','a','p',' '))
3087 return 0; /* only support 'rap ' grouping */
3089 avio_rb32(pb); /* grouping_type_parameter */
3091 entries = avio_rb32(pb);
3095 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP atom\n");
3096 av_free(sc->rap_group);
3097 sc->rap_group_count = 0;
3098 sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group));
3100 return AVERROR(ENOMEM);
3102 for (i = 0; i < entries && !pb->eof_reached; i++) {
3103 sc->rap_group[i].count = avio_rb32(pb); /* sample_count */
3104 sc->rap_group[i].index = avio_rb32(pb); /* group_description_index */
3107 sc->rap_group_count = i;
3109 if (pb->eof_reached) {
3110 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3118 * Get ith edit list entry (media time, duration).
3120 static int get_edit_list_entry(MOVContext *mov,
3121 const MOVStreamContext *msc,
3122 unsigned int edit_list_index,
3123 int64_t *edit_list_media_time,
3124 int64_t *edit_list_duration,
3125 int64_t global_timescale)
3127 if (edit_list_index == msc->elst_count) {
3130 *edit_list_media_time = msc->elst_data[edit_list_index].time;
3131 *edit_list_duration = msc->elst_data[edit_list_index].duration;
3133 /* duration is in global timescale units;convert to msc timescale */
3134 if (global_timescale == 0) {
3135 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3138 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3144 * Find the closest previous frame to the timestamp_pts, in e_old index
3145 * entries. Searching for just any frame / just key frames can be controlled by
3146 * last argument 'flag'.
3147 * Note that if ctts_data is not NULL, we will always search for a key frame
3148 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3149 * return the first frame of the video.
3151 * Here the timestamp_pts is considered to be a presentation timestamp and
3152 * the timestamp of index entries are considered to be decoding timestamps.
3154 * Returns 0 if successful in finding a frame, else returns -1.
3155 * Places the found index corresponding output arg.
3157 * If ctts_old is not NULL, then refines the searched entry by searching
3158 * backwards from the found timestamp, to find the frame with correct PTS.
3160 * Places the found ctts_index and ctts_sample in corresponding output args.
3162 static int find_prev_closest_index(AVStream *st,
3163 AVIndexEntry *e_old,
3167 int64_t timestamp_pts,
3170 int64_t* ctts_index,
3171 int64_t* ctts_sample)
3173 MOVStreamContext *msc = st->priv_data;
3174 AVIndexEntry *e_keep = st->index_entries;
3175 int nb_keep = st->nb_index_entries;
3177 int64_t index_ctts_count;
3181 // If dts_shift > 0, then all the index timestamps will have to be offset by
3182 // at least dts_shift amount to obtain PTS.
3183 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3184 if (msc->dts_shift > 0) {
3185 timestamp_pts -= msc->dts_shift;
3188 st->index_entries = e_old;
3189 st->nb_index_entries = nb_old;
3190 *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3192 // Keep going backwards in the index entries until the timestamp is the same.
3194 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3196 if ((flag & AVSEEK_FLAG_ANY) ||
3197 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3203 // If we have CTTS then refine the search, by searching backwards over PTS
3204 // computed by adding corresponding CTTS durations to index timestamps.
3205 if (ctts_data && *index >= 0) {
3206 av_assert0(ctts_index);
3207 av_assert0(ctts_sample);
3208 // Find out the ctts_index for the found frame.
3211 for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3212 if (*ctts_index < ctts_count) {
3214 if (ctts_data[*ctts_index].count == *ctts_sample) {
3221 while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3222 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3223 // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3224 // compensated by dts_shift above.
3225 if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3226 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3231 if (*ctts_sample == 0) {
3233 if (*ctts_index >= 0)
3234 *ctts_sample = ctts_data[*ctts_index].count - 1;
3241 /* restore AVStream state*/
3242 st->index_entries = e_keep;
3243 st->nb_index_entries = nb_keep;
3244 return *index >= 0 ? 0 : -1;
3248 * Add index entry with the given values, to the end of st->index_entries.
3249 * Returns the new size st->index_entries if successful, else returns -1.
3251 * This function is similar to ff_add_index_entry in libavformat/utils.c
3252 * except that here we are always unconditionally adding an index entry to
3253 * the end, instead of searching the entries list and skipping the add if
3254 * there is an existing entry with the same timestamp.
3255 * This is needed because the mov_fix_index calls this func with the same
3256 * unincremented timestamp for successive discarded frames.
3258 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3259 int size, int distance, int flags)
3261 AVIndexEntry *entries, *ie;
3263 const size_t min_size_needed = (st->nb_index_entries + 1) * sizeof(AVIndexEntry);
3265 // Double the allocation each time, to lower memory fragmentation.
3266 // Another difference from ff_add_index_entry function.
3267 const size_t requested_size =
3268 min_size_needed > st->index_entries_allocated_size ?
3269 FFMAX(min_size_needed, 2 * st->index_entries_allocated_size) :
3272 if((unsigned)st->nb_index_entries + 1 >= UINT_MAX / sizeof(AVIndexEntry))
3275 entries = av_fast_realloc(st->index_entries,
3276 &st->index_entries_allocated_size,
3281 st->index_entries= entries;
3283 index= st->nb_index_entries++;
3284 ie= &entries[index];
3287 ie->timestamp = timestamp;
3288 ie->min_distance= distance;
3295 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3296 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3298 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3299 int64_t* frame_duration_buffer,
3300 int frame_duration_buffer_size) {
3302 av_assert0(end_index >= 0 && end_index <= st->nb_index_entries);
3303 for (i = 0; i < frame_duration_buffer_size; i++) {
3304 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3305 st->index_entries[end_index - 1 - i].timestamp = end_ts;
3310 * Append a new ctts entry to ctts_data.
3311 * Returns the new ctts_count if successful, else returns -1.
3313 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3314 int count, int duration)
3316 MOVStts *ctts_buf_new;
3317 const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVStts);
3318 const size_t requested_size =
3319 min_size_needed > *allocated_size ?
3320 FFMAX(min_size_needed, 2 * (*allocated_size)) :
3323 if((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
3326 ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3331 *ctts_data = ctts_buf_new;
3333 ctts_buf_new[*ctts_count].count = count;
3334 ctts_buf_new[*ctts_count].duration = duration;
3336 *ctts_count = (*ctts_count) + 1;
3340 #define MAX_REORDER_DELAY 16
3341 static void mov_estimate_video_delay(MOVContext *c, AVStream* st) {
3342 MOVStreamContext *msc = st->priv_data;
3345 int ctts_sample = 0;
3346 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3348 int j, r, num_swaps;
3350 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3351 pts_buf[j] = INT64_MIN;
3353 if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3354 st->codecpar->codec_id == AV_CODEC_ID_H264) {
3355 st->codecpar->video_delay = 0;
3356 for(ind = 0; ind < st->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3357 // Point j to the last elem of the buffer and insert the current pts there.
3359 buf_start = (buf_start + 1);
3360 if (buf_start == MAX_REORDER_DELAY + 1)
3363 pts_buf[j] = st->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3365 // The timestamps that are already in the sorted buffer, and are greater than the
3366 // current pts, are exactly the timestamps that need to be buffered to output PTS
3367 // in correct sorted order.
3368 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3369 // can be computed as the maximum no. of swaps any particular timestamp needs to
3370 // go through, to keep this buffer in sorted order.
3372 while (j != buf_start) {
3374 if (r < 0) r = MAX_REORDER_DELAY;
3375 if (pts_buf[j] < pts_buf[r]) {
3376 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3383 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3386 if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3391 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3392 st->codecpar->video_delay, st->index);
3396 static void mov_current_sample_inc(MOVStreamContext *sc)
3398 sc->current_sample++;
3399 sc->current_index++;
3400 if (sc->index_ranges &&
3401 sc->current_index >= sc->current_index_range->end &&
3402 sc->current_index_range->end) {
3403 sc->current_index_range++;
3404 sc->current_index = sc->current_index_range->start;
3408 static void mov_current_sample_dec(MOVStreamContext *sc)
3410 sc->current_sample--;
3411 sc->current_index--;
3412 if (sc->index_ranges &&
3413 sc->current_index < sc->current_index_range->start &&
3414 sc->current_index_range > sc->index_ranges) {
3415 sc->current_index_range--;
3416 sc->current_index = sc->current_index_range->end - 1;
3420 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3424 sc->current_sample = current_sample;
3425 sc->current_index = current_sample;
3426 if (!sc->index_ranges) {
3430 for (sc->current_index_range = sc->index_ranges;
3431 sc->current_index_range->end;
3432 sc->current_index_range++) {
3433 range_size = sc->current_index_range->end - sc->current_index_range->start;
3434 if (range_size > current_sample) {
3435 sc->current_index = sc->current_index_range->start + current_sample;
3438 current_sample -= range_size;
3443 * Fix st->index_entries, so that it contains only the entries (and the entries
3444 * which are needed to decode them) that fall in the edit list time ranges.
3445 * Also fixes the timestamps of the index entries to match the timeline
3446 * specified the edit lists.
3448 static void mov_fix_index(MOVContext *mov, AVStream *st)
3450 MOVStreamContext *msc = st->priv_data;
3451 AVIndexEntry *e_old = st->index_entries;
3452 int nb_old = st->nb_index_entries;
3453 const AVIndexEntry *e_old_end = e_old + nb_old;
3454 const AVIndexEntry *current = NULL;
3455 MOVStts *ctts_data_old = msc->ctts_data;
3456 int64_t ctts_index_old = 0;
3457 int64_t ctts_sample_old = 0;
3458 int64_t ctts_count_old = msc->ctts_count;
3459 int64_t edit_list_media_time = 0;
3460 int64_t edit_list_duration = 0;
3461 int64_t frame_duration = 0;
3462 int64_t edit_list_dts_counter = 0;
3463 int64_t edit_list_dts_entry_end = 0;
3464 int64_t edit_list_start_ctts_sample = 0;
3466 int64_t curr_ctts = 0;
3467 int64_t empty_edits_sum_duration = 0;
3468 int64_t edit_list_index = 0;
3471 int64_t start_dts = 0;
3472 int64_t edit_list_start_encountered = 0;
3473 int64_t search_timestamp = 0;
3474 int64_t* frame_duration_buffer = NULL;
3475 int num_discarded_begin = 0;
3476 int first_non_zero_audio_edit = -1;
3477 int packet_skip_samples = 0;
3478 MOVIndexRange *current_index_range;
3480 int found_keyframe_after_edit = 0;
3481 int found_non_empty_edit = 0;
3483 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
3487 // allocate the index ranges array
3488 msc->index_ranges = av_malloc((msc->elst_count + 1) * sizeof(msc->index_ranges[0]));
3489 if (!msc->index_ranges) {
3490 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
3493 msc->current_index_range = msc->index_ranges;
3494 current_index_range = msc->index_ranges - 1;
3496 // Clean AVStream from traces of old index
3497 st->index_entries = NULL;
3498 st->index_entries_allocated_size = 0;
3499 st->nb_index_entries = 0;
3501 // Clean ctts fields of MOVStreamContext
3502 msc->ctts_data = NULL;
3503 msc->ctts_count = 0;
3504 msc->ctts_index = 0;
3505 msc->ctts_sample = 0;
3506 msc->ctts_allocated_size = 0;
3508 // Reinitialize min_corrected_pts so that it can be computed again.
3509 msc->min_corrected_pts = -1;
3511 // If the dts_shift is positive (in case of negative ctts values in mov),
3512 // then negate the DTS by dts_shift
3513 if (msc->dts_shift > 0) {
3514 edit_list_dts_entry_end -= msc->dts_shift;
3515 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
3518 start_dts = edit_list_dts_entry_end;
3520 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
3521 &edit_list_duration, mov->time_scale)) {
3522 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
3523 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
3525 edit_list_dts_counter = edit_list_dts_entry_end;
3526 edit_list_dts_entry_end += edit_list_duration;
3527 num_discarded_begin = 0;
3528 if (!found_non_empty_edit && edit_list_media_time == -1) {
3529 empty_edits_sum_duration += edit_list_duration;
3532 found_non_empty_edit = 1;
3534 // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
3535 // according to the edit list below.
3536 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3537 if (first_non_zero_audio_edit < 0) {
3538 first_non_zero_audio_edit = 1;
3540 first_non_zero_audio_edit = 0;
3543 if (first_non_zero_audio_edit > 0)
3544 st->skip_samples = msc->start_pad = 0;
3547 // While reordering frame index according to edit list we must handle properly
3548 // the scenario when edit list entry starts from none key frame.
3549 // We find closest previous key frame and preserve it and consequent frames in index.
3550 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
3551 search_timestamp = edit_list_media_time;
3552 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3553 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
3554 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
3555 // edit_list_media_time to cover the decoder delay.
3556 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
3559 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
3560 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3561 av_log(mov->fc, AV_LOG_WARNING,
3562 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
3563 st->index, edit_list_index, search_timestamp);
3564 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
3565 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3566 av_log(mov->fc, AV_LOG_WARNING,
3567 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
3568 st->index, edit_list_index, search_timestamp);
3571 ctts_sample_old = 0;
3574 current = e_old + index;
3575 edit_list_start_ctts_sample = ctts_sample_old;
3577 // Iterate over index and arrange it according to edit list
3578 edit_list_start_encountered = 0;
3579 found_keyframe_after_edit = 0;
3580 for (; current < e_old_end; current++, index++) {
3581 // check if frame outside edit list mark it for discard
3582 frame_duration = (current + 1 < e_old_end) ?
3583 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
3585 flags = current->flags;
3587 // frames (pts) before or after edit list
3588 curr_cts = current->timestamp + msc->dts_shift;
3591 if (ctts_data_old && ctts_index_old < ctts_count_old) {
3592 curr_ctts = ctts_data_old[ctts_index_old].duration;
3593 av_log(mov->fc, AV_LOG_DEBUG, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
3594 curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
3595 curr_cts += curr_ctts;
3597 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
3598 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3599 &msc->ctts_allocated_size,
3600 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3601 ctts_data_old[ctts_index_old].duration) == -1) {
3602 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3604 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3605 ctts_data_old[ctts_index_old].duration);
3609 ctts_sample_old = 0;
3610 edit_list_start_ctts_sample = 0;
3614 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
3615 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
3616 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
3617 first_non_zero_audio_edit > 0) {
3618 packet_skip_samples = edit_list_media_time - curr_cts;
3619 st->skip_samples += packet_skip_samples;
3621 // Shift the index entry timestamp by packet_skip_samples to be correct.
3622 edit_list_dts_counter -= packet_skip_samples;
3623 if (edit_list_start_encountered == 0) {
3624 edit_list_start_encountered = 1;
3625 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
3626 // discarded packets.
3627 if (frame_duration_buffer) {
3628 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3629 frame_duration_buffer, num_discarded_begin);
3630 av_freep(&frame_duration_buffer);
3634 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
3636 flags |= AVINDEX_DISCARD_FRAME;
3637 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
3639 if (edit_list_start_encountered == 0) {
3640 num_discarded_begin++;
3641 frame_duration_buffer = av_realloc(frame_duration_buffer,
3642 num_discarded_begin * sizeof(int64_t));
3643 if (!frame_duration_buffer) {
3644 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
3647 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
3649 // Increment skip_samples for the first non-zero audio edit list
3650 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3651 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
3652 st->skip_samples += frame_duration;
3657 if (msc->min_corrected_pts < 0) {
3658 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
3660 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
3662 if (edit_list_start_encountered == 0) {
3663 edit_list_start_encountered = 1;
3664 // Make timestamps strictly monotonically increasing by rewriting timestamps for
3665 // discarded packets.
3666 if (frame_duration_buffer) {
3667 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3668 frame_duration_buffer, num_discarded_begin);
3669 av_freep(&frame_duration_buffer);
3674 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
3675 current->min_distance, flags) == -1) {
3676 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
3680 // Update the index ranges array
3681 if (current_index_range < msc->index_ranges || index != current_index_range->end) {
3682 current_index_range++;
3683 current_index_range->start = index;
3685 current_index_range->end = index + 1;
3687 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
3688 if (edit_list_start_encountered > 0) {
3689 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
3692 // Break when found first key frame after edit entry completion
3693 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
3694 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
3695 if (ctts_data_old) {
3696 // If we have CTTS and this is the first keyframe after edit elist,
3697 // wait for one more, because there might be trailing B-frames after this I-frame
3698 // that do belong to the edit.
3699 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
3700 found_keyframe_after_edit = 1;
3703 if (ctts_sample_old != 0) {
3704 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3705 &msc->ctts_allocated_size,
3706 ctts_sample_old - edit_list_start_ctts_sample,
3707 ctts_data_old[ctts_index_old].duration) == -1) {
3708 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3709 ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
3710 ctts_data_old[ctts_index_old].duration);
3719 // If there are empty edits, then msc->min_corrected_pts might be positive
3720 // intentionally. So we subtract the sum duration of emtpy edits here.
3721 msc->min_corrected_pts -= empty_edits_sum_duration;
3723 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
3724 // dts by that amount to make the first pts zero.
3725 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
3726 if (msc->min_corrected_pts > 0) {
3727 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
3728 for (i = 0; i < st->nb_index_entries; ++i) {
3729 st->index_entries[i].timestamp -= msc->min_corrected_pts;
3733 // Start time should be equal to zero or the duration of any empty edits.
3734 st->start_time = empty_edits_sum_duration;
3736 // Update av stream length, if it ends up shorter than the track's media duration
3737 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
3738 msc->start_pad = st->skip_samples;
3740 // Free the old index and the old CTTS structures
3742 av_free(ctts_data_old);
3743 av_freep(&frame_duration_buffer);
3745 // Null terminate the index ranges array
3746 current_index_range++;
3747 current_index_range->start = 0;
3748 current_index_range->end = 0;
3749 msc->current_index = msc->index_ranges[0].start;
3752 static void mov_build_index(MOVContext *mov, AVStream *st)
3754 MOVStreamContext *sc = st->priv_data;
3755 int64_t current_offset;
3756 int64_t current_dts = 0;
3757 unsigned int stts_index = 0;
3758 unsigned int stsc_index = 0;
3759 unsigned int stss_index = 0;
3760 unsigned int stps_index = 0;
3762 uint64_t stream_size = 0;
3763 MOVStts *ctts_data_old = sc->ctts_data;
3764 unsigned int ctts_count_old = sc->ctts_count;
3766 if (sc->elst_count) {
3767 int i, edit_start_index = 0, multiple_edits = 0;
3768 int64_t empty_duration = 0; // empty duration of the first edit list entry
3769 int64_t start_time = 0; // start time of the media
3771 for (i = 0; i < sc->elst_count; i++) {
3772 const MOVElst *e = &sc->elst_data[i];
3773 if (i == 0 && e->time == -1) {
3774 /* if empty, the first entry is the start time of the stream
3775 * relative to the presentation itself */
3776 empty_duration = e->duration;
3777 edit_start_index = 1;
3778 } else if (i == edit_start_index && e->time >= 0) {
3779 start_time = e->time;
3785 if (multiple_edits && !mov->advanced_editlist)
3786 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
3787 "Use -advanced_editlist to correctly decode otherwise "
3788 "a/v desync might occur\n");
3790 /* adjust first dts according to edit list */
3791 if ((empty_duration || start_time) && mov->time_scale > 0) {
3793 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
3794 sc->time_offset = start_time - empty_duration;
3795 sc->min_corrected_pts = start_time;
3796 if (!mov->advanced_editlist)
3797 current_dts = -sc->time_offset;
3800 if (!multiple_edits && !mov->advanced_editlist &&
3801 st->codecpar->codec_id == AV_CODEC_ID_AAC && start_time > 0)
3802 sc->start_pad = start_time;
3805 /* only use old uncompressed audio chunk demuxing when stts specifies it */
3806 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3807 sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
3808 unsigned int current_sample = 0;
3809 unsigned int stts_sample = 0;
3810 unsigned int sample_size;
3811 unsigned int distance = 0;
3812 unsigned int rap_group_index = 0;
3813 unsigned int rap_group_sample = 0;
3814 int64_t last_dts = 0;
3815 int64_t dts_correction = 0;
3816 int rap_group_present = sc->rap_group_count && sc->rap_group;
3817 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
3819 current_dts -= sc->dts_shift;
3820 last_dts = current_dts;
3822 if (!sc->sample_count || st->nb_index_entries)
3824 if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
3826 if (av_reallocp_array(&st->index_entries,
3827 st->nb_index_entries + sc->sample_count,
3828 sizeof(*st->index_entries)) < 0) {
3829 st->nb_index_entries = 0;
3832 st->index_entries_allocated_size = (st->nb_index_entries + sc->sample_count) * sizeof(*st->index_entries);
3834 if (ctts_data_old) {
3835 // Expand ctts entries such that we have a 1-1 mapping with samples
3836 if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
3839 sc->ctts_allocated_size = 0;
3840 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size,
3841 sc->sample_count * sizeof(*sc->ctts_data));
3842 if (!sc->ctts_data) {
3843 av_free(ctts_data_old);
3847 memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
3849 for (i = 0; i < ctts_count_old &&
3850 sc->ctts_count < sc->sample_count; i++)
3851 for (j = 0; j < ctts_data_old[i].count &&
3852 sc->ctts_count < sc->sample_count; j++)
3853 add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
3854 &sc->ctts_allocated_size, 1,
3855 ctts_data_old[i].duration);
3856 av_free(ctts_data_old);
3859 for (i = 0; i < sc->chunk_count; i++) {
3860 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
3861 current_offset = sc->chunk_offsets[i];
3862 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3863 i + 1 == sc->stsc_data[stsc_index + 1].first)
3866 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
3867 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
3868 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
3869 sc->stsz_sample_size = sc->sample_size;
3871 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
3872 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
3873 sc->stsz_sample_size = sc->sample_size;
3876 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
3878 if (current_sample >= sc->sample_count) {
3879 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
3883 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
3885 if (stss_index + 1 < sc->keyframe_count)
3887 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
3889 if (stps_index + 1 < sc->stps_count)
3892 if (rap_group_present && rap_group_index < sc->rap_group_count) {
3893 if (sc->rap_group[rap_group_index].index > 0)
3895 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
3896 rap_group_sample = 0;
3900 if (sc->keyframe_absent
3902 && !rap_group_present
3903 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
3907 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
3908 if (sc->pseudo_stream_id == -1 ||
3909 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
3911 if (sample_size > 0x3FFFFFFF) {
3912 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
3915 e = &st->index_entries[st->nb_index_entries++];
3916 e->pos = current_offset;
3917 e->timestamp = current_dts;
3918 e->size = sample_size;
3919 e->min_distance = distance;
3920 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
3921 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
3922 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
3923 current_offset, current_dts, sample_size, distance, keyframe);
3924 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries < 100)
3925 ff_rfps_add_frame(mov->fc, st, current_dts);
3928 current_offset += sample_size;
3929 stream_size += sample_size;
3931 /* A negative sample duration is invalid based on the spec,
3932 * but some samples need it to correct the DTS. */
3933 if (sc->stts_data[stts_index].duration < 0) {
3934 av_log(mov->fc, AV_LOG_WARNING,
3935 "Invalid SampleDelta %d in STTS, at %d st:%d\n",
3936 sc->stts_data[stts_index].duration, stts_index,
3938 dts_correction += sc->stts_data[stts_index].duration - 1;
3939 sc->stts_data[stts_index].duration = 1;
3941 current_dts += sc->stts_data[stts_index].duration;
3942 if (!dts_correction || current_dts + dts_correction > last_dts) {
3943 current_dts += dts_correction;
3946 /* Avoid creating non-monotonous DTS */
3947 dts_correction += current_dts - last_dts - 1;
3948 current_dts = last_dts + 1;
3950 last_dts = current_dts;
3954 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
3960 if (st->duration > 0)
3961 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
3963 unsigned chunk_samples, total = 0;
3965 if (!sc->chunk_count)
3968 // compute total chunk count
3969 for (i = 0; i < sc->stsc_count; i++) {
3970 unsigned count, chunk_count;
3972 chunk_samples = sc->stsc_data[i].count;
3973 if (i != sc->stsc_count - 1 &&
3974 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
3975 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
3979 if (sc->samples_per_frame >= 160) { // gsm
3980 count = chunk_samples / sc->samples_per_frame;
3981 } else if (sc->samples_per_frame > 1) {
3982 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
3983 count = (chunk_samples+samples-1) / samples;
3985 count = (chunk_samples+1023) / 1024;
3988 if (mov_stsc_index_valid(i, sc->stsc_count))
3989 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
3991 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
3992 total += chunk_count * count;
3995 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
3996 if (total >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
3998 if (av_reallocp_array(&st->index_entries,
3999 st->nb_index_entries + total,
4000 sizeof(*st->index_entries)) < 0) {
4001 st->nb_index_entries = 0;
4004 st->index_entries_allocated_size = (st->nb_index_entries + total) * sizeof(*st->index_entries);
4007 for (i = 0; i < sc->chunk_count; i++) {
4008 current_offset = sc->chunk_offsets[i];
4009 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4010 i + 1 == sc->stsc_data[stsc_index + 1].first)
4012 chunk_samples = sc->stsc_data[stsc_index].count;
4014 while (chunk_samples > 0) {
4016 unsigned size, samples;
4018 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4019 avpriv_request_sample(mov->fc,
4020 "Zero bytes per frame, but %d samples per frame",
4021 sc->samples_per_frame);
4025 if (sc->samples_per_frame >= 160) { // gsm
4026 samples = sc->samples_per_frame;
4027 size = sc->bytes_per_frame;
4029 if (sc->samples_per_frame > 1) {
4030 samples = FFMIN((1024 / sc->samples_per_frame)*
4031 sc->samples_per_frame, chunk_samples);
4032 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
4034 samples = FFMIN(1024, chunk_samples);
4035 size = samples * sc->sample_size;
4039 if (st->nb_index_entries >= total) {
4040 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4043 if (size > 0x3FFFFFFF) {
4044 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4047 e = &st->index_entries[st->nb_index_entries++];
4048 e->pos = current_offset;
4049 e->timestamp = current_dts;
4051 e->min_distance = 0;
4052 e->flags = AVINDEX_KEYFRAME;
4053 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4054 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4057 current_offset += size;
4058 current_dts += samples;
4059 chunk_samples -= samples;
4064 if (!mov->ignore_editlist && mov->advanced_editlist) {
4065 // Fix index according to edit lists.
4066 mov_fix_index(mov, st);
4069 // Update start time of the stream.
4070 if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries > 0) {
4071 st->start_time = st->index_entries[0].timestamp + sc->dts_shift;
4072 if (sc->ctts_data) {
4073 st->start_time += sc->ctts_data[0].duration;
4077 mov_estimate_video_delay(mov, st);
4080 static int test_same_origin(const char *src, const char *ref) {
4090 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4091 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4093 if (strlen(src) == 0) {
4095 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4096 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4097 strlen(src_host) + 1 >= sizeof(src_host) ||
4098 strlen(ref_host) + 1 >= sizeof(ref_host)) {
4100 } else if (strcmp(src_proto, ref_proto) ||
4101 strcmp(src_auth, ref_auth) ||
4102 strcmp(src_host, ref_host) ||
4103 src_port != ref_port) {
4109 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4111 /* try relative path, we do not try the absolute because it can leak information about our
4112 system to an attacker */
4113 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4114 char filename[1025];
4115 const char *src_path;
4118 /* find a source dir */
4119 src_path = strrchr(src, '/');
4125 /* find a next level down to target */
4126 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4127 if (ref->path[l] == '/') {
4128 if (i == ref->nlvl_to - 1)
4134 /* compose filename if next level down to target was found */
4135 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4136 memcpy(filename, src, src_path - src);
4137 filename[src_path - src] = 0;
4139 for (i = 1; i < ref->nlvl_from; i++)
4140 av_strlcat(filename, "../", sizeof(filename));
4142 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4143 if (!c->use_absolute_path) {
4144 int same_origin = test_same_origin(src, filename);
4147 av_log(c->fc, AV_LOG_ERROR,
4148 "Reference with mismatching origin, %s not tried for security reasons, "
4149 "set demuxer option use_absolute_path to allow it anyway\n",
4151 return AVERROR(ENOENT);
4154 if(strstr(ref->path + l + 1, "..") ||
4155 strstr(ref->path + l + 1, ":") ||
4156 (ref->nlvl_from > 1 && same_origin < 0) ||
4157 (filename[0] == '/' && src_path == src))
4158 return AVERROR(ENOENT);
4161 if (strlen(filename) + 1 == sizeof(filename))
4162 return AVERROR(ENOENT);
4163 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4166 } else if (c->use_absolute_path) {
4167 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4168 "this is a possible security issue\n");
4169 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4172 av_log(c->fc, AV_LOG_ERROR,
4173 "Absolute path %s not tried for security reasons, "
4174 "set demuxer option use_absolute_path to allow absolute paths\n",
4178 return AVERROR(ENOENT);
4181 static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
4183 if (sc->time_scale <= 0) {
4184 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4185 sc->time_scale = c->time_scale;
4186 if (sc->time_scale <= 0)
4191 static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4194 MOVStreamContext *sc;
4197 st = avformat_new_stream(c->fc, NULL);
4198 if (!st) return AVERROR(ENOMEM);
4200 sc = av_mallocz(sizeof(MOVStreamContext));
4201 if (!sc) return AVERROR(ENOMEM);
4204 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
4205 sc->ffindex = st->index;
4206 c->trak_index = st->index;
4208 if ((ret = mov_read_default(c, pb, atom)) < 0)
4213 // Here stsc refers to a chunk not described in stco. This is technically invalid,
4214 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4215 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4217 av_freep(&sc->stsc_data);
4221 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4222 (!sc->sample_size && !sc->sample_count))) ||
4223 (!sc->chunk_count && sc->sample_count)) {
4224 av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4228 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4229 av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4231 return AVERROR_INVALIDDATA;
4234 fix_timescale(c, sc);
4236 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4238 mov_build_index(c, st);
4240 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4241 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4242 if (c->enable_drefs) {
4243 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4244 av_log(c->fc, AV_LOG_ERROR,
4245 "stream %d, error opening alias: path='%s', dir='%s', "
4246 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4247 st->index, dref->path, dref->dir, dref->filename,
4248 dref->volume, dref->nlvl_from, dref->nlvl_to);
4250 av_log(c->fc, AV_LOG_WARNING,
4251 "Skipped opening external track: "
4252 "stream %d, alias: path='%s', dir='%s', "
4253 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4254 "Set enable_drefs to allow this.\n",
4255 st->index, dref->path, dref->dir, dref->filename,
4256 dref->volume, dref->nlvl_from, dref->nlvl_to);
4260 sc->pb_is_copied = 1;
4263 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4264 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4265 sc->height && sc->width &&
4266 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4267 st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4268 ((double)st->codecpar->width * sc->height), INT_MAX);
4271 #if FF_API_R_FRAME_RATE
4272 if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4273 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
4274 sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4278 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4279 if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4280 TAG_IS_AVCI(st->codecpar->codec_tag)) {
4281 ret = ff_generate_avci_extradata(st);
4286 switch (st->codecpar->codec_id) {
4287 #if CONFIG_H261_DECODER
4288 case AV_CODEC_ID_H261:
4290 #if CONFIG_H263_DECODER
4291 case AV_CODEC_ID_H263:
4293 #if CONFIG_MPEG4_DECODER
4294 case AV_CODEC_ID_MPEG4:
4296 st->codecpar->width = 0; /* let decoder init width/height */
4297 st->codecpar->height= 0;
4301 // If the duration of the mp3 packets is not constant, then they could need a parser
4302 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4303 && sc->stts_count > 3
4304 && sc->stts_count*10 > st->nb_frames
4305 && sc->time_scale == st->codecpar->sample_rate) {
4306 st->need_parsing = AVSTREAM_PARSE_FULL;
4308 /* Do not need those anymore. */
4309 av_freep(&sc->chunk_offsets);
4310 av_freep(&sc->sample_sizes);
4311 av_freep(&sc->keyframes);
4312 av_freep(&sc->stts_data);
4313 av_freep(&sc->stps_data);
4314 av_freep(&sc->elst_data);
4315 av_freep(&sc->rap_group);
4320 static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4323 c->itunes_metadata = 1;
4324 ret = mov_read_default(c, pb, atom);
4325 c->itunes_metadata = 0;
4329 static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4338 count = avio_rb32(pb);
4339 if (count > UINT_MAX / sizeof(*c->meta_keys) - 1) {
4340 av_log(c->fc, AV_LOG_ERROR,
4341 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
4342 return AVERROR_INVALIDDATA;
4345 c->meta_keys_count = count + 1;
4346 c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
4348 return AVERROR(ENOMEM);
4350 for (i = 1; i <= count; ++i) {
4351 uint32_t key_size = avio_rb32(pb);
4352 uint32_t type = avio_rl32(pb);
4354 av_log(c->fc, AV_LOG_ERROR,
4355 "The key# %"PRIu32" in meta has invalid size:"
4356 "%"PRIu32"\n", i, key_size);
4357 return AVERROR_INVALIDDATA;
4360 if (type != MKTAG('m','d','t','a')) {
4361 avio_skip(pb, key_size);
4363 c->meta_keys[i] = av_mallocz(key_size + 1);
4364 if (!c->meta_keys[i])
4365 return AVERROR(ENOMEM);
4366 avio_read(pb, c->meta_keys[i], key_size);
4372 static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4374 int64_t end = avio_tell(pb) + atom.size;
4375 uint8_t *key = NULL, *val = NULL, *mean = NULL;
4379 MOVStreamContext *sc;
4381 if (c->fc->nb_streams < 1)
4383 st = c->fc->streams[c->fc->nb_streams-1];
4386 for (i = 0; i < 3; i++) {
4390 if (end - avio_tell(pb) <= 12)
4393 len = avio_rb32(pb);
4394 tag = avio_rl32(pb);
4395 avio_skip(pb, 4); // flags
4397 if (len < 12 || len - 12 > end - avio_tell(pb))
4401 if (tag == MKTAG('m', 'e', 'a', 'n'))
4403 else if (tag == MKTAG('n', 'a', 'm', 'e'))
4405 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
4412 *p = av_malloc(len + 1);
4414 ret = AVERROR(ENOMEM);
4417 ret = ffio_read_size(pb, *p, len);
4425 if (mean && key && val) {
4426 if (strcmp(key, "iTunSMPB") == 0) {
4427 int priming, remainder, samples;
4428 if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
4429 if(priming>0 && priming<16384)
4430 sc->start_pad = priming;
4433 if (strcmp(key, "cdec") != 0) {
4434 av_dict_set(&c->fc->metadata, key, val,
4435 AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
4439 av_log(c->fc, AV_LOG_VERBOSE,
4440 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
4443 avio_seek(pb, end, SEEK_SET);
4450 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4452 while (atom.size > 8) {
4456 tag = avio_rl32(pb);
4458 if (tag == MKTAG('h','d','l','r')) {
4459 avio_seek(pb, -8, SEEK_CUR);
4461 return mov_read_default(c, pb, atom);
4467 // return 1 when matrix is identity, 0 otherwise
4468 #define IS_MATRIX_IDENT(matrix) \
4469 ( (matrix)[0][0] == (1 << 16) && \
4470 (matrix)[1][1] == (1 << 16) && \
4471 (matrix)[2][2] == (1 << 30) && \
4472 !(matrix)[0][1] && !(matrix)[0][2] && \
4473 !(matrix)[1][0] && !(matrix)[1][2] && \
4474 !(matrix)[2][0] && !(matrix)[2][1])
4476 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4481 int display_matrix[3][3];
4482 int res_display_matrix[3][3] = { { 0 } };
4484 MOVStreamContext *sc;
4488 if (c->fc->nb_streams < 1)
4490 st = c->fc->streams[c->fc->nb_streams-1];
4493 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4494 // avoids corrupting AVStreams mapped to an earlier tkhd.
4496 return AVERROR_INVALIDDATA;
4498 version = avio_r8(pb);
4499 flags = avio_rb24(pb);
4500 st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
4506 avio_rb32(pb); /* creation time */
4507 avio_rb32(pb); /* modification time */
4509 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4510 avio_rb32(pb); /* reserved */
4512 /* highlevel (considering edits) duration in movie timebase */
4513 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4514 avio_rb32(pb); /* reserved */
4515 avio_rb32(pb); /* reserved */
4517 avio_rb16(pb); /* layer */
4518 avio_rb16(pb); /* alternate group */
4519 avio_rb16(pb); /* volume */
4520 avio_rb16(pb); /* reserved */
4522 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4523 // they're kept in fixed point format through all calculations
4524 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4525 // side data, but the scale factor is not needed to calculate aspect ratio
4526 for (i = 0; i < 3; i++) {
4527 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
4528 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
4529 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
4532 width = avio_rb32(pb); // 16.16 fixed point track width
4533 height = avio_rb32(pb); // 16.16 fixed point track height
4534 sc->width = width >> 16;
4535 sc->height = height >> 16;
4537 // apply the moov display matrix (after the tkhd one)
4538 for (i = 0; i < 3; i++) {
4539 const int sh[3] = { 16, 16, 30 };
4540 for (j = 0; j < 3; j++) {
4541 for (e = 0; e < 3; e++) {
4542 res_display_matrix[i][j] +=
4543 ((int64_t) display_matrix[i][e] *
4544 c->movie_display_matrix[e][j]) >> sh[e];
4549 // save the matrix when it is not the default identity
4550 if (!IS_MATRIX_IDENT(res_display_matrix)) {
4553 av_freep(&sc->display_matrix);
4554 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4555 if (!sc->display_matrix)
4556 return AVERROR(ENOMEM);
4558 for (i = 0; i < 3; i++)
4559 for (j = 0; j < 3; j++)
4560 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4562 #if FF_API_OLD_ROTATE_API
4563 rotate = av_display_rotation_get(sc->display_matrix);
4564 if (!isnan(rotate)) {
4565 char rotate_buf[64];
4567 if (rotate < 0) // for backward compatibility
4569 snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate);
4570 av_dict_set(&st->metadata, "rotate", rotate_buf, 0);
4575 // transform the display width/height according to the matrix
4576 // to keep the same scale, use [width height 1<<16]
4577 if (width && height && sc->display_matrix) {
4578 double disp_transform[2];
4580 for (i = 0; i < 2; i++)
4581 disp_transform[i] = hypot(sc->display_matrix[0 + i],
4582 sc->display_matrix[3 + i]);
4584 if (disp_transform[0] > 0 && disp_transform[1] > 0 &&
4585 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4586 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4587 st->sample_aspect_ratio = av_d2q(
4588 disp_transform[0] / disp_transform[1],
4594 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4596 MOVFragment *frag = &c->fragment;
4597 MOVTrackExt *trex = NULL;
4598 int flags, track_id, i;
4600 avio_r8(pb); /* version */
4601 flags = avio_rb24(pb);
4603 track_id = avio_rb32(pb);
4605 return AVERROR_INVALIDDATA;
4606 for (i = 0; i < c->trex_count; i++)
4607 if (c->trex_data[i].track_id == track_id) {
4608 trex = &c->trex_data[i];
4612 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4615 c->fragment.found_tfhd = 1;
4616 frag->track_id = track_id;
4617 set_frag_stream(&c->frag_index, track_id);
4619 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4620 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4621 frag->moof_offset : frag->implicit_offset;
4622 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4624 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4625 avio_rb32(pb) : trex->duration;
4626 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4627 avio_rb32(pb) : trex->size;
4628 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4629 avio_rb32(pb) : trex->flags;
4630 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4635 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4640 num = atom.size / 4;
4641 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4642 return AVERROR(ENOMEM);
4644 av_free(c->chapter_tracks);
4645 c->chapter_tracks = new_tracks;
4646 c->nb_chapter_tracks = num;
4648 for (i = 0; i < num && !pb->eof_reached; i++)
4649 c->chapter_tracks[i] = avio_rb32(pb);
4654 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4659 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4660 return AVERROR_INVALIDDATA;
4661 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4662 sizeof(*c->trex_data))) < 0) {
4667 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4669 trex = &c->trex_data[c->trex_count++];
4670 avio_r8(pb); /* version */
4671 avio_rb24(pb); /* flags */
4672 trex->track_id = avio_rb32(pb);
4673 trex->stsd_id = avio_rb32(pb);
4674 trex->duration = avio_rb32(pb);
4675 trex->size = avio_rb32(pb);
4676 trex->flags = avio_rb32(pb);
4680 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4682 MOVFragment *frag = &c->fragment;
4683 AVStream *st = NULL;
4684 MOVStreamContext *sc;
4686 MOVFragmentStreamInfo * frag_stream_info;
4687 int64_t base_media_decode_time;
4689 for (i = 0; i < c->fc->nb_streams; i++) {
4690 if (c->fc->streams[i]->id == frag->track_id) {
4691 st = c->fc->streams[i];
4696 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4700 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4702 version = avio_r8(pb);
4703 avio_rb24(pb); /* flags */
4705 base_media_decode_time = avio_rb64(pb);
4707 base_media_decode_time = avio_rb32(pb);
4710 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4711 if (frag_stream_info)
4712 frag_stream_info->tfdt_dts = base_media_decode_time;
4713 sc->track_end = base_media_decode_time;
4718 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4720 MOVFragment *frag = &c->fragment;
4721 AVStream *st = NULL;
4722 MOVStreamContext *sc;
4725 int64_t dts, pts = AV_NOPTS_VALUE;
4726 int data_offset = 0;
4727 unsigned entries, first_sample_flags = frag->flags;
4728 int flags, distance, i;
4729 int64_t prev_dts = AV_NOPTS_VALUE;
4730 int next_frag_index = -1, index_entry_pos;
4731 size_t requested_size;
4732 size_t old_ctts_allocated_size;
4733 AVIndexEntry *new_entries;
4734 MOVFragmentStreamInfo * frag_stream_info;
4736 if (!frag->found_tfhd) {
4737 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4738 return AVERROR_INVALIDDATA;
4741 for (i = 0; i < c->fc->nb_streams; i++) {
4742 if (c->fc->streams[i]->id == frag->track_id) {
4743 st = c->fc->streams[i];
4748 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4752 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4755 // Find the next frag_index index that has a valid index_entry for
4756 // the current track_id.
4758 // A valid index_entry means the trun for the fragment was read
4759 // and it's samples are in index_entries at the given position.
4760 // New index entries will be inserted before the index_entry found.
4761 index_entry_pos = st->nb_index_entries;
4762 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4763 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4764 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4765 next_frag_index = i;
4766 index_entry_pos = frag_stream_info->index_entry;
4770 av_assert0(index_entry_pos <= st->nb_index_entries);
4772 avio_r8(pb); /* version */
4773 flags = avio_rb24(pb);
4774 entries = avio_rb32(pb);
4775 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4777 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4778 return AVERROR_INVALIDDATA;
4779 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4780 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4782 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4783 if (frag_stream_info)
4785 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4786 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4787 pts = frag_stream_info->first_tfra_pts;
4788 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4789 ", using it for pts\n", pts);
4790 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4791 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4792 // pts = frag_stream_info->sidx_pts;
4793 dts = frag_stream_info->sidx_pts - sc->time_offset;
4794 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4795 ", using it for pts\n", pts);
4796 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4797 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4798 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4799 ", using it for dts\n", dts);
4801 dts = sc->track_end - sc->time_offset;
4802 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4803 ", using it for dts\n", dts);
4806 dts = sc->track_end - sc->time_offset;
4807 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4808 ", using it for dts\n", dts);
4810 offset = frag->base_data_offset + data_offset;
4812 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4814 // realloc space for new index entries
4815 if((uint64_t)st->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4816 entries = UINT_MAX / sizeof(AVIndexEntry) - st->nb_index_entries;
4817 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4822 requested_size = (st->nb_index_entries + entries) * sizeof(AVIndexEntry);
4823 new_entries = av_fast_realloc(st->index_entries,
4824 &st->index_entries_allocated_size,
4827 return AVERROR(ENOMEM);
4828 st->index_entries= new_entries;
4830 requested_size = (st->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4831 old_ctts_allocated_size = sc->ctts_allocated_size;
4832 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4835 return AVERROR(ENOMEM);
4836 sc->ctts_data = ctts_data;
4838 // In case there were samples without ctts entries, ensure they get
4839 // zero valued entries. This ensures clips which mix boxes with and
4840 // without ctts entries don't pickup uninitialized data.
4841 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4842 sc->ctts_allocated_size - old_ctts_allocated_size);
4844 if (index_entry_pos < st->nb_index_entries) {
4845 // Make hole in index_entries and ctts_data for new samples
4846 memmove(st->index_entries + index_entry_pos + entries,
4847 st->index_entries + index_entry_pos,
4848 sizeof(*st->index_entries) *
4849 (st->nb_index_entries - index_entry_pos));
4850 memmove(sc->ctts_data + index_entry_pos + entries,
4851 sc->ctts_data + index_entry_pos,
4852 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4853 if (index_entry_pos < sc->current_sample) {
4854 sc->current_sample += entries;
4858 st->nb_index_entries += entries;
4859 sc->ctts_count = st->nb_index_entries;
4861 // Record the index_entry position in frag_index of this fragment
4862 if (frag_stream_info)
4863 frag_stream_info->index_entry = index_entry_pos;
4865 if (index_entry_pos > 0)
4866 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4868 for (i = 0; i < entries && !pb->eof_reached; i++) {
4869 unsigned sample_size = frag->size;
4870 int sample_flags = i ? frag->flags : first_sample_flags;
4871 unsigned sample_duration = frag->duration;
4872 unsigned ctts_duration = 0;
4874 int index_entry_flags = 0;
4876 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4877 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4878 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4879 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4881 mov_update_dts_shift(sc, ctts_duration, c->fc);
4882 if (pts != AV_NOPTS_VALUE) {
4883 dts = pts - sc->dts_shift;
4884 if (flags & MOV_TRUN_SAMPLE_CTS) {
4885 dts -= ctts_duration;
4887 dts -= sc->time_offset;
4889 av_log(c->fc, AV_LOG_DEBUG,
4890 "pts %"PRId64" calculated dts %"PRId64
4891 " sc->dts_shift %d ctts.duration %d"
4892 " sc->time_offset %"PRId64
4893 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4895 sc->dts_shift, ctts_duration,
4896 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4897 pts = AV_NOPTS_VALUE;
4900 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4904 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4905 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4908 index_entry_flags |= AVINDEX_KEYFRAME;
4910 // Fragments can overlap in time. Discard overlapping frames after
4912 if (prev_dts >= dts)
4913 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4915 st->index_entries[index_entry_pos].pos = offset;
4916 st->index_entries[index_entry_pos].timestamp = dts;
4917 st->index_entries[index_entry_pos].size= sample_size;
4918 st->index_entries[index_entry_pos].min_distance= distance;
4919 st->index_entries[index_entry_pos].flags = index_entry_flags;
4921 sc->ctts_data[index_entry_pos].count = 1;
4922 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4925 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4926 "size %u, distance %d, keyframe %d\n", st->index,
4927 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4929 dts += sample_duration;
4930 offset += sample_size;
4931 sc->data_size += sample_size;
4933 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4934 1 <= INT_MAX - sc->nb_frames_for_fps
4936 sc->duration_for_fps += sample_duration;
4937 sc->nb_frames_for_fps ++;
4941 // EOF found before reading all entries. Fix the hole this would
4942 // leave in index_entries and ctts_data
4943 int gap = entries - i;
4944 memmove(st->index_entries + index_entry_pos,
4945 st->index_entries + index_entry_pos + gap,
4946 sizeof(*st->index_entries) *
4947 (st->nb_index_entries - (index_entry_pos + gap)));
4948 memmove(sc->ctts_data + index_entry_pos,
4949 sc->ctts_data + index_entry_pos + gap,
4950 sizeof(*sc->ctts_data) *
4951 (sc->ctts_count - (index_entry_pos + gap)));
4953 st->nb_index_entries -= gap;
4954 sc->ctts_count -= gap;
4955 if (index_entry_pos < sc->current_sample) {
4956 sc->current_sample -= gap;
4961 // The end of this new fragment may overlap in time with the start
4962 // of the next fragment in index_entries. Mark the samples in the next
4963 // fragment that overlap with AVINDEX_DISCARD_FRAME
4964 prev_dts = AV_NOPTS_VALUE;
4965 if (index_entry_pos > 0)
4966 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4967 for (i = index_entry_pos; i < st->nb_index_entries; i++) {
4968 if (prev_dts < st->index_entries[i].timestamp)
4970 st->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
4973 // If a hole was created to insert the new index_entries into,
4974 // the index_entry recorded for all subsequent moof must
4975 // be incremented by the number of entries inserted.
4976 fix_frag_index_entries(&c->frag_index, next_frag_index,
4977 frag->track_id, entries);
4979 if (pb->eof_reached) {
4980 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
4984 frag->implicit_offset = offset;
4986 sc->track_end = dts + sc->time_offset;
4987 if (st->duration < sc->track_end)
4988 st->duration = sc->track_end;
4993 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4995 int64_t offset = avio_tell(pb) + atom.size, pts, timestamp;
4997 unsigned i, j, track_id, item_count;
4998 AVStream *st = NULL;
4999 AVStream *ref_st = NULL;
5000 MOVStreamContext *sc, *ref_sc = NULL;
5001 AVRational timescale;
5003 version = avio_r8(pb);
5005 avpriv_request_sample(c->fc, "sidx version %u", version);
5009 avio_rb24(pb); // flags
5011 track_id = avio_rb32(pb); // Reference ID
5012 for (i = 0; i < c->fc->nb_streams; i++) {
5013 if (c->fc->streams[i]->id == track_id) {
5014 st = c->fc->streams[i];
5019 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5025 timescale = av_make_q(1, avio_rb32(pb));
5027 if (timescale.den <= 0) {
5028 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5029 return AVERROR_INVALIDDATA;
5033 pts = avio_rb32(pb);
5034 offset += avio_rb32(pb);
5036 pts = avio_rb64(pb);
5037 offset += avio_rb64(pb);
5040 avio_rb16(pb); // reserved
5042 item_count = avio_rb16(pb);
5044 for (i = 0; i < item_count; i++) {
5046 MOVFragmentStreamInfo * frag_stream_info;
5047 uint32_t size = avio_rb32(pb);
5048 uint32_t duration = avio_rb32(pb);
5049 if (size & 0x80000000) {
5050 avpriv_request_sample(c->fc, "sidx reference_type 1");
5051 return AVERROR_PATCHWELCOME;
5053 avio_rb32(pb); // sap_flags
5054 timestamp = av_rescale_q(pts, timescale, st->time_base);
5056 index = update_frag_index(c, offset);
5057 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5058 if (frag_stream_info)
5059 frag_stream_info->sidx_pts = timestamp;
5065 st->duration = sc->track_end = pts;
5069 if (offset == avio_size(pb)) {
5070 // Find first entry in fragment index that came from an sidx.
5071 // This will pretty much always be the first entry.
5072 for (i = 0; i < c->frag_index.nb_items; i++) {
5073 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5074 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5075 MOVFragmentStreamInfo * si;
5076 si = &item->stream_info[j];
5077 if (si->sidx_pts != AV_NOPTS_VALUE) {
5078 ref_st = c->fc->streams[j];
5079 ref_sc = ref_st->priv_data;
5084 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5085 st = c->fc->streams[i];
5087 if (!sc->has_sidx) {
5088 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5092 c->frag_index.complete = 1;
5098 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5099 /* like the files created with Adobe Premiere 5.0, for samples see */
5100 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5101 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5106 return 0; /* continue */
5107 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5108 avio_skip(pb, atom.size - 4);
5111 atom.type = avio_rl32(pb);
5113 if (atom.type != MKTAG('m','d','a','t')) {
5114 avio_skip(pb, atom.size);
5117 err = mov_read_mdat(c, pb, atom);
5121 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5126 uint8_t *moov_data; /* uncompressed data */
5127 long cmov_len, moov_len;
5130 avio_rb32(pb); /* dcom atom */
5131 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5132 return AVERROR_INVALIDDATA;
5133 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5134 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5135 return AVERROR_INVALIDDATA;
5137 avio_rb32(pb); /* cmvd atom */
5138 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5139 return AVERROR_INVALIDDATA;
5140 moov_len = avio_rb32(pb); /* uncompressed size */
5141 cmov_len = atom.size - 6 * 4;
5143 cmov_data = av_malloc(cmov_len);
5145 return AVERROR(ENOMEM);
5146 moov_data = av_malloc(moov_len);
5149 return AVERROR(ENOMEM);
5151 ret = ffio_read_size(pb, cmov_data, cmov_len);
5153 goto free_and_return;
5155 ret = AVERROR_INVALIDDATA;
5156 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5157 goto free_and_return;
5158 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5159 goto free_and_return;
5160 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5161 atom.type = MKTAG('m','o','o','v');
5162 atom.size = moov_len;
5163 ret = mov_read_default(c, &ctx, atom);
5169 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5170 return AVERROR(ENOSYS);
5174 /* edit list atom */
5175 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5177 MOVStreamContext *sc;
5178 int i, edit_count, version;
5179 int64_t elst_entry_size;
5181 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5183 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5185 version = avio_r8(pb); /* version */
5186 avio_rb24(pb); /* flags */
5187 edit_count = avio_rb32(pb); /* entries */
5190 elst_entry_size = version == 1 ? 20 : 12;
5191 if (atom.size != edit_count * elst_entry_size) {
5192 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5193 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5194 edit_count, atom.size + 8);
5195 return AVERROR_INVALIDDATA;
5197 edit_count = atom.size / elst_entry_size;
5198 if (edit_count * elst_entry_size != atom.size) {
5199 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.", atom.size, edit_count);
5207 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5208 av_free(sc->elst_data);
5210 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5212 return AVERROR(ENOMEM);
5214 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5215 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5216 MOVElst *e = &sc->elst_data[i];
5219 e->duration = avio_rb64(pb);
5220 e->time = avio_rb64(pb);
5223 e->duration = avio_rb32(pb); /* segment duration */
5224 e->time = (int32_t)avio_rb32(pb); /* media time */
5227 e->rate = avio_rb32(pb) / 65536.0;
5229 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5230 e->duration, e->time, e->rate);
5232 if (e->time < 0 && e->time != -1 &&
5233 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5234 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5235 c->fc->nb_streams-1, i, e->time);
5236 return AVERROR_INVALIDDATA;
5244 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5246 MOVStreamContext *sc;
5248 if (c->fc->nb_streams < 1)
5249 return AVERROR_INVALIDDATA;
5250 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5251 sc->timecode_track = avio_rb32(pb);
5255 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5260 if (c->fc->nb_streams < 1)
5262 st = c->fc->streams[c->fc->nb_streams - 1];
5264 if (atom.size < 4) {
5265 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5266 return AVERROR_INVALIDDATA;
5269 /* For now, propagate only the OBUs, if any. Once libavcodec is
5270 updated to handle isobmff style extradata this can be removed. */
5276 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5283 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5286 int version, color_range, color_primaries, color_trc, color_space;
5288 if (c->fc->nb_streams < 1)
5290 st = c->fc->streams[c->fc->nb_streams - 1];
5292 if (atom.size < 5) {
5293 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5294 return AVERROR_INVALIDDATA;
5297 version = avio_r8(pb);
5299 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5302 avio_skip(pb, 3); /* flags */
5304 avio_skip(pb, 2); /* profile + level */
5305 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5306 color_primaries = avio_r8(pb);
5307 color_trc = avio_r8(pb);
5308 color_space = avio_r8(pb);
5309 if (avio_rb16(pb)) /* codecIntializationDataSize */
5310 return AVERROR_INVALIDDATA;
5312 if (!av_color_primaries_name(color_primaries))
5313 color_primaries = AVCOL_PRI_UNSPECIFIED;
5314 if (!av_color_transfer_name(color_trc))
5315 color_trc = AVCOL_TRC_UNSPECIFIED;
5316 if (!av_color_space_name(color_space))
5317 color_space = AVCOL_SPC_UNSPECIFIED;
5319 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5320 st->codecpar->color_primaries = color_primaries;
5321 st->codecpar->color_trc = color_trc;
5322 st->codecpar->color_space = color_space;
5327 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5329 MOVStreamContext *sc;
5332 if (c->fc->nb_streams < 1)
5333 return AVERROR_INVALIDDATA;
5335 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5337 if (atom.size < 5) {
5338 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5339 return AVERROR_INVALIDDATA;
5342 version = avio_r8(pb);
5344 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5347 avio_skip(pb, 3); /* flags */
5349 sc->mastering = av_mastering_display_metadata_alloc();
5351 return AVERROR(ENOMEM);
5353 for (i = 0; i < 3; i++) {
5354 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5355 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5357 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5358 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5360 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5361 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5363 sc->mastering->has_primaries = 1;
5364 sc->mastering->has_luminance = 1;
5369 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5371 MOVStreamContext *sc;
5372 const int mapping[3] = {1, 2, 0};
5373 const int chroma_den = 50000;
5374 const int luma_den = 10000;
5377 if (c->fc->nb_streams < 1)
5378 return AVERROR_INVALIDDATA;
5380 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5382 if (atom.size < 24) {
5383 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5384 return AVERROR_INVALIDDATA;
5387 sc->mastering = av_mastering_display_metadata_alloc();
5389 return AVERROR(ENOMEM);
5391 for (i = 0; i < 3; i++) {
5392 const int j = mapping[i];
5393 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5394 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5396 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5397 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5399 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5400 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5402 sc->mastering->has_luminance = 1;
5403 sc->mastering->has_primaries = 1;
5408 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5410 MOVStreamContext *sc;
5413 if (c->fc->nb_streams < 1)
5414 return AVERROR_INVALIDDATA;
5416 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5418 if (atom.size < 5) {
5419 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5420 return AVERROR_INVALIDDATA;
5423 version = avio_r8(pb);
5425 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5428 avio_skip(pb, 3); /* flags */
5430 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5432 return AVERROR(ENOMEM);
5434 sc->coll->MaxCLL = avio_rb16(pb);
5435 sc->coll->MaxFALL = avio_rb16(pb);
5440 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5442 MOVStreamContext *sc;
5444 if (c->fc->nb_streams < 1)
5445 return AVERROR_INVALIDDATA;
5447 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5449 if (atom.size < 4) {
5450 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5451 return AVERROR_INVALIDDATA;
5454 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5456 return AVERROR(ENOMEM);
5458 sc->coll->MaxCLL = avio_rb16(pb);
5459 sc->coll->MaxFALL = avio_rb16(pb);
5464 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5467 MOVStreamContext *sc;
5468 enum AVStereo3DType type;
5471 if (c->fc->nb_streams < 1)
5474 st = c->fc->streams[c->fc->nb_streams - 1];
5477 if (atom.size < 5) {
5478 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5479 return AVERROR_INVALIDDATA;
5481 avio_skip(pb, 4); /* version + flags */
5486 type = AV_STEREO3D_2D;
5489 type = AV_STEREO3D_TOPBOTTOM;
5492 type = AV_STEREO3D_SIDEBYSIDE;
5495 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5499 sc->stereo3d = av_stereo3d_alloc();
5501 return AVERROR(ENOMEM);
5503 sc->stereo3d->type = type;
5507 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5510 MOVStreamContext *sc;
5511 int size, version, layout;
5512 int32_t yaw, pitch, roll;
5513 uint32_t l = 0, t = 0, r = 0, b = 0;
5514 uint32_t tag, padding = 0;
5515 enum AVSphericalProjection projection;
5517 if (c->fc->nb_streams < 1)
5520 st = c->fc->streams[c->fc->nb_streams - 1];
5523 if (atom.size < 8) {
5524 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5525 return AVERROR_INVALIDDATA;
5528 size = avio_rb32(pb);
5529 if (size <= 12 || size > atom.size)
5530 return AVERROR_INVALIDDATA;
5532 tag = avio_rl32(pb);
5533 if (tag != MKTAG('s','v','h','d')) {
5534 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5537 version = avio_r8(pb);
5539 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5543 avio_skip(pb, 3); /* flags */
5544 avio_skip(pb, size - 12); /* metadata_source */
5546 size = avio_rb32(pb);
5547 if (size > atom.size)
5548 return AVERROR_INVALIDDATA;
5550 tag = avio_rl32(pb);
5551 if (tag != MKTAG('p','r','o','j')) {
5552 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5556 size = avio_rb32(pb);
5557 if (size > atom.size)
5558 return AVERROR_INVALIDDATA;
5560 tag = avio_rl32(pb);
5561 if (tag != MKTAG('p','r','h','d')) {
5562 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5565 version = avio_r8(pb);
5567 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5571 avio_skip(pb, 3); /* flags */
5573 /* 16.16 fixed point */
5574 yaw = avio_rb32(pb);
5575 pitch = avio_rb32(pb);
5576 roll = avio_rb32(pb);
5578 size = avio_rb32(pb);
5579 if (size > atom.size)
5580 return AVERROR_INVALIDDATA;
5582 tag = avio_rl32(pb);
5583 version = avio_r8(pb);
5585 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5589 avio_skip(pb, 3); /* flags */
5591 case MKTAG('c','b','m','p'):
5592 layout = avio_rb32(pb);
5594 av_log(c->fc, AV_LOG_WARNING,
5595 "Unsupported cubemap layout %d\n", layout);
5598 projection = AV_SPHERICAL_CUBEMAP;
5599 padding = avio_rb32(pb);
5601 case MKTAG('e','q','u','i'):
5607 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5608 av_log(c->fc, AV_LOG_ERROR,
5609 "Invalid bounding rectangle coordinates "
5610 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5611 return AVERROR_INVALIDDATA;
5614 if (l || t || r || b)
5615 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5617 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5620 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5624 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5626 return AVERROR(ENOMEM);
5628 sc->spherical->projection = projection;
5630 sc->spherical->yaw = yaw;
5631 sc->spherical->pitch = pitch;
5632 sc->spherical->roll = roll;
5634 sc->spherical->padding = padding;
5636 sc->spherical->bound_left = l;
5637 sc->spherical->bound_top = t;
5638 sc->spherical->bound_right = r;
5639 sc->spherical->bound_bottom = b;
5644 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5647 uint8_t *buffer = av_malloc(len + 1);
5651 return AVERROR(ENOMEM);
5654 ret = ffio_read_size(pb, buffer, len);
5658 /* Check for mandatory keys and values, try to support XML as best-effort */
5659 if (!sc->spherical &&
5660 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5661 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5662 av_stristr(val, "true") &&
5663 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5664 av_stristr(val, "true") &&
5665 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5666 av_stristr(val, "equirectangular")) {
5667 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5671 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5673 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5674 enum AVStereo3DType mode;
5676 if (av_stristr(buffer, "left-right"))
5677 mode = AV_STEREO3D_SIDEBYSIDE;
5678 else if (av_stristr(buffer, "top-bottom"))
5679 mode = AV_STEREO3D_TOPBOTTOM;
5681 mode = AV_STEREO3D_2D;
5683 sc->stereo3d = av_stereo3d_alloc();
5687 sc->stereo3d->type = mode;
5691 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5693 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5694 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5696 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5697 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5699 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5707 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5710 MOVStreamContext *sc;
5713 static const uint8_t uuid_isml_manifest[] = {
5714 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5715 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5717 static const uint8_t uuid_xmp[] = {
5718 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5719 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5721 static const uint8_t uuid_spherical[] = {
5722 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5723 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5726 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5727 return AVERROR_INVALIDDATA;
5729 if (c->fc->nb_streams < 1)
5731 st = c->fc->streams[c->fc->nb_streams - 1];
5734 ret = avio_read(pb, uuid, sizeof(uuid));
5737 } else if (ret != sizeof(uuid)) {
5738 return AVERROR_INVALIDDATA;
5740 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5741 uint8_t *buffer, *ptr;
5743 size_t len = atom.size - sizeof(uuid);
5746 return AVERROR_INVALIDDATA;
5748 ret = avio_skip(pb, 4); // zeroes
5751 buffer = av_mallocz(len + 1);
5753 return AVERROR(ENOMEM);
5755 ret = avio_read(pb, buffer, len);
5759 } else if (ret != len) {
5761 return AVERROR_INVALIDDATA;
5765 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5766 ptr += sizeof("systemBitrate=\"") - 1;
5767 c->bitrates_count++;
5768 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5770 c->bitrates_count = 0;
5772 return AVERROR(ENOMEM);
5775 ret = strtol(ptr, &endptr, 10);
5776 if (ret < 0 || errno || *endptr != '"') {
5777 c->bitrates[c->bitrates_count - 1] = 0;
5779 c->bitrates[c->bitrates_count - 1] = ret;
5784 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5786 size_t len = atom.size - sizeof(uuid);
5787 if (c->export_xmp) {
5788 buffer = av_mallocz(len + 1);
5790 return AVERROR(ENOMEM);
5792 ret = avio_read(pb, buffer, len);
5796 } else if (ret != len) {
5798 return AVERROR_INVALIDDATA;
5801 av_dict_set(&c->fc->metadata, "xmp", buffer, 0);
5804 // skip all uuid atom, which makes it fast for long uuid-xmp file
5805 ret = avio_skip(pb, len);
5809 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5810 size_t len = atom.size - sizeof(uuid);
5811 ret = mov_parse_uuid_spherical(sc, pb, len);
5815 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5821 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5824 uint8_t content[16];
5829 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5835 && !memcmp(content, "Anevia\x1A\x1A", 8)
5836 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5837 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5843 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5845 uint32_t format = avio_rl32(pb);
5846 MOVStreamContext *sc;
5850 if (c->fc->nb_streams < 1)
5852 st = c->fc->streams[c->fc->nb_streams - 1];
5857 case MKTAG('e','n','c','v'): // encrypted video
5858 case MKTAG('e','n','c','a'): // encrypted audio
5859 id = mov_codec_id(st, format);
5860 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5861 st->codecpar->codec_id != id) {
5862 av_log(c->fc, AV_LOG_WARNING,
5863 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5864 (char*)&format, st->codecpar->codec_id);
5868 st->codecpar->codec_id = id;
5869 sc->format = format;
5873 if (format != sc->format) {
5874 av_log(c->fc, AV_LOG_WARNING,
5875 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5876 (char*)&format, (char*)&sc->format);
5885 * Gets the current encryption info and associated current stream context. If
5886 * we are parsing a track fragment, this will return the specific encryption
5887 * info for this fragment; otherwise this will return the global encryption
5888 * info for the current stream.
5890 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5892 MOVFragmentStreamInfo *frag_stream_info;
5896 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5897 if (frag_stream_info) {
5898 for (i = 0; i < c->fc->nb_streams; i++) {
5899 if (c->fc->streams[i]->id == frag_stream_info->id) {
5900 st = c->fc->streams[i];
5904 if (i == c->fc->nb_streams)
5906 *sc = st->priv_data;
5908 if (!frag_stream_info->encryption_index) {
5909 // If this stream isn't encrypted, don't create the index.
5910 if (!(*sc)->cenc.default_encrypted_sample)
5912 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5913 if (!frag_stream_info->encryption_index)
5914 return AVERROR(ENOMEM);
5916 *encryption_index = frag_stream_info->encryption_index;
5919 // No current track fragment, using stream level encryption info.
5921 if (c->fc->nb_streams < 1)
5923 st = c->fc->streams[c->fc->nb_streams - 1];
5924 *sc = st->priv_data;
5926 if (!(*sc)->cenc.encryption_index) {
5927 // If this stream isn't encrypted, don't create the index.
5928 if (!(*sc)->cenc.default_encrypted_sample)
5930 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5931 if (!(*sc)->cenc.encryption_index)
5932 return AVERROR(ENOMEM);
5935 *encryption_index = (*sc)->cenc.encryption_index;
5940 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
5943 unsigned int subsample_count;
5944 AVSubsampleEncryptionInfo *subsamples;
5946 if (!sc->cenc.default_encrypted_sample) {
5947 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
5948 return AVERROR_INVALIDDATA;
5951 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
5953 return AVERROR(ENOMEM);
5955 if (sc->cenc.per_sample_iv_size != 0) {
5956 if (avio_read(pb, (*sample)->iv, sc->cenc.per_sample_iv_size) != sc->cenc.per_sample_iv_size) {
5957 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
5958 av_encryption_info_free(*sample);
5960 return AVERROR_INVALIDDATA;
5964 if (use_subsamples) {
5965 subsample_count = avio_rb16(pb);
5966 av_free((*sample)->subsamples);
5967 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
5968 if (!(*sample)->subsamples) {
5969 av_encryption_info_free(*sample);
5971 return AVERROR(ENOMEM);
5974 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
5975 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
5976 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
5979 if (pb->eof_reached) {
5980 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
5981 av_encryption_info_free(*sample);
5983 return AVERROR_INVALIDDATA;
5985 (*sample)->subsample_count = subsample_count;
5991 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5993 AVEncryptionInfo **encrypted_samples;
5994 MOVEncryptionIndex *encryption_index;
5995 MOVStreamContext *sc;
5996 int use_subsamples, ret;
5997 unsigned int sample_count, i, alloc_size = 0;
5999 ret = get_current_encryption_info(c, &encryption_index, &sc);
6003 if (encryption_index->nb_encrypted_samples) {
6004 // This can happen if we have both saio/saiz and senc atoms.
6005 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6009 avio_r8(pb); /* version */
6010 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6012 sample_count = avio_rb32(pb);
6013 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6014 return AVERROR(ENOMEM);
6016 for (i = 0; i < sample_count; i++) {
6017 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6018 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6019 min_samples * sizeof(*encrypted_samples));
6020 if (encrypted_samples) {
6021 encryption_index->encrypted_samples = encrypted_samples;
6023 ret = mov_read_sample_encryption_info(
6024 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6026 ret = AVERROR(ENOMEM);
6028 if (pb->eof_reached) {
6029 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6030 ret = AVERROR_INVALIDDATA;
6035 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6036 av_freep(&encryption_index->encrypted_samples);
6040 encryption_index->nb_encrypted_samples = sample_count;
6045 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6047 AVEncryptionInfo **sample, **encrypted_samples;
6049 size_t sample_count, sample_info_size, i;
6051 unsigned int alloc_size = 0;
6053 if (encryption_index->nb_encrypted_samples)
6055 sample_count = encryption_index->auxiliary_info_sample_count;
6056 if (encryption_index->auxiliary_offsets_count != 1) {
6057 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6058 return AVERROR_PATCHWELCOME;
6060 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6061 return AVERROR(ENOMEM);
6063 prev_pos = avio_tell(pb);
6064 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6065 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6066 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6070 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6071 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6072 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6073 min_samples * sizeof(*encrypted_samples));
6074 if (!encrypted_samples) {
6075 ret = AVERROR(ENOMEM);
6078 encryption_index->encrypted_samples = encrypted_samples;
6080 sample = &encryption_index->encrypted_samples[i];
6081 sample_info_size = encryption_index->auxiliary_info_default_size
6082 ? encryption_index->auxiliary_info_default_size
6083 : encryption_index->auxiliary_info_sizes[i];
6085 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6089 if (pb->eof_reached) {
6090 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6091 ret = AVERROR_INVALIDDATA;
6093 encryption_index->nb_encrypted_samples = sample_count;
6097 avio_seek(pb, prev_pos, SEEK_SET);
6099 for (; i > 0; i--) {
6100 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6102 av_freep(&encryption_index->encrypted_samples);
6108 * Tries to read the given number of bytes from the stream and puts it in a
6109 * newly allocated buffer. This reads in small chunks to avoid allocating large
6110 * memory if the file contains an invalid/malicious size value.
6112 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6114 const unsigned int block_size = 1024 * 1024;
6115 uint8_t *buffer = NULL;
6116 unsigned int alloc_size = 0, offset = 0;
6117 while (offset < size) {
6118 unsigned int new_size =
6119 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6120 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6121 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6124 return AVERROR(ENOMEM);
6126 buffer = new_buffer;
6128 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6130 return AVERROR_INVALIDDATA;
6139 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6141 MOVEncryptionIndex *encryption_index;
6142 MOVStreamContext *sc;
6144 unsigned int sample_count, aux_info_type, aux_info_param;
6146 ret = get_current_encryption_info(c, &encryption_index, &sc);
6150 if (encryption_index->nb_encrypted_samples) {
6151 // This can happen if we have both saio/saiz and senc atoms.
6152 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6156 if (encryption_index->auxiliary_info_sample_count) {
6157 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6158 return AVERROR_INVALIDDATA;
6161 avio_r8(pb); /* version */
6162 if (avio_rb24(pb) & 0x01) { /* flags */
6163 aux_info_type = avio_rb32(pb);
6164 aux_info_param = avio_rb32(pb);
6165 if (sc->cenc.default_encrypted_sample) {
6166 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6167 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6170 if (aux_info_param != 0) {
6171 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6175 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6176 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6177 aux_info_type == MKBETAG('c','e','n','s') ||
6178 aux_info_type == MKBETAG('c','b','c','1') ||
6179 aux_info_type == MKBETAG('c','b','c','s')) &&
6180 aux_info_param == 0) {
6181 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6182 return AVERROR_INVALIDDATA;
6187 } else if (!sc->cenc.default_encrypted_sample) {
6188 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6192 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6193 sample_count = avio_rb32(pb);
6194 encryption_index->auxiliary_info_sample_count = sample_count;
6196 if (encryption_index->auxiliary_info_default_size == 0) {
6197 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6199 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6204 if (encryption_index->auxiliary_offsets_count) {
6205 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6211 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6213 uint64_t *auxiliary_offsets;
6214 MOVEncryptionIndex *encryption_index;
6215 MOVStreamContext *sc;
6217 unsigned int version, entry_count, aux_info_type, aux_info_param;
6218 unsigned int alloc_size = 0;
6220 ret = get_current_encryption_info(c, &encryption_index, &sc);
6224 if (encryption_index->nb_encrypted_samples) {
6225 // This can happen if we have both saio/saiz and senc atoms.
6226 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6230 if (encryption_index->auxiliary_offsets_count) {
6231 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6232 return AVERROR_INVALIDDATA;
6235 version = avio_r8(pb); /* version */
6236 if (avio_rb24(pb) & 0x01) { /* flags */
6237 aux_info_type = avio_rb32(pb);
6238 aux_info_param = avio_rb32(pb);
6239 if (sc->cenc.default_encrypted_sample) {
6240 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6241 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6244 if (aux_info_param != 0) {
6245 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6249 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6250 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6251 aux_info_type == MKBETAG('c','e','n','s') ||
6252 aux_info_type == MKBETAG('c','b','c','1') ||
6253 aux_info_type == MKBETAG('c','b','c','s')) &&
6254 aux_info_param == 0) {
6255 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6256 return AVERROR_INVALIDDATA;
6261 } else if (!sc->cenc.default_encrypted_sample) {
6262 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6266 entry_count = avio_rb32(pb);
6267 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6268 return AVERROR(ENOMEM);
6270 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6271 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6272 auxiliary_offsets = av_fast_realloc(
6273 encryption_index->auxiliary_offsets, &alloc_size,
6274 min_offsets * sizeof(*auxiliary_offsets));
6275 if (!auxiliary_offsets) {
6276 av_freep(&encryption_index->auxiliary_offsets);
6277 return AVERROR(ENOMEM);
6279 encryption_index->auxiliary_offsets = auxiliary_offsets;
6282 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6284 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6286 if (c->frag_index.current >= 0) {
6287 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6291 if (pb->eof_reached) {
6292 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6293 av_freep(&encryption_index->auxiliary_offsets);
6294 return AVERROR_INVALIDDATA;
6297 encryption_index->auxiliary_offsets_count = entry_count;
6299 if (encryption_index->auxiliary_info_sample_count) {
6300 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6306 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6308 AVEncryptionInitInfo *info, *old_init_info;
6311 uint8_t *side_data, *extra_data, *old_side_data;
6312 size_t side_data_size;
6313 int ret = 0, old_side_data_size;
6314 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6316 if (c->fc->nb_streams < 1)
6318 st = c->fc->streams[c->fc->nb_streams-1];
6320 version = avio_r8(pb); /* version */
6321 avio_rb24(pb); /* flags */
6323 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6324 /* key_id_size */ 16, /* data_size */ 0);
6326 return AVERROR(ENOMEM);
6328 if (avio_read(pb, info->system_id, 16) != 16) {
6329 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6330 ret = AVERROR_INVALIDDATA;
6335 kid_count = avio_rb32(pb);
6336 if (kid_count >= INT_MAX / sizeof(*key_ids))
6337 return AVERROR(ENOMEM);
6339 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6340 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6341 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6342 min_kid_count * sizeof(*key_ids));
6344 ret = AVERROR(ENOMEM);
6347 info->key_ids = key_ids;
6349 info->key_ids[i] = av_mallocz(16);
6350 if (!info->key_ids[i]) {
6351 ret = AVERROR(ENOMEM);
6354 info->num_key_ids = i + 1;
6356 if (avio_read(pb, info->key_ids[i], 16) != 16) {
6357 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6358 ret = AVERROR_INVALIDDATA;
6363 if (pb->eof_reached) {
6364 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6365 ret = AVERROR_INVALIDDATA;
6370 extra_data_size = avio_rb32(pb);
6371 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6375 av_freep(&info->data); // malloc(0) may still allocate something.
6376 info->data = extra_data;
6377 info->data_size = extra_data_size;
6379 // If there is existing initialization data, append to the list.
6380 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6381 if (old_side_data) {
6382 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6383 if (old_init_info) {
6384 // Append to the end of the list.
6385 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6391 info = old_init_info;
6393 // Assume existing side-data will be valid, so the only error we could get is OOM.
6394 ret = AVERROR(ENOMEM);
6399 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6401 ret = AVERROR(ENOMEM);
6404 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6405 side_data, side_data_size);
6410 av_encryption_init_info_free(info);
6414 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6417 MOVStreamContext *sc;
6419 if (c->fc->nb_streams < 1)
6421 st = c->fc->streams[c->fc->nb_streams-1];
6424 if (sc->pseudo_stream_id != 0) {
6425 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6426 return AVERROR_PATCHWELCOME;
6430 return AVERROR_INVALIDDATA;
6432 avio_rb32(pb); /* version and flags */
6434 if (!sc->cenc.default_encrypted_sample) {
6435 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6436 if (!sc->cenc.default_encrypted_sample) {
6437 return AVERROR(ENOMEM);
6441 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6445 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6448 MOVStreamContext *sc;
6449 unsigned int version, pattern, is_protected, iv_size;
6451 if (c->fc->nb_streams < 1)
6453 st = c->fc->streams[c->fc->nb_streams-1];
6456 if (sc->pseudo_stream_id != 0) {
6457 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6458 return AVERROR_PATCHWELCOME;
6461 if (!sc->cenc.default_encrypted_sample) {
6462 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6463 if (!sc->cenc.default_encrypted_sample) {
6464 return AVERROR(ENOMEM);
6469 return AVERROR_INVALIDDATA;
6471 version = avio_r8(pb); /* version */
6472 avio_rb24(pb); /* flags */
6474 avio_r8(pb); /* reserved */
6475 pattern = avio_r8(pb);
6478 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6479 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6482 is_protected = avio_r8(pb);
6483 if (is_protected && !sc->cenc.encryption_index) {
6484 // The whole stream should be by-default encrypted.
6485 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6486 if (!sc->cenc.encryption_index)
6487 return AVERROR(ENOMEM);
6489 sc->cenc.per_sample_iv_size = avio_r8(pb);
6490 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6491 sc->cenc.per_sample_iv_size != 16) {
6492 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6493 return AVERROR_INVALIDDATA;
6495 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6496 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6497 return AVERROR_INVALIDDATA;
6500 if (is_protected && !sc->cenc.per_sample_iv_size) {
6501 iv_size = avio_r8(pb);
6502 if (iv_size != 8 && iv_size != 16) {
6503 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6504 return AVERROR_INVALIDDATA;
6507 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6508 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6509 return AVERROR_INVALIDDATA;
6516 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6519 int last, type, size, ret;
6522 if (c->fc->nb_streams < 1)
6524 st = c->fc->streams[c->fc->nb_streams-1];
6526 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6527 return AVERROR_INVALIDDATA;
6529 /* Check FlacSpecificBox version. */
6530 if (avio_r8(pb) != 0)
6531 return AVERROR_INVALIDDATA;
6533 avio_rb24(pb); /* Flags */
6535 avio_read(pb, buf, sizeof(buf));
6536 flac_parse_block_header(buf, &last, &type, &size);
6538 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6539 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6540 return AVERROR_INVALIDDATA;
6543 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6548 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6553 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6557 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6558 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6559 return AVERROR_PATCHWELCOME;
6562 if (!sc->cenc.aes_ctr) {
6563 /* initialize the cipher */
6564 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6565 if (!sc->cenc.aes_ctr) {
6566 return AVERROR(ENOMEM);
6569 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6575 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6577 if (!sample->subsample_count)
6579 /* decrypt the whole packet */
6580 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6584 for (i = 0; i < sample->subsample_count; i++)
6586 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6587 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6588 return AVERROR_INVALIDDATA;
6591 /* skip the clear bytes */
6592 input += sample->subsamples[i].bytes_of_clear_data;
6593 size -= sample->subsamples[i].bytes_of_clear_data;
6595 /* decrypt the encrypted bytes */
6596 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6597 input += sample->subsamples[i].bytes_of_protected_data;
6598 size -= sample->subsamples[i].bytes_of_protected_data;
6602 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6603 return AVERROR_INVALIDDATA;
6609 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6611 MOVFragmentStreamInfo *frag_stream_info;
6612 MOVEncryptionIndex *encryption_index;
6613 AVEncryptionInfo *encrypted_sample;
6614 int encrypted_index, ret;
6616 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6617 encrypted_index = current_index;
6618 encryption_index = NULL;
6619 if (frag_stream_info) {
6620 // Note this only supports encryption info in the first sample descriptor.
6621 if (mov->fragment.stsd_id == 1) {
6622 if (frag_stream_info->encryption_index) {
6623 encrypted_index = current_index - frag_stream_info->index_entry;
6624 encryption_index = frag_stream_info->encryption_index;
6626 encryption_index = sc->cenc.encryption_index;
6630 encryption_index = sc->cenc.encryption_index;
6633 if (encryption_index) {
6634 if (encryption_index->auxiliary_info_sample_count &&
6635 !encryption_index->nb_encrypted_samples) {
6636 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6637 return AVERROR_INVALIDDATA;
6639 if (encryption_index->auxiliary_offsets_count &&
6640 !encryption_index->nb_encrypted_samples) {
6641 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6642 return AVERROR_INVALIDDATA;
6645 if (!encryption_index->nb_encrypted_samples) {
6646 // Full-sample encryption with default settings.
6647 encrypted_sample = sc->cenc.default_encrypted_sample;
6648 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6649 // Per-sample setting override.
6650 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6652 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6653 return AVERROR_INVALIDDATA;
6656 if (mov->decryption_key) {
6657 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6660 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6662 return AVERROR(ENOMEM);
6663 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6673 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6675 const int OPUS_SEEK_PREROLL_MS = 80;
6681 if (c->fc->nb_streams < 1)
6683 st = c->fc->streams[c->fc->nb_streams-1];
6685 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6686 return AVERROR_INVALIDDATA;
6688 /* Check OpusSpecificBox version. */
6689 if (avio_r8(pb) != 0) {
6690 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6691 return AVERROR_INVALIDDATA;
6694 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6695 size = atom.size + 8;
6697 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
6700 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6701 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6702 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6703 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6705 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6706 little-endian; aside from the preceeding magic and version they're
6707 otherwise currently identical. Data after output gain at offset 16
6708 doesn't need to be bytewapped. */
6709 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6710 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6711 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6712 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6714 st->codecpar->initial_padding = pre_skip;
6715 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6716 (AVRational){1, 1000},
6717 (AVRational){1, 48000});
6722 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6725 unsigned format_info;
6726 int channel_assignment, channel_assignment1, channel_assignment2;
6729 if (c->fc->nb_streams < 1)
6731 st = c->fc->streams[c->fc->nb_streams-1];
6734 return AVERROR_INVALIDDATA;
6736 format_info = avio_rb32(pb);
6738 ratebits = (format_info >> 28) & 0xF;
6739 channel_assignment1 = (format_info >> 15) & 0x1F;
6740 channel_assignment2 = format_info & 0x1FFF;
6741 if (channel_assignment2)
6742 channel_assignment = channel_assignment2;
6744 channel_assignment = channel_assignment1;
6746 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6747 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6748 st->codecpar->channels = truehd_channels(channel_assignment);
6749 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6754 static const MOVParseTableEntry mov_default_parse_table[] = {
6755 { MKTAG('A','C','L','R'), mov_read_aclr },
6756 { MKTAG('A','P','R','G'), mov_read_avid },
6757 { MKTAG('A','A','L','P'), mov_read_avid },
6758 { MKTAG('A','R','E','S'), mov_read_ares },
6759 { MKTAG('a','v','s','s'), mov_read_avss },
6760 { MKTAG('a','v','1','C'), mov_read_av1c },
6761 { MKTAG('c','h','p','l'), mov_read_chpl },
6762 { MKTAG('c','o','6','4'), mov_read_stco },
6763 { MKTAG('c','o','l','r'), mov_read_colr },
6764 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6765 { MKTAG('d','i','n','f'), mov_read_default },
6766 { MKTAG('D','p','x','E'), mov_read_dpxe },
6767 { MKTAG('d','r','e','f'), mov_read_dref },
6768 { MKTAG('e','d','t','s'), mov_read_default },
6769 { MKTAG('e','l','s','t'), mov_read_elst },
6770 { MKTAG('e','n','d','a'), mov_read_enda },
6771 { MKTAG('f','i','e','l'), mov_read_fiel },
6772 { MKTAG('a','d','r','m'), mov_read_adrm },
6773 { MKTAG('f','t','y','p'), mov_read_ftyp },
6774 { MKTAG('g','l','b','l'), mov_read_glbl },
6775 { MKTAG('h','d','l','r'), mov_read_hdlr },
6776 { MKTAG('i','l','s','t'), mov_read_ilst },
6777 { MKTAG('j','p','2','h'), mov_read_jp2h },
6778 { MKTAG('m','d','a','t'), mov_read_mdat },
6779 { MKTAG('m','d','h','d'), mov_read_mdhd },
6780 { MKTAG('m','d','i','a'), mov_read_default },
6781 { MKTAG('m','e','t','a'), mov_read_meta },
6782 { MKTAG('m','i','n','f'), mov_read_default },
6783 { MKTAG('m','o','o','f'), mov_read_moof },
6784 { MKTAG('m','o','o','v'), mov_read_moov },
6785 { MKTAG('m','v','e','x'), mov_read_default },
6786 { MKTAG('m','v','h','d'), mov_read_mvhd },
6787 { MKTAG('S','M','I',' '), mov_read_svq3 },
6788 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6789 { MKTAG('a','v','c','C'), mov_read_glbl },
6790 { MKTAG('p','a','s','p'), mov_read_pasp },
6791 { MKTAG('s','i','d','x'), mov_read_sidx },
6792 { MKTAG('s','t','b','l'), mov_read_default },
6793 { MKTAG('s','t','c','o'), mov_read_stco },
6794 { MKTAG('s','t','p','s'), mov_read_stps },
6795 { MKTAG('s','t','r','f'), mov_read_strf },
6796 { MKTAG('s','t','s','c'), mov_read_stsc },
6797 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6798 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6799 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6800 { MKTAG('s','t','t','s'), mov_read_stts },
6801 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6802 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
6803 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6804 { MKTAG('t','f','d','t'), mov_read_tfdt },
6805 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6806 { MKTAG('t','r','a','k'), mov_read_trak },
6807 { MKTAG('t','r','a','f'), mov_read_default },
6808 { MKTAG('t','r','e','f'), mov_read_default },
6809 { MKTAG('t','m','c','d'), mov_read_tmcd },
6810 { MKTAG('c','h','a','p'), mov_read_chap },
6811 { MKTAG('t','r','e','x'), mov_read_trex },
6812 { MKTAG('t','r','u','n'), mov_read_trun },
6813 { MKTAG('u','d','t','a'), mov_read_default },
6814 { MKTAG('w','a','v','e'), mov_read_wave },
6815 { MKTAG('e','s','d','s'), mov_read_esds },
6816 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6817 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6818 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6819 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6820 { MKTAG('w','f','e','x'), mov_read_wfex },
6821 { MKTAG('c','m','o','v'), mov_read_cmov },
6822 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6823 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6824 { MKTAG('s','b','g','p'), mov_read_sbgp },
6825 { MKTAG('h','v','c','C'), mov_read_glbl },
6826 { MKTAG('u','u','i','d'), mov_read_uuid },
6827 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6828 { MKTAG('f','r','e','e'), mov_read_free },
6829 { MKTAG('-','-','-','-'), mov_read_custom },
6830 { MKTAG('s','i','n','f'), mov_read_default },
6831 { MKTAG('f','r','m','a'), mov_read_frma },
6832 { MKTAG('s','e','n','c'), mov_read_senc },
6833 { MKTAG('s','a','i','z'), mov_read_saiz },
6834 { MKTAG('s','a','i','o'), mov_read_saio },
6835 { MKTAG('p','s','s','h'), mov_read_pssh },
6836 { MKTAG('s','c','h','m'), mov_read_schm },
6837 { MKTAG('s','c','h','i'), mov_read_default },
6838 { MKTAG('t','e','n','c'), mov_read_tenc },
6839 { MKTAG('d','f','L','a'), mov_read_dfla },
6840 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6841 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6842 { MKTAG('d','O','p','s'), mov_read_dops },
6843 { MKTAG('d','m','l','p'), mov_read_dmlp },
6844 { MKTAG('S','m','D','m'), mov_read_smdm },
6845 { MKTAG('C','o','L','L'), mov_read_coll },
6846 { MKTAG('v','p','c','C'), mov_read_vpcc },
6847 { MKTAG('m','d','c','v'), mov_read_mdcv },
6848 { MKTAG('c','l','l','i'), mov_read_clli },
6852 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6854 int64_t total_size = 0;
6858 if (c->atom_depth > 10) {
6859 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6860 return AVERROR_INVALIDDATA;
6865 atom.size = INT64_MAX;
6866 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6867 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
6870 if (atom.size >= 8) {
6871 a.size = avio_rb32(pb);
6872 a.type = avio_rl32(pb);
6873 if (a.type == MKTAG('f','r','e','e') &&
6875 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT &&
6878 uint32_t *type = (uint32_t *)buf + 1;
6879 if (avio_read(pb, buf, 8) != 8)
6880 return AVERROR_INVALIDDATA;
6881 avio_seek(pb, -8, SEEK_CUR);
6882 if (*type == MKTAG('m','v','h','d') ||
6883 *type == MKTAG('c','m','o','v')) {
6884 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free atom.\n");
6885 a.type = MKTAG('m','o','o','v');
6888 if (atom.type != MKTAG('r','o','o','t') &&
6889 atom.type != MKTAG('m','o','o','v'))
6891 if (a.type == MKTAG('t','r','a','k') || a.type == MKTAG('m','d','a','t'))
6893 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
6900 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
6901 a.size = avio_rb64(pb) - 8;
6905 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
6906 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
6908 a.size = atom.size - total_size + 8;
6913 a.size = FFMIN(a.size, atom.size - total_size);
6915 for (i = 0; mov_default_parse_table[i].type; i++)
6916 if (mov_default_parse_table[i].type == a.type) {
6917 parse = mov_default_parse_table[i].parse;
6921 // container is user data
6922 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
6923 atom.type == MKTAG('i','l','s','t')))
6924 parse = mov_read_udta_string;
6926 // Supports parsing the QuickTime Metadata Keys.
6927 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
6928 if (!parse && c->found_hdlr_mdta &&
6929 atom.type == MKTAG('m','e','t','a') &&
6930 a.type == MKTAG('k','e','y','s')) {
6931 parse = mov_read_keys;
6934 if (!parse) { /* skip leaf atoms data */
6935 avio_skip(pb, a.size);
6937 int64_t start_pos = avio_tell(pb);
6939 int err = parse(c, pb, a);
6944 if (c->found_moov && c->found_mdat &&
6945 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
6946 start_pos + a.size == avio_size(pb))) {
6947 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
6948 c->next_root_atom = start_pos + a.size;
6952 left = a.size - avio_tell(pb) + start_pos;
6953 if (left > 0) /* skip garbage at atom end */
6954 avio_skip(pb, left);
6955 else if (left < 0) {
6956 av_log(c->fc, AV_LOG_WARNING,
6957 "overread end of atom '%.4s' by %"PRId64" bytes\n",
6958 (char*)&a.type, -left);
6959 avio_seek(pb, left, SEEK_CUR);
6963 total_size += a.size;
6966 if (total_size < atom.size && atom.size < 0x7ffff)
6967 avio_skip(pb, atom.size - total_size);
6973 static int mov_probe(const AVProbeData *p)
6978 int moov_offset = -1;
6980 /* check file header */
6983 /* ignore invalid offset */
6984 if ((offset + 8) > (unsigned int)p->buf_size)
6986 tag = AV_RL32(p->buf + offset + 4);
6988 /* check for obvious tags */
6989 case MKTAG('m','o','o','v'):
6990 moov_offset = offset + 4;
6991 case MKTAG('m','d','a','t'):
6992 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
6993 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
6994 case MKTAG('f','t','y','p'):
6995 if (AV_RB32(p->buf+offset) < 8 &&
6996 (AV_RB32(p->buf+offset) != 1 ||
6997 offset + 12 > (unsigned int)p->buf_size ||
6998 AV_RB64(p->buf+offset + 8) == 0)) {
6999 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7000 } else if (tag == MKTAG('f','t','y','p') &&
7001 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
7002 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
7004 score = FFMAX(score, 5);
7006 score = AVPROBE_SCORE_MAX;
7008 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7010 /* those are more common words, so rate then a bit less */
7011 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
7012 case MKTAG('w','i','d','e'):
7013 case MKTAG('f','r','e','e'):
7014 case MKTAG('j','u','n','k'):
7015 case MKTAG('p','i','c','t'):
7016 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
7017 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7019 case MKTAG(0x82,0x82,0x7f,0x7d):
7020 case MKTAG('s','k','i','p'):
7021 case MKTAG('u','u','i','d'):
7022 case MKTAG('p','r','f','l'):
7023 /* if we only find those cause probedata is too small at least rate them */
7024 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7025 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7028 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7031 if(score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
7032 /* moov atom in the header - we should make sure that this is not a
7033 * MOV-packed MPEG-PS */
7034 offset = moov_offset;
7036 while(offset < (p->buf_size - 16)){ /* Sufficient space */
7037 /* We found an actual hdlr atom */
7038 if(AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7039 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7040 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')){
7041 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7042 /* We found a media handler reference atom describing an
7043 * MPEG-PS-in-MOV, return a
7044 * low score to force expanding the probe window until
7045 * mpegps_probe finds what it needs */
7056 // must be done after parsing all trak because there's no order requirement
7057 static void mov_read_chapters(AVFormatContext *s)
7059 MOVContext *mov = s->priv_data;
7061 MOVStreamContext *sc;
7066 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7067 chapter_track = mov->chapter_tracks[j];
7069 for (i = 0; i < s->nb_streams; i++)
7070 if (s->streams[i]->id == chapter_track) {
7075 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7080 cur_pos = avio_tell(sc->pb);
7082 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7083 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7084 if (st->nb_index_entries) {
7085 // Retrieve the first frame, if possible
7087 AVIndexEntry *sample = &st->index_entries[0];
7088 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7089 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7093 if (av_get_packet(sc->pb, &pkt, sample->size) < 0)
7096 st->attached_pic = pkt;
7097 st->attached_pic.stream_index = st->index;
7098 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
7101 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7102 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7103 st->discard = AVDISCARD_ALL;
7104 for (i = 0; i < st->nb_index_entries; i++) {
7105 AVIndexEntry *sample = &st->index_entries[i];
7106 int64_t end = i+1 < st->nb_index_entries ? st->index_entries[i+1].timestamp : st->duration;
7111 if (end < sample->timestamp) {
7112 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7113 end = AV_NOPTS_VALUE;
7116 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7117 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7121 // the first two bytes are the length of the title
7122 len = avio_rb16(sc->pb);
7123 if (len > sample->size-2)
7125 title_len = 2*len + 1;
7126 if (!(title = av_mallocz(title_len)))
7129 // The samples could theoretically be in any encoding if there's an encd
7130 // atom following, but in practice are only utf-8 or utf-16, distinguished
7131 // instead by the presence of a BOM
7135 ch = avio_rb16(sc->pb);
7137 avio_get_str16be(sc->pb, len, title, title_len);
7138 else if (ch == 0xfffe)
7139 avio_get_str16le(sc->pb, len, title, title_len);
7142 if (len == 1 || len == 2)
7145 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7149 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7154 avio_seek(sc->pb, cur_pos, SEEK_SET);
7158 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7159 uint32_t value, int flags)
7162 char buf[AV_TIMECODE_STR_SIZE];
7163 AVRational rate = st->avg_frame_rate;
7164 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7167 av_dict_set(&st->metadata, "timecode",
7168 av_timecode_make_string(&tc, buf, value), 0);
7172 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7174 MOVStreamContext *sc = st->priv_data;
7175 char buf[AV_TIMECODE_STR_SIZE];
7176 int64_t cur_pos = avio_tell(sc->pb);
7177 int hh, mm, ss, ff, drop;
7179 if (!st->nb_index_entries)
7182 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7183 avio_skip(s->pb, 13);
7184 hh = avio_r8(s->pb);
7185 mm = avio_r8(s->pb);
7186 ss = avio_r8(s->pb);
7187 drop = avio_r8(s->pb);
7188 ff = avio_r8(s->pb);
7189 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7190 hh, mm, ss, drop ? ';' : ':', ff);
7191 av_dict_set(&st->metadata, "timecode", buf, 0);
7193 avio_seek(sc->pb, cur_pos, SEEK_SET);
7197 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7199 MOVStreamContext *sc = st->priv_data;
7201 int64_t cur_pos = avio_tell(sc->pb);
7204 if (!st->nb_index_entries)
7207 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7208 value = avio_rb32(s->pb);
7210 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7211 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7212 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7214 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7215 * not the case) and thus assume "frame number format" instead of QT one.
7216 * No sample with tmcd track can be found with a QT timecode at the moment,
7217 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7219 parse_timecode_in_framenum_format(s, st, value, flags);
7221 avio_seek(sc->pb, cur_pos, SEEK_SET);
7225 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7227 if (!index || !*index) return;
7228 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7229 av_encryption_info_free((*index)->encrypted_samples[i]);
7231 av_freep(&(*index)->encrypted_samples);
7232 av_freep(&(*index)->auxiliary_info_sizes);
7233 av_freep(&(*index)->auxiliary_offsets);
7237 static int mov_read_close(AVFormatContext *s)
7239 MOVContext *mov = s->priv_data;
7242 for (i = 0; i < s->nb_streams; i++) {
7243 AVStream *st = s->streams[i];
7244 MOVStreamContext *sc = st->priv_data;
7249 av_freep(&sc->ctts_data);
7250 for (j = 0; j < sc->drefs_count; j++) {
7251 av_freep(&sc->drefs[j].path);
7252 av_freep(&sc->drefs[j].dir);
7254 av_freep(&sc->drefs);
7256 sc->drefs_count = 0;
7258 if (!sc->pb_is_copied)
7259 ff_format_io_close(s, &sc->pb);
7262 av_freep(&sc->chunk_offsets);
7263 av_freep(&sc->stsc_data);
7264 av_freep(&sc->sample_sizes);
7265 av_freep(&sc->keyframes);
7266 av_freep(&sc->stts_data);
7267 av_freep(&sc->sdtp_data);
7268 av_freep(&sc->stps_data);
7269 av_freep(&sc->elst_data);
7270 av_freep(&sc->rap_group);
7271 av_freep(&sc->display_matrix);
7272 av_freep(&sc->index_ranges);
7275 for (j = 0; j < sc->stsd_count; j++)
7276 av_free(sc->extradata[j]);
7277 av_freep(&sc->extradata);
7278 av_freep(&sc->extradata_size);
7280 mov_free_encryption_index(&sc->cenc.encryption_index);
7281 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7282 av_aes_ctr_free(sc->cenc.aes_ctr);
7284 av_freep(&sc->stereo3d);
7285 av_freep(&sc->spherical);
7286 av_freep(&sc->mastering);
7287 av_freep(&sc->coll);
7290 if (mov->dv_demux) {
7291 avformat_free_context(mov->dv_fctx);
7292 mov->dv_fctx = NULL;
7295 if (mov->meta_keys) {
7296 for (i = 1; i < mov->meta_keys_count; i++) {
7297 av_freep(&mov->meta_keys[i]);
7299 av_freep(&mov->meta_keys);
7302 av_freep(&mov->trex_data);
7303 av_freep(&mov->bitrates);
7305 for (i = 0; i < mov->frag_index.nb_items; i++) {
7306 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7307 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7308 mov_free_encryption_index(&frag[j].encryption_index);
7310 av_freep(&mov->frag_index.item[i].stream_info);
7312 av_freep(&mov->frag_index.item);
7314 av_freep(&mov->aes_decrypt);
7315 av_freep(&mov->chapter_tracks);
7320 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7324 for (i = 0; i < s->nb_streams; i++) {
7325 AVStream *st = s->streams[i];
7326 MOVStreamContext *sc = st->priv_data;
7328 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7329 sc->timecode_track == tmcd_id)
7335 /* look for a tmcd track not referenced by any video track, and export it globally */
7336 static void export_orphan_timecode(AVFormatContext *s)
7340 for (i = 0; i < s->nb_streams; i++) {
7341 AVStream *st = s->streams[i];
7343 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7344 !tmcd_is_referenced(s, i + 1)) {
7345 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7347 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7354 static int read_tfra(MOVContext *mov, AVIOContext *f)
7356 int version, fieldlength, i, j;
7357 int64_t pos = avio_tell(f);
7358 uint32_t size = avio_rb32(f);
7359 unsigned track_id, item_count;
7361 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7364 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7366 version = avio_r8(f);
7368 track_id = avio_rb32(f);
7369 fieldlength = avio_rb32(f);
7370 item_count = avio_rb32(f);
7371 for (i = 0; i < item_count; i++) {
7372 int64_t time, offset;
7374 MOVFragmentStreamInfo * frag_stream_info;
7377 return AVERROR_INVALIDDATA;
7381 time = avio_rb64(f);
7382 offset = avio_rb64(f);
7384 time = avio_rb32(f);
7385 offset = avio_rb32(f);
7388 // The first sample of each stream in a fragment is always a random
7389 // access sample. So it's entry in the tfra can be used as the
7390 // initial PTS of the fragment.
7391 index = update_frag_index(mov, offset);
7392 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7393 if (frag_stream_info &&
7394 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7395 frag_stream_info->first_tfra_pts = time;
7397 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7399 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7401 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7405 avio_seek(f, pos + size, SEEK_SET);
7409 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7411 int64_t stream_size = avio_size(f);
7412 int64_t original_pos = avio_tell(f);
7416 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7420 mfra_size = avio_rb32(f);
7421 if (mfra_size < 0 || mfra_size > stream_size) {
7422 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7425 if ((seek_ret = avio_seek(f, -mfra_size, SEEK_CUR)) < 0) {
7429 if (avio_rb32(f) != mfra_size) {
7430 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7433 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7434 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7437 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7439 ret = read_tfra(c, f);
7445 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7447 av_log(c->fc, AV_LOG_ERROR,
7448 "failed to seek back after looking for mfra\n");
7454 static int mov_read_header(AVFormatContext *s)
7456 MOVContext *mov = s->priv_data;
7457 AVIOContext *pb = s->pb;
7459 MOVAtom atom = { AV_RL32("root") };
7462 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7463 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7464 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7465 return AVERROR(EINVAL);
7469 mov->trak_index = -1;
7470 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7471 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7472 atom.size = avio_size(pb);
7474 atom.size = INT64_MAX;
7476 /* check MOV header */
7478 if (mov->moov_retry)
7479 avio_seek(pb, 0, SEEK_SET);
7480 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7481 av_log(s, AV_LOG_ERROR, "error reading header\n");
7485 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7486 if (!mov->found_moov) {
7487 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7489 return AVERROR_INVALIDDATA;
7491 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7493 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7494 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7495 mov_read_chapters(s);
7496 for (i = 0; i < s->nb_streams; i++)
7497 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7498 mov_read_timecode_track(s, s->streams[i]);
7499 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7500 mov_read_rtmd_track(s, s->streams[i]);
7504 /* copy timecode metadata from tmcd tracks to the related video streams */
7505 for (i = 0; i < s->nb_streams; i++) {
7506 AVStream *st = s->streams[i];
7507 MOVStreamContext *sc = st->priv_data;
7508 if (sc->timecode_track > 0) {
7509 AVDictionaryEntry *tcr;
7510 int tmcd_st_id = -1;
7512 for (j = 0; j < s->nb_streams; j++)
7513 if (s->streams[j]->id == sc->timecode_track)
7516 if (tmcd_st_id < 0 || tmcd_st_id == i)
7518 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7520 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7523 export_orphan_timecode(s);
7525 for (i = 0; i < s->nb_streams; i++) {
7526 AVStream *st = s->streams[i];
7527 MOVStreamContext *sc = st->priv_data;
7528 fix_timescale(mov, sc);
7529 if(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7530 st->skip_samples = sc->start_pad;
7532 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7533 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7534 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7535 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7536 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7537 st->codecpar->width = sc->width;
7538 st->codecpar->height = sc->height;
7540 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7541 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7545 if (mov->handbrake_version &&
7546 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7547 st->codecpar->codec_id == AV_CODEC_ID_MP3
7549 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7550 st->need_parsing = AVSTREAM_PARSE_FULL;
7554 if (mov->trex_data) {
7555 for (i = 0; i < s->nb_streams; i++) {
7556 AVStream *st = s->streams[i];
7557 MOVStreamContext *sc = st->priv_data;
7558 if (st->duration > 0) {
7559 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7560 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7561 sc->data_size, sc->time_scale);
7563 return AVERROR_INVALIDDATA;
7565 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7570 if (mov->use_mfra_for > 0) {
7571 for (i = 0; i < s->nb_streams; i++) {
7572 AVStream *st = s->streams[i];
7573 MOVStreamContext *sc = st->priv_data;
7574 if (sc->duration_for_fps > 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 /
7582 sc->duration_for_fps;
7587 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7588 if (mov->bitrates[i]) {
7589 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7593 ff_rfps_calculate(s);
7595 for (i = 0; i < s->nb_streams; i++) {
7596 AVStream *st = s->streams[i];
7597 MOVStreamContext *sc = st->priv_data;
7599 switch (st->codecpar->codec_type) {
7600 case AVMEDIA_TYPE_AUDIO:
7601 err = ff_replaygain_export(st, s->metadata);
7607 case AVMEDIA_TYPE_VIDEO:
7608 if (sc->display_matrix) {
7609 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7610 sizeof(int32_t) * 9);
7614 sc->display_matrix = NULL;
7617 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7618 (uint8_t *)sc->stereo3d,
7619 sizeof(*sc->stereo3d));
7623 sc->stereo3d = NULL;
7625 if (sc->spherical) {
7626 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7627 (uint8_t *)sc->spherical,
7628 sc->spherical_size);
7632 sc->spherical = NULL;
7634 if (sc->mastering) {
7635 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7636 (uint8_t *)sc->mastering,
7637 sizeof(*sc->mastering));
7641 sc->mastering = NULL;
7644 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7645 (uint8_t *)sc->coll,
7655 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7657 for (i = 0; i < mov->frag_index.nb_items; i++)
7658 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7659 mov->frag_index.item[i].headers_read = 1;
7664 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7666 AVIndexEntry *sample = NULL;
7667 int64_t best_dts = INT64_MAX;
7669 for (i = 0; i < s->nb_streams; i++) {
7670 AVStream *avst = s->streams[i];
7671 MOVStreamContext *msc = avst->priv_data;
7672 if (msc->pb && msc->current_sample < avst->nb_index_entries) {
7673 AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample];
7674 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7675 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7676 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7677 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7678 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb &&
7679 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7680 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7681 sample = current_sample;
7690 static int should_retry(AVIOContext *pb, int error_code) {
7691 if (error_code == AVERROR_EOF || avio_feof(pb))
7697 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7700 MOVContext *mov = s->priv_data;
7702 if (index >= 0 && index < mov->frag_index.nb_items)
7703 target = mov->frag_index.item[index].moof_offset;
7704 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7705 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7706 return AVERROR_INVALIDDATA;
7709 mov->next_root_atom = 0;
7710 if (index < 0 || index >= mov->frag_index.nb_items)
7711 index = search_frag_moof_offset(&mov->frag_index, target);
7712 if (index < mov->frag_index.nb_items) {
7713 if (index + 1 < mov->frag_index.nb_items)
7714 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7715 if (mov->frag_index.item[index].headers_read)
7717 mov->frag_index.item[index].headers_read = 1;
7720 mov->found_mdat = 0;
7722 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7725 if (avio_feof(s->pb))
7727 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7732 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7734 uint8_t *side, *extradata;
7737 /* Save the current index. */
7738 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7740 /* Notify the decoder that extradata changed. */
7741 extradata_size = sc->extradata_size[sc->last_stsd_index];
7742 extradata = sc->extradata[sc->last_stsd_index];
7743 if (extradata_size > 0 && extradata) {
7744 side = av_packet_new_side_data(pkt,
7745 AV_PKT_DATA_NEW_EXTRADATA,
7748 return AVERROR(ENOMEM);
7749 memcpy(side, extradata, extradata_size);
7755 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7757 MOVContext *mov = s->priv_data;
7758 MOVStreamContext *sc;
7759 AVIndexEntry *sample;
7760 AVStream *st = NULL;
7761 int64_t current_index;
7765 sample = mov_find_next_sample(s, &st);
7766 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7767 if (!mov->next_root_atom)
7769 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7774 /* must be done just before reading, to avoid infinite loop on sample */
7775 current_index = sc->current_index;
7776 mov_current_sample_inc(sc);
7778 if (mov->next_root_atom) {
7779 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7780 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7783 if (st->discard != AVDISCARD_ALL) {
7784 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7785 if (ret64 != sample->pos) {
7786 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7787 sc->ffindex, sample->pos);
7788 if (should_retry(sc->pb, ret64)) {
7789 mov_current_sample_dec(sc);
7791 return AVERROR_INVALIDDATA;
7794 if( st->discard == AVDISCARD_NONKEY && 0==(sample->flags & AVINDEX_KEYFRAME) ) {
7795 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7799 ret = av_get_packet(sc->pb, pkt, sample->size);
7801 if (should_retry(sc->pb, ret)) {
7802 mov_current_sample_dec(sc);
7806 if (sc->has_palette) {
7809 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7811 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7813 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7814 sc->has_palette = 0;
7817 #if CONFIG_DV_DEMUXER
7818 if (mov->dv_demux && sc->dv_audio_container) {
7819 avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7820 av_freep(&pkt->data);
7822 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7827 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7828 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7829 st->need_parsing = AVSTREAM_PARSE_FULL;
7833 pkt->stream_index = sc->ffindex;
7834 pkt->dts = sample->timestamp;
7835 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7836 pkt->flags |= AV_PKT_FLAG_DISCARD;
7838 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7839 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
7840 /* update ctts context */
7842 if (sc->ctts_index < sc->ctts_count &&
7843 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
7845 sc->ctts_sample = 0;
7848 int64_t next_dts = (sc->current_sample < st->nb_index_entries) ?
7849 st->index_entries[sc->current_sample].timestamp : st->duration;
7851 if (next_dts >= pkt->dts)
7852 pkt->duration = next_dts - pkt->dts;
7853 pkt->pts = pkt->dts;
7855 if (st->discard == AVDISCARD_ALL)
7857 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
7858 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
7859 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
7860 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
7862 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
7863 pkt->pos = sample->pos;
7865 /* Multiple stsd handling. */
7866 if (sc->stsc_data) {
7867 /* Keep track of the stsc index for the given sample, then check
7868 * if the stsd index is different from the last used one. */
7870 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
7871 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
7873 sc->stsc_sample = 0;
7874 /* Do not check indexes after a switch. */
7875 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
7876 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
7877 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
7878 ret = mov_change_extradata(sc, pkt);
7885 aax_filter(pkt->data, pkt->size, mov);
7887 ret = cenc_filter(mov, st, sc, pkt, current_index);
7889 av_packet_unref(pkt);
7896 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
7898 MOVContext *mov = s->priv_data;
7901 if (!mov->frag_index.complete)
7904 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
7907 if (!mov->frag_index.item[index].headers_read)
7908 return mov_switch_root(s, -1, index);
7909 if (index + 1 < mov->frag_index.nb_items)
7910 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7915 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
7917 MOVStreamContext *sc = st->priv_data;
7918 int sample, time_sample, ret;
7921 // Here we consider timestamp to be PTS, hence try to offset it so that we
7922 // can search over the DTS timeline.
7923 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
7925 ret = mov_seek_fragment(s, st, timestamp);
7929 sample = av_index_search_timestamp(st, timestamp, flags);
7930 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
7931 if (sample < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp)
7933 if (sample < 0) /* not sure what to do */
7934 return AVERROR_INVALIDDATA;
7935 mov_current_sample_set(sc, sample);
7936 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
7937 /* adjust ctts index */
7938 if (sc->ctts_data) {
7940 for (i = 0; i < sc->ctts_count; i++) {
7941 int next = time_sample + sc->ctts_data[i].count;
7942 if (next > sc->current_sample) {
7944 sc->ctts_sample = sc->current_sample - time_sample;
7951 /* adjust stsd index */
7952 if (sc->chunk_count) {
7954 for (i = 0; i < sc->stsc_count; i++) {
7955 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
7956 if (next > sc->current_sample) {
7958 sc->stsc_sample = sc->current_sample - time_sample;
7961 av_assert0(next == (int)next);
7969 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
7971 MOVContext *mc = s->priv_data;
7976 if (stream_index >= s->nb_streams)
7977 return AVERROR_INVALIDDATA;
7979 st = s->streams[stream_index];
7980 sample = mov_seek_stream(s, st, sample_time, flags);
7984 if (mc->seek_individually) {
7985 /* adjust seek timestamp to found sample timestamp */
7986 int64_t seek_timestamp = st->index_entries[sample].timestamp;
7988 for (i = 0; i < s->nb_streams; i++) {
7990 MOVStreamContext *sc = s->streams[i]->priv_data;
7992 st->skip_samples = (sample_time <= 0) ? sc->start_pad : 0;
7994 if (stream_index == i)
7997 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
7998 mov_seek_stream(s, st, timestamp, flags);
8001 for (i = 0; i < s->nb_streams; i++) {
8002 MOVStreamContext *sc;
8005 mov_current_sample_set(sc, 0);
8008 MOVStreamContext *sc;
8009 AVIndexEntry *entry = mov_find_next_sample(s, &st);
8011 return AVERROR_INVALIDDATA;
8013 if (sc->ffindex == stream_index && sc->current_sample == sample)
8015 mov_current_sample_inc(sc);
8021 #define OFFSET(x) offsetof(MOVContext, x)
8022 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
8023 static const AVOption mov_options[] = {
8024 {"use_absolute_path",
8025 "allow using absolute path when opening alias, this is a possible security issue",
8026 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
8028 {"seek_streams_individually",
8029 "Seek each stream individually to the closest point",
8030 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
8032 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
8034 {"advanced_editlist",
8035 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
8036 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
8038 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8041 "use mfra for fragment timestamps",
8042 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8043 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8045 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8046 FLAGS, "use_mfra_for" },
8047 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8048 FLAGS, "use_mfra_for" },
8049 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8050 FLAGS, "use_mfra_for" },
8051 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8052 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8053 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8054 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8055 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8056 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8057 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8058 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8059 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8060 .flags = AV_OPT_FLAG_DECODING_PARAM },
8061 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8062 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8063 {.i64 = 0}, 0, 1, FLAGS },
8068 static const AVClass mov_class = {
8069 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8070 .item_name = av_default_item_name,
8071 .option = mov_options,
8072 .version = LIBAVUTIL_VERSION_INT,
8075 AVInputFormat ff_mov_demuxer = {
8076 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8077 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8078 .priv_class = &mov_class,
8079 .priv_data_size = sizeof(MOVContext),
8080 .extensions = "mov,mp4,m4a,3gp,3g2,mj2",
8081 .read_probe = mov_probe,
8082 .read_header = mov_read_header,
8083 .read_packet = mov_read_packet,
8084 .read_close = mov_read_close,
8085 .read_seek = mov_read_seek,
8086 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,