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 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1844 } else if (atom.size > 8) { /* to read frma, esds atoms */
1845 if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
1847 ret = ffio_ensure_seekback(pb, 8);
1850 buffer = avio_rb64(pb);
1852 if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
1853 && buffer >> 32 <= atom.size
1854 && buffer >> 32 >= 8) {
1857 } else if (!st->codecpar->extradata_size) {
1858 #define ALAC_EXTRADATA_SIZE 36
1859 st->codecpar->extradata = av_mallocz(ALAC_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
1860 if (!st->codecpar->extradata)
1861 return AVERROR(ENOMEM);
1862 st->codecpar->extradata_size = ALAC_EXTRADATA_SIZE;
1863 AV_WB32(st->codecpar->extradata , ALAC_EXTRADATA_SIZE);
1864 AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
1865 AV_WB64(st->codecpar->extradata + 12, buffer);
1866 avio_read(pb, st->codecpar->extradata + 20, 16);
1867 avio_skip(pb, atom.size - 24);
1871 if ((ret = mov_read_default(c, pb, atom)) < 0)
1874 avio_skip(pb, atom.size);
1879 * This function reads atom content and puts data in extradata without tag
1880 * nor size unlike mov_read_extradata.
1882 static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1887 if (c->fc->nb_streams < 1)
1889 st = c->fc->streams[c->fc->nb_streams-1];
1891 if ((uint64_t)atom.size > (1<<30))
1892 return AVERROR_INVALIDDATA;
1894 if (atom.size >= 10) {
1895 // Broken files created by legacy versions of libavformat will
1896 // wrap a whole fiel atom inside of a glbl atom.
1897 unsigned size = avio_rb32(pb);
1898 unsigned type = avio_rl32(pb);
1899 avio_seek(pb, -8, SEEK_CUR);
1900 if (type == MKTAG('f','i','e','l') && size == atom.size)
1901 return mov_read_default(c, pb, atom);
1903 if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
1904 av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
1907 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1910 if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
1911 /* HEVC-based Dolby Vision derived from hvc1.
1912 Happens to match with an identifier
1913 previously utilized for DV. Thus, if we have
1914 the hvcC extradata box available as specified,
1915 set codec to HEVC */
1916 st->codecpar->codec_id = AV_CODEC_ID_HEVC;
1921 static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1924 uint8_t profile_level;
1927 if (c->fc->nb_streams < 1)
1929 st = c->fc->streams[c->fc->nb_streams-1];
1931 if (atom.size >= (1<<28) || atom.size < 7)
1932 return AVERROR_INVALIDDATA;
1934 profile_level = avio_r8(pb);
1935 if ((profile_level & 0xf0) != 0xc0)
1938 avio_seek(pb, 6, SEEK_CUR);
1939 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
1947 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
1948 * but can have extradata appended at the end after the 40 bytes belonging
1951 static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1956 if (c->fc->nb_streams < 1)
1958 if (atom.size <= 40)
1960 st = c->fc->streams[c->fc->nb_streams-1];
1962 if ((uint64_t)atom.size > (1<<30))
1963 return AVERROR_INVALIDDATA;
1966 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
1973 static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1976 MOVStreamContext *sc;
1977 unsigned int i, entries;
1979 if (c->fc->nb_streams < 1)
1981 st = c->fc->streams[c->fc->nb_streams-1];
1984 avio_r8(pb); /* version */
1985 avio_rb24(pb); /* flags */
1987 entries = avio_rb32(pb);
1992 if (sc->chunk_offsets)
1993 av_log(c->fc, AV_LOG_WARNING, "Duplicated STCO atom\n");
1994 av_free(sc->chunk_offsets);
1995 sc->chunk_count = 0;
1996 sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
1997 if (!sc->chunk_offsets)
1998 return AVERROR(ENOMEM);
1999 sc->chunk_count = entries;
2001 if (atom.type == MKTAG('s','t','c','o'))
2002 for (i = 0; i < entries && !pb->eof_reached; i++)
2003 sc->chunk_offsets[i] = avio_rb32(pb);
2004 else if (atom.type == MKTAG('c','o','6','4'))
2005 for (i = 0; i < entries && !pb->eof_reached; i++)
2006 sc->chunk_offsets[i] = avio_rb64(pb);
2008 return AVERROR_INVALIDDATA;
2010 sc->chunk_count = i;
2012 if (pb->eof_reached) {
2013 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2020 static int mov_codec_id(AVStream *st, uint32_t format)
2022 int id = ff_codec_get_id(ff_codec_movaudio_tags, format);
2025 ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2026 (format & 0xFFFF) == 'T' + ('S' << 8)))
2027 id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format) & 0xFFFF);
2029 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2030 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2031 } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2032 /* skip old ASF MPEG-4 tag */
2033 format && format != MKTAG('m','p','4','s')) {
2034 id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2036 id = ff_codec_get_id(ff_codec_bmp_tags, format);
2038 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
2039 else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2040 (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE &&
2041 st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2042 id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
2044 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
2046 id = ff_codec_get_id(ff_codec_movdata_tags, format);
2050 st->codecpar->codec_tag = format;
2055 static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
2056 AVStream *st, MOVStreamContext *sc)
2058 uint8_t codec_name[32] = { 0 };
2062 /* The first 16 bytes of the video sample description are already
2063 * read in ff_mov_read_stsd_entries() */
2064 stsd_start = avio_tell(pb) - 16;
2066 avio_rb16(pb); /* version */
2067 avio_rb16(pb); /* revision level */
2068 avio_rb32(pb); /* vendor */
2069 avio_rb32(pb); /* temporal quality */
2070 avio_rb32(pb); /* spatial quality */
2072 st->codecpar->width = avio_rb16(pb); /* width */
2073 st->codecpar->height = avio_rb16(pb); /* height */
2075 avio_rb32(pb); /* horiz resolution */
2076 avio_rb32(pb); /* vert resolution */
2077 avio_rb32(pb); /* data size, always 0 */
2078 avio_rb16(pb); /* frames per samples */
2080 len = avio_r8(pb); /* codec name, pascal string */
2083 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2085 avio_skip(pb, 31 - len);
2088 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2090 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2091 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2092 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2093 st->codecpar->width &= ~1;
2094 st->codecpar->height &= ~1;
2096 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2097 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2098 !strncmp(codec_name, "Sorenson H263", 13))
2099 st->codecpar->codec_id = AV_CODEC_ID_FLV1;
2101 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2103 avio_seek(pb, stsd_start, SEEK_SET);
2105 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2106 st->codecpar->bits_per_coded_sample &= 0x1F;
2107 sc->has_palette = 1;
2111 static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
2112 AVStream *st, MOVStreamContext *sc)
2114 int bits_per_sample, flags;
2115 uint16_t version = avio_rb16(pb);
2116 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2118 avio_rb16(pb); /* revision level */
2119 avio_rb32(pb); /* vendor */
2121 st->codecpar->channels = avio_rb16(pb); /* channel count */
2122 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2123 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", st->codecpar->channels);
2125 sc->audio_cid = avio_rb16(pb);
2126 avio_rb16(pb); /* packet size = 0 */
2128 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2130 // Read QT version 1 fields. In version 0 these do not exist.
2131 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2133 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2134 (sc->stsd_version == 0 && version > 0)) {
2136 sc->samples_per_frame = avio_rb32(pb);
2137 avio_rb32(pb); /* bytes per packet */
2138 sc->bytes_per_frame = avio_rb32(pb);
2139 avio_rb32(pb); /* bytes per sample */
2140 } else if (version == 2) {
2141 avio_rb32(pb); /* sizeof struct only */
2142 st->codecpar->sample_rate = av_int2double(avio_rb64(pb));
2143 st->codecpar->channels = avio_rb32(pb);
2144 avio_rb32(pb); /* always 0x7F000000 */
2145 st->codecpar->bits_per_coded_sample = avio_rb32(pb);
2147 flags = avio_rb32(pb); /* lpcm format specific flag */
2148 sc->bytes_per_frame = avio_rb32(pb);
2149 sc->samples_per_frame = avio_rb32(pb);
2150 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2151 st->codecpar->codec_id =
2152 ff_mov_get_lpcm_codec_id(st->codecpar->bits_per_coded_sample,
2155 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2156 /* can't correctly handle variable sized packet as audio unit */
2157 switch (st->codecpar->codec_id) {
2158 case AV_CODEC_ID_MP2:
2159 case AV_CODEC_ID_MP3:
2160 st->need_parsing = AVSTREAM_PARSE_FULL;
2166 if (sc->format == 0) {
2167 if (st->codecpar->bits_per_coded_sample == 8)
2168 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2169 else if (st->codecpar->bits_per_coded_sample == 16)
2170 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2173 switch (st->codecpar->codec_id) {
2174 case AV_CODEC_ID_PCM_S8:
2175 case AV_CODEC_ID_PCM_U8:
2176 if (st->codecpar->bits_per_coded_sample == 16)
2177 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16BE;
2179 case AV_CODEC_ID_PCM_S16LE:
2180 case AV_CODEC_ID_PCM_S16BE:
2181 if (st->codecpar->bits_per_coded_sample == 8)
2182 st->codecpar->codec_id = AV_CODEC_ID_PCM_S8;
2183 else if (st->codecpar->bits_per_coded_sample == 24)
2184 st->codecpar->codec_id =
2185 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2186 AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
2187 else if (st->codecpar->bits_per_coded_sample == 32)
2188 st->codecpar->codec_id =
2189 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2190 AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
2192 /* set values for old format before stsd version 1 appeared */
2193 case AV_CODEC_ID_MACE3:
2194 sc->samples_per_frame = 6;
2195 sc->bytes_per_frame = 2 * st->codecpar->channels;
2197 case AV_CODEC_ID_MACE6:
2198 sc->samples_per_frame = 6;
2199 sc->bytes_per_frame = 1 * st->codecpar->channels;
2201 case AV_CODEC_ID_ADPCM_IMA_QT:
2202 sc->samples_per_frame = 64;
2203 sc->bytes_per_frame = 34 * st->codecpar->channels;
2205 case AV_CODEC_ID_GSM:
2206 sc->samples_per_frame = 160;
2207 sc->bytes_per_frame = 33;
2213 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2214 if (bits_per_sample) {
2215 st->codecpar->bits_per_coded_sample = bits_per_sample;
2216 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->channels;
2220 static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
2221 AVStream *st, MOVStreamContext *sc,
2224 // ttxt stsd contains display flags, justification, background
2225 // color, fonts, and default styles, so fake an atom to read it
2226 MOVAtom fake_atom = { .size = size };
2227 // mp4s contains a regular esds atom
2228 if (st->codecpar->codec_tag != AV_RL32("mp4s"))
2229 mov_read_glbl(c, pb, fake_atom);
2230 st->codecpar->width = sc->width;
2231 st->codecpar->height = sc->height;
2234 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2239 y = (ycbcr >> 16) & 0xFF;
2240 cr = (ycbcr >> 8) & 0xFF;
2243 b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
2244 g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
2245 r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
2247 return (r << 16) | (g << 8) | b;
2250 static int mov_rewrite_dvd_sub_extradata(AVStream *st)
2252 char buf[256] = {0};
2253 uint8_t *src = st->codecpar->extradata;
2256 if (st->codecpar->extradata_size != 64)
2259 if (st->codecpar->width > 0 && st->codecpar->height > 0)
2260 snprintf(buf, sizeof(buf), "size: %dx%d\n",
2261 st->codecpar->width, st->codecpar->height);
2262 av_strlcat(buf, "palette: ", sizeof(buf));
2264 for (i = 0; i < 16; i++) {
2265 uint32_t yuv = AV_RB32(src + i * 4);
2266 uint32_t rgba = yuv_to_rgba(yuv);
2268 av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2271 if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2274 ret = ff_alloc_extradata(st->codecpar, strlen(buf));
2277 memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2282 static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
2283 AVStream *st, MOVStreamContext *sc,
2288 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2289 if ((int)size != size)
2290 return AVERROR(ENOMEM);
2292 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2296 MOVStreamContext *tmcd_ctx = st->priv_data;
2298 val = AV_RB32(st->codecpar->extradata + 4);
2299 tmcd_ctx->tmcd_flags = val;
2300 st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2301 st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2302 #if FF_API_LAVF_AVCTX
2303 FF_DISABLE_DEPRECATION_WARNINGS
2304 st->codec->time_base = av_inv_q(st->avg_frame_rate);
2305 FF_ENABLE_DEPRECATION_WARNINGS
2307 /* adjust for per frame dur in counter mode */
2308 if (tmcd_ctx->tmcd_flags & 0x0008) {
2309 int timescale = AV_RB32(st->codecpar->extradata + 8);
2310 int framedur = AV_RB32(st->codecpar->extradata + 12);
2311 st->avg_frame_rate.num *= timescale;
2312 st->avg_frame_rate.den *= framedur;
2313 #if FF_API_LAVF_AVCTX
2314 FF_DISABLE_DEPRECATION_WARNINGS
2315 st->codec->time_base.den *= timescale;
2316 st->codec->time_base.num *= framedur;
2317 FF_ENABLE_DEPRECATION_WARNINGS
2321 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2322 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2323 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2324 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2325 if (str_size > 0 && size >= (int)str_size + 26) {
2326 char *reel_name = av_malloc(str_size + 1);
2328 return AVERROR(ENOMEM);
2329 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2330 reel_name[str_size] = 0; /* Add null terminator */
2331 /* don't add reel_name if emtpy string */
2332 if (*reel_name == 0) {
2335 av_dict_set(&st->metadata, "reel_name", reel_name, AV_DICT_DONT_STRDUP_VAL);
2342 /* other codec type, just skip (rtp, mp4s ...) */
2343 avio_skip(pb, size);
2348 static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
2349 AVStream *st, MOVStreamContext *sc)
2351 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2352 !st->codecpar->sample_rate && sc->time_scale > 1)
2353 st->codecpar->sample_rate = sc->time_scale;
2355 /* special codec parameters handling */
2356 switch (st->codecpar->codec_id) {
2357 #if CONFIG_DV_DEMUXER
2358 case AV_CODEC_ID_DVAUDIO:
2359 c->dv_fctx = avformat_alloc_context();
2361 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2362 return AVERROR(ENOMEM);
2364 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2366 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2367 return AVERROR(ENOMEM);
2369 sc->dv_audio_container = 1;
2370 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
2373 /* no ifdef since parameters are always those */
2374 case AV_CODEC_ID_QCELP:
2375 st->codecpar->channels = 1;
2376 // force sample rate for qcelp when not stored in mov
2377 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2378 st->codecpar->sample_rate = 8000;
2379 // FIXME: Why is the following needed for some files?
2380 sc->samples_per_frame = 160;
2381 if (!sc->bytes_per_frame)
2382 sc->bytes_per_frame = 35;
2384 case AV_CODEC_ID_AMR_NB:
2385 st->codecpar->channels = 1;
2386 /* force sample rate for amr, stsd in 3gp does not store sample rate */
2387 st->codecpar->sample_rate = 8000;
2389 case AV_CODEC_ID_AMR_WB:
2390 st->codecpar->channels = 1;
2391 st->codecpar->sample_rate = 16000;
2393 case AV_CODEC_ID_MP2:
2394 case AV_CODEC_ID_MP3:
2395 /* force type after stsd for m1a hdlr */
2396 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2398 case AV_CODEC_ID_GSM:
2399 case AV_CODEC_ID_ADPCM_MS:
2400 case AV_CODEC_ID_ADPCM_IMA_WAV:
2401 case AV_CODEC_ID_ILBC:
2402 case AV_CODEC_ID_MACE3:
2403 case AV_CODEC_ID_MACE6:
2404 case AV_CODEC_ID_QDM2:
2405 st->codecpar->block_align = sc->bytes_per_frame;
2407 case AV_CODEC_ID_ALAC:
2408 if (st->codecpar->extradata_size == 36) {
2409 st->codecpar->channels = AV_RB8 (st->codecpar->extradata + 21);
2410 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2413 case AV_CODEC_ID_AC3:
2414 case AV_CODEC_ID_EAC3:
2415 case AV_CODEC_ID_MPEG1VIDEO:
2416 case AV_CODEC_ID_VC1:
2417 case AV_CODEC_ID_VP8:
2418 case AV_CODEC_ID_VP9:
2419 st->need_parsing = AVSTREAM_PARSE_FULL;
2427 static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
2428 int codec_tag, int format,
2431 int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2434 (codec_tag != format &&
2435 // AVID 1:1 samples with differing data format and codec tag exist
2436 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
2437 // prores is allowed to have differing data format and codec tag
2438 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
2440 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
2441 (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id
2442 : codec_tag != MKTAG('j','p','e','g')))) {
2443 /* Multiple fourcc, we skip JPEG. This is not correct, we should
2444 * export it as a separate AVStream but this needs a few changes
2445 * in the MOV demuxer, patch welcome. */
2447 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
2448 avio_skip(pb, size);
2455 int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
2458 MOVStreamContext *sc;
2459 int pseudo_stream_id;
2461 av_assert0 (c->fc->nb_streams >= 1);
2462 st = c->fc->streams[c->fc->nb_streams-1];
2465 for (pseudo_stream_id = 0;
2466 pseudo_stream_id < entries && !pb->eof_reached;
2467 pseudo_stream_id++) {
2468 //Parsing Sample description table
2470 int ret, dref_id = 1;
2471 MOVAtom a = { AV_RL32("stsd") };
2472 int64_t start_pos = avio_tell(pb);
2473 int64_t size = avio_rb32(pb); /* size */
2474 uint32_t format = avio_rl32(pb); /* data format */
2477 avio_rb32(pb); /* reserved */
2478 avio_rb16(pb); /* reserved */
2479 dref_id = avio_rb16(pb);
2480 } else if (size <= 7) {
2481 av_log(c->fc, AV_LOG_ERROR,
2482 "invalid size %"PRId64" in stsd\n", size);
2483 return AVERROR_INVALIDDATA;
2486 if (mov_skip_multiple_stsd(c, pb, st->codecpar->codec_tag, format,
2487 size - (avio_tell(pb) - start_pos))) {
2492 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
2493 sc->dref_id= dref_id;
2494 sc->format = format;
2496 id = mov_codec_id(st, format);
2498 av_log(c->fc, AV_LOG_TRACE,
2499 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
2500 av_fourcc2str(format), st->codecpar->codec_type);
2502 st->codecpar->codec_id = id;
2503 if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) {
2504 mov_parse_stsd_video(c, pb, st, sc);
2505 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
2506 mov_parse_stsd_audio(c, pb, st, sc);
2507 if (st->codecpar->sample_rate < 0) {
2508 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
2509 return AVERROR_INVALIDDATA;
2511 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
2512 mov_parse_stsd_subtitle(c, pb, st, sc,
2513 size - (avio_tell(pb) - start_pos));
2515 ret = mov_parse_stsd_data(c, pb, st, sc,
2516 size - (avio_tell(pb) - start_pos));
2520 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
2521 a.size = size - (avio_tell(pb) - start_pos);
2523 if ((ret = mov_read_default(c, pb, a)) < 0)
2525 } else if (a.size > 0)
2526 avio_skip(pb, a.size);
2528 if (sc->extradata && st->codecpar->extradata) {
2529 int extra_size = st->codecpar->extradata_size;
2531 /* Move the current stream extradata to the stream context one. */
2532 sc->extradata_size[pseudo_stream_id] = extra_size;
2533 sc->extradata[pseudo_stream_id] = av_malloc(extra_size + AV_INPUT_BUFFER_PADDING_SIZE);
2534 if (!sc->extradata[pseudo_stream_id])
2535 return AVERROR(ENOMEM);
2536 memcpy(sc->extradata[pseudo_stream_id], st->codecpar->extradata, extra_size);
2537 av_freep(&st->codecpar->extradata);
2538 st->codecpar->extradata_size = 0;
2543 if (pb->eof_reached) {
2544 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
2551 static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2554 MOVStreamContext *sc;
2557 if (c->fc->nb_streams < 1)
2559 st = c->fc->streams[c->fc->nb_streams - 1];
2562 sc->stsd_version = avio_r8(pb);
2563 avio_rb24(pb); /* flags */
2564 entries = avio_rb32(pb);
2566 /* Each entry contains a size (4 bytes) and format (4 bytes). */
2567 if (entries <= 0 || entries > atom.size / 8) {
2568 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
2569 return AVERROR_INVALIDDATA;
2572 if (sc->extradata) {
2573 av_log(c->fc, AV_LOG_ERROR,
2574 "Duplicate stsd found in this track.\n");
2575 return AVERROR_INVALIDDATA;
2578 /* Prepare space for hosting multiple extradata. */
2579 sc->extradata = av_mallocz_array(entries, sizeof(*sc->extradata));
2581 return AVERROR(ENOMEM);
2583 sc->extradata_size = av_mallocz_array(entries, sizeof(*sc->extradata_size));
2584 if (!sc->extradata_size) {
2585 ret = AVERROR(ENOMEM);
2589 ret = ff_mov_read_stsd_entries(c, pb, entries);
2593 /* Restore back the primary extradata. */
2594 av_freep(&st->codecpar->extradata);
2595 st->codecpar->extradata_size = sc->extradata_size[0];
2596 if (sc->extradata_size[0]) {
2597 st->codecpar->extradata = av_mallocz(sc->extradata_size[0] + AV_INPUT_BUFFER_PADDING_SIZE);
2598 if (!st->codecpar->extradata)
2599 return AVERROR(ENOMEM);
2600 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
2603 return mov_finalize_stsd_codec(c, pb, st, sc);
2605 if (sc->extradata) {
2607 for (j = 0; j < sc->stsd_count; j++)
2608 av_freep(&sc->extradata[j]);
2611 av_freep(&sc->extradata);
2612 av_freep(&sc->extradata_size);
2616 static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2619 MOVStreamContext *sc;
2620 unsigned int i, entries;
2622 if (c->fc->nb_streams < 1)
2624 st = c->fc->streams[c->fc->nb_streams-1];
2627 avio_r8(pb); /* version */
2628 avio_rb24(pb); /* flags */
2630 entries = avio_rb32(pb);
2631 if ((uint64_t)entries * 12 + 4 > atom.size)
2632 return AVERROR_INVALIDDATA;
2634 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
2639 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSC atom\n");
2640 av_free(sc->stsc_data);
2642 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
2644 return AVERROR(ENOMEM);
2646 for (i = 0; i < entries && !pb->eof_reached; i++) {
2647 sc->stsc_data[i].first = avio_rb32(pb);
2648 sc->stsc_data[i].count = avio_rb32(pb);
2649 sc->stsc_data[i].id = avio_rb32(pb);
2653 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
2654 int64_t first_min = i + 1;
2655 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
2656 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
2657 sc->stsc_data[i].first < first_min ||
2658 sc->stsc_data[i].count < 1 ||
2659 sc->stsc_data[i].id < 1) {
2660 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);
2661 if (i+1 >= sc->stsc_count) {
2662 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
2663 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
2664 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
2665 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
2666 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
2669 av_assert0(sc->stsc_data[i+1].first >= 2);
2670 // We replace this entry by the next valid
2671 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
2672 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
2673 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
2677 if (pb->eof_reached) {
2678 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
2685 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
2687 return index < count - 1;
2690 /* Compute the samples value for the stsc entry at the given index. */
2691 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
2695 if (mov_stsc_index_valid(index, sc->stsc_count))
2696 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
2698 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
2699 av_assert0(sc->stsc_data[index].first <= sc->chunk_count);
2700 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
2703 return sc->stsc_data[index].count * (int64_t)chunk_count;
2706 static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2709 MOVStreamContext *sc;
2710 unsigned i, entries;
2712 if (c->fc->nb_streams < 1)
2714 st = c->fc->streams[c->fc->nb_streams-1];
2717 avio_rb32(pb); // version + flags
2719 entries = avio_rb32(pb);
2721 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
2722 av_free(sc->stps_data);
2724 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
2726 return AVERROR(ENOMEM);
2728 for (i = 0; i < entries && !pb->eof_reached; i++) {
2729 sc->stps_data[i] = avio_rb32(pb);
2734 if (pb->eof_reached) {
2735 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
2742 static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2745 MOVStreamContext *sc;
2746 unsigned int i, entries;
2748 if (c->fc->nb_streams < 1)
2750 st = c->fc->streams[c->fc->nb_streams-1];
2753 avio_r8(pb); /* version */
2754 avio_rb24(pb); /* flags */
2756 entries = avio_rb32(pb);
2758 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
2762 sc->keyframe_absent = 1;
2763 if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
2764 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2768 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
2769 if (entries >= UINT_MAX / sizeof(int))
2770 return AVERROR_INVALIDDATA;
2771 av_freep(&sc->keyframes);
2772 sc->keyframe_count = 0;
2773 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
2775 return AVERROR(ENOMEM);
2777 for (i = 0; i < entries && !pb->eof_reached; i++) {
2778 sc->keyframes[i] = avio_rb32(pb);
2781 sc->keyframe_count = i;
2783 if (pb->eof_reached) {
2784 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
2791 static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2794 MOVStreamContext *sc;
2795 unsigned int i, entries, sample_size, field_size, num_bytes;
2800 if (c->fc->nb_streams < 1)
2802 st = c->fc->streams[c->fc->nb_streams-1];
2805 avio_r8(pb); /* version */
2806 avio_rb24(pb); /* flags */
2808 if (atom.type == MKTAG('s','t','s','z')) {
2809 sample_size = avio_rb32(pb);
2810 if (!sc->sample_size) /* do not overwrite value computed in stsd */
2811 sc->sample_size = sample_size;
2812 sc->stsz_sample_size = sample_size;
2816 avio_rb24(pb); /* reserved */
2817 field_size = avio_r8(pb);
2819 entries = avio_rb32(pb);
2821 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
2823 sc->sample_count = entries;
2827 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
2828 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
2829 return AVERROR_INVALIDDATA;
2834 if (entries >= (UINT_MAX - 4) / field_size)
2835 return AVERROR_INVALIDDATA;
2836 if (sc->sample_sizes)
2837 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
2838 av_free(sc->sample_sizes);
2839 sc->sample_count = 0;
2840 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
2841 if (!sc->sample_sizes)
2842 return AVERROR(ENOMEM);
2844 num_bytes = (entries*field_size+4)>>3;
2846 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
2848 av_freep(&sc->sample_sizes);
2849 return AVERROR(ENOMEM);
2852 ret = ffio_read_size(pb, buf, num_bytes);
2854 av_freep(&sc->sample_sizes);
2856 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
2860 init_get_bits(&gb, buf, 8*num_bytes);
2862 for (i = 0; i < entries && !pb->eof_reached; i++) {
2863 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
2864 sc->data_size += sc->sample_sizes[i];
2867 sc->sample_count = i;
2871 if (pb->eof_reached) {
2872 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSZ atom\n");
2879 static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2882 MOVStreamContext *sc;
2883 unsigned int i, entries, alloc_size = 0;
2885 int64_t total_sample_count=0;
2887 if (c->fc->nb_streams < 1)
2889 st = c->fc->streams[c->fc->nb_streams-1];
2892 avio_r8(pb); /* version */
2893 avio_rb24(pb); /* flags */
2894 entries = avio_rb32(pb);
2896 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
2897 c->fc->nb_streams-1, entries);
2900 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
2901 av_freep(&sc->stts_data);
2903 if (entries >= INT_MAX / sizeof(*sc->stts_data))
2904 return AVERROR(ENOMEM);
2906 for (i = 0; i < entries && !pb->eof_reached; i++) {
2907 int sample_duration;
2908 unsigned int sample_count;
2909 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
2910 MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
2911 min_entries * sizeof(*sc->stts_data));
2913 av_freep(&sc->stts_data);
2915 return AVERROR(ENOMEM);
2917 sc->stts_count = min_entries;
2918 sc->stts_data = stts_data;
2920 sample_count=avio_rb32(pb);
2921 sample_duration = avio_rb32(pb);
2923 sc->stts_data[i].count= sample_count;
2924 sc->stts_data[i].duration= sample_duration;
2926 av_log(c->fc, AV_LOG_TRACE, "sample_count=%d, sample_duration=%d\n",
2927 sample_count, sample_duration);
2929 duration+=(int64_t)sample_duration*(uint64_t)sample_count;
2930 total_sample_count+=sample_count;
2936 duration <= INT64_MAX - sc->duration_for_fps &&
2937 total_sample_count <= INT_MAX - sc->nb_frames_for_fps
2939 sc->duration_for_fps += duration;
2940 sc->nb_frames_for_fps += total_sample_count;
2943 if (pb->eof_reached) {
2944 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
2948 st->nb_frames= total_sample_count;
2950 st->duration= FFMIN(st->duration, duration);
2951 sc->track_end = duration;
2955 static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2958 MOVStreamContext *sc;
2961 if (c->fc->nb_streams < 1)
2963 st = c->fc->streams[c->fc->nb_streams - 1];
2966 avio_r8(pb); /* version */
2967 avio_rb24(pb); /* flags */
2968 entries = atom.size - 4;
2970 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
2971 c->fc->nb_streams - 1, entries);
2974 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
2975 av_freep(&sc->sdtp_data);
2978 sc->sdtp_data = av_mallocz(entries);
2980 return AVERROR(ENOMEM);
2982 for (i = 0; i < entries && !pb->eof_reached; i++)
2983 sc->sdtp_data[i] = avio_r8(pb);
2989 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
2992 if (duration == INT_MIN) {
2993 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
2996 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3000 static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3003 MOVStreamContext *sc;
3004 unsigned int i, entries, ctts_count = 0;
3006 if (c->fc->nb_streams < 1)
3008 st = c->fc->streams[c->fc->nb_streams-1];
3011 avio_r8(pb); /* version */
3012 avio_rb24(pb); /* flags */
3013 entries = avio_rb32(pb);
3015 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3019 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3020 return AVERROR_INVALIDDATA;
3021 av_freep(&sc->ctts_data);
3022 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3024 return AVERROR(ENOMEM);
3026 for (i = 0; i < entries && !pb->eof_reached; i++) {
3027 int count =avio_rb32(pb);
3028 int duration =avio_rb32(pb);
3031 av_log(c->fc, AV_LOG_TRACE,
3032 "ignoring CTTS entry with count=%d duration=%d\n",
3037 add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3040 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3043 if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3044 av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3045 av_freep(&sc->ctts_data);
3051 mov_update_dts_shift(sc, duration, c->fc);
3054 sc->ctts_count = ctts_count;
3056 if (pb->eof_reached) {
3057 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3061 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3066 static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3069 MOVStreamContext *sc;
3070 unsigned int i, entries;
3072 uint32_t grouping_type;
3074 if (c->fc->nb_streams < 1)
3076 st = c->fc->streams[c->fc->nb_streams-1];
3079 version = avio_r8(pb); /* version */
3080 avio_rb24(pb); /* flags */
3081 grouping_type = avio_rl32(pb);
3082 if (grouping_type != MKTAG( 'r','a','p',' '))
3083 return 0; /* only support 'rap ' grouping */
3085 avio_rb32(pb); /* grouping_type_parameter */
3087 entries = avio_rb32(pb);
3091 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP atom\n");
3092 av_free(sc->rap_group);
3093 sc->rap_group_count = 0;
3094 sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group));
3096 return AVERROR(ENOMEM);
3098 for (i = 0; i < entries && !pb->eof_reached; i++) {
3099 sc->rap_group[i].count = avio_rb32(pb); /* sample_count */
3100 sc->rap_group[i].index = avio_rb32(pb); /* group_description_index */
3103 sc->rap_group_count = i;
3105 if (pb->eof_reached) {
3106 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3114 * Get ith edit list entry (media time, duration).
3116 static int get_edit_list_entry(MOVContext *mov,
3117 const MOVStreamContext *msc,
3118 unsigned int edit_list_index,
3119 int64_t *edit_list_media_time,
3120 int64_t *edit_list_duration,
3121 int64_t global_timescale)
3123 if (edit_list_index == msc->elst_count) {
3126 *edit_list_media_time = msc->elst_data[edit_list_index].time;
3127 *edit_list_duration = msc->elst_data[edit_list_index].duration;
3129 /* duration is in global timescale units;convert to msc timescale */
3130 if (global_timescale == 0) {
3131 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3134 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3140 * Find the closest previous frame to the timestamp_pts, in e_old index
3141 * entries. Searching for just any frame / just key frames can be controlled by
3142 * last argument 'flag'.
3143 * Note that if ctts_data is not NULL, we will always search for a key frame
3144 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3145 * return the first frame of the video.
3147 * Here the timestamp_pts is considered to be a presentation timestamp and
3148 * the timestamp of index entries are considered to be decoding timestamps.
3150 * Returns 0 if successful in finding a frame, else returns -1.
3151 * Places the found index corresponding output arg.
3153 * If ctts_old is not NULL, then refines the searched entry by searching
3154 * backwards from the found timestamp, to find the frame with correct PTS.
3156 * Places the found ctts_index and ctts_sample in corresponding output args.
3158 static int find_prev_closest_index(AVStream *st,
3159 AVIndexEntry *e_old,
3163 int64_t timestamp_pts,
3166 int64_t* ctts_index,
3167 int64_t* ctts_sample)
3169 MOVStreamContext *msc = st->priv_data;
3170 AVIndexEntry *e_keep = st->index_entries;
3171 int nb_keep = st->nb_index_entries;
3173 int64_t index_ctts_count;
3177 // If dts_shift > 0, then all the index timestamps will have to be offset by
3178 // at least dts_shift amount to obtain PTS.
3179 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3180 if (msc->dts_shift > 0) {
3181 timestamp_pts -= msc->dts_shift;
3184 st->index_entries = e_old;
3185 st->nb_index_entries = nb_old;
3186 *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3188 // Keep going backwards in the index entries until the timestamp is the same.
3190 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3192 if ((flag & AVSEEK_FLAG_ANY) ||
3193 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3199 // If we have CTTS then refine the search, by searching backwards over PTS
3200 // computed by adding corresponding CTTS durations to index timestamps.
3201 if (ctts_data && *index >= 0) {
3202 av_assert0(ctts_index);
3203 av_assert0(ctts_sample);
3204 // Find out the ctts_index for the found frame.
3207 for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3208 if (*ctts_index < ctts_count) {
3210 if (ctts_data[*ctts_index].count == *ctts_sample) {
3217 while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3218 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3219 // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3220 // compensated by dts_shift above.
3221 if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3222 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3227 if (*ctts_sample == 0) {
3229 if (*ctts_index >= 0)
3230 *ctts_sample = ctts_data[*ctts_index].count - 1;
3237 /* restore AVStream state*/
3238 st->index_entries = e_keep;
3239 st->nb_index_entries = nb_keep;
3240 return *index >= 0 ? 0 : -1;
3244 * Add index entry with the given values, to the end of st->index_entries.
3245 * Returns the new size st->index_entries if successful, else returns -1.
3247 * This function is similar to ff_add_index_entry in libavformat/utils.c
3248 * except that here we are always unconditionally adding an index entry to
3249 * the end, instead of searching the entries list and skipping the add if
3250 * there is an existing entry with the same timestamp.
3251 * This is needed because the mov_fix_index calls this func with the same
3252 * unincremented timestamp for successive discarded frames.
3254 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3255 int size, int distance, int flags)
3257 AVIndexEntry *entries, *ie;
3259 const size_t min_size_needed = (st->nb_index_entries + 1) * sizeof(AVIndexEntry);
3261 // Double the allocation each time, to lower memory fragmentation.
3262 // Another difference from ff_add_index_entry function.
3263 const size_t requested_size =
3264 min_size_needed > st->index_entries_allocated_size ?
3265 FFMAX(min_size_needed, 2 * st->index_entries_allocated_size) :
3268 if((unsigned)st->nb_index_entries + 1 >= UINT_MAX / sizeof(AVIndexEntry))
3271 entries = av_fast_realloc(st->index_entries,
3272 &st->index_entries_allocated_size,
3277 st->index_entries= entries;
3279 index= st->nb_index_entries++;
3280 ie= &entries[index];
3283 ie->timestamp = timestamp;
3284 ie->min_distance= distance;
3291 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3292 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3294 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3295 int64_t* frame_duration_buffer,
3296 int frame_duration_buffer_size) {
3298 av_assert0(end_index >= 0 && end_index <= st->nb_index_entries);
3299 for (i = 0; i < frame_duration_buffer_size; i++) {
3300 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3301 st->index_entries[end_index - 1 - i].timestamp = end_ts;
3306 * Append a new ctts entry to ctts_data.
3307 * Returns the new ctts_count if successful, else returns -1.
3309 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3310 int count, int duration)
3312 MOVStts *ctts_buf_new;
3313 const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVStts);
3314 const size_t requested_size =
3315 min_size_needed > *allocated_size ?
3316 FFMAX(min_size_needed, 2 * (*allocated_size)) :
3319 if((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
3322 ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3327 *ctts_data = ctts_buf_new;
3329 ctts_buf_new[*ctts_count].count = count;
3330 ctts_buf_new[*ctts_count].duration = duration;
3332 *ctts_count = (*ctts_count) + 1;
3336 #define MAX_REORDER_DELAY 16
3337 static void mov_estimate_video_delay(MOVContext *c, AVStream* st) {
3338 MOVStreamContext *msc = st->priv_data;
3341 int ctts_sample = 0;
3342 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3344 int j, r, num_swaps;
3346 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3347 pts_buf[j] = INT64_MIN;
3349 if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3350 st->codecpar->codec_id == AV_CODEC_ID_H264) {
3351 st->codecpar->video_delay = 0;
3352 for(ind = 0; ind < st->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3353 // Point j to the last elem of the buffer and insert the current pts there.
3355 buf_start = (buf_start + 1);
3356 if (buf_start == MAX_REORDER_DELAY + 1)
3359 pts_buf[j] = st->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3361 // The timestamps that are already in the sorted buffer, and are greater than the
3362 // current pts, are exactly the timestamps that need to be buffered to output PTS
3363 // in correct sorted order.
3364 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3365 // can be computed as the maximum no. of swaps any particular timestamp needs to
3366 // go through, to keep this buffer in sorted order.
3368 while (j != buf_start) {
3370 if (r < 0) r = MAX_REORDER_DELAY;
3371 if (pts_buf[j] < pts_buf[r]) {
3372 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3379 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3382 if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3387 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3388 st->codecpar->video_delay, st->index);
3392 static void mov_current_sample_inc(MOVStreamContext *sc)
3394 sc->current_sample++;
3395 sc->current_index++;
3396 if (sc->index_ranges &&
3397 sc->current_index >= sc->current_index_range->end &&
3398 sc->current_index_range->end) {
3399 sc->current_index_range++;
3400 sc->current_index = sc->current_index_range->start;
3404 static void mov_current_sample_dec(MOVStreamContext *sc)
3406 sc->current_sample--;
3407 sc->current_index--;
3408 if (sc->index_ranges &&
3409 sc->current_index < sc->current_index_range->start &&
3410 sc->current_index_range > sc->index_ranges) {
3411 sc->current_index_range--;
3412 sc->current_index = sc->current_index_range->end - 1;
3416 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3420 sc->current_sample = current_sample;
3421 sc->current_index = current_sample;
3422 if (!sc->index_ranges) {
3426 for (sc->current_index_range = sc->index_ranges;
3427 sc->current_index_range->end;
3428 sc->current_index_range++) {
3429 range_size = sc->current_index_range->end - sc->current_index_range->start;
3430 if (range_size > current_sample) {
3431 sc->current_index = sc->current_index_range->start + current_sample;
3434 current_sample -= range_size;
3439 * Fix st->index_entries, so that it contains only the entries (and the entries
3440 * which are needed to decode them) that fall in the edit list time ranges.
3441 * Also fixes the timestamps of the index entries to match the timeline
3442 * specified the edit lists.
3444 static void mov_fix_index(MOVContext *mov, AVStream *st)
3446 MOVStreamContext *msc = st->priv_data;
3447 AVIndexEntry *e_old = st->index_entries;
3448 int nb_old = st->nb_index_entries;
3449 const AVIndexEntry *e_old_end = e_old + nb_old;
3450 const AVIndexEntry *current = NULL;
3451 MOVStts *ctts_data_old = msc->ctts_data;
3452 int64_t ctts_index_old = 0;
3453 int64_t ctts_sample_old = 0;
3454 int64_t ctts_count_old = msc->ctts_count;
3455 int64_t edit_list_media_time = 0;
3456 int64_t edit_list_duration = 0;
3457 int64_t frame_duration = 0;
3458 int64_t edit_list_dts_counter = 0;
3459 int64_t edit_list_dts_entry_end = 0;
3460 int64_t edit_list_start_ctts_sample = 0;
3462 int64_t curr_ctts = 0;
3463 int64_t empty_edits_sum_duration = 0;
3464 int64_t edit_list_index = 0;
3467 int64_t start_dts = 0;
3468 int64_t edit_list_start_encountered = 0;
3469 int64_t search_timestamp = 0;
3470 int64_t* frame_duration_buffer = NULL;
3471 int num_discarded_begin = 0;
3472 int first_non_zero_audio_edit = -1;
3473 int packet_skip_samples = 0;
3474 MOVIndexRange *current_index_range;
3476 int found_keyframe_after_edit = 0;
3477 int found_non_empty_edit = 0;
3479 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
3483 // allocate the index ranges array
3484 msc->index_ranges = av_malloc((msc->elst_count + 1) * sizeof(msc->index_ranges[0]));
3485 if (!msc->index_ranges) {
3486 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
3489 msc->current_index_range = msc->index_ranges;
3490 current_index_range = msc->index_ranges - 1;
3492 // Clean AVStream from traces of old index
3493 st->index_entries = NULL;
3494 st->index_entries_allocated_size = 0;
3495 st->nb_index_entries = 0;
3497 // Clean ctts fields of MOVStreamContext
3498 msc->ctts_data = NULL;
3499 msc->ctts_count = 0;
3500 msc->ctts_index = 0;
3501 msc->ctts_sample = 0;
3502 msc->ctts_allocated_size = 0;
3504 // Reinitialize min_corrected_pts so that it can be computed again.
3505 msc->min_corrected_pts = -1;
3507 // If the dts_shift is positive (in case of negative ctts values in mov),
3508 // then negate the DTS by dts_shift
3509 if (msc->dts_shift > 0) {
3510 edit_list_dts_entry_end -= msc->dts_shift;
3511 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
3514 start_dts = edit_list_dts_entry_end;
3516 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
3517 &edit_list_duration, mov->time_scale)) {
3518 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
3519 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
3521 edit_list_dts_counter = edit_list_dts_entry_end;
3522 edit_list_dts_entry_end += edit_list_duration;
3523 num_discarded_begin = 0;
3524 if (!found_non_empty_edit && edit_list_media_time == -1) {
3525 empty_edits_sum_duration += edit_list_duration;
3528 found_non_empty_edit = 1;
3530 // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
3531 // according to the edit list below.
3532 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3533 if (first_non_zero_audio_edit < 0) {
3534 first_non_zero_audio_edit = 1;
3536 first_non_zero_audio_edit = 0;
3539 if (first_non_zero_audio_edit > 0)
3540 st->skip_samples = msc->start_pad = 0;
3543 // While reordering frame index according to edit list we must handle properly
3544 // the scenario when edit list entry starts from none key frame.
3545 // We find closest previous key frame and preserve it and consequent frames in index.
3546 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
3547 search_timestamp = edit_list_media_time;
3548 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3549 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
3550 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
3551 // edit_list_media_time to cover the decoder delay.
3552 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
3555 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
3556 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3557 av_log(mov->fc, AV_LOG_WARNING,
3558 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
3559 st->index, edit_list_index, search_timestamp);
3560 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
3561 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3562 av_log(mov->fc, AV_LOG_WARNING,
3563 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
3564 st->index, edit_list_index, search_timestamp);
3567 ctts_sample_old = 0;
3570 current = e_old + index;
3571 edit_list_start_ctts_sample = ctts_sample_old;
3573 // Iterate over index and arrange it according to edit list
3574 edit_list_start_encountered = 0;
3575 found_keyframe_after_edit = 0;
3576 for (; current < e_old_end; current++, index++) {
3577 // check if frame outside edit list mark it for discard
3578 frame_duration = (current + 1 < e_old_end) ?
3579 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
3581 flags = current->flags;
3583 // frames (pts) before or after edit list
3584 curr_cts = current->timestamp + msc->dts_shift;
3587 if (ctts_data_old && ctts_index_old < ctts_count_old) {
3588 curr_ctts = ctts_data_old[ctts_index_old].duration;
3589 av_log(mov->fc, AV_LOG_DEBUG, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
3590 curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
3591 curr_cts += curr_ctts;
3593 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
3594 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3595 &msc->ctts_allocated_size,
3596 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3597 ctts_data_old[ctts_index_old].duration) == -1) {
3598 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3600 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3601 ctts_data_old[ctts_index_old].duration);
3605 ctts_sample_old = 0;
3606 edit_list_start_ctts_sample = 0;
3610 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
3611 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
3612 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
3613 first_non_zero_audio_edit > 0) {
3614 packet_skip_samples = edit_list_media_time - curr_cts;
3615 st->skip_samples += packet_skip_samples;
3617 // Shift the index entry timestamp by packet_skip_samples to be correct.
3618 edit_list_dts_counter -= packet_skip_samples;
3619 if (edit_list_start_encountered == 0) {
3620 edit_list_start_encountered = 1;
3621 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
3622 // discarded packets.
3623 if (frame_duration_buffer) {
3624 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3625 frame_duration_buffer, num_discarded_begin);
3626 av_freep(&frame_duration_buffer);
3630 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
3632 flags |= AVINDEX_DISCARD_FRAME;
3633 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
3635 if (edit_list_start_encountered == 0) {
3636 num_discarded_begin++;
3637 frame_duration_buffer = av_realloc(frame_duration_buffer,
3638 num_discarded_begin * sizeof(int64_t));
3639 if (!frame_duration_buffer) {
3640 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
3643 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
3645 // Increment skip_samples for the first non-zero audio edit list
3646 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3647 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
3648 st->skip_samples += frame_duration;
3653 if (msc->min_corrected_pts < 0) {
3654 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
3656 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
3658 if (edit_list_start_encountered == 0) {
3659 edit_list_start_encountered = 1;
3660 // Make timestamps strictly monotonically increasing by rewriting timestamps for
3661 // discarded packets.
3662 if (frame_duration_buffer) {
3663 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3664 frame_duration_buffer, num_discarded_begin);
3665 av_freep(&frame_duration_buffer);
3670 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
3671 current->min_distance, flags) == -1) {
3672 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
3676 // Update the index ranges array
3677 if (current_index_range < msc->index_ranges || index != current_index_range->end) {
3678 current_index_range++;
3679 current_index_range->start = index;
3681 current_index_range->end = index + 1;
3683 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
3684 if (edit_list_start_encountered > 0) {
3685 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
3688 // Break when found first key frame after edit entry completion
3689 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
3690 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
3691 if (ctts_data_old) {
3692 // If we have CTTS and this is the first keyframe after edit elist,
3693 // wait for one more, because there might be trailing B-frames after this I-frame
3694 // that do belong to the edit.
3695 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
3696 found_keyframe_after_edit = 1;
3699 if (ctts_sample_old != 0) {
3700 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3701 &msc->ctts_allocated_size,
3702 ctts_sample_old - edit_list_start_ctts_sample,
3703 ctts_data_old[ctts_index_old].duration) == -1) {
3704 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3705 ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
3706 ctts_data_old[ctts_index_old].duration);
3715 // If there are empty edits, then msc->min_corrected_pts might be positive
3716 // intentionally. So we subtract the sum duration of emtpy edits here.
3717 msc->min_corrected_pts -= empty_edits_sum_duration;
3719 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
3720 // dts by that amount to make the first pts zero.
3721 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
3722 if (msc->min_corrected_pts > 0) {
3723 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
3724 for (i = 0; i < st->nb_index_entries; ++i) {
3725 st->index_entries[i].timestamp -= msc->min_corrected_pts;
3729 // Start time should be equal to zero or the duration of any empty edits.
3730 st->start_time = empty_edits_sum_duration;
3732 // Update av stream length, if it ends up shorter than the track's media duration
3733 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
3734 msc->start_pad = st->skip_samples;
3736 // Free the old index and the old CTTS structures
3738 av_free(ctts_data_old);
3739 av_freep(&frame_duration_buffer);
3741 // Null terminate the index ranges array
3742 current_index_range++;
3743 current_index_range->start = 0;
3744 current_index_range->end = 0;
3745 msc->current_index = msc->index_ranges[0].start;
3748 static void mov_build_index(MOVContext *mov, AVStream *st)
3750 MOVStreamContext *sc = st->priv_data;
3751 int64_t current_offset;
3752 int64_t current_dts = 0;
3753 unsigned int stts_index = 0;
3754 unsigned int stsc_index = 0;
3755 unsigned int stss_index = 0;
3756 unsigned int stps_index = 0;
3758 uint64_t stream_size = 0;
3759 MOVStts *ctts_data_old = sc->ctts_data;
3760 unsigned int ctts_count_old = sc->ctts_count;
3762 if (sc->elst_count) {
3763 int i, edit_start_index = 0, multiple_edits = 0;
3764 int64_t empty_duration = 0; // empty duration of the first edit list entry
3765 int64_t start_time = 0; // start time of the media
3767 for (i = 0; i < sc->elst_count; i++) {
3768 const MOVElst *e = &sc->elst_data[i];
3769 if (i == 0 && e->time == -1) {
3770 /* if empty, the first entry is the start time of the stream
3771 * relative to the presentation itself */
3772 empty_duration = e->duration;
3773 edit_start_index = 1;
3774 } else if (i == edit_start_index && e->time >= 0) {
3775 start_time = e->time;
3781 if (multiple_edits && !mov->advanced_editlist)
3782 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
3783 "Use -advanced_editlist to correctly decode otherwise "
3784 "a/v desync might occur\n");
3786 /* adjust first dts according to edit list */
3787 if ((empty_duration || start_time) && mov->time_scale > 0) {
3789 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
3790 sc->time_offset = start_time - empty_duration;
3791 sc->min_corrected_pts = start_time;
3792 if (!mov->advanced_editlist)
3793 current_dts = -sc->time_offset;
3796 if (!multiple_edits && !mov->advanced_editlist &&
3797 st->codecpar->codec_id == AV_CODEC_ID_AAC && start_time > 0)
3798 sc->start_pad = start_time;
3801 /* only use old uncompressed audio chunk demuxing when stts specifies it */
3802 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3803 sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
3804 unsigned int current_sample = 0;
3805 unsigned int stts_sample = 0;
3806 unsigned int sample_size;
3807 unsigned int distance = 0;
3808 unsigned int rap_group_index = 0;
3809 unsigned int rap_group_sample = 0;
3810 int64_t last_dts = 0;
3811 int64_t dts_correction = 0;
3812 int rap_group_present = sc->rap_group_count && sc->rap_group;
3813 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
3815 current_dts -= sc->dts_shift;
3816 last_dts = current_dts;
3818 if (!sc->sample_count || st->nb_index_entries)
3820 if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
3822 if (av_reallocp_array(&st->index_entries,
3823 st->nb_index_entries + sc->sample_count,
3824 sizeof(*st->index_entries)) < 0) {
3825 st->nb_index_entries = 0;
3828 st->index_entries_allocated_size = (st->nb_index_entries + sc->sample_count) * sizeof(*st->index_entries);
3830 if (ctts_data_old) {
3831 // Expand ctts entries such that we have a 1-1 mapping with samples
3832 if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
3835 sc->ctts_allocated_size = 0;
3836 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size,
3837 sc->sample_count * sizeof(*sc->ctts_data));
3838 if (!sc->ctts_data) {
3839 av_free(ctts_data_old);
3843 memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
3845 for (i = 0; i < ctts_count_old &&
3846 sc->ctts_count < sc->sample_count; i++)
3847 for (j = 0; j < ctts_data_old[i].count &&
3848 sc->ctts_count < sc->sample_count; j++)
3849 add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
3850 &sc->ctts_allocated_size, 1,
3851 ctts_data_old[i].duration);
3852 av_free(ctts_data_old);
3855 for (i = 0; i < sc->chunk_count; i++) {
3856 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
3857 current_offset = sc->chunk_offsets[i];
3858 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3859 i + 1 == sc->stsc_data[stsc_index + 1].first)
3862 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
3863 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
3864 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
3865 sc->stsz_sample_size = sc->sample_size;
3867 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
3868 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
3869 sc->stsz_sample_size = sc->sample_size;
3872 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
3874 if (current_sample >= sc->sample_count) {
3875 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
3879 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
3881 if (stss_index + 1 < sc->keyframe_count)
3883 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
3885 if (stps_index + 1 < sc->stps_count)
3888 if (rap_group_present && rap_group_index < sc->rap_group_count) {
3889 if (sc->rap_group[rap_group_index].index > 0)
3891 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
3892 rap_group_sample = 0;
3896 if (sc->keyframe_absent
3898 && !rap_group_present
3899 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
3903 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
3904 if (sc->pseudo_stream_id == -1 ||
3905 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
3907 if (sample_size > 0x3FFFFFFF) {
3908 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
3911 e = &st->index_entries[st->nb_index_entries++];
3912 e->pos = current_offset;
3913 e->timestamp = current_dts;
3914 e->size = sample_size;
3915 e->min_distance = distance;
3916 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
3917 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
3918 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
3919 current_offset, current_dts, sample_size, distance, keyframe);
3920 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries < 100)
3921 ff_rfps_add_frame(mov->fc, st, current_dts);
3924 current_offset += sample_size;
3925 stream_size += sample_size;
3927 /* A negative sample duration is invalid based on the spec,
3928 * but some samples need it to correct the DTS. */
3929 if (sc->stts_data[stts_index].duration < 0) {
3930 av_log(mov->fc, AV_LOG_WARNING,
3931 "Invalid SampleDelta %d in STTS, at %d st:%d\n",
3932 sc->stts_data[stts_index].duration, stts_index,
3934 dts_correction += sc->stts_data[stts_index].duration - 1;
3935 sc->stts_data[stts_index].duration = 1;
3937 current_dts += sc->stts_data[stts_index].duration;
3938 if (!dts_correction || current_dts + dts_correction > last_dts) {
3939 current_dts += dts_correction;
3942 /* Avoid creating non-monotonous DTS */
3943 dts_correction += current_dts - last_dts - 1;
3944 current_dts = last_dts + 1;
3946 last_dts = current_dts;
3950 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
3956 if (st->duration > 0)
3957 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
3959 unsigned chunk_samples, total = 0;
3961 if (!sc->chunk_count)
3964 // compute total chunk count
3965 for (i = 0; i < sc->stsc_count; i++) {
3966 unsigned count, chunk_count;
3968 chunk_samples = sc->stsc_data[i].count;
3969 if (i != sc->stsc_count - 1 &&
3970 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
3971 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
3975 if (sc->samples_per_frame >= 160) { // gsm
3976 count = chunk_samples / sc->samples_per_frame;
3977 } else if (sc->samples_per_frame > 1) {
3978 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
3979 count = (chunk_samples+samples-1) / samples;
3981 count = (chunk_samples+1023) / 1024;
3984 if (mov_stsc_index_valid(i, sc->stsc_count))
3985 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
3987 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
3988 total += chunk_count * count;
3991 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
3992 if (total >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
3994 if (av_reallocp_array(&st->index_entries,
3995 st->nb_index_entries + total,
3996 sizeof(*st->index_entries)) < 0) {
3997 st->nb_index_entries = 0;
4000 st->index_entries_allocated_size = (st->nb_index_entries + total) * sizeof(*st->index_entries);
4003 for (i = 0; i < sc->chunk_count; i++) {
4004 current_offset = sc->chunk_offsets[i];
4005 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4006 i + 1 == sc->stsc_data[stsc_index + 1].first)
4008 chunk_samples = sc->stsc_data[stsc_index].count;
4010 while (chunk_samples > 0) {
4012 unsigned size, samples;
4014 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4015 avpriv_request_sample(mov->fc,
4016 "Zero bytes per frame, but %d samples per frame",
4017 sc->samples_per_frame);
4021 if (sc->samples_per_frame >= 160) { // gsm
4022 samples = sc->samples_per_frame;
4023 size = sc->bytes_per_frame;
4025 if (sc->samples_per_frame > 1) {
4026 samples = FFMIN((1024 / sc->samples_per_frame)*
4027 sc->samples_per_frame, chunk_samples);
4028 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
4030 samples = FFMIN(1024, chunk_samples);
4031 size = samples * sc->sample_size;
4035 if (st->nb_index_entries >= total) {
4036 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4039 if (size > 0x3FFFFFFF) {
4040 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4043 e = &st->index_entries[st->nb_index_entries++];
4044 e->pos = current_offset;
4045 e->timestamp = current_dts;
4047 e->min_distance = 0;
4048 e->flags = AVINDEX_KEYFRAME;
4049 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4050 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4053 current_offset += size;
4054 current_dts += samples;
4055 chunk_samples -= samples;
4060 if (!mov->ignore_editlist && mov->advanced_editlist) {
4061 // Fix index according to edit lists.
4062 mov_fix_index(mov, st);
4065 // Update start time of the stream.
4066 if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries > 0) {
4067 st->start_time = st->index_entries[0].timestamp + sc->dts_shift;
4068 if (sc->ctts_data) {
4069 st->start_time += sc->ctts_data[0].duration;
4073 mov_estimate_video_delay(mov, st);
4076 static int test_same_origin(const char *src, const char *ref) {
4086 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4087 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4089 if (strlen(src) == 0) {
4091 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4092 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4093 strlen(src_host) + 1 >= sizeof(src_host) ||
4094 strlen(ref_host) + 1 >= sizeof(ref_host)) {
4096 } else if (strcmp(src_proto, ref_proto) ||
4097 strcmp(src_auth, ref_auth) ||
4098 strcmp(src_host, ref_host) ||
4099 src_port != ref_port) {
4105 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4107 /* try relative path, we do not try the absolute because it can leak information about our
4108 system to an attacker */
4109 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4110 char filename[1025];
4111 const char *src_path;
4114 /* find a source dir */
4115 src_path = strrchr(src, '/');
4121 /* find a next level down to target */
4122 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4123 if (ref->path[l] == '/') {
4124 if (i == ref->nlvl_to - 1)
4130 /* compose filename if next level down to target was found */
4131 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4132 memcpy(filename, src, src_path - src);
4133 filename[src_path - src] = 0;
4135 for (i = 1; i < ref->nlvl_from; i++)
4136 av_strlcat(filename, "../", sizeof(filename));
4138 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4139 if (!c->use_absolute_path) {
4140 int same_origin = test_same_origin(src, filename);
4143 av_log(c->fc, AV_LOG_ERROR,
4144 "Reference with mismatching origin, %s not tried for security reasons, "
4145 "set demuxer option use_absolute_path to allow it anyway\n",
4147 return AVERROR(ENOENT);
4150 if(strstr(ref->path + l + 1, "..") ||
4151 strstr(ref->path + l + 1, ":") ||
4152 (ref->nlvl_from > 1 && same_origin < 0) ||
4153 (filename[0] == '/' && src_path == src))
4154 return AVERROR(ENOENT);
4157 if (strlen(filename) + 1 == sizeof(filename))
4158 return AVERROR(ENOENT);
4159 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4162 } else if (c->use_absolute_path) {
4163 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4164 "this is a possible security issue\n");
4165 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4168 av_log(c->fc, AV_LOG_ERROR,
4169 "Absolute path %s not tried for security reasons, "
4170 "set demuxer option use_absolute_path to allow absolute paths\n",
4174 return AVERROR(ENOENT);
4177 static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
4179 if (sc->time_scale <= 0) {
4180 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4181 sc->time_scale = c->time_scale;
4182 if (sc->time_scale <= 0)
4187 static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4190 MOVStreamContext *sc;
4193 st = avformat_new_stream(c->fc, NULL);
4194 if (!st) return AVERROR(ENOMEM);
4196 sc = av_mallocz(sizeof(MOVStreamContext));
4197 if (!sc) return AVERROR(ENOMEM);
4200 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
4201 sc->ffindex = st->index;
4202 c->trak_index = st->index;
4204 if ((ret = mov_read_default(c, pb, atom)) < 0)
4209 // Here stsc refers to a chunk not described in stco. This is technically invalid,
4210 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4211 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4213 av_freep(&sc->stsc_data);
4217 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4218 (!sc->sample_size && !sc->sample_count))) ||
4219 (!sc->chunk_count && sc->sample_count)) {
4220 av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4224 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4225 av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4227 return AVERROR_INVALIDDATA;
4230 fix_timescale(c, sc);
4232 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4234 mov_build_index(c, st);
4236 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4237 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4238 if (c->enable_drefs) {
4239 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4240 av_log(c->fc, AV_LOG_ERROR,
4241 "stream %d, error opening alias: path='%s', dir='%s', "
4242 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4243 st->index, dref->path, dref->dir, dref->filename,
4244 dref->volume, dref->nlvl_from, dref->nlvl_to);
4246 av_log(c->fc, AV_LOG_WARNING,
4247 "Skipped opening external track: "
4248 "stream %d, alias: path='%s', dir='%s', "
4249 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4250 "Set enable_drefs to allow this.\n",
4251 st->index, dref->path, dref->dir, dref->filename,
4252 dref->volume, dref->nlvl_from, dref->nlvl_to);
4256 sc->pb_is_copied = 1;
4259 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4260 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4261 sc->height && sc->width &&
4262 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4263 st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4264 ((double)st->codecpar->width * sc->height), INT_MAX);
4267 #if FF_API_R_FRAME_RATE
4268 if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4269 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
4270 sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4274 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4275 if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4276 TAG_IS_AVCI(st->codecpar->codec_tag)) {
4277 ret = ff_generate_avci_extradata(st);
4282 switch (st->codecpar->codec_id) {
4283 #if CONFIG_H261_DECODER
4284 case AV_CODEC_ID_H261:
4286 #if CONFIG_H263_DECODER
4287 case AV_CODEC_ID_H263:
4289 #if CONFIG_MPEG4_DECODER
4290 case AV_CODEC_ID_MPEG4:
4292 st->codecpar->width = 0; /* let decoder init width/height */
4293 st->codecpar->height= 0;
4297 // If the duration of the mp3 packets is not constant, then they could need a parser
4298 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4299 && sc->stts_count > 3
4300 && sc->stts_count*10 > st->nb_frames
4301 && sc->time_scale == st->codecpar->sample_rate) {
4302 st->need_parsing = AVSTREAM_PARSE_FULL;
4304 /* Do not need those anymore. */
4305 av_freep(&sc->chunk_offsets);
4306 av_freep(&sc->sample_sizes);
4307 av_freep(&sc->keyframes);
4308 av_freep(&sc->stts_data);
4309 av_freep(&sc->stps_data);
4310 av_freep(&sc->elst_data);
4311 av_freep(&sc->rap_group);
4316 static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4319 c->itunes_metadata = 1;
4320 ret = mov_read_default(c, pb, atom);
4321 c->itunes_metadata = 0;
4325 static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4334 count = avio_rb32(pb);
4335 if (count > UINT_MAX / sizeof(*c->meta_keys) - 1) {
4336 av_log(c->fc, AV_LOG_ERROR,
4337 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
4338 return AVERROR_INVALIDDATA;
4341 c->meta_keys_count = count + 1;
4342 c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
4344 return AVERROR(ENOMEM);
4346 for (i = 1; i <= count; ++i) {
4347 uint32_t key_size = avio_rb32(pb);
4348 uint32_t type = avio_rl32(pb);
4350 av_log(c->fc, AV_LOG_ERROR,
4351 "The key# %"PRIu32" in meta has invalid size:"
4352 "%"PRIu32"\n", i, key_size);
4353 return AVERROR_INVALIDDATA;
4356 if (type != MKTAG('m','d','t','a')) {
4357 avio_skip(pb, key_size);
4359 c->meta_keys[i] = av_mallocz(key_size + 1);
4360 if (!c->meta_keys[i])
4361 return AVERROR(ENOMEM);
4362 avio_read(pb, c->meta_keys[i], key_size);
4368 static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4370 int64_t end = avio_tell(pb) + atom.size;
4371 uint8_t *key = NULL, *val = NULL, *mean = NULL;
4375 MOVStreamContext *sc;
4377 if (c->fc->nb_streams < 1)
4379 st = c->fc->streams[c->fc->nb_streams-1];
4382 for (i = 0; i < 3; i++) {
4386 if (end - avio_tell(pb) <= 12)
4389 len = avio_rb32(pb);
4390 tag = avio_rl32(pb);
4391 avio_skip(pb, 4); // flags
4393 if (len < 12 || len - 12 > end - avio_tell(pb))
4397 if (tag == MKTAG('m', 'e', 'a', 'n'))
4399 else if (tag == MKTAG('n', 'a', 'm', 'e'))
4401 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
4408 *p = av_malloc(len + 1);
4410 ret = AVERROR(ENOMEM);
4413 ret = ffio_read_size(pb, *p, len);
4421 if (mean && key && val) {
4422 if (strcmp(key, "iTunSMPB") == 0) {
4423 int priming, remainder, samples;
4424 if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
4425 if(priming>0 && priming<16384)
4426 sc->start_pad = priming;
4429 if (strcmp(key, "cdec") != 0) {
4430 av_dict_set(&c->fc->metadata, key, val,
4431 AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
4435 av_log(c->fc, AV_LOG_VERBOSE,
4436 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
4439 avio_seek(pb, end, SEEK_SET);
4446 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4448 while (atom.size > 8) {
4452 tag = avio_rl32(pb);
4454 if (tag == MKTAG('h','d','l','r')) {
4455 avio_seek(pb, -8, SEEK_CUR);
4457 return mov_read_default(c, pb, atom);
4463 // return 1 when matrix is identity, 0 otherwise
4464 #define IS_MATRIX_IDENT(matrix) \
4465 ( (matrix)[0][0] == (1 << 16) && \
4466 (matrix)[1][1] == (1 << 16) && \
4467 (matrix)[2][2] == (1 << 30) && \
4468 !(matrix)[0][1] && !(matrix)[0][2] && \
4469 !(matrix)[1][0] && !(matrix)[1][2] && \
4470 !(matrix)[2][0] && !(matrix)[2][1])
4472 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4477 int display_matrix[3][3];
4478 int res_display_matrix[3][3] = { { 0 } };
4480 MOVStreamContext *sc;
4484 if (c->fc->nb_streams < 1)
4486 st = c->fc->streams[c->fc->nb_streams-1];
4489 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4490 // avoids corrupting AVStreams mapped to an earlier tkhd.
4492 return AVERROR_INVALIDDATA;
4494 version = avio_r8(pb);
4495 flags = avio_rb24(pb);
4496 st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
4502 avio_rb32(pb); /* creation time */
4503 avio_rb32(pb); /* modification time */
4505 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4506 avio_rb32(pb); /* reserved */
4508 /* highlevel (considering edits) duration in movie timebase */
4509 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4510 avio_rb32(pb); /* reserved */
4511 avio_rb32(pb); /* reserved */
4513 avio_rb16(pb); /* layer */
4514 avio_rb16(pb); /* alternate group */
4515 avio_rb16(pb); /* volume */
4516 avio_rb16(pb); /* reserved */
4518 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4519 // they're kept in fixed point format through all calculations
4520 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4521 // side data, but the scale factor is not needed to calculate aspect ratio
4522 for (i = 0; i < 3; i++) {
4523 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
4524 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
4525 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
4528 width = avio_rb32(pb); // 16.16 fixed point track width
4529 height = avio_rb32(pb); // 16.16 fixed point track height
4530 sc->width = width >> 16;
4531 sc->height = height >> 16;
4533 // apply the moov display matrix (after the tkhd one)
4534 for (i = 0; i < 3; i++) {
4535 const int sh[3] = { 16, 16, 30 };
4536 for (j = 0; j < 3; j++) {
4537 for (e = 0; e < 3; e++) {
4538 res_display_matrix[i][j] +=
4539 ((int64_t) display_matrix[i][e] *
4540 c->movie_display_matrix[e][j]) >> sh[e];
4545 // save the matrix when it is not the default identity
4546 if (!IS_MATRIX_IDENT(res_display_matrix)) {
4549 av_freep(&sc->display_matrix);
4550 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4551 if (!sc->display_matrix)
4552 return AVERROR(ENOMEM);
4554 for (i = 0; i < 3; i++)
4555 for (j = 0; j < 3; j++)
4556 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4558 #if FF_API_OLD_ROTATE_API
4559 rotate = av_display_rotation_get(sc->display_matrix);
4560 if (!isnan(rotate)) {
4561 char rotate_buf[64];
4563 if (rotate < 0) // for backward compatibility
4565 snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate);
4566 av_dict_set(&st->metadata, "rotate", rotate_buf, 0);
4571 // transform the display width/height according to the matrix
4572 // to keep the same scale, use [width height 1<<16]
4573 if (width && height && sc->display_matrix) {
4574 double disp_transform[2];
4576 for (i = 0; i < 2; i++)
4577 disp_transform[i] = hypot(sc->display_matrix[0 + i],
4578 sc->display_matrix[3 + i]);
4580 if (disp_transform[0] > 0 && disp_transform[1] > 0 &&
4581 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4582 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4583 st->sample_aspect_ratio = av_d2q(
4584 disp_transform[0] / disp_transform[1],
4590 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4592 MOVFragment *frag = &c->fragment;
4593 MOVTrackExt *trex = NULL;
4594 int flags, track_id, i;
4596 avio_r8(pb); /* version */
4597 flags = avio_rb24(pb);
4599 track_id = avio_rb32(pb);
4601 return AVERROR_INVALIDDATA;
4602 for (i = 0; i < c->trex_count; i++)
4603 if (c->trex_data[i].track_id == track_id) {
4604 trex = &c->trex_data[i];
4608 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4611 c->fragment.found_tfhd = 1;
4612 frag->track_id = track_id;
4613 set_frag_stream(&c->frag_index, track_id);
4615 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4616 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4617 frag->moof_offset : frag->implicit_offset;
4618 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4620 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4621 avio_rb32(pb) : trex->duration;
4622 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4623 avio_rb32(pb) : trex->size;
4624 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4625 avio_rb32(pb) : trex->flags;
4626 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4631 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4636 num = atom.size / 4;
4637 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4638 return AVERROR(ENOMEM);
4640 av_free(c->chapter_tracks);
4641 c->chapter_tracks = new_tracks;
4642 c->nb_chapter_tracks = num;
4644 for (i = 0; i < num && !pb->eof_reached; i++)
4645 c->chapter_tracks[i] = avio_rb32(pb);
4650 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4655 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4656 return AVERROR_INVALIDDATA;
4657 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4658 sizeof(*c->trex_data))) < 0) {
4663 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4665 trex = &c->trex_data[c->trex_count++];
4666 avio_r8(pb); /* version */
4667 avio_rb24(pb); /* flags */
4668 trex->track_id = avio_rb32(pb);
4669 trex->stsd_id = avio_rb32(pb);
4670 trex->duration = avio_rb32(pb);
4671 trex->size = avio_rb32(pb);
4672 trex->flags = avio_rb32(pb);
4676 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4678 MOVFragment *frag = &c->fragment;
4679 AVStream *st = NULL;
4680 MOVStreamContext *sc;
4682 MOVFragmentStreamInfo * frag_stream_info;
4683 int64_t base_media_decode_time;
4685 for (i = 0; i < c->fc->nb_streams; i++) {
4686 if (c->fc->streams[i]->id == frag->track_id) {
4687 st = c->fc->streams[i];
4692 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4696 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4698 version = avio_r8(pb);
4699 avio_rb24(pb); /* flags */
4701 base_media_decode_time = avio_rb64(pb);
4703 base_media_decode_time = avio_rb32(pb);
4706 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4707 if (frag_stream_info)
4708 frag_stream_info->tfdt_dts = base_media_decode_time;
4709 sc->track_end = base_media_decode_time;
4714 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4716 MOVFragment *frag = &c->fragment;
4717 AVStream *st = NULL;
4718 MOVStreamContext *sc;
4721 int64_t dts, pts = AV_NOPTS_VALUE;
4722 int data_offset = 0;
4723 unsigned entries, first_sample_flags = frag->flags;
4724 int flags, distance, i;
4725 int64_t prev_dts = AV_NOPTS_VALUE;
4726 int next_frag_index = -1, index_entry_pos;
4727 size_t requested_size;
4728 size_t old_ctts_allocated_size;
4729 AVIndexEntry *new_entries;
4730 MOVFragmentStreamInfo * frag_stream_info;
4732 if (!frag->found_tfhd) {
4733 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4734 return AVERROR_INVALIDDATA;
4737 for (i = 0; i < c->fc->nb_streams; i++) {
4738 if (c->fc->streams[i]->id == frag->track_id) {
4739 st = c->fc->streams[i];
4744 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4748 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4751 // Find the next frag_index index that has a valid index_entry for
4752 // the current track_id.
4754 // A valid index_entry means the trun for the fragment was read
4755 // and it's samples are in index_entries at the given position.
4756 // New index entries will be inserted before the index_entry found.
4757 index_entry_pos = st->nb_index_entries;
4758 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4759 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4760 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4761 next_frag_index = i;
4762 index_entry_pos = frag_stream_info->index_entry;
4766 av_assert0(index_entry_pos <= st->nb_index_entries);
4768 avio_r8(pb); /* version */
4769 flags = avio_rb24(pb);
4770 entries = avio_rb32(pb);
4771 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4773 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4774 return AVERROR_INVALIDDATA;
4775 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4776 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4778 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4779 if (frag_stream_info)
4781 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4782 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4783 pts = frag_stream_info->first_tfra_pts;
4784 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4785 ", using it for pts\n", pts);
4786 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4787 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4788 // pts = frag_stream_info->sidx_pts;
4789 dts = frag_stream_info->sidx_pts - sc->time_offset;
4790 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4791 ", using it for pts\n", pts);
4792 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4793 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4794 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4795 ", using it for dts\n", dts);
4797 dts = sc->track_end - sc->time_offset;
4798 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4799 ", using it for dts\n", dts);
4802 dts = sc->track_end - sc->time_offset;
4803 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4804 ", using it for dts\n", dts);
4806 offset = frag->base_data_offset + data_offset;
4808 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4810 // realloc space for new index entries
4811 if((uint64_t)st->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4812 entries = UINT_MAX / sizeof(AVIndexEntry) - st->nb_index_entries;
4813 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4818 requested_size = (st->nb_index_entries + entries) * sizeof(AVIndexEntry);
4819 new_entries = av_fast_realloc(st->index_entries,
4820 &st->index_entries_allocated_size,
4823 return AVERROR(ENOMEM);
4824 st->index_entries= new_entries;
4826 requested_size = (st->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4827 old_ctts_allocated_size = sc->ctts_allocated_size;
4828 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4831 return AVERROR(ENOMEM);
4832 sc->ctts_data = ctts_data;
4834 // In case there were samples without ctts entries, ensure they get
4835 // zero valued entries. This ensures clips which mix boxes with and
4836 // without ctts entries don't pickup uninitialized data.
4837 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4838 sc->ctts_allocated_size - old_ctts_allocated_size);
4840 if (index_entry_pos < st->nb_index_entries) {
4841 // Make hole in index_entries and ctts_data for new samples
4842 memmove(st->index_entries + index_entry_pos + entries,
4843 st->index_entries + index_entry_pos,
4844 sizeof(*st->index_entries) *
4845 (st->nb_index_entries - index_entry_pos));
4846 memmove(sc->ctts_data + index_entry_pos + entries,
4847 sc->ctts_data + index_entry_pos,
4848 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4849 if (index_entry_pos < sc->current_sample) {
4850 sc->current_sample += entries;
4854 st->nb_index_entries += entries;
4855 sc->ctts_count = st->nb_index_entries;
4857 // Record the index_entry position in frag_index of this fragment
4858 if (frag_stream_info)
4859 frag_stream_info->index_entry = index_entry_pos;
4861 if (index_entry_pos > 0)
4862 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4864 for (i = 0; i < entries && !pb->eof_reached; i++) {
4865 unsigned sample_size = frag->size;
4866 int sample_flags = i ? frag->flags : first_sample_flags;
4867 unsigned sample_duration = frag->duration;
4868 unsigned ctts_duration = 0;
4870 int index_entry_flags = 0;
4872 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4873 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4874 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4875 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4877 mov_update_dts_shift(sc, ctts_duration, c->fc);
4878 if (pts != AV_NOPTS_VALUE) {
4879 dts = pts - sc->dts_shift;
4880 if (flags & MOV_TRUN_SAMPLE_CTS) {
4881 dts -= ctts_duration;
4883 dts -= sc->time_offset;
4885 av_log(c->fc, AV_LOG_DEBUG,
4886 "pts %"PRId64" calculated dts %"PRId64
4887 " sc->dts_shift %d ctts.duration %d"
4888 " sc->time_offset %"PRId64
4889 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4891 sc->dts_shift, ctts_duration,
4892 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4893 pts = AV_NOPTS_VALUE;
4896 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4900 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4901 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4904 index_entry_flags |= AVINDEX_KEYFRAME;
4906 // Fragments can overlap in time. Discard overlapping frames after
4908 if (prev_dts >= dts)
4909 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4911 st->index_entries[index_entry_pos].pos = offset;
4912 st->index_entries[index_entry_pos].timestamp = dts;
4913 st->index_entries[index_entry_pos].size= sample_size;
4914 st->index_entries[index_entry_pos].min_distance= distance;
4915 st->index_entries[index_entry_pos].flags = index_entry_flags;
4917 sc->ctts_data[index_entry_pos].count = 1;
4918 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4921 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4922 "size %u, distance %d, keyframe %d\n", st->index,
4923 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4925 dts += sample_duration;
4926 offset += sample_size;
4927 sc->data_size += sample_size;
4929 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4930 1 <= INT_MAX - sc->nb_frames_for_fps
4932 sc->duration_for_fps += sample_duration;
4933 sc->nb_frames_for_fps ++;
4937 // EOF found before reading all entries. Fix the hole this would
4938 // leave in index_entries and ctts_data
4939 int gap = entries - i;
4940 memmove(st->index_entries + index_entry_pos,
4941 st->index_entries + index_entry_pos + gap,
4942 sizeof(*st->index_entries) *
4943 (st->nb_index_entries - (index_entry_pos + gap)));
4944 memmove(sc->ctts_data + index_entry_pos,
4945 sc->ctts_data + index_entry_pos + gap,
4946 sizeof(*sc->ctts_data) *
4947 (sc->ctts_count - (index_entry_pos + gap)));
4949 st->nb_index_entries -= gap;
4950 sc->ctts_count -= gap;
4951 if (index_entry_pos < sc->current_sample) {
4952 sc->current_sample -= gap;
4957 // The end of this new fragment may overlap in time with the start
4958 // of the next fragment in index_entries. Mark the samples in the next
4959 // fragment that overlap with AVINDEX_DISCARD_FRAME
4960 prev_dts = AV_NOPTS_VALUE;
4961 if (index_entry_pos > 0)
4962 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4963 for (i = index_entry_pos; i < st->nb_index_entries; i++) {
4964 if (prev_dts < st->index_entries[i].timestamp)
4966 st->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
4969 // If a hole was created to insert the new index_entries into,
4970 // the index_entry recorded for all subsequent moof must
4971 // be incremented by the number of entries inserted.
4972 fix_frag_index_entries(&c->frag_index, next_frag_index,
4973 frag->track_id, entries);
4975 if (pb->eof_reached) {
4976 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
4980 frag->implicit_offset = offset;
4982 sc->track_end = dts + sc->time_offset;
4983 if (st->duration < sc->track_end)
4984 st->duration = sc->track_end;
4989 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4991 int64_t offset = avio_tell(pb) + atom.size, pts, timestamp;
4993 unsigned i, j, track_id, item_count;
4994 AVStream *st = NULL;
4995 AVStream *ref_st = NULL;
4996 MOVStreamContext *sc, *ref_sc = NULL;
4997 AVRational timescale;
4999 version = avio_r8(pb);
5001 avpriv_request_sample(c->fc, "sidx version %u", version);
5005 avio_rb24(pb); // flags
5007 track_id = avio_rb32(pb); // Reference ID
5008 for (i = 0; i < c->fc->nb_streams; i++) {
5009 if (c->fc->streams[i]->id == track_id) {
5010 st = c->fc->streams[i];
5015 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5021 timescale = av_make_q(1, avio_rb32(pb));
5023 if (timescale.den <= 0) {
5024 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5025 return AVERROR_INVALIDDATA;
5029 pts = avio_rb32(pb);
5030 offset += avio_rb32(pb);
5032 pts = avio_rb64(pb);
5033 offset += avio_rb64(pb);
5036 avio_rb16(pb); // reserved
5038 item_count = avio_rb16(pb);
5040 for (i = 0; i < item_count; i++) {
5042 MOVFragmentStreamInfo * frag_stream_info;
5043 uint32_t size = avio_rb32(pb);
5044 uint32_t duration = avio_rb32(pb);
5045 if (size & 0x80000000) {
5046 avpriv_request_sample(c->fc, "sidx reference_type 1");
5047 return AVERROR_PATCHWELCOME;
5049 avio_rb32(pb); // sap_flags
5050 timestamp = av_rescale_q(pts, timescale, st->time_base);
5052 index = update_frag_index(c, offset);
5053 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5054 if (frag_stream_info)
5055 frag_stream_info->sidx_pts = timestamp;
5061 st->duration = sc->track_end = pts;
5065 if (offset == avio_size(pb)) {
5066 // Find first entry in fragment index that came from an sidx.
5067 // This will pretty much always be the first entry.
5068 for (i = 0; i < c->frag_index.nb_items; i++) {
5069 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5070 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5071 MOVFragmentStreamInfo * si;
5072 si = &item->stream_info[j];
5073 if (si->sidx_pts != AV_NOPTS_VALUE) {
5074 ref_st = c->fc->streams[j];
5075 ref_sc = ref_st->priv_data;
5080 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5081 st = c->fc->streams[i];
5083 if (!sc->has_sidx) {
5084 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5088 c->frag_index.complete = 1;
5094 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5095 /* like the files created with Adobe Premiere 5.0, for samples see */
5096 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5097 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5102 return 0; /* continue */
5103 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5104 avio_skip(pb, atom.size - 4);
5107 atom.type = avio_rl32(pb);
5109 if (atom.type != MKTAG('m','d','a','t')) {
5110 avio_skip(pb, atom.size);
5113 err = mov_read_mdat(c, pb, atom);
5117 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5122 uint8_t *moov_data; /* uncompressed data */
5123 long cmov_len, moov_len;
5126 avio_rb32(pb); /* dcom atom */
5127 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5128 return AVERROR_INVALIDDATA;
5129 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5130 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5131 return AVERROR_INVALIDDATA;
5133 avio_rb32(pb); /* cmvd atom */
5134 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5135 return AVERROR_INVALIDDATA;
5136 moov_len = avio_rb32(pb); /* uncompressed size */
5137 cmov_len = atom.size - 6 * 4;
5139 cmov_data = av_malloc(cmov_len);
5141 return AVERROR(ENOMEM);
5142 moov_data = av_malloc(moov_len);
5145 return AVERROR(ENOMEM);
5147 ret = ffio_read_size(pb, cmov_data, cmov_len);
5149 goto free_and_return;
5151 ret = AVERROR_INVALIDDATA;
5152 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5153 goto free_and_return;
5154 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5155 goto free_and_return;
5156 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5157 atom.type = MKTAG('m','o','o','v');
5158 atom.size = moov_len;
5159 ret = mov_read_default(c, &ctx, atom);
5165 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5166 return AVERROR(ENOSYS);
5170 /* edit list atom */
5171 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5173 MOVStreamContext *sc;
5174 int i, edit_count, version;
5175 int64_t elst_entry_size;
5177 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5179 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5181 version = avio_r8(pb); /* version */
5182 avio_rb24(pb); /* flags */
5183 edit_count = avio_rb32(pb); /* entries */
5186 elst_entry_size = version == 1 ? 20 : 12;
5187 if (atom.size != edit_count * elst_entry_size) {
5188 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5189 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5190 edit_count, atom.size + 8);
5191 return AVERROR_INVALIDDATA;
5193 edit_count = atom.size / elst_entry_size;
5194 if (edit_count * elst_entry_size != atom.size) {
5195 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.", atom.size, edit_count);
5203 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5204 av_free(sc->elst_data);
5206 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5208 return AVERROR(ENOMEM);
5210 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5211 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5212 MOVElst *e = &sc->elst_data[i];
5215 e->duration = avio_rb64(pb);
5216 e->time = avio_rb64(pb);
5219 e->duration = avio_rb32(pb); /* segment duration */
5220 e->time = (int32_t)avio_rb32(pb); /* media time */
5223 e->rate = avio_rb32(pb) / 65536.0;
5225 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5226 e->duration, e->time, e->rate);
5228 if (e->time < 0 && e->time != -1 &&
5229 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5230 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5231 c->fc->nb_streams-1, i, e->time);
5232 return AVERROR_INVALIDDATA;
5240 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5242 MOVStreamContext *sc;
5244 if (c->fc->nb_streams < 1)
5245 return AVERROR_INVALIDDATA;
5246 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5247 sc->timecode_track = avio_rb32(pb);
5251 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5256 if (c->fc->nb_streams < 1)
5258 st = c->fc->streams[c->fc->nb_streams - 1];
5260 if (atom.size < 4) {
5261 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5262 return AVERROR_INVALIDDATA;
5265 /* For now, propagate only the OBUs, if any. Once libavcodec is
5266 updated to handle isobmff style extradata this can be removed. */
5272 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5279 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5282 int version, color_range, color_primaries, color_trc, color_space;
5284 if (c->fc->nb_streams < 1)
5286 st = c->fc->streams[c->fc->nb_streams - 1];
5288 if (atom.size < 5) {
5289 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5290 return AVERROR_INVALIDDATA;
5293 version = avio_r8(pb);
5295 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5298 avio_skip(pb, 3); /* flags */
5300 avio_skip(pb, 2); /* profile + level */
5301 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5302 color_primaries = avio_r8(pb);
5303 color_trc = avio_r8(pb);
5304 color_space = avio_r8(pb);
5305 if (avio_rb16(pb)) /* codecIntializationDataSize */
5306 return AVERROR_INVALIDDATA;
5308 if (!av_color_primaries_name(color_primaries))
5309 color_primaries = AVCOL_PRI_UNSPECIFIED;
5310 if (!av_color_transfer_name(color_trc))
5311 color_trc = AVCOL_TRC_UNSPECIFIED;
5312 if (!av_color_space_name(color_space))
5313 color_space = AVCOL_SPC_UNSPECIFIED;
5315 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5316 st->codecpar->color_primaries = color_primaries;
5317 st->codecpar->color_trc = color_trc;
5318 st->codecpar->color_space = color_space;
5323 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5325 MOVStreamContext *sc;
5328 if (c->fc->nb_streams < 1)
5329 return AVERROR_INVALIDDATA;
5331 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5333 if (atom.size < 5) {
5334 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5335 return AVERROR_INVALIDDATA;
5338 version = avio_r8(pb);
5340 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5343 avio_skip(pb, 3); /* flags */
5345 sc->mastering = av_mastering_display_metadata_alloc();
5347 return AVERROR(ENOMEM);
5349 for (i = 0; i < 3; i++) {
5350 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5351 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5353 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5354 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5356 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5357 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5359 sc->mastering->has_primaries = 1;
5360 sc->mastering->has_luminance = 1;
5365 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5367 MOVStreamContext *sc;
5368 const int mapping[3] = {1, 2, 0};
5369 const int chroma_den = 50000;
5370 const int luma_den = 10000;
5373 if (c->fc->nb_streams < 1)
5374 return AVERROR_INVALIDDATA;
5376 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5378 if (atom.size < 24) {
5379 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5380 return AVERROR_INVALIDDATA;
5383 sc->mastering = av_mastering_display_metadata_alloc();
5385 return AVERROR(ENOMEM);
5387 for (i = 0; i < 3; i++) {
5388 const int j = mapping[i];
5389 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5390 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5392 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5393 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5395 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5396 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5398 sc->mastering->has_luminance = 1;
5399 sc->mastering->has_primaries = 1;
5404 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5406 MOVStreamContext *sc;
5409 if (c->fc->nb_streams < 1)
5410 return AVERROR_INVALIDDATA;
5412 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5414 if (atom.size < 5) {
5415 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5416 return AVERROR_INVALIDDATA;
5419 version = avio_r8(pb);
5421 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5424 avio_skip(pb, 3); /* flags */
5426 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5428 return AVERROR(ENOMEM);
5430 sc->coll->MaxCLL = avio_rb16(pb);
5431 sc->coll->MaxFALL = avio_rb16(pb);
5436 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5438 MOVStreamContext *sc;
5440 if (c->fc->nb_streams < 1)
5441 return AVERROR_INVALIDDATA;
5443 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5445 if (atom.size < 4) {
5446 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5447 return AVERROR_INVALIDDATA;
5450 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5452 return AVERROR(ENOMEM);
5454 sc->coll->MaxCLL = avio_rb16(pb);
5455 sc->coll->MaxFALL = avio_rb16(pb);
5460 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5463 MOVStreamContext *sc;
5464 enum AVStereo3DType type;
5467 if (c->fc->nb_streams < 1)
5470 st = c->fc->streams[c->fc->nb_streams - 1];
5473 if (atom.size < 5) {
5474 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5475 return AVERROR_INVALIDDATA;
5477 avio_skip(pb, 4); /* version + flags */
5482 type = AV_STEREO3D_2D;
5485 type = AV_STEREO3D_TOPBOTTOM;
5488 type = AV_STEREO3D_SIDEBYSIDE;
5491 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5495 sc->stereo3d = av_stereo3d_alloc();
5497 return AVERROR(ENOMEM);
5499 sc->stereo3d->type = type;
5503 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5506 MOVStreamContext *sc;
5507 int size, version, layout;
5508 int32_t yaw, pitch, roll;
5509 uint32_t l = 0, t = 0, r = 0, b = 0;
5510 uint32_t tag, padding = 0;
5511 enum AVSphericalProjection projection;
5513 if (c->fc->nb_streams < 1)
5516 st = c->fc->streams[c->fc->nb_streams - 1];
5519 if (atom.size < 8) {
5520 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5521 return AVERROR_INVALIDDATA;
5524 size = avio_rb32(pb);
5525 if (size <= 12 || size > atom.size)
5526 return AVERROR_INVALIDDATA;
5528 tag = avio_rl32(pb);
5529 if (tag != MKTAG('s','v','h','d')) {
5530 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5533 version = avio_r8(pb);
5535 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5539 avio_skip(pb, 3); /* flags */
5540 avio_skip(pb, size - 12); /* metadata_source */
5542 size = avio_rb32(pb);
5543 if (size > atom.size)
5544 return AVERROR_INVALIDDATA;
5546 tag = avio_rl32(pb);
5547 if (tag != MKTAG('p','r','o','j')) {
5548 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5552 size = avio_rb32(pb);
5553 if (size > atom.size)
5554 return AVERROR_INVALIDDATA;
5556 tag = avio_rl32(pb);
5557 if (tag != MKTAG('p','r','h','d')) {
5558 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5561 version = avio_r8(pb);
5563 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5567 avio_skip(pb, 3); /* flags */
5569 /* 16.16 fixed point */
5570 yaw = avio_rb32(pb);
5571 pitch = avio_rb32(pb);
5572 roll = avio_rb32(pb);
5574 size = avio_rb32(pb);
5575 if (size > atom.size)
5576 return AVERROR_INVALIDDATA;
5578 tag = avio_rl32(pb);
5579 version = avio_r8(pb);
5581 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5585 avio_skip(pb, 3); /* flags */
5587 case MKTAG('c','b','m','p'):
5588 layout = avio_rb32(pb);
5590 av_log(c->fc, AV_LOG_WARNING,
5591 "Unsupported cubemap layout %d\n", layout);
5594 projection = AV_SPHERICAL_CUBEMAP;
5595 padding = avio_rb32(pb);
5597 case MKTAG('e','q','u','i'):
5603 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5604 av_log(c->fc, AV_LOG_ERROR,
5605 "Invalid bounding rectangle coordinates "
5606 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5607 return AVERROR_INVALIDDATA;
5610 if (l || t || r || b)
5611 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5613 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5616 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5620 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5622 return AVERROR(ENOMEM);
5624 sc->spherical->projection = projection;
5626 sc->spherical->yaw = yaw;
5627 sc->spherical->pitch = pitch;
5628 sc->spherical->roll = roll;
5630 sc->spherical->padding = padding;
5632 sc->spherical->bound_left = l;
5633 sc->spherical->bound_top = t;
5634 sc->spherical->bound_right = r;
5635 sc->spherical->bound_bottom = b;
5640 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5643 uint8_t *buffer = av_malloc(len + 1);
5647 return AVERROR(ENOMEM);
5650 ret = ffio_read_size(pb, buffer, len);
5654 /* Check for mandatory keys and values, try to support XML as best-effort */
5655 if (!sc->spherical &&
5656 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5657 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5658 av_stristr(val, "true") &&
5659 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5660 av_stristr(val, "true") &&
5661 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5662 av_stristr(val, "equirectangular")) {
5663 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5667 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5669 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5670 enum AVStereo3DType mode;
5672 if (av_stristr(buffer, "left-right"))
5673 mode = AV_STEREO3D_SIDEBYSIDE;
5674 else if (av_stristr(buffer, "top-bottom"))
5675 mode = AV_STEREO3D_TOPBOTTOM;
5677 mode = AV_STEREO3D_2D;
5679 sc->stereo3d = av_stereo3d_alloc();
5683 sc->stereo3d->type = mode;
5687 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5689 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5690 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5692 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5693 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5695 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5703 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5706 MOVStreamContext *sc;
5709 static const uint8_t uuid_isml_manifest[] = {
5710 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5711 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5713 static const uint8_t uuid_xmp[] = {
5714 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5715 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5717 static const uint8_t uuid_spherical[] = {
5718 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5719 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5722 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5723 return AVERROR_INVALIDDATA;
5725 if (c->fc->nb_streams < 1)
5727 st = c->fc->streams[c->fc->nb_streams - 1];
5730 ret = avio_read(pb, uuid, sizeof(uuid));
5733 } else if (ret != sizeof(uuid)) {
5734 return AVERROR_INVALIDDATA;
5736 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5737 uint8_t *buffer, *ptr;
5739 size_t len = atom.size - sizeof(uuid);
5742 return AVERROR_INVALIDDATA;
5744 ret = avio_skip(pb, 4); // zeroes
5747 buffer = av_mallocz(len + 1);
5749 return AVERROR(ENOMEM);
5751 ret = avio_read(pb, buffer, len);
5755 } else if (ret != len) {
5757 return AVERROR_INVALIDDATA;
5761 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5762 ptr += sizeof("systemBitrate=\"") - 1;
5763 c->bitrates_count++;
5764 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5766 c->bitrates_count = 0;
5768 return AVERROR(ENOMEM);
5771 ret = strtol(ptr, &endptr, 10);
5772 if (ret < 0 || errno || *endptr != '"') {
5773 c->bitrates[c->bitrates_count - 1] = 0;
5775 c->bitrates[c->bitrates_count - 1] = ret;
5780 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5782 size_t len = atom.size - sizeof(uuid);
5783 if (c->export_xmp) {
5784 buffer = av_mallocz(len + 1);
5786 return AVERROR(ENOMEM);
5788 ret = avio_read(pb, buffer, len);
5792 } else if (ret != len) {
5794 return AVERROR_INVALIDDATA;
5797 av_dict_set(&c->fc->metadata, "xmp", buffer, 0);
5800 // skip all uuid atom, which makes it fast for long uuid-xmp file
5801 ret = avio_skip(pb, len);
5805 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5806 size_t len = atom.size - sizeof(uuid);
5807 ret = mov_parse_uuid_spherical(sc, pb, len);
5811 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5817 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5820 uint8_t content[16];
5825 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5831 && !memcmp(content, "Anevia\x1A\x1A", 8)
5832 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5833 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5839 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5841 uint32_t format = avio_rl32(pb);
5842 MOVStreamContext *sc;
5846 if (c->fc->nb_streams < 1)
5848 st = c->fc->streams[c->fc->nb_streams - 1];
5853 case MKTAG('e','n','c','v'): // encrypted video
5854 case MKTAG('e','n','c','a'): // encrypted audio
5855 id = mov_codec_id(st, format);
5856 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5857 st->codecpar->codec_id != id) {
5858 av_log(c->fc, AV_LOG_WARNING,
5859 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5860 (char*)&format, st->codecpar->codec_id);
5864 st->codecpar->codec_id = id;
5865 sc->format = format;
5869 if (format != sc->format) {
5870 av_log(c->fc, AV_LOG_WARNING,
5871 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5872 (char*)&format, (char*)&sc->format);
5881 * Gets the current encryption info and associated current stream context. If
5882 * we are parsing a track fragment, this will return the specific encryption
5883 * info for this fragment; otherwise this will return the global encryption
5884 * info for the current stream.
5886 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5888 MOVFragmentStreamInfo *frag_stream_info;
5892 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5893 if (frag_stream_info) {
5894 for (i = 0; i < c->fc->nb_streams; i++) {
5895 if (c->fc->streams[i]->id == frag_stream_info->id) {
5896 st = c->fc->streams[i];
5900 if (i == c->fc->nb_streams)
5902 *sc = st->priv_data;
5904 if (!frag_stream_info->encryption_index) {
5905 // If this stream isn't encrypted, don't create the index.
5906 if (!(*sc)->cenc.default_encrypted_sample)
5908 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5909 if (!frag_stream_info->encryption_index)
5910 return AVERROR(ENOMEM);
5912 *encryption_index = frag_stream_info->encryption_index;
5915 // No current track fragment, using stream level encryption info.
5917 if (c->fc->nb_streams < 1)
5919 st = c->fc->streams[c->fc->nb_streams - 1];
5920 *sc = st->priv_data;
5922 if (!(*sc)->cenc.encryption_index) {
5923 // If this stream isn't encrypted, don't create the index.
5924 if (!(*sc)->cenc.default_encrypted_sample)
5926 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5927 if (!(*sc)->cenc.encryption_index)
5928 return AVERROR(ENOMEM);
5931 *encryption_index = (*sc)->cenc.encryption_index;
5936 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
5939 unsigned int subsample_count;
5940 AVSubsampleEncryptionInfo *subsamples;
5942 if (!sc->cenc.default_encrypted_sample) {
5943 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
5944 return AVERROR_INVALIDDATA;
5947 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
5949 return AVERROR(ENOMEM);
5951 if (sc->cenc.per_sample_iv_size != 0) {
5952 if (avio_read(pb, (*sample)->iv, sc->cenc.per_sample_iv_size) != sc->cenc.per_sample_iv_size) {
5953 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
5954 av_encryption_info_free(*sample);
5956 return AVERROR_INVALIDDATA;
5960 if (use_subsamples) {
5961 subsample_count = avio_rb16(pb);
5962 av_free((*sample)->subsamples);
5963 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
5964 if (!(*sample)->subsamples) {
5965 av_encryption_info_free(*sample);
5967 return AVERROR(ENOMEM);
5970 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
5971 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
5972 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
5975 if (pb->eof_reached) {
5976 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
5977 av_encryption_info_free(*sample);
5979 return AVERROR_INVALIDDATA;
5981 (*sample)->subsample_count = subsample_count;
5987 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5989 AVEncryptionInfo **encrypted_samples;
5990 MOVEncryptionIndex *encryption_index;
5991 MOVStreamContext *sc;
5992 int use_subsamples, ret;
5993 unsigned int sample_count, i, alloc_size = 0;
5995 ret = get_current_encryption_info(c, &encryption_index, &sc);
5999 if (encryption_index->nb_encrypted_samples) {
6000 // This can happen if we have both saio/saiz and senc atoms.
6001 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6005 avio_r8(pb); /* version */
6006 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6008 sample_count = avio_rb32(pb);
6009 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6010 return AVERROR(ENOMEM);
6012 for (i = 0; i < sample_count; i++) {
6013 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6014 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6015 min_samples * sizeof(*encrypted_samples));
6016 if (encrypted_samples) {
6017 encryption_index->encrypted_samples = encrypted_samples;
6019 ret = mov_read_sample_encryption_info(
6020 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6022 ret = AVERROR(ENOMEM);
6024 if (pb->eof_reached) {
6025 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6026 ret = AVERROR_INVALIDDATA;
6031 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6032 av_freep(&encryption_index->encrypted_samples);
6036 encryption_index->nb_encrypted_samples = sample_count;
6041 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6043 AVEncryptionInfo **sample, **encrypted_samples;
6045 size_t sample_count, sample_info_size, i;
6047 unsigned int alloc_size = 0;
6049 if (encryption_index->nb_encrypted_samples)
6051 sample_count = encryption_index->auxiliary_info_sample_count;
6052 if (encryption_index->auxiliary_offsets_count != 1) {
6053 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6054 return AVERROR_PATCHWELCOME;
6056 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6057 return AVERROR(ENOMEM);
6059 prev_pos = avio_tell(pb);
6060 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6061 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6062 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6066 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6067 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6068 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6069 min_samples * sizeof(*encrypted_samples));
6070 if (!encrypted_samples) {
6071 ret = AVERROR(ENOMEM);
6074 encryption_index->encrypted_samples = encrypted_samples;
6076 sample = &encryption_index->encrypted_samples[i];
6077 sample_info_size = encryption_index->auxiliary_info_default_size
6078 ? encryption_index->auxiliary_info_default_size
6079 : encryption_index->auxiliary_info_sizes[i];
6081 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6085 if (pb->eof_reached) {
6086 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6087 ret = AVERROR_INVALIDDATA;
6089 encryption_index->nb_encrypted_samples = sample_count;
6093 avio_seek(pb, prev_pos, SEEK_SET);
6095 for (; i > 0; i--) {
6096 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6098 av_freep(&encryption_index->encrypted_samples);
6104 * Tries to read the given number of bytes from the stream and puts it in a
6105 * newly allocated buffer. This reads in small chunks to avoid allocating large
6106 * memory if the file contains an invalid/malicious size value.
6108 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6110 const unsigned int block_size = 1024 * 1024;
6111 uint8_t *buffer = NULL;
6112 unsigned int alloc_size = 0, offset = 0;
6113 while (offset < size) {
6114 unsigned int new_size =
6115 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6116 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6117 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6120 return AVERROR(ENOMEM);
6122 buffer = new_buffer;
6124 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6126 return AVERROR_INVALIDDATA;
6135 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6137 MOVEncryptionIndex *encryption_index;
6138 MOVStreamContext *sc;
6140 unsigned int sample_count, aux_info_type, aux_info_param;
6142 ret = get_current_encryption_info(c, &encryption_index, &sc);
6146 if (encryption_index->nb_encrypted_samples) {
6147 // This can happen if we have both saio/saiz and senc atoms.
6148 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6152 if (encryption_index->auxiliary_info_sample_count) {
6153 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6154 return AVERROR_INVALIDDATA;
6157 avio_r8(pb); /* version */
6158 if (avio_rb24(pb) & 0x01) { /* flags */
6159 aux_info_type = avio_rb32(pb);
6160 aux_info_param = avio_rb32(pb);
6161 if (sc->cenc.default_encrypted_sample) {
6162 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6163 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6166 if (aux_info_param != 0) {
6167 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6171 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6172 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6173 aux_info_type == MKBETAG('c','e','n','s') ||
6174 aux_info_type == MKBETAG('c','b','c','1') ||
6175 aux_info_type == MKBETAG('c','b','c','s')) &&
6176 aux_info_param == 0) {
6177 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6178 return AVERROR_INVALIDDATA;
6183 } else if (!sc->cenc.default_encrypted_sample) {
6184 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6188 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6189 sample_count = avio_rb32(pb);
6190 encryption_index->auxiliary_info_sample_count = sample_count;
6192 if (encryption_index->auxiliary_info_default_size == 0) {
6193 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6195 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6200 if (encryption_index->auxiliary_offsets_count) {
6201 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6207 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6209 uint64_t *auxiliary_offsets;
6210 MOVEncryptionIndex *encryption_index;
6211 MOVStreamContext *sc;
6213 unsigned int version, entry_count, aux_info_type, aux_info_param;
6214 unsigned int alloc_size = 0;
6216 ret = get_current_encryption_info(c, &encryption_index, &sc);
6220 if (encryption_index->nb_encrypted_samples) {
6221 // This can happen if we have both saio/saiz and senc atoms.
6222 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6226 if (encryption_index->auxiliary_offsets_count) {
6227 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6228 return AVERROR_INVALIDDATA;
6231 version = avio_r8(pb); /* version */
6232 if (avio_rb24(pb) & 0x01) { /* flags */
6233 aux_info_type = avio_rb32(pb);
6234 aux_info_param = avio_rb32(pb);
6235 if (sc->cenc.default_encrypted_sample) {
6236 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6237 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6240 if (aux_info_param != 0) {
6241 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6245 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6246 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6247 aux_info_type == MKBETAG('c','e','n','s') ||
6248 aux_info_type == MKBETAG('c','b','c','1') ||
6249 aux_info_type == MKBETAG('c','b','c','s')) &&
6250 aux_info_param == 0) {
6251 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6252 return AVERROR_INVALIDDATA;
6257 } else if (!sc->cenc.default_encrypted_sample) {
6258 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6262 entry_count = avio_rb32(pb);
6263 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6264 return AVERROR(ENOMEM);
6266 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6267 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6268 auxiliary_offsets = av_fast_realloc(
6269 encryption_index->auxiliary_offsets, &alloc_size,
6270 min_offsets * sizeof(*auxiliary_offsets));
6271 if (!auxiliary_offsets) {
6272 av_freep(&encryption_index->auxiliary_offsets);
6273 return AVERROR(ENOMEM);
6275 encryption_index->auxiliary_offsets = auxiliary_offsets;
6278 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6280 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6282 if (c->frag_index.current >= 0) {
6283 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6287 if (pb->eof_reached) {
6288 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6289 av_freep(&encryption_index->auxiliary_offsets);
6290 return AVERROR_INVALIDDATA;
6293 encryption_index->auxiliary_offsets_count = entry_count;
6295 if (encryption_index->auxiliary_info_sample_count) {
6296 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6302 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6304 AVEncryptionInitInfo *info, *old_init_info;
6307 uint8_t *side_data, *extra_data, *old_side_data;
6308 size_t side_data_size;
6309 int ret = 0, old_side_data_size;
6310 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6312 if (c->fc->nb_streams < 1)
6314 st = c->fc->streams[c->fc->nb_streams-1];
6316 version = avio_r8(pb); /* version */
6317 avio_rb24(pb); /* flags */
6319 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6320 /* key_id_size */ 16, /* data_size */ 0);
6322 return AVERROR(ENOMEM);
6324 if (avio_read(pb, info->system_id, 16) != 16) {
6325 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6326 ret = AVERROR_INVALIDDATA;
6331 kid_count = avio_rb32(pb);
6332 if (kid_count >= INT_MAX / sizeof(*key_ids))
6333 return AVERROR(ENOMEM);
6335 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6336 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6337 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6338 min_kid_count * sizeof(*key_ids));
6340 ret = AVERROR(ENOMEM);
6343 info->key_ids = key_ids;
6345 info->key_ids[i] = av_mallocz(16);
6346 if (!info->key_ids[i]) {
6347 ret = AVERROR(ENOMEM);
6350 info->num_key_ids = i + 1;
6352 if (avio_read(pb, info->key_ids[i], 16) != 16) {
6353 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6354 ret = AVERROR_INVALIDDATA;
6359 if (pb->eof_reached) {
6360 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6361 ret = AVERROR_INVALIDDATA;
6366 extra_data_size = avio_rb32(pb);
6367 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6371 av_freep(&info->data); // malloc(0) may still allocate something.
6372 info->data = extra_data;
6373 info->data_size = extra_data_size;
6375 // If there is existing initialization data, append to the list.
6376 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6377 if (old_side_data) {
6378 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6379 if (old_init_info) {
6380 // Append to the end of the list.
6381 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6387 info = old_init_info;
6389 // Assume existing side-data will be valid, so the only error we could get is OOM.
6390 ret = AVERROR(ENOMEM);
6395 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6397 ret = AVERROR(ENOMEM);
6400 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6401 side_data, side_data_size);
6406 av_encryption_init_info_free(info);
6410 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6413 MOVStreamContext *sc;
6415 if (c->fc->nb_streams < 1)
6417 st = c->fc->streams[c->fc->nb_streams-1];
6420 if (sc->pseudo_stream_id != 0) {
6421 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6422 return AVERROR_PATCHWELCOME;
6426 return AVERROR_INVALIDDATA;
6428 avio_rb32(pb); /* version and flags */
6430 if (!sc->cenc.default_encrypted_sample) {
6431 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6432 if (!sc->cenc.default_encrypted_sample) {
6433 return AVERROR(ENOMEM);
6437 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6441 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6444 MOVStreamContext *sc;
6445 unsigned int version, pattern, is_protected, iv_size;
6447 if (c->fc->nb_streams < 1)
6449 st = c->fc->streams[c->fc->nb_streams-1];
6452 if (sc->pseudo_stream_id != 0) {
6453 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6454 return AVERROR_PATCHWELCOME;
6457 if (!sc->cenc.default_encrypted_sample) {
6458 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6459 if (!sc->cenc.default_encrypted_sample) {
6460 return AVERROR(ENOMEM);
6465 return AVERROR_INVALIDDATA;
6467 version = avio_r8(pb); /* version */
6468 avio_rb24(pb); /* flags */
6470 avio_r8(pb); /* reserved */
6471 pattern = avio_r8(pb);
6474 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6475 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6478 is_protected = avio_r8(pb);
6479 if (is_protected && !sc->cenc.encryption_index) {
6480 // The whole stream should be by-default encrypted.
6481 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6482 if (!sc->cenc.encryption_index)
6483 return AVERROR(ENOMEM);
6485 sc->cenc.per_sample_iv_size = avio_r8(pb);
6486 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6487 sc->cenc.per_sample_iv_size != 16) {
6488 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6489 return AVERROR_INVALIDDATA;
6491 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6492 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6493 return AVERROR_INVALIDDATA;
6496 if (is_protected && !sc->cenc.per_sample_iv_size) {
6497 iv_size = avio_r8(pb);
6498 if (iv_size != 8 && iv_size != 16) {
6499 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6500 return AVERROR_INVALIDDATA;
6503 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6504 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6505 return AVERROR_INVALIDDATA;
6512 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6515 int last, type, size, ret;
6518 if (c->fc->nb_streams < 1)
6520 st = c->fc->streams[c->fc->nb_streams-1];
6522 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6523 return AVERROR_INVALIDDATA;
6525 /* Check FlacSpecificBox version. */
6526 if (avio_r8(pb) != 0)
6527 return AVERROR_INVALIDDATA;
6529 avio_rb24(pb); /* Flags */
6531 avio_read(pb, buf, sizeof(buf));
6532 flac_parse_block_header(buf, &last, &type, &size);
6534 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6535 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6536 return AVERROR_INVALIDDATA;
6539 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6544 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6549 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6553 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6554 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6555 return AVERROR_PATCHWELCOME;
6558 if (!sc->cenc.aes_ctr) {
6559 /* initialize the cipher */
6560 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6561 if (!sc->cenc.aes_ctr) {
6562 return AVERROR(ENOMEM);
6565 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6571 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6573 if (!sample->subsample_count)
6575 /* decrypt the whole packet */
6576 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6580 for (i = 0; i < sample->subsample_count; i++)
6582 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6583 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6584 return AVERROR_INVALIDDATA;
6587 /* skip the clear bytes */
6588 input += sample->subsamples[i].bytes_of_clear_data;
6589 size -= sample->subsamples[i].bytes_of_clear_data;
6591 /* decrypt the encrypted bytes */
6592 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6593 input += sample->subsamples[i].bytes_of_protected_data;
6594 size -= sample->subsamples[i].bytes_of_protected_data;
6598 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6599 return AVERROR_INVALIDDATA;
6605 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6607 MOVFragmentStreamInfo *frag_stream_info;
6608 MOVEncryptionIndex *encryption_index;
6609 AVEncryptionInfo *encrypted_sample;
6610 int encrypted_index, ret;
6612 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6613 encrypted_index = current_index;
6614 encryption_index = NULL;
6615 if (frag_stream_info) {
6616 // Note this only supports encryption info in the first sample descriptor.
6617 if (mov->fragment.stsd_id == 1) {
6618 if (frag_stream_info->encryption_index) {
6619 encrypted_index = current_index - frag_stream_info->index_entry;
6620 encryption_index = frag_stream_info->encryption_index;
6622 encryption_index = sc->cenc.encryption_index;
6626 encryption_index = sc->cenc.encryption_index;
6629 if (encryption_index) {
6630 if (encryption_index->auxiliary_info_sample_count &&
6631 !encryption_index->nb_encrypted_samples) {
6632 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6633 return AVERROR_INVALIDDATA;
6635 if (encryption_index->auxiliary_offsets_count &&
6636 !encryption_index->nb_encrypted_samples) {
6637 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6638 return AVERROR_INVALIDDATA;
6641 if (!encryption_index->nb_encrypted_samples) {
6642 // Full-sample encryption with default settings.
6643 encrypted_sample = sc->cenc.default_encrypted_sample;
6644 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6645 // Per-sample setting override.
6646 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6648 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6649 return AVERROR_INVALIDDATA;
6652 if (mov->decryption_key) {
6653 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6656 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6658 return AVERROR(ENOMEM);
6659 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6669 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6671 const int OPUS_SEEK_PREROLL_MS = 80;
6677 if (c->fc->nb_streams < 1)
6679 st = c->fc->streams[c->fc->nb_streams-1];
6681 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6682 return AVERROR_INVALIDDATA;
6684 /* Check OpusSpecificBox version. */
6685 if (avio_r8(pb) != 0) {
6686 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6687 return AVERROR_INVALIDDATA;
6690 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6691 size = atom.size + 8;
6693 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
6696 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6697 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6698 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6699 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6701 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6702 little-endian; aside from the preceeding magic and version they're
6703 otherwise currently identical. Data after output gain at offset 16
6704 doesn't need to be bytewapped. */
6705 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6706 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6707 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6708 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6710 st->codecpar->initial_padding = pre_skip;
6711 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6712 (AVRational){1, 1000},
6713 (AVRational){1, 48000});
6718 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6721 unsigned format_info;
6722 int channel_assignment, channel_assignment1, channel_assignment2;
6725 if (c->fc->nb_streams < 1)
6727 st = c->fc->streams[c->fc->nb_streams-1];
6730 return AVERROR_INVALIDDATA;
6732 format_info = avio_rb32(pb);
6734 ratebits = (format_info >> 28) & 0xF;
6735 channel_assignment1 = (format_info >> 15) & 0x1F;
6736 channel_assignment2 = format_info & 0x1FFF;
6737 if (channel_assignment2)
6738 channel_assignment = channel_assignment2;
6740 channel_assignment = channel_assignment1;
6742 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6743 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6744 st->codecpar->channels = truehd_channels(channel_assignment);
6745 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6750 static const MOVParseTableEntry mov_default_parse_table[] = {
6751 { MKTAG('A','C','L','R'), mov_read_aclr },
6752 { MKTAG('A','P','R','G'), mov_read_avid },
6753 { MKTAG('A','A','L','P'), mov_read_avid },
6754 { MKTAG('A','R','E','S'), mov_read_ares },
6755 { MKTAG('a','v','s','s'), mov_read_avss },
6756 { MKTAG('a','v','1','C'), mov_read_av1c },
6757 { MKTAG('c','h','p','l'), mov_read_chpl },
6758 { MKTAG('c','o','6','4'), mov_read_stco },
6759 { MKTAG('c','o','l','r'), mov_read_colr },
6760 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6761 { MKTAG('d','i','n','f'), mov_read_default },
6762 { MKTAG('D','p','x','E'), mov_read_dpxe },
6763 { MKTAG('d','r','e','f'), mov_read_dref },
6764 { MKTAG('e','d','t','s'), mov_read_default },
6765 { MKTAG('e','l','s','t'), mov_read_elst },
6766 { MKTAG('e','n','d','a'), mov_read_enda },
6767 { MKTAG('f','i','e','l'), mov_read_fiel },
6768 { MKTAG('a','d','r','m'), mov_read_adrm },
6769 { MKTAG('f','t','y','p'), mov_read_ftyp },
6770 { MKTAG('g','l','b','l'), mov_read_glbl },
6771 { MKTAG('h','d','l','r'), mov_read_hdlr },
6772 { MKTAG('i','l','s','t'), mov_read_ilst },
6773 { MKTAG('j','p','2','h'), mov_read_jp2h },
6774 { MKTAG('m','d','a','t'), mov_read_mdat },
6775 { MKTAG('m','d','h','d'), mov_read_mdhd },
6776 { MKTAG('m','d','i','a'), mov_read_default },
6777 { MKTAG('m','e','t','a'), mov_read_meta },
6778 { MKTAG('m','i','n','f'), mov_read_default },
6779 { MKTAG('m','o','o','f'), mov_read_moof },
6780 { MKTAG('m','o','o','v'), mov_read_moov },
6781 { MKTAG('m','v','e','x'), mov_read_default },
6782 { MKTAG('m','v','h','d'), mov_read_mvhd },
6783 { MKTAG('S','M','I',' '), mov_read_svq3 },
6784 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6785 { MKTAG('a','v','c','C'), mov_read_glbl },
6786 { MKTAG('p','a','s','p'), mov_read_pasp },
6787 { MKTAG('s','i','d','x'), mov_read_sidx },
6788 { MKTAG('s','t','b','l'), mov_read_default },
6789 { MKTAG('s','t','c','o'), mov_read_stco },
6790 { MKTAG('s','t','p','s'), mov_read_stps },
6791 { MKTAG('s','t','r','f'), mov_read_strf },
6792 { MKTAG('s','t','s','c'), mov_read_stsc },
6793 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6794 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6795 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6796 { MKTAG('s','t','t','s'), mov_read_stts },
6797 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6798 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
6799 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6800 { MKTAG('t','f','d','t'), mov_read_tfdt },
6801 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6802 { MKTAG('t','r','a','k'), mov_read_trak },
6803 { MKTAG('t','r','a','f'), mov_read_default },
6804 { MKTAG('t','r','e','f'), mov_read_default },
6805 { MKTAG('t','m','c','d'), mov_read_tmcd },
6806 { MKTAG('c','h','a','p'), mov_read_chap },
6807 { MKTAG('t','r','e','x'), mov_read_trex },
6808 { MKTAG('t','r','u','n'), mov_read_trun },
6809 { MKTAG('u','d','t','a'), mov_read_default },
6810 { MKTAG('w','a','v','e'), mov_read_wave },
6811 { MKTAG('e','s','d','s'), mov_read_esds },
6812 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6813 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6814 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6815 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6816 { MKTAG('w','f','e','x'), mov_read_wfex },
6817 { MKTAG('c','m','o','v'), mov_read_cmov },
6818 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6819 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6820 { MKTAG('s','b','g','p'), mov_read_sbgp },
6821 { MKTAG('h','v','c','C'), mov_read_glbl },
6822 { MKTAG('u','u','i','d'), mov_read_uuid },
6823 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6824 { MKTAG('f','r','e','e'), mov_read_free },
6825 { MKTAG('-','-','-','-'), mov_read_custom },
6826 { MKTAG('s','i','n','f'), mov_read_default },
6827 { MKTAG('f','r','m','a'), mov_read_frma },
6828 { MKTAG('s','e','n','c'), mov_read_senc },
6829 { MKTAG('s','a','i','z'), mov_read_saiz },
6830 { MKTAG('s','a','i','o'), mov_read_saio },
6831 { MKTAG('p','s','s','h'), mov_read_pssh },
6832 { MKTAG('s','c','h','m'), mov_read_schm },
6833 { MKTAG('s','c','h','i'), mov_read_default },
6834 { MKTAG('t','e','n','c'), mov_read_tenc },
6835 { MKTAG('d','f','L','a'), mov_read_dfla },
6836 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6837 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6838 { MKTAG('d','O','p','s'), mov_read_dops },
6839 { MKTAG('d','m','l','p'), mov_read_dmlp },
6840 { MKTAG('S','m','D','m'), mov_read_smdm },
6841 { MKTAG('C','o','L','L'), mov_read_coll },
6842 { MKTAG('v','p','c','C'), mov_read_vpcc },
6843 { MKTAG('m','d','c','v'), mov_read_mdcv },
6844 { MKTAG('c','l','l','i'), mov_read_clli },
6848 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6850 int64_t total_size = 0;
6854 if (c->atom_depth > 10) {
6855 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6856 return AVERROR_INVALIDDATA;
6861 atom.size = INT64_MAX;
6862 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6863 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
6866 if (atom.size >= 8) {
6867 a.size = avio_rb32(pb);
6868 a.type = avio_rl32(pb);
6869 if (a.type == MKTAG('f','r','e','e') &&
6871 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT &&
6874 uint32_t *type = (uint32_t *)buf + 1;
6875 if (avio_read(pb, buf, 8) != 8)
6876 return AVERROR_INVALIDDATA;
6877 avio_seek(pb, -8, SEEK_CUR);
6878 if (*type == MKTAG('m','v','h','d') ||
6879 *type == MKTAG('c','m','o','v')) {
6880 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free atom.\n");
6881 a.type = MKTAG('m','o','o','v');
6884 if (atom.type != MKTAG('r','o','o','t') &&
6885 atom.type != MKTAG('m','o','o','v'))
6887 if (a.type == MKTAG('t','r','a','k') || a.type == MKTAG('m','d','a','t'))
6889 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
6896 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
6897 a.size = avio_rb64(pb) - 8;
6901 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
6902 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
6904 a.size = atom.size - total_size + 8;
6909 a.size = FFMIN(a.size, atom.size - total_size);
6911 for (i = 0; mov_default_parse_table[i].type; i++)
6912 if (mov_default_parse_table[i].type == a.type) {
6913 parse = mov_default_parse_table[i].parse;
6917 // container is user data
6918 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
6919 atom.type == MKTAG('i','l','s','t')))
6920 parse = mov_read_udta_string;
6922 // Supports parsing the QuickTime Metadata Keys.
6923 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
6924 if (!parse && c->found_hdlr_mdta &&
6925 atom.type == MKTAG('m','e','t','a') &&
6926 a.type == MKTAG('k','e','y','s')) {
6927 parse = mov_read_keys;
6930 if (!parse) { /* skip leaf atoms data */
6931 avio_skip(pb, a.size);
6933 int64_t start_pos = avio_tell(pb);
6935 int err = parse(c, pb, a);
6940 if (c->found_moov && c->found_mdat &&
6941 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
6942 start_pos + a.size == avio_size(pb))) {
6943 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
6944 c->next_root_atom = start_pos + a.size;
6948 left = a.size - avio_tell(pb) + start_pos;
6949 if (left > 0) /* skip garbage at atom end */
6950 avio_skip(pb, left);
6951 else if (left < 0) {
6952 av_log(c->fc, AV_LOG_WARNING,
6953 "overread end of atom '%.4s' by %"PRId64" bytes\n",
6954 (char*)&a.type, -left);
6955 avio_seek(pb, left, SEEK_CUR);
6959 total_size += a.size;
6962 if (total_size < atom.size && atom.size < 0x7ffff)
6963 avio_skip(pb, atom.size - total_size);
6969 static int mov_probe(const AVProbeData *p)
6974 int moov_offset = -1;
6976 /* check file header */
6979 /* ignore invalid offset */
6980 if ((offset + 8) > (unsigned int)p->buf_size)
6982 tag = AV_RL32(p->buf + offset + 4);
6984 /* check for obvious tags */
6985 case MKTAG('m','o','o','v'):
6986 moov_offset = offset + 4;
6987 case MKTAG('m','d','a','t'):
6988 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
6989 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
6990 case MKTAG('f','t','y','p'):
6991 if (AV_RB32(p->buf+offset) < 8 &&
6992 (AV_RB32(p->buf+offset) != 1 ||
6993 offset + 12 > (unsigned int)p->buf_size ||
6994 AV_RB64(p->buf+offset + 8) == 0)) {
6995 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
6996 } else if (tag == MKTAG('f','t','y','p') &&
6997 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
6998 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
7000 score = FFMAX(score, 5);
7002 score = AVPROBE_SCORE_MAX;
7004 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7006 /* those are more common words, so rate then a bit less */
7007 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
7008 case MKTAG('w','i','d','e'):
7009 case MKTAG('f','r','e','e'):
7010 case MKTAG('j','u','n','k'):
7011 case MKTAG('p','i','c','t'):
7012 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
7013 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7015 case MKTAG(0x82,0x82,0x7f,0x7d):
7016 case MKTAG('s','k','i','p'):
7017 case MKTAG('u','u','i','d'):
7018 case MKTAG('p','r','f','l'):
7019 /* if we only find those cause probedata is too small at least rate them */
7020 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7021 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7024 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7027 if(score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
7028 /* moov atom in the header - we should make sure that this is not a
7029 * MOV-packed MPEG-PS */
7030 offset = moov_offset;
7032 while(offset < (p->buf_size - 16)){ /* Sufficient space */
7033 /* We found an actual hdlr atom */
7034 if(AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7035 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7036 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')){
7037 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7038 /* We found a media handler reference atom describing an
7039 * MPEG-PS-in-MOV, return a
7040 * low score to force expanding the probe window until
7041 * mpegps_probe finds what it needs */
7052 // must be done after parsing all trak because there's no order requirement
7053 static void mov_read_chapters(AVFormatContext *s)
7055 MOVContext *mov = s->priv_data;
7057 MOVStreamContext *sc;
7062 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7063 chapter_track = mov->chapter_tracks[j];
7065 for (i = 0; i < s->nb_streams; i++)
7066 if (s->streams[i]->id == chapter_track) {
7071 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7076 cur_pos = avio_tell(sc->pb);
7078 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7079 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7080 if (st->nb_index_entries) {
7081 // Retrieve the first frame, if possible
7083 AVIndexEntry *sample = &st->index_entries[0];
7084 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7085 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7089 if (av_get_packet(sc->pb, &pkt, sample->size) < 0)
7092 st->attached_pic = pkt;
7093 st->attached_pic.stream_index = st->index;
7094 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
7097 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7098 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7099 st->discard = AVDISCARD_ALL;
7100 for (i = 0; i < st->nb_index_entries; i++) {
7101 AVIndexEntry *sample = &st->index_entries[i];
7102 int64_t end = i+1 < st->nb_index_entries ? st->index_entries[i+1].timestamp : st->duration;
7107 if (end < sample->timestamp) {
7108 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7109 end = AV_NOPTS_VALUE;
7112 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7113 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7117 // the first two bytes are the length of the title
7118 len = avio_rb16(sc->pb);
7119 if (len > sample->size-2)
7121 title_len = 2*len + 1;
7122 if (!(title = av_mallocz(title_len)))
7125 // The samples could theoretically be in any encoding if there's an encd
7126 // atom following, but in practice are only utf-8 or utf-16, distinguished
7127 // instead by the presence of a BOM
7131 ch = avio_rb16(sc->pb);
7133 avio_get_str16be(sc->pb, len, title, title_len);
7134 else if (ch == 0xfffe)
7135 avio_get_str16le(sc->pb, len, title, title_len);
7138 if (len == 1 || len == 2)
7141 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7145 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7150 avio_seek(sc->pb, cur_pos, SEEK_SET);
7154 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7155 uint32_t value, int flags)
7158 char buf[AV_TIMECODE_STR_SIZE];
7159 AVRational rate = st->avg_frame_rate;
7160 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7163 av_dict_set(&st->metadata, "timecode",
7164 av_timecode_make_string(&tc, buf, value), 0);
7168 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7170 MOVStreamContext *sc = st->priv_data;
7171 char buf[AV_TIMECODE_STR_SIZE];
7172 int64_t cur_pos = avio_tell(sc->pb);
7173 int hh, mm, ss, ff, drop;
7175 if (!st->nb_index_entries)
7178 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7179 avio_skip(s->pb, 13);
7180 hh = avio_r8(s->pb);
7181 mm = avio_r8(s->pb);
7182 ss = avio_r8(s->pb);
7183 drop = avio_r8(s->pb);
7184 ff = avio_r8(s->pb);
7185 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7186 hh, mm, ss, drop ? ';' : ':', ff);
7187 av_dict_set(&st->metadata, "timecode", buf, 0);
7189 avio_seek(sc->pb, cur_pos, SEEK_SET);
7193 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7195 MOVStreamContext *sc = st->priv_data;
7197 int64_t cur_pos = avio_tell(sc->pb);
7200 if (!st->nb_index_entries)
7203 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7204 value = avio_rb32(s->pb);
7206 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7207 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7208 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7210 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7211 * not the case) and thus assume "frame number format" instead of QT one.
7212 * No sample with tmcd track can be found with a QT timecode at the moment,
7213 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7215 parse_timecode_in_framenum_format(s, st, value, flags);
7217 avio_seek(sc->pb, cur_pos, SEEK_SET);
7221 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7223 if (!index || !*index) return;
7224 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7225 av_encryption_info_free((*index)->encrypted_samples[i]);
7227 av_freep(&(*index)->encrypted_samples);
7228 av_freep(&(*index)->auxiliary_info_sizes);
7229 av_freep(&(*index)->auxiliary_offsets);
7233 static int mov_read_close(AVFormatContext *s)
7235 MOVContext *mov = s->priv_data;
7238 for (i = 0; i < s->nb_streams; i++) {
7239 AVStream *st = s->streams[i];
7240 MOVStreamContext *sc = st->priv_data;
7245 av_freep(&sc->ctts_data);
7246 for (j = 0; j < sc->drefs_count; j++) {
7247 av_freep(&sc->drefs[j].path);
7248 av_freep(&sc->drefs[j].dir);
7250 av_freep(&sc->drefs);
7252 sc->drefs_count = 0;
7254 if (!sc->pb_is_copied)
7255 ff_format_io_close(s, &sc->pb);
7258 av_freep(&sc->chunk_offsets);
7259 av_freep(&sc->stsc_data);
7260 av_freep(&sc->sample_sizes);
7261 av_freep(&sc->keyframes);
7262 av_freep(&sc->stts_data);
7263 av_freep(&sc->sdtp_data);
7264 av_freep(&sc->stps_data);
7265 av_freep(&sc->elst_data);
7266 av_freep(&sc->rap_group);
7267 av_freep(&sc->display_matrix);
7268 av_freep(&sc->index_ranges);
7271 for (j = 0; j < sc->stsd_count; j++)
7272 av_free(sc->extradata[j]);
7273 av_freep(&sc->extradata);
7274 av_freep(&sc->extradata_size);
7276 mov_free_encryption_index(&sc->cenc.encryption_index);
7277 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7278 av_aes_ctr_free(sc->cenc.aes_ctr);
7280 av_freep(&sc->stereo3d);
7281 av_freep(&sc->spherical);
7282 av_freep(&sc->mastering);
7283 av_freep(&sc->coll);
7286 if (mov->dv_demux) {
7287 avformat_free_context(mov->dv_fctx);
7288 mov->dv_fctx = NULL;
7291 if (mov->meta_keys) {
7292 for (i = 1; i < mov->meta_keys_count; i++) {
7293 av_freep(&mov->meta_keys[i]);
7295 av_freep(&mov->meta_keys);
7298 av_freep(&mov->trex_data);
7299 av_freep(&mov->bitrates);
7301 for (i = 0; i < mov->frag_index.nb_items; i++) {
7302 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7303 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7304 mov_free_encryption_index(&frag[j].encryption_index);
7306 av_freep(&mov->frag_index.item[i].stream_info);
7308 av_freep(&mov->frag_index.item);
7310 av_freep(&mov->aes_decrypt);
7311 av_freep(&mov->chapter_tracks);
7316 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7320 for (i = 0; i < s->nb_streams; i++) {
7321 AVStream *st = s->streams[i];
7322 MOVStreamContext *sc = st->priv_data;
7324 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7325 sc->timecode_track == tmcd_id)
7331 /* look for a tmcd track not referenced by any video track, and export it globally */
7332 static void export_orphan_timecode(AVFormatContext *s)
7336 for (i = 0; i < s->nb_streams; i++) {
7337 AVStream *st = s->streams[i];
7339 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7340 !tmcd_is_referenced(s, i + 1)) {
7341 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7343 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7350 static int read_tfra(MOVContext *mov, AVIOContext *f)
7352 int version, fieldlength, i, j;
7353 int64_t pos = avio_tell(f);
7354 uint32_t size = avio_rb32(f);
7355 unsigned track_id, item_count;
7357 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7360 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7362 version = avio_r8(f);
7364 track_id = avio_rb32(f);
7365 fieldlength = avio_rb32(f);
7366 item_count = avio_rb32(f);
7367 for (i = 0; i < item_count; i++) {
7368 int64_t time, offset;
7370 MOVFragmentStreamInfo * frag_stream_info;
7373 return AVERROR_INVALIDDATA;
7377 time = avio_rb64(f);
7378 offset = avio_rb64(f);
7380 time = avio_rb32(f);
7381 offset = avio_rb32(f);
7384 // The first sample of each stream in a fragment is always a random
7385 // access sample. So it's entry in the tfra can be used as the
7386 // initial PTS of the fragment.
7387 index = update_frag_index(mov, offset);
7388 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7389 if (frag_stream_info &&
7390 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7391 frag_stream_info->first_tfra_pts = time;
7393 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7395 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7397 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7401 avio_seek(f, pos + size, SEEK_SET);
7405 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7407 int64_t stream_size = avio_size(f);
7408 int64_t original_pos = avio_tell(f);
7412 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7416 mfra_size = avio_rb32(f);
7417 if (mfra_size < 0 || mfra_size > stream_size) {
7418 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7421 if ((seek_ret = avio_seek(f, -mfra_size, SEEK_CUR)) < 0) {
7425 if (avio_rb32(f) != mfra_size) {
7426 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7429 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7430 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7433 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7435 ret = read_tfra(c, f);
7441 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7443 av_log(c->fc, AV_LOG_ERROR,
7444 "failed to seek back after looking for mfra\n");
7450 static int mov_read_header(AVFormatContext *s)
7452 MOVContext *mov = s->priv_data;
7453 AVIOContext *pb = s->pb;
7455 MOVAtom atom = { AV_RL32("root") };
7458 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7459 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7460 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7461 return AVERROR(EINVAL);
7465 mov->trak_index = -1;
7466 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7467 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7468 atom.size = avio_size(pb);
7470 atom.size = INT64_MAX;
7472 /* check MOV header */
7474 if (mov->moov_retry)
7475 avio_seek(pb, 0, SEEK_SET);
7476 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7477 av_log(s, AV_LOG_ERROR, "error reading header\n");
7481 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7482 if (!mov->found_moov) {
7483 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7485 return AVERROR_INVALIDDATA;
7487 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7489 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7490 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7491 mov_read_chapters(s);
7492 for (i = 0; i < s->nb_streams; i++)
7493 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7494 mov_read_timecode_track(s, s->streams[i]);
7495 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7496 mov_read_rtmd_track(s, s->streams[i]);
7500 /* copy timecode metadata from tmcd tracks to the related video streams */
7501 for (i = 0; i < s->nb_streams; i++) {
7502 AVStream *st = s->streams[i];
7503 MOVStreamContext *sc = st->priv_data;
7504 if (sc->timecode_track > 0) {
7505 AVDictionaryEntry *tcr;
7506 int tmcd_st_id = -1;
7508 for (j = 0; j < s->nb_streams; j++)
7509 if (s->streams[j]->id == sc->timecode_track)
7512 if (tmcd_st_id < 0 || tmcd_st_id == i)
7514 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7516 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7519 export_orphan_timecode(s);
7521 for (i = 0; i < s->nb_streams; i++) {
7522 AVStream *st = s->streams[i];
7523 MOVStreamContext *sc = st->priv_data;
7524 fix_timescale(mov, sc);
7525 if(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7526 st->skip_samples = sc->start_pad;
7528 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7529 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7530 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7531 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7532 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7533 st->codecpar->width = sc->width;
7534 st->codecpar->height = sc->height;
7536 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7537 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7541 if (mov->handbrake_version &&
7542 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7543 st->codecpar->codec_id == AV_CODEC_ID_MP3
7545 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7546 st->need_parsing = AVSTREAM_PARSE_FULL;
7550 if (mov->trex_data) {
7551 for (i = 0; i < s->nb_streams; i++) {
7552 AVStream *st = s->streams[i];
7553 MOVStreamContext *sc = st->priv_data;
7554 if (st->duration > 0) {
7555 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7556 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7557 sc->data_size, sc->time_scale);
7559 return AVERROR_INVALIDDATA;
7561 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7566 if (mov->use_mfra_for > 0) {
7567 for (i = 0; i < s->nb_streams; i++) {
7568 AVStream *st = s->streams[i];
7569 MOVStreamContext *sc = st->priv_data;
7570 if (sc->duration_for_fps > 0) {
7571 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7572 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7573 sc->data_size, sc->time_scale);
7575 return AVERROR_INVALIDDATA;
7577 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7578 sc->duration_for_fps;
7583 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7584 if (mov->bitrates[i]) {
7585 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7589 ff_rfps_calculate(s);
7591 for (i = 0; i < s->nb_streams; i++) {
7592 AVStream *st = s->streams[i];
7593 MOVStreamContext *sc = st->priv_data;
7595 switch (st->codecpar->codec_type) {
7596 case AVMEDIA_TYPE_AUDIO:
7597 err = ff_replaygain_export(st, s->metadata);
7603 case AVMEDIA_TYPE_VIDEO:
7604 if (sc->display_matrix) {
7605 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7606 sizeof(int32_t) * 9);
7610 sc->display_matrix = NULL;
7613 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7614 (uint8_t *)sc->stereo3d,
7615 sizeof(*sc->stereo3d));
7619 sc->stereo3d = NULL;
7621 if (sc->spherical) {
7622 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7623 (uint8_t *)sc->spherical,
7624 sc->spherical_size);
7628 sc->spherical = NULL;
7630 if (sc->mastering) {
7631 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7632 (uint8_t *)sc->mastering,
7633 sizeof(*sc->mastering));
7637 sc->mastering = NULL;
7640 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7641 (uint8_t *)sc->coll,
7651 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7653 for (i = 0; i < mov->frag_index.nb_items; i++)
7654 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7655 mov->frag_index.item[i].headers_read = 1;
7660 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7662 AVIndexEntry *sample = NULL;
7663 int64_t best_dts = INT64_MAX;
7665 for (i = 0; i < s->nb_streams; i++) {
7666 AVStream *avst = s->streams[i];
7667 MOVStreamContext *msc = avst->priv_data;
7668 if (msc->pb && msc->current_sample < avst->nb_index_entries) {
7669 AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample];
7670 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7671 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7672 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7673 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7674 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb &&
7675 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7676 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7677 sample = current_sample;
7686 static int should_retry(AVIOContext *pb, int error_code) {
7687 if (error_code == AVERROR_EOF || avio_feof(pb))
7693 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7696 MOVContext *mov = s->priv_data;
7698 if (index >= 0 && index < mov->frag_index.nb_items)
7699 target = mov->frag_index.item[index].moof_offset;
7700 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7701 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7702 return AVERROR_INVALIDDATA;
7705 mov->next_root_atom = 0;
7706 if (index < 0 || index >= mov->frag_index.nb_items)
7707 index = search_frag_moof_offset(&mov->frag_index, target);
7708 if (index < mov->frag_index.nb_items) {
7709 if (index + 1 < mov->frag_index.nb_items)
7710 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7711 if (mov->frag_index.item[index].headers_read)
7713 mov->frag_index.item[index].headers_read = 1;
7716 mov->found_mdat = 0;
7718 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7721 if (avio_feof(s->pb))
7723 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7728 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7730 uint8_t *side, *extradata;
7733 /* Save the current index. */
7734 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7736 /* Notify the decoder that extradata changed. */
7737 extradata_size = sc->extradata_size[sc->last_stsd_index];
7738 extradata = sc->extradata[sc->last_stsd_index];
7739 if (extradata_size > 0 && extradata) {
7740 side = av_packet_new_side_data(pkt,
7741 AV_PKT_DATA_NEW_EXTRADATA,
7744 return AVERROR(ENOMEM);
7745 memcpy(side, extradata, extradata_size);
7751 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7753 MOVContext *mov = s->priv_data;
7754 MOVStreamContext *sc;
7755 AVIndexEntry *sample;
7756 AVStream *st = NULL;
7757 int64_t current_index;
7761 sample = mov_find_next_sample(s, &st);
7762 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7763 if (!mov->next_root_atom)
7765 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7770 /* must be done just before reading, to avoid infinite loop on sample */
7771 current_index = sc->current_index;
7772 mov_current_sample_inc(sc);
7774 if (mov->next_root_atom) {
7775 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7776 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7779 if (st->discard != AVDISCARD_ALL) {
7780 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7781 if (ret64 != sample->pos) {
7782 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7783 sc->ffindex, sample->pos);
7784 if (should_retry(sc->pb, ret64)) {
7785 mov_current_sample_dec(sc);
7787 return AVERROR_INVALIDDATA;
7790 if( st->discard == AVDISCARD_NONKEY && 0==(sample->flags & AVINDEX_KEYFRAME) ) {
7791 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7795 ret = av_get_packet(sc->pb, pkt, sample->size);
7797 if (should_retry(sc->pb, ret)) {
7798 mov_current_sample_dec(sc);
7802 if (sc->has_palette) {
7805 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7807 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7809 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7810 sc->has_palette = 0;
7813 #if CONFIG_DV_DEMUXER
7814 if (mov->dv_demux && sc->dv_audio_container) {
7815 avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7816 av_freep(&pkt->data);
7818 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7823 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7824 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7825 st->need_parsing = AVSTREAM_PARSE_FULL;
7829 pkt->stream_index = sc->ffindex;
7830 pkt->dts = sample->timestamp;
7831 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7832 pkt->flags |= AV_PKT_FLAG_DISCARD;
7834 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7835 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
7836 /* update ctts context */
7838 if (sc->ctts_index < sc->ctts_count &&
7839 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
7841 sc->ctts_sample = 0;
7844 int64_t next_dts = (sc->current_sample < st->nb_index_entries) ?
7845 st->index_entries[sc->current_sample].timestamp : st->duration;
7847 if (next_dts >= pkt->dts)
7848 pkt->duration = next_dts - pkt->dts;
7849 pkt->pts = pkt->dts;
7851 if (st->discard == AVDISCARD_ALL)
7853 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
7854 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
7855 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
7856 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
7858 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
7859 pkt->pos = sample->pos;
7861 /* Multiple stsd handling. */
7862 if (sc->stsc_data) {
7863 /* Keep track of the stsc index for the given sample, then check
7864 * if the stsd index is different from the last used one. */
7866 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
7867 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
7869 sc->stsc_sample = 0;
7870 /* Do not check indexes after a switch. */
7871 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
7872 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
7873 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
7874 ret = mov_change_extradata(sc, pkt);
7881 aax_filter(pkt->data, pkt->size, mov);
7883 ret = cenc_filter(mov, st, sc, pkt, current_index);
7885 av_packet_unref(pkt);
7892 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
7894 MOVContext *mov = s->priv_data;
7897 if (!mov->frag_index.complete)
7900 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
7903 if (!mov->frag_index.item[index].headers_read)
7904 return mov_switch_root(s, -1, index);
7905 if (index + 1 < mov->frag_index.nb_items)
7906 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7911 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
7913 MOVStreamContext *sc = st->priv_data;
7914 int sample, time_sample, ret;
7917 // Here we consider timestamp to be PTS, hence try to offset it so that we
7918 // can search over the DTS timeline.
7919 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
7921 ret = mov_seek_fragment(s, st, timestamp);
7925 sample = av_index_search_timestamp(st, timestamp, flags);
7926 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
7927 if (sample < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp)
7929 if (sample < 0) /* not sure what to do */
7930 return AVERROR_INVALIDDATA;
7931 mov_current_sample_set(sc, sample);
7932 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
7933 /* adjust ctts index */
7934 if (sc->ctts_data) {
7936 for (i = 0; i < sc->ctts_count; i++) {
7937 int next = time_sample + sc->ctts_data[i].count;
7938 if (next > sc->current_sample) {
7940 sc->ctts_sample = sc->current_sample - time_sample;
7947 /* adjust stsd index */
7948 if (sc->chunk_count) {
7950 for (i = 0; i < sc->stsc_count; i++) {
7951 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
7952 if (next > sc->current_sample) {
7954 sc->stsc_sample = sc->current_sample - time_sample;
7957 av_assert0(next == (int)next);
7965 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
7967 MOVContext *mc = s->priv_data;
7972 if (stream_index >= s->nb_streams)
7973 return AVERROR_INVALIDDATA;
7975 st = s->streams[stream_index];
7976 sample = mov_seek_stream(s, st, sample_time, flags);
7980 if (mc->seek_individually) {
7981 /* adjust seek timestamp to found sample timestamp */
7982 int64_t seek_timestamp = st->index_entries[sample].timestamp;
7984 for (i = 0; i < s->nb_streams; i++) {
7986 MOVStreamContext *sc = s->streams[i]->priv_data;
7988 st->skip_samples = (sample_time <= 0) ? sc->start_pad : 0;
7990 if (stream_index == i)
7993 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
7994 mov_seek_stream(s, st, timestamp, flags);
7997 for (i = 0; i < s->nb_streams; i++) {
7998 MOVStreamContext *sc;
8001 mov_current_sample_set(sc, 0);
8004 MOVStreamContext *sc;
8005 AVIndexEntry *entry = mov_find_next_sample(s, &st);
8007 return AVERROR_INVALIDDATA;
8009 if (sc->ffindex == stream_index && sc->current_sample == sample)
8011 mov_current_sample_inc(sc);
8017 #define OFFSET(x) offsetof(MOVContext, x)
8018 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
8019 static const AVOption mov_options[] = {
8020 {"use_absolute_path",
8021 "allow using absolute path when opening alias, this is a possible security issue",
8022 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
8024 {"seek_streams_individually",
8025 "Seek each stream individually to the closest point",
8026 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
8028 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
8030 {"advanced_editlist",
8031 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
8032 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
8034 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8037 "use mfra for fragment timestamps",
8038 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8039 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8041 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8042 FLAGS, "use_mfra_for" },
8043 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8044 FLAGS, "use_mfra_for" },
8045 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8046 FLAGS, "use_mfra_for" },
8047 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8048 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8049 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8050 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8051 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8052 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8053 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8054 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8055 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8056 .flags = AV_OPT_FLAG_DECODING_PARAM },
8057 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8058 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8059 {.i64 = 0}, 0, 1, FLAGS },
8064 static const AVClass mov_class = {
8065 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8066 .item_name = av_default_item_name,
8067 .option = mov_options,
8068 .version = LIBAVUTIL_VERSION_INT,
8071 AVInputFormat ff_mov_demuxer = {
8072 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8073 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8074 .priv_class = &mov_class,
8075 .priv_data_size = sizeof(MOVContext),
8076 .extensions = "mov,mp4,m4a,3gp,3g2,mj2",
8077 .read_probe = mov_probe,
8078 .read_header = mov_read_header,
8079 .read_packet = mov_read_packet,
8080 .read_close = mov_read_close,
8081 .read_seek = mov_read_seek,
8082 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,