3 * Copyright (c) 2001 Fabrice Bellard
4 * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
6 * first version by Francois Revol <revol@free.fr>
7 * seek function by Gael Chardon <gael.dev@4now.net>
9 * This file is part of FFmpeg.
11 * FFmpeg is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * FFmpeg is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with FFmpeg; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30 #include "libavutil/attributes.h"
31 #include "libavutil/channel_layout.h"
32 #include "libavutil/internal.h"
33 #include "libavutil/intreadwrite.h"
34 #include "libavutil/intfloat.h"
35 #include "libavutil/mathematics.h"
36 #include "libavutil/time_internal.h"
37 #include "libavutil/avassert.h"
38 #include "libavutil/avstring.h"
39 #include "libavutil/dict.h"
40 #include "libavutil/display.h"
41 #include "libavutil/opt.h"
42 #include "libavutil/aes.h"
43 #include "libavutil/aes_ctr.h"
44 #include "libavutil/pixdesc.h"
45 #include "libavutil/sha.h"
46 #include "libavutil/spherical.h"
47 #include "libavutil/stereo3d.h"
48 #include "libavutil/timecode.h"
49 #include "libavcodec/ac3tab.h"
50 #include "libavcodec/flac.h"
51 #include "libavcodec/mpegaudiodecheader.h"
52 #include "libavcodec/mlp_parse.h"
55 #include "avio_internal.h"
58 #include "libavcodec/get_bits.h"
61 #include "replaygain.h"
67 #include "qtpalette.h"
69 /* those functions parse an atom */
70 /* links atom IDs to parse functions */
71 typedef struct MOVParseTableEntry {
73 int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
76 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
77 static int mov_read_mfra(MOVContext *c, AVIOContext *f);
78 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
79 int count, int duration);
81 static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb,
82 unsigned len, const char *key)
86 short current, total = 0;
87 avio_rb16(pb); // unknown
88 current = avio_rb16(pb);
90 total = avio_rb16(pb);
92 snprintf(buf, sizeof(buf), "%d", current);
94 snprintf(buf, sizeof(buf), "%d/%d", current, total);
95 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
96 av_dict_set(&c->fc->metadata, key, buf, 0);
101 static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb,
102 unsigned len, const char *key)
104 /* bypass padding bytes */
109 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
110 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
115 static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb,
116 unsigned len, const char *key)
118 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
119 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
124 static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb,
125 unsigned len, const char *key)
129 avio_r8(pb); // unknown
132 if (genre < 1 || genre > ID3v1_GENRE_MAX)
134 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
135 av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
140 static const uint32_t mac_to_unicode[128] = {
141 0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
142 0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
143 0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
144 0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
145 0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
146 0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
147 0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
148 0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
149 0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
150 0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
151 0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
152 0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
153 0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
154 0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
155 0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
156 0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
159 static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len,
160 char *dst, int dstlen)
163 char *end = dst+dstlen-1;
166 for (i = 0; i < len; i++) {
167 uint8_t t, c = avio_r8(pb);
175 PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
181 static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
185 MOVStreamContext *sc;
190 case 0xd: id = AV_CODEC_ID_MJPEG; break;
191 case 0xe: id = AV_CODEC_ID_PNG; break;
192 case 0x1b: id = AV_CODEC_ID_BMP; break;
194 av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
199 st = avformat_new_stream(c->fc, NULL);
201 return AVERROR(ENOMEM);
202 sc = av_mallocz(sizeof(*sc));
204 return AVERROR(ENOMEM);
207 ret = av_get_packet(pb, &pkt, len);
211 if (pkt.size >= 8 && id != AV_CODEC_ID_BMP) {
212 if (AV_RB64(pkt.data) == 0x89504e470d0a1a0a) {
213 id = AV_CODEC_ID_PNG;
215 id = AV_CODEC_ID_MJPEG;
219 st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
221 st->attached_pic = pkt;
222 st->attached_pic.stream_index = st->index;
223 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
225 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
226 st->codecpar->codec_id = id;
232 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
234 char language[4] = { 0 };
235 char buf[200], place[100];
236 uint16_t langcode = 0;
237 double longitude, latitude, altitude;
238 const char *key = "location";
240 if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
241 av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
242 return AVERROR_INVALIDDATA;
245 avio_skip(pb, 4); // version+flags
246 langcode = avio_rb16(pb);
247 ff_mov_lang_to_iso639(langcode, language);
250 len -= avio_get_str(pb, len, place, sizeof(place));
252 av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
253 return AVERROR_INVALIDDATA;
255 avio_skip(pb, 1); // role
259 av_log(c->fc, AV_LOG_ERROR,
260 "loci too short (%u bytes left, need at least %d)\n", len, 12);
261 return AVERROR_INVALIDDATA;
263 longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
264 latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
265 altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
267 // Try to output in the same format as the ?xyz field
268 snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
270 av_strlcatf(buf, sizeof(buf), "%+f", altitude);
271 av_strlcatf(buf, sizeof(buf), "/%s", place);
273 if (*language && strcmp(language, "und")) {
275 snprintf(key2, sizeof(key2), "%s-%s", key, language);
276 av_dict_set(&c->fc->metadata, key2, buf, 0);
278 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
279 return av_dict_set(&c->fc->metadata, key, buf, 0);
282 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
288 if (c->ignore_chapters)
291 n_hmmt = avio_rb32(pb);
292 for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
293 int moment_time = avio_rb32(pb);
294 avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
299 static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
302 char key2[32], language[4] = {0};
304 const char *key = NULL;
305 uint16_t langcode = 0;
306 uint32_t data_type = 0, str_size, str_size_alloc;
307 int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
312 case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
313 case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
314 case MKTAG( 'X','M','P','_'):
315 if (c->export_xmp) { key = "xmp"; raw = 1; } break;
316 case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
317 case MKTAG( 'a','k','I','D'): key = "account_type";
318 parse = mov_metadata_int8_no_padding; break;
319 case MKTAG( 'a','p','I','D'): key = "account_id"; break;
320 case MKTAG( 'c','a','t','g'): key = "category"; break;
321 case MKTAG( 'c','p','i','l'): key = "compilation";
322 parse = mov_metadata_int8_no_padding; break;
323 case MKTAG( 'c','p','r','t'): key = "copyright"; break;
324 case MKTAG( 'd','e','s','c'): key = "description"; break;
325 case MKTAG( 'd','i','s','k'): key = "disc";
326 parse = mov_metadata_track_or_disc_number; break;
327 case MKTAG( 'e','g','i','d'): key = "episode_uid";
328 parse = mov_metadata_int8_no_padding; break;
329 case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
330 case MKTAG( 'g','n','r','e'): key = "genre";
331 parse = mov_metadata_gnre; break;
332 case MKTAG( 'h','d','v','d'): key = "hd_video";
333 parse = mov_metadata_int8_no_padding; break;
334 case MKTAG( 'H','M','M','T'):
335 return mov_metadata_hmmt(c, pb, atom.size);
336 case MKTAG( 'k','e','y','w'): key = "keywords"; break;
337 case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
338 case MKTAG( 'l','o','c','i'):
339 return mov_metadata_loci(c, pb, atom.size);
340 case MKTAG( 'm','a','n','u'): key = "make"; break;
341 case MKTAG( 'm','o','d','l'): key = "model"; break;
342 case MKTAG( 'p','c','s','t'): key = "podcast";
343 parse = mov_metadata_int8_no_padding; break;
344 case MKTAG( 'p','g','a','p'): key = "gapless_playback";
345 parse = mov_metadata_int8_no_padding; break;
346 case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
347 case MKTAG( 'r','t','n','g'): key = "rating";
348 parse = mov_metadata_int8_no_padding; break;
349 case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
350 case MKTAG( 's','o','a','l'): key = "sort_album"; break;
351 case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
352 case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
353 case MKTAG( 's','o','n','m'): key = "sort_name"; break;
354 case MKTAG( 's','o','s','n'): key = "sort_show"; break;
355 case MKTAG( 's','t','i','k'): key = "media_type";
356 parse = mov_metadata_int8_no_padding; break;
357 case MKTAG( 't','r','k','n'): key = "track";
358 parse = mov_metadata_track_or_disc_number; break;
359 case MKTAG( 't','v','e','n'): key = "episode_id"; break;
360 case MKTAG( 't','v','e','s'): key = "episode_sort";
361 parse = mov_metadata_int8_bypass_padding; break;
362 case MKTAG( 't','v','n','n'): key = "network"; break;
363 case MKTAG( 't','v','s','h'): key = "show"; break;
364 case MKTAG( 't','v','s','n'): key = "season_number";
365 parse = mov_metadata_int8_bypass_padding; break;
366 case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
367 case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
368 case MKTAG(0xa9,'a','l','b'): key = "album"; break;
369 case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
370 case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
371 case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
372 case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
373 case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
374 case MKTAG(0xa9,'d','a','y'): key = "date"; break;
375 case MKTAG(0xa9,'d','i','r'): key = "director"; break;
376 case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
377 case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
378 case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
379 case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
380 case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
381 case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
382 case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
383 case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
384 case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
385 case MKTAG(0xa9,'m','a','k'): key = "make"; break;
386 case MKTAG(0xa9,'m','o','d'): key = "model"; break;
387 case MKTAG(0xa9,'n','a','m'): key = "title"; break;
388 case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
389 case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
390 case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
391 case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
392 case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
393 case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
394 case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
395 case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
396 case MKTAG(0xa9,'t','r','k'): key = "track"; break;
397 case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
398 case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
399 case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
400 case MKTAG(0xa9,'x','y','z'): key = "location"; break;
403 if (c->itunes_metadata && atom.size > 8) {
404 int data_size = avio_rb32(pb);
405 int tag = avio_rl32(pb);
406 if (tag == MKTAG('d','a','t','a') && data_size <= atom.size) {
407 data_type = avio_rb32(pb); // type
408 avio_rb32(pb); // unknown
409 str_size = data_size - 16;
412 if (atom.type == MKTAG('c', 'o', 'v', 'r')) {
413 int ret = mov_read_covr(c, pb, data_type, str_size);
415 av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
418 atom.size -= str_size;
422 } else if (!key && c->found_hdlr_mdta && c->meta_keys) {
423 uint32_t index = AV_RB32(&atom.type);
424 if (index < c->meta_keys_count && index > 0) {
425 key = c->meta_keys[index];
427 av_log(c->fc, AV_LOG_WARNING,
428 "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
429 index, c->meta_keys_count);
433 } else if (atom.size > 4 && key && !c->itunes_metadata && !raw) {
434 str_size = avio_rb16(pb); // string length
435 if (str_size > atom.size) {
437 avio_seek(pb, -2, SEEK_CUR);
438 av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
441 langcode = avio_rb16(pb);
442 ff_mov_lang_to_iso639(langcode, language);
445 str_size = atom.size;
447 if (c->export_all && !key) {
448 snprintf(tmp_key, 5, "%.4s", (char*)&atom.type);
454 if (atom.size < 0 || str_size >= INT_MAX/2)
455 return AVERROR_INVALIDDATA;
457 // Allocates enough space if data_type is a int32 or float32 number, otherwise
458 // worst-case requirement for output string in case of utf8 coded input
459 num = (data_type >= 21 && data_type <= 23);
460 str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
461 str = av_mallocz(str_size_alloc);
463 return AVERROR(ENOMEM);
466 parse(c, pb, str_size, key);
468 if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
469 mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
470 } else if (data_type == 21) { // BE signed integer, variable size
473 val = (int8_t)avio_r8(pb);
474 else if (str_size == 2)
475 val = (int16_t)avio_rb16(pb);
476 else if (str_size == 3)
477 val = ((int32_t)(avio_rb24(pb)<<8))>>8;
478 else if (str_size == 4)
479 val = (int32_t)avio_rb32(pb);
480 if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
481 av_log(c->fc, AV_LOG_ERROR,
482 "Failed to store the number (%d) in string.\n", val);
484 return AVERROR_INVALIDDATA;
486 } else if (data_type == 22) { // BE unsigned integer, variable size
487 unsigned int val = 0;
490 else if (str_size == 2)
492 else if (str_size == 3)
494 else if (str_size == 4)
496 if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
497 av_log(c->fc, AV_LOG_ERROR,
498 "Failed to store the number (%u) in string.\n", val);
500 return AVERROR_INVALIDDATA;
502 } else if (data_type == 23 && str_size >= 4) { // BE float32
503 float val = av_int2float(avio_rb32(pb));
504 if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
505 av_log(c->fc, AV_LOG_ERROR,
506 "Failed to store the float32 number (%f) in string.\n", val);
508 return AVERROR_INVALIDDATA;
511 int ret = ffio_read_size(pb, str, str_size);
518 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
519 av_dict_set(&c->fc->metadata, key, str, 0);
520 if (*language && strcmp(language, "und")) {
521 snprintf(key2, sizeof(key2), "%s-%s", key, language);
522 av_dict_set(&c->fc->metadata, key2, str, 0);
524 if (!strcmp(key, "encoder")) {
525 int major, minor, micro;
526 if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, µ) == 3) {
527 c->handbrake_version = 1000000*major + 1000*minor + micro;
536 static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
539 int i, nb_chapters, str_len, version;
543 if (c->ignore_chapters)
546 if ((atom.size -= 5) < 0)
549 version = avio_r8(pb);
552 avio_rb32(pb); // ???
553 nb_chapters = avio_r8(pb);
555 for (i = 0; i < nb_chapters; i++) {
559 start = avio_rb64(pb);
560 str_len = avio_r8(pb);
562 if ((atom.size -= 9+str_len) < 0)
565 ret = ffio_read_size(pb, str, str_len);
569 avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
574 #define MIN_DATA_ENTRY_BOX_SIZE 12
575 static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
578 MOVStreamContext *sc;
581 if (c->fc->nb_streams < 1)
583 st = c->fc->streams[c->fc->nb_streams-1];
586 avio_rb32(pb); // version + flags
587 entries = avio_rb32(pb);
589 entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
590 entries >= UINT_MAX / sizeof(*sc->drefs))
591 return AVERROR_INVALIDDATA;
595 sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
597 return AVERROR(ENOMEM);
598 sc->drefs_count = entries;
600 for (i = 0; i < entries; i++) {
601 MOVDref *dref = &sc->drefs[i];
602 uint32_t size = avio_rb32(pb);
603 int64_t next = avio_tell(pb) + size - 4;
606 return AVERROR_INVALIDDATA;
608 dref->type = avio_rl32(pb);
609 avio_rb32(pb); // version + flags
611 if (dref->type == MKTAG('a','l','i','s') && size > 150) {
612 /* macintosh alias record */
613 uint16_t volume_len, len;
619 volume_len = avio_r8(pb);
620 volume_len = FFMIN(volume_len, 27);
621 ret = ffio_read_size(pb, dref->volume, 27);
624 dref->volume[volume_len] = 0;
625 av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
630 len = FFMIN(len, 63);
631 ret = ffio_read_size(pb, dref->filename, 63);
634 dref->filename[len] = 0;
635 av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
639 /* read next level up_from_alias/down_to_target */
640 dref->nlvl_from = avio_rb16(pb);
641 dref->nlvl_to = avio_rb16(pb);
642 av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
643 dref->nlvl_from, dref->nlvl_to);
647 for (type = 0; type != -1 && avio_tell(pb) < next; ) {
650 type = avio_rb16(pb);
652 av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
655 if (type == 2) { // absolute path
657 dref->path = av_mallocz(len+1);
659 return AVERROR(ENOMEM);
661 ret = ffio_read_size(pb, dref->path, len);
663 av_freep(&dref->path);
666 if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
668 memmove(dref->path, dref->path+volume_len, len);
671 // trim string of any ending zeros
672 for (j = len - 1; j >= 0; j--) {
673 if (dref->path[j] == 0)
678 for (j = 0; j < len; j++)
679 if (dref->path[j] == ':' || dref->path[j] == 0)
681 av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
682 } else if (type == 0) { // directory name
684 dref->dir = av_malloc(len+1);
686 return AVERROR(ENOMEM);
688 ret = ffio_read_size(pb, dref->dir, len);
690 av_freep(&dref->dir);
694 for (j = 0; j < len; j++)
695 if (dref->dir[j] == ':')
697 av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
702 av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
707 avio_seek(pb, next, SEEK_SET);
712 static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
721 avio_r8(pb); /* version */
722 avio_rb24(pb); /* flags */
725 ctype = avio_rl32(pb);
726 type = avio_rl32(pb); /* component subtype */
728 av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
729 av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
731 if (c->trak_index < 0) { // meta not inside a trak
732 if (type == MKTAG('m','d','t','a')) {
733 c->found_hdlr_mdta = 1;
738 st = c->fc->streams[c->fc->nb_streams-1];
740 if (type == MKTAG('v','i','d','e'))
741 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
742 else if (type == MKTAG('s','o','u','n'))
743 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
744 else if (type == MKTAG('m','1','a',' '))
745 st->codecpar->codec_id = AV_CODEC_ID_MP2;
746 else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
747 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
749 avio_rb32(pb); /* component manufacture */
750 avio_rb32(pb); /* component flags */
751 avio_rb32(pb); /* component flags mask */
753 title_size = atom.size - 24;
754 if (title_size > 0) {
755 if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
756 return AVERROR_INVALIDDATA;
757 title_str = av_malloc(title_size + 1); /* Add null terminator */
759 return AVERROR(ENOMEM);
761 ret = ffio_read_size(pb, title_str, title_size);
763 av_freep(&title_str);
766 title_str[title_size] = 0;
768 int off = (!c->isom && title_str[0] == title_size - 1);
769 // flag added so as to not set stream handler name if already set from mdia->hdlr
770 av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
772 av_freep(&title_str);
778 static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
780 return ff_mov_read_esds(c->fc, pb);
783 static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
786 enum AVAudioServiceType *ast;
787 int ac3info, acmod, lfeon, bsmod;
789 if (c->fc->nb_streams < 1)
791 st = c->fc->streams[c->fc->nb_streams-1];
793 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
796 return AVERROR(ENOMEM);
798 ac3info = avio_rb24(pb);
799 bsmod = (ac3info >> 14) & 0x7;
800 acmod = (ac3info >> 11) & 0x7;
801 lfeon = (ac3info >> 10) & 0x1;
802 st->codecpar->channels = ((int[]){2,1,2,3,3,4,4,5})[acmod] + lfeon;
803 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
805 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
807 if (st->codecpar->channels > 1 && bsmod == 0x7)
808 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
810 #if FF_API_LAVF_AVCTX
811 FF_DISABLE_DEPRECATION_WARNINGS
812 st->codec->audio_service_type = *ast;
813 FF_ENABLE_DEPRECATION_WARNINGS
819 static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
822 enum AVAudioServiceType *ast;
823 int eac3info, acmod, lfeon, bsmod;
825 if (c->fc->nb_streams < 1)
827 st = c->fc->streams[c->fc->nb_streams-1];
829 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
832 return AVERROR(ENOMEM);
834 /* No need to parse fields for additional independent substreams and its
835 * associated dependent substreams since libavcodec's E-AC-3 decoder
836 * does not support them yet. */
837 avio_rb16(pb); /* data_rate and num_ind_sub */
838 eac3info = avio_rb24(pb);
839 bsmod = (eac3info >> 12) & 0x1f;
840 acmod = (eac3info >> 9) & 0x7;
841 lfeon = (eac3info >> 8) & 0x1;
842 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
844 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
845 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
847 if (st->codecpar->channels > 1 && bsmod == 0x7)
848 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
850 #if FF_API_LAVF_AVCTX
851 FF_DISABLE_DEPRECATION_WARNINGS
852 st->codec->audio_service_type = *ast;
853 FF_ENABLE_DEPRECATION_WARNINGS
859 static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
861 const uint32_t ddts_size = 20;
864 uint32_t frame_duration_code = 0;
865 uint32_t channel_layout_code = 0;
868 buf = av_malloc(ddts_size + AV_INPUT_BUFFER_PADDING_SIZE);
870 return AVERROR(ENOMEM);
872 if (avio_read(pb, buf, ddts_size) < ddts_size) {
874 return AVERROR_INVALIDDATA;
877 init_get_bits(&gb, buf, 8*ddts_size);
879 if (c->fc->nb_streams < 1) {
883 st = c->fc->streams[c->fc->nb_streams-1];
885 st->codecpar->sample_rate = get_bits_long(&gb, 32);
886 if (st->codecpar->sample_rate <= 0) {
887 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
889 return AVERROR_INVALIDDATA;
891 skip_bits_long(&gb, 32); /* max bitrate */
892 st->codecpar->bit_rate = get_bits_long(&gb, 32);
893 st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
894 frame_duration_code = get_bits(&gb, 2);
895 skip_bits(&gb, 30); /* various fields */
896 channel_layout_code = get_bits(&gb, 16);
898 st->codecpar->frame_size =
899 (frame_duration_code == 0) ? 512 :
900 (frame_duration_code == 1) ? 1024 :
901 (frame_duration_code == 2) ? 2048 :
902 (frame_duration_code == 3) ? 4096 : 0;
904 if (channel_layout_code > 0xff) {
905 av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout");
907 st->codecpar->channel_layout =
908 ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
909 ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
910 ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
911 ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
912 ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
913 ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0);
915 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
921 static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
925 if (c->fc->nb_streams < 1)
927 st = c->fc->streams[c->fc->nb_streams-1];
932 /* skip version and flags */
935 ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
940 static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
945 if (c->fc->nb_streams < 1)
947 st = c->fc->streams[c->fc->nb_streams-1];
949 if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
950 av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
955 static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
957 const int num = avio_rb32(pb);
958 const int den = avio_rb32(pb);
961 if (c->fc->nb_streams < 1)
963 st = c->fc->streams[c->fc->nb_streams-1];
965 if ((st->sample_aspect_ratio.den != 1 || st->sample_aspect_ratio.num) && // default
966 (den != st->sample_aspect_ratio.den || num != st->sample_aspect_ratio.num)) {
967 av_log(c->fc, AV_LOG_WARNING,
968 "sample aspect ratio already set to %d:%d, ignoring 'pasp' atom (%d:%d)\n",
969 st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
971 } else if (den != 0) {
972 av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den,
978 /* this atom contains actual media data */
979 static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
981 if (atom.size == 0) /* wrong one (MP4) */
984 return 0; /* now go for moov */
987 #define DRM_BLOB_SIZE 56
989 static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
991 uint8_t intermediate_key[20];
992 uint8_t intermediate_iv[20];
995 uint8_t file_checksum[20];
996 uint8_t calculated_checksum[20];
1000 uint8_t *activation_bytes = c->activation_bytes;
1001 uint8_t *fixed_key = c->audible_fixed_key;
1005 sha = av_sha_alloc();
1007 return AVERROR(ENOMEM);
1008 c->aes_decrypt = av_aes_alloc();
1009 if (!c->aes_decrypt) {
1010 ret = AVERROR(ENOMEM);
1014 /* drm blob processing */
1015 avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1016 avio_read(pb, input, DRM_BLOB_SIZE);
1017 avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1018 avio_read(pb, file_checksum, 20);
1020 av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == "); // required by external tools
1021 for (i = 0; i < 20; i++)
1022 av_log(c->fc, AV_LOG_INFO, "%02x", file_checksum[i]);
1023 av_log(c->fc, AV_LOG_INFO, "\n");
1025 /* verify activation data */
1026 if (!activation_bytes) {
1027 av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1028 ret = 0; /* allow ffprobe to continue working on .aax files */
1031 if (c->activation_bytes_size != 4) {
1032 av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1033 ret = AVERROR(EINVAL);
1037 /* verify fixed key */
1038 if (c->audible_fixed_key_size != 16) {
1039 av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1040 ret = AVERROR(EINVAL);
1044 /* AAX (and AAX+) key derivation */
1045 av_sha_init(sha, 160);
1046 av_sha_update(sha, fixed_key, 16);
1047 av_sha_update(sha, activation_bytes, 4);
1048 av_sha_final(sha, intermediate_key);
1049 av_sha_init(sha, 160);
1050 av_sha_update(sha, fixed_key, 16);
1051 av_sha_update(sha, intermediate_key, 20);
1052 av_sha_update(sha, activation_bytes, 4);
1053 av_sha_final(sha, intermediate_iv);
1054 av_sha_init(sha, 160);
1055 av_sha_update(sha, intermediate_key, 16);
1056 av_sha_update(sha, intermediate_iv, 16);
1057 av_sha_final(sha, calculated_checksum);
1058 if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1059 av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1060 ret = AVERROR_INVALIDDATA;
1063 av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1064 av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1065 for (i = 0; i < 4; i++) {
1066 // file data (in output) is stored in big-endian mode
1067 if (activation_bytes[i] != output[3 - i]) { // critical error
1068 av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1069 ret = AVERROR_INVALIDDATA;
1073 memcpy(c->file_key, output + 8, 16);
1074 memcpy(input, output + 26, 16);
1075 av_sha_init(sha, 160);
1076 av_sha_update(sha, input, 16);
1077 av_sha_update(sha, c->file_key, 16);
1078 av_sha_update(sha, fixed_key, 16);
1079 av_sha_final(sha, c->file_iv);
1087 // Audible AAX (and AAX+) bytestream decryption
1088 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1091 unsigned char iv[16];
1093 memcpy(iv, c->file_iv, 16); // iv is overwritten
1094 blocks = size >> 4; // trailing bytes are not encrypted!
1095 av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1096 av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1101 /* read major brand, minor version and compatible brands and store them as metadata */
1102 static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1105 int comp_brand_size;
1106 char* comp_brands_str;
1107 uint8_t type[5] = {0};
1108 int ret = ffio_read_size(pb, type, 4);
1112 if (strcmp(type, "qt "))
1114 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1115 av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1116 minor_ver = avio_rb32(pb); /* minor version */
1117 av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1119 comp_brand_size = atom.size - 8;
1120 if (comp_brand_size < 0)
1121 return AVERROR_INVALIDDATA;
1122 comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1123 if (!comp_brands_str)
1124 return AVERROR(ENOMEM);
1126 ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1128 av_freep(&comp_brands_str);
1131 comp_brands_str[comp_brand_size] = 0;
1132 av_dict_set(&c->fc->metadata, "compatible_brands",
1133 comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1138 /* this atom should contain all header atoms */
1139 static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1143 if (c->found_moov) {
1144 av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1145 avio_skip(pb, atom.size);
1149 if ((ret = mov_read_default(c, pb, atom)) < 0)
1151 /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1152 /* so we don't parse the whole file if over a network */
1154 return 0; /* now go for mdat */
1157 static MOVFragmentStreamInfo * get_frag_stream_info(
1158 MOVFragmentIndex *frag_index,
1163 MOVFragmentIndexItem * item;
1165 if (index < 0 || index >= frag_index->nb_items)
1167 item = &frag_index->item[index];
1168 for (i = 0; i < item->nb_stream_info; i++)
1169 if (item->stream_info[i].id == id)
1170 return &item->stream_info[i];
1172 // This shouldn't happen
1176 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1179 MOVFragmentIndexItem * item;
1181 if (frag_index->current < 0 ||
1182 frag_index->current >= frag_index->nb_items)
1185 item = &frag_index->item[frag_index->current];
1186 for (i = 0; i < item->nb_stream_info; i++)
1187 if (item->stream_info[i].id == id) {
1192 // id not found. This shouldn't happen.
1196 static MOVFragmentStreamInfo * get_current_frag_stream_info(
1197 MOVFragmentIndex *frag_index)
1199 MOVFragmentIndexItem *item;
1200 if (frag_index->current < 0 ||
1201 frag_index->current >= frag_index->nb_items)
1204 item = &frag_index->item[frag_index->current];
1205 if (item->current >= 0 && item->current < item->nb_stream_info)
1206 return &item->stream_info[item->current];
1208 // This shouldn't happen
1212 static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
1215 int64_t moof_offset;
1217 // Optimize for appending new entries
1218 if (!frag_index->nb_items ||
1219 frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1220 return frag_index->nb_items;
1223 b = frag_index->nb_items;
1227 moof_offset = frag_index->item[m].moof_offset;
1228 if (moof_offset >= offset)
1230 if (moof_offset <= offset)
1236 static int64_t get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
1238 av_assert0(frag_stream_info);
1239 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1240 return frag_stream_info->sidx_pts;
1241 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1242 return frag_stream_info->first_tfra_pts;
1243 return frag_stream_info->tfdt_dts;
1246 static int64_t get_frag_time(MOVFragmentIndex *frag_index,
1247 int index, int track_id)
1249 MOVFragmentStreamInfo * frag_stream_info;
1253 if (track_id >= 0) {
1254 frag_stream_info = get_frag_stream_info(frag_index, index, track_id);
1255 return frag_stream_info->sidx_pts;
1258 for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1259 frag_stream_info = &frag_index->item[index].stream_info[i];
1260 timestamp = get_stream_info_time(frag_stream_info);
1261 if (timestamp != AV_NOPTS_VALUE)
1264 return AV_NOPTS_VALUE;
1267 static int search_frag_timestamp(MOVFragmentIndex *frag_index,
1268 AVStream *st, int64_t timestamp)
1275 // If the stream is referenced by any sidx, limit the search
1276 // to fragments that referenced this stream in the sidx
1277 MOVStreamContext *sc = st->priv_data;
1283 b = frag_index->nb_items;
1286 m0 = m = (a + b) >> 1;
1289 (frag_time = get_frag_time(frag_index, m, id)) == AV_NOPTS_VALUE)
1292 if (m < b && frag_time <= timestamp)
1301 static int update_frag_index(MOVContext *c, int64_t offset)
1304 MOVFragmentIndexItem * item;
1305 MOVFragmentStreamInfo * frag_stream_info;
1307 // If moof_offset already exists in frag_index, return index to it
1308 index = search_frag_moof_offset(&c->frag_index, offset);
1309 if (index < c->frag_index.nb_items &&
1310 c->frag_index.item[index].moof_offset == offset)
1313 // offset is not yet in frag index.
1314 // Insert new item at index (sorted by moof offset)
1315 item = av_fast_realloc(c->frag_index.item,
1316 &c->frag_index.allocated_size,
1317 (c->frag_index.nb_items + 1) *
1318 sizeof(*c->frag_index.item));
1321 c->frag_index.item = item;
1323 frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1324 sizeof(*item->stream_info));
1325 if (!frag_stream_info)
1328 for (i = 0; i < c->fc->nb_streams; i++) {
1329 // Avoid building frag index if streams lack track id.
1330 if (c->fc->streams[i]->id < 0)
1331 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",
5798 buffer, AV_DICT_DONT_STRDUP_VAL);
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 ret = AVERROR(ENOMEM);
6337 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6338 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6339 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6340 min_kid_count * sizeof(*key_ids));
6342 ret = AVERROR(ENOMEM);
6345 info->key_ids = key_ids;
6347 info->key_ids[i] = av_mallocz(16);
6348 if (!info->key_ids[i]) {
6349 ret = AVERROR(ENOMEM);
6352 info->num_key_ids = i + 1;
6354 if (avio_read(pb, info->key_ids[i], 16) != 16) {
6355 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6356 ret = AVERROR_INVALIDDATA;
6361 if (pb->eof_reached) {
6362 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6363 ret = AVERROR_INVALIDDATA;
6368 extra_data_size = avio_rb32(pb);
6369 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6373 av_freep(&info->data); // malloc(0) may still allocate something.
6374 info->data = extra_data;
6375 info->data_size = extra_data_size;
6377 // If there is existing initialization data, append to the list.
6378 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6379 if (old_side_data) {
6380 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6381 if (old_init_info) {
6382 // Append to the end of the list.
6383 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6389 info = old_init_info;
6391 // Assume existing side-data will be valid, so the only error we could get is OOM.
6392 ret = AVERROR(ENOMEM);
6397 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6399 ret = AVERROR(ENOMEM);
6402 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6403 side_data, side_data_size);
6408 av_encryption_init_info_free(info);
6412 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6415 MOVStreamContext *sc;
6417 if (c->fc->nb_streams < 1)
6419 st = c->fc->streams[c->fc->nb_streams-1];
6422 if (sc->pseudo_stream_id != 0) {
6423 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6424 return AVERROR_PATCHWELCOME;
6428 return AVERROR_INVALIDDATA;
6430 avio_rb32(pb); /* version and flags */
6432 if (!sc->cenc.default_encrypted_sample) {
6433 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6434 if (!sc->cenc.default_encrypted_sample) {
6435 return AVERROR(ENOMEM);
6439 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6443 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6446 MOVStreamContext *sc;
6447 unsigned int version, pattern, is_protected, iv_size;
6449 if (c->fc->nb_streams < 1)
6451 st = c->fc->streams[c->fc->nb_streams-1];
6454 if (sc->pseudo_stream_id != 0) {
6455 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6456 return AVERROR_PATCHWELCOME;
6459 if (!sc->cenc.default_encrypted_sample) {
6460 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6461 if (!sc->cenc.default_encrypted_sample) {
6462 return AVERROR(ENOMEM);
6467 return AVERROR_INVALIDDATA;
6469 version = avio_r8(pb); /* version */
6470 avio_rb24(pb); /* flags */
6472 avio_r8(pb); /* reserved */
6473 pattern = avio_r8(pb);
6476 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6477 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6480 is_protected = avio_r8(pb);
6481 if (is_protected && !sc->cenc.encryption_index) {
6482 // The whole stream should be by-default encrypted.
6483 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6484 if (!sc->cenc.encryption_index)
6485 return AVERROR(ENOMEM);
6487 sc->cenc.per_sample_iv_size = avio_r8(pb);
6488 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6489 sc->cenc.per_sample_iv_size != 16) {
6490 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6491 return AVERROR_INVALIDDATA;
6493 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6494 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6495 return AVERROR_INVALIDDATA;
6498 if (is_protected && !sc->cenc.per_sample_iv_size) {
6499 iv_size = avio_r8(pb);
6500 if (iv_size != 8 && iv_size != 16) {
6501 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6502 return AVERROR_INVALIDDATA;
6505 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6506 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6507 return AVERROR_INVALIDDATA;
6514 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6517 int last, type, size, ret;
6520 if (c->fc->nb_streams < 1)
6522 st = c->fc->streams[c->fc->nb_streams-1];
6524 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6525 return AVERROR_INVALIDDATA;
6527 /* Check FlacSpecificBox version. */
6528 if (avio_r8(pb) != 0)
6529 return AVERROR_INVALIDDATA;
6531 avio_rb24(pb); /* Flags */
6533 avio_read(pb, buf, sizeof(buf));
6534 flac_parse_block_header(buf, &last, &type, &size);
6536 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6537 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6538 return AVERROR_INVALIDDATA;
6541 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6546 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6551 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6555 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6556 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6557 return AVERROR_PATCHWELCOME;
6560 if (!sc->cenc.aes_ctr) {
6561 /* initialize the cipher */
6562 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6563 if (!sc->cenc.aes_ctr) {
6564 return AVERROR(ENOMEM);
6567 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6573 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6575 if (!sample->subsample_count)
6577 /* decrypt the whole packet */
6578 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6582 for (i = 0; i < sample->subsample_count; i++)
6584 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6585 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6586 return AVERROR_INVALIDDATA;
6589 /* skip the clear bytes */
6590 input += sample->subsamples[i].bytes_of_clear_data;
6591 size -= sample->subsamples[i].bytes_of_clear_data;
6593 /* decrypt the encrypted bytes */
6594 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6595 input += sample->subsamples[i].bytes_of_protected_data;
6596 size -= sample->subsamples[i].bytes_of_protected_data;
6600 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6601 return AVERROR_INVALIDDATA;
6607 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6609 MOVFragmentStreamInfo *frag_stream_info;
6610 MOVEncryptionIndex *encryption_index;
6611 AVEncryptionInfo *encrypted_sample;
6612 int encrypted_index, ret;
6614 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6615 encrypted_index = current_index;
6616 encryption_index = NULL;
6617 if (frag_stream_info) {
6618 // Note this only supports encryption info in the first sample descriptor.
6619 if (mov->fragment.stsd_id == 1) {
6620 if (frag_stream_info->encryption_index) {
6621 encrypted_index = current_index - frag_stream_info->index_entry;
6622 encryption_index = frag_stream_info->encryption_index;
6624 encryption_index = sc->cenc.encryption_index;
6628 encryption_index = sc->cenc.encryption_index;
6631 if (encryption_index) {
6632 if (encryption_index->auxiliary_info_sample_count &&
6633 !encryption_index->nb_encrypted_samples) {
6634 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6635 return AVERROR_INVALIDDATA;
6637 if (encryption_index->auxiliary_offsets_count &&
6638 !encryption_index->nb_encrypted_samples) {
6639 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6640 return AVERROR_INVALIDDATA;
6643 if (!encryption_index->nb_encrypted_samples) {
6644 // Full-sample encryption with default settings.
6645 encrypted_sample = sc->cenc.default_encrypted_sample;
6646 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6647 // Per-sample setting override.
6648 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6650 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6651 return AVERROR_INVALIDDATA;
6654 if (mov->decryption_key) {
6655 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6658 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6660 return AVERROR(ENOMEM);
6661 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6671 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6673 const int OPUS_SEEK_PREROLL_MS = 80;
6679 if (c->fc->nb_streams < 1)
6681 st = c->fc->streams[c->fc->nb_streams-1];
6683 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6684 return AVERROR_INVALIDDATA;
6686 /* Check OpusSpecificBox version. */
6687 if (avio_r8(pb) != 0) {
6688 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6689 return AVERROR_INVALIDDATA;
6692 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6693 size = atom.size + 8;
6695 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
6698 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6699 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6700 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6701 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6703 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6704 little-endian; aside from the preceeding magic and version they're
6705 otherwise currently identical. Data after output gain at offset 16
6706 doesn't need to be bytewapped. */
6707 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6708 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6709 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6710 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6712 st->codecpar->initial_padding = pre_skip;
6713 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6714 (AVRational){1, 1000},
6715 (AVRational){1, 48000});
6720 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6723 unsigned format_info;
6724 int channel_assignment, channel_assignment1, channel_assignment2;
6727 if (c->fc->nb_streams < 1)
6729 st = c->fc->streams[c->fc->nb_streams-1];
6732 return AVERROR_INVALIDDATA;
6734 format_info = avio_rb32(pb);
6736 ratebits = (format_info >> 28) & 0xF;
6737 channel_assignment1 = (format_info >> 15) & 0x1F;
6738 channel_assignment2 = format_info & 0x1FFF;
6739 if (channel_assignment2)
6740 channel_assignment = channel_assignment2;
6742 channel_assignment = channel_assignment1;
6744 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6745 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6746 st->codecpar->channels = truehd_channels(channel_assignment);
6747 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6752 static const MOVParseTableEntry mov_default_parse_table[] = {
6753 { MKTAG('A','C','L','R'), mov_read_aclr },
6754 { MKTAG('A','P','R','G'), mov_read_avid },
6755 { MKTAG('A','A','L','P'), mov_read_avid },
6756 { MKTAG('A','R','E','S'), mov_read_ares },
6757 { MKTAG('a','v','s','s'), mov_read_avss },
6758 { MKTAG('a','v','1','C'), mov_read_av1c },
6759 { MKTAG('c','h','p','l'), mov_read_chpl },
6760 { MKTAG('c','o','6','4'), mov_read_stco },
6761 { MKTAG('c','o','l','r'), mov_read_colr },
6762 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6763 { MKTAG('d','i','n','f'), mov_read_default },
6764 { MKTAG('D','p','x','E'), mov_read_dpxe },
6765 { MKTAG('d','r','e','f'), mov_read_dref },
6766 { MKTAG('e','d','t','s'), mov_read_default },
6767 { MKTAG('e','l','s','t'), mov_read_elst },
6768 { MKTAG('e','n','d','a'), mov_read_enda },
6769 { MKTAG('f','i','e','l'), mov_read_fiel },
6770 { MKTAG('a','d','r','m'), mov_read_adrm },
6771 { MKTAG('f','t','y','p'), mov_read_ftyp },
6772 { MKTAG('g','l','b','l'), mov_read_glbl },
6773 { MKTAG('h','d','l','r'), mov_read_hdlr },
6774 { MKTAG('i','l','s','t'), mov_read_ilst },
6775 { MKTAG('j','p','2','h'), mov_read_jp2h },
6776 { MKTAG('m','d','a','t'), mov_read_mdat },
6777 { MKTAG('m','d','h','d'), mov_read_mdhd },
6778 { MKTAG('m','d','i','a'), mov_read_default },
6779 { MKTAG('m','e','t','a'), mov_read_meta },
6780 { MKTAG('m','i','n','f'), mov_read_default },
6781 { MKTAG('m','o','o','f'), mov_read_moof },
6782 { MKTAG('m','o','o','v'), mov_read_moov },
6783 { MKTAG('m','v','e','x'), mov_read_default },
6784 { MKTAG('m','v','h','d'), mov_read_mvhd },
6785 { MKTAG('S','M','I',' '), mov_read_svq3 },
6786 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6787 { MKTAG('a','v','c','C'), mov_read_glbl },
6788 { MKTAG('p','a','s','p'), mov_read_pasp },
6789 { MKTAG('s','i','d','x'), mov_read_sidx },
6790 { MKTAG('s','t','b','l'), mov_read_default },
6791 { MKTAG('s','t','c','o'), mov_read_stco },
6792 { MKTAG('s','t','p','s'), mov_read_stps },
6793 { MKTAG('s','t','r','f'), mov_read_strf },
6794 { MKTAG('s','t','s','c'), mov_read_stsc },
6795 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6796 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6797 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6798 { MKTAG('s','t','t','s'), mov_read_stts },
6799 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6800 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
6801 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6802 { MKTAG('t','f','d','t'), mov_read_tfdt },
6803 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6804 { MKTAG('t','r','a','k'), mov_read_trak },
6805 { MKTAG('t','r','a','f'), mov_read_default },
6806 { MKTAG('t','r','e','f'), mov_read_default },
6807 { MKTAG('t','m','c','d'), mov_read_tmcd },
6808 { MKTAG('c','h','a','p'), mov_read_chap },
6809 { MKTAG('t','r','e','x'), mov_read_trex },
6810 { MKTAG('t','r','u','n'), mov_read_trun },
6811 { MKTAG('u','d','t','a'), mov_read_default },
6812 { MKTAG('w','a','v','e'), mov_read_wave },
6813 { MKTAG('e','s','d','s'), mov_read_esds },
6814 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6815 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6816 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6817 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6818 { MKTAG('w','f','e','x'), mov_read_wfex },
6819 { MKTAG('c','m','o','v'), mov_read_cmov },
6820 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6821 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6822 { MKTAG('s','b','g','p'), mov_read_sbgp },
6823 { MKTAG('h','v','c','C'), mov_read_glbl },
6824 { MKTAG('u','u','i','d'), mov_read_uuid },
6825 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6826 { MKTAG('f','r','e','e'), mov_read_free },
6827 { MKTAG('-','-','-','-'), mov_read_custom },
6828 { MKTAG('s','i','n','f'), mov_read_default },
6829 { MKTAG('f','r','m','a'), mov_read_frma },
6830 { MKTAG('s','e','n','c'), mov_read_senc },
6831 { MKTAG('s','a','i','z'), mov_read_saiz },
6832 { MKTAG('s','a','i','o'), mov_read_saio },
6833 { MKTAG('p','s','s','h'), mov_read_pssh },
6834 { MKTAG('s','c','h','m'), mov_read_schm },
6835 { MKTAG('s','c','h','i'), mov_read_default },
6836 { MKTAG('t','e','n','c'), mov_read_tenc },
6837 { MKTAG('d','f','L','a'), mov_read_dfla },
6838 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6839 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6840 { MKTAG('d','O','p','s'), mov_read_dops },
6841 { MKTAG('d','m','l','p'), mov_read_dmlp },
6842 { MKTAG('S','m','D','m'), mov_read_smdm },
6843 { MKTAG('C','o','L','L'), mov_read_coll },
6844 { MKTAG('v','p','c','C'), mov_read_vpcc },
6845 { MKTAG('m','d','c','v'), mov_read_mdcv },
6846 { MKTAG('c','l','l','i'), mov_read_clli },
6850 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6852 int64_t total_size = 0;
6856 if (c->atom_depth > 10) {
6857 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6858 return AVERROR_INVALIDDATA;
6863 atom.size = INT64_MAX;
6864 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6865 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
6868 if (atom.size >= 8) {
6869 a.size = avio_rb32(pb);
6870 a.type = avio_rl32(pb);
6871 if (a.type == MKTAG('f','r','e','e') &&
6873 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT &&
6876 uint32_t *type = (uint32_t *)buf + 1;
6877 if (avio_read(pb, buf, 8) != 8)
6878 return AVERROR_INVALIDDATA;
6879 avio_seek(pb, -8, SEEK_CUR);
6880 if (*type == MKTAG('m','v','h','d') ||
6881 *type == MKTAG('c','m','o','v')) {
6882 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free atom.\n");
6883 a.type = MKTAG('m','o','o','v');
6886 if (atom.type != MKTAG('r','o','o','t') &&
6887 atom.type != MKTAG('m','o','o','v'))
6889 if (a.type == MKTAG('t','r','a','k') || a.type == MKTAG('m','d','a','t'))
6891 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
6898 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
6899 a.size = avio_rb64(pb) - 8;
6903 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
6904 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
6906 a.size = atom.size - total_size + 8;
6911 a.size = FFMIN(a.size, atom.size - total_size);
6913 for (i = 0; mov_default_parse_table[i].type; i++)
6914 if (mov_default_parse_table[i].type == a.type) {
6915 parse = mov_default_parse_table[i].parse;
6919 // container is user data
6920 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
6921 atom.type == MKTAG('i','l','s','t')))
6922 parse = mov_read_udta_string;
6924 // Supports parsing the QuickTime Metadata Keys.
6925 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
6926 if (!parse && c->found_hdlr_mdta &&
6927 atom.type == MKTAG('m','e','t','a') &&
6928 a.type == MKTAG('k','e','y','s')) {
6929 parse = mov_read_keys;
6932 if (!parse) { /* skip leaf atoms data */
6933 avio_skip(pb, a.size);
6935 int64_t start_pos = avio_tell(pb);
6937 int err = parse(c, pb, a);
6942 if (c->found_moov && c->found_mdat &&
6943 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
6944 start_pos + a.size == avio_size(pb))) {
6945 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
6946 c->next_root_atom = start_pos + a.size;
6950 left = a.size - avio_tell(pb) + start_pos;
6951 if (left > 0) /* skip garbage at atom end */
6952 avio_skip(pb, left);
6953 else if (left < 0) {
6954 av_log(c->fc, AV_LOG_WARNING,
6955 "overread end of atom '%.4s' by %"PRId64" bytes\n",
6956 (char*)&a.type, -left);
6957 avio_seek(pb, left, SEEK_CUR);
6961 total_size += a.size;
6964 if (total_size < atom.size && atom.size < 0x7ffff)
6965 avio_skip(pb, atom.size - total_size);
6971 static int mov_probe(const AVProbeData *p)
6976 int moov_offset = -1;
6978 /* check file header */
6981 /* ignore invalid offset */
6982 if ((offset + 8) > (unsigned int)p->buf_size)
6984 tag = AV_RL32(p->buf + offset + 4);
6986 /* check for obvious tags */
6987 case MKTAG('m','o','o','v'):
6988 moov_offset = offset + 4;
6989 case MKTAG('m','d','a','t'):
6990 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
6991 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
6992 case MKTAG('f','t','y','p'):
6993 if (AV_RB32(p->buf+offset) < 8 &&
6994 (AV_RB32(p->buf+offset) != 1 ||
6995 offset + 12 > (unsigned int)p->buf_size ||
6996 AV_RB64(p->buf+offset + 8) == 0)) {
6997 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
6998 } else if (tag == MKTAG('f','t','y','p') &&
6999 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
7000 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
7002 score = FFMAX(score, 5);
7004 score = AVPROBE_SCORE_MAX;
7006 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7008 /* those are more common words, so rate then a bit less */
7009 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
7010 case MKTAG('w','i','d','e'):
7011 case MKTAG('f','r','e','e'):
7012 case MKTAG('j','u','n','k'):
7013 case MKTAG('p','i','c','t'):
7014 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
7015 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7017 case MKTAG(0x82,0x82,0x7f,0x7d):
7018 case MKTAG('s','k','i','p'):
7019 case MKTAG('u','u','i','d'):
7020 case MKTAG('p','r','f','l'):
7021 /* if we only find those cause probedata is too small at least rate them */
7022 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7023 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7026 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7029 if(score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
7030 /* moov atom in the header - we should make sure that this is not a
7031 * MOV-packed MPEG-PS */
7032 offset = moov_offset;
7034 while(offset < (p->buf_size - 16)){ /* Sufficient space */
7035 /* We found an actual hdlr atom */
7036 if(AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7037 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7038 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')){
7039 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7040 /* We found a media handler reference atom describing an
7041 * MPEG-PS-in-MOV, return a
7042 * low score to force expanding the probe window until
7043 * mpegps_probe finds what it needs */
7054 // must be done after parsing all trak because there's no order requirement
7055 static void mov_read_chapters(AVFormatContext *s)
7057 MOVContext *mov = s->priv_data;
7059 MOVStreamContext *sc;
7064 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7065 chapter_track = mov->chapter_tracks[j];
7067 for (i = 0; i < s->nb_streams; i++)
7068 if (s->streams[i]->id == chapter_track) {
7073 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7078 cur_pos = avio_tell(sc->pb);
7080 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7081 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7082 if (st->nb_index_entries) {
7083 // Retrieve the first frame, if possible
7085 AVIndexEntry *sample = &st->index_entries[0];
7086 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7087 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7091 if (av_get_packet(sc->pb, &pkt, sample->size) < 0)
7094 st->attached_pic = pkt;
7095 st->attached_pic.stream_index = st->index;
7096 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
7099 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7100 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7101 st->discard = AVDISCARD_ALL;
7102 for (i = 0; i < st->nb_index_entries; i++) {
7103 AVIndexEntry *sample = &st->index_entries[i];
7104 int64_t end = i+1 < st->nb_index_entries ? st->index_entries[i+1].timestamp : st->duration;
7109 if (end < sample->timestamp) {
7110 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7111 end = AV_NOPTS_VALUE;
7114 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7115 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7119 // the first two bytes are the length of the title
7120 len = avio_rb16(sc->pb);
7121 if (len > sample->size-2)
7123 title_len = 2*len + 1;
7124 if (!(title = av_mallocz(title_len)))
7127 // The samples could theoretically be in any encoding if there's an encd
7128 // atom following, but in practice are only utf-8 or utf-16, distinguished
7129 // instead by the presence of a BOM
7133 ch = avio_rb16(sc->pb);
7135 avio_get_str16be(sc->pb, len, title, title_len);
7136 else if (ch == 0xfffe)
7137 avio_get_str16le(sc->pb, len, title, title_len);
7140 if (len == 1 || len == 2)
7143 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7147 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7152 avio_seek(sc->pb, cur_pos, SEEK_SET);
7156 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7157 uint32_t value, int flags)
7160 char buf[AV_TIMECODE_STR_SIZE];
7161 AVRational rate = st->avg_frame_rate;
7162 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7165 av_dict_set(&st->metadata, "timecode",
7166 av_timecode_make_string(&tc, buf, value), 0);
7170 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7172 MOVStreamContext *sc = st->priv_data;
7173 char buf[AV_TIMECODE_STR_SIZE];
7174 int64_t cur_pos = avio_tell(sc->pb);
7175 int hh, mm, ss, ff, drop;
7177 if (!st->nb_index_entries)
7180 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7181 avio_skip(s->pb, 13);
7182 hh = avio_r8(s->pb);
7183 mm = avio_r8(s->pb);
7184 ss = avio_r8(s->pb);
7185 drop = avio_r8(s->pb);
7186 ff = avio_r8(s->pb);
7187 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7188 hh, mm, ss, drop ? ';' : ':', ff);
7189 av_dict_set(&st->metadata, "timecode", buf, 0);
7191 avio_seek(sc->pb, cur_pos, SEEK_SET);
7195 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7197 MOVStreamContext *sc = st->priv_data;
7199 int64_t cur_pos = avio_tell(sc->pb);
7202 if (!st->nb_index_entries)
7205 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7206 value = avio_rb32(s->pb);
7208 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7209 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7210 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7212 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7213 * not the case) and thus assume "frame number format" instead of QT one.
7214 * No sample with tmcd track can be found with a QT timecode at the moment,
7215 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7217 parse_timecode_in_framenum_format(s, st, value, flags);
7219 avio_seek(sc->pb, cur_pos, SEEK_SET);
7223 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7225 if (!index || !*index) return;
7226 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7227 av_encryption_info_free((*index)->encrypted_samples[i]);
7229 av_freep(&(*index)->encrypted_samples);
7230 av_freep(&(*index)->auxiliary_info_sizes);
7231 av_freep(&(*index)->auxiliary_offsets);
7235 static int mov_read_close(AVFormatContext *s)
7237 MOVContext *mov = s->priv_data;
7240 for (i = 0; i < s->nb_streams; i++) {
7241 AVStream *st = s->streams[i];
7242 MOVStreamContext *sc = st->priv_data;
7247 av_freep(&sc->ctts_data);
7248 for (j = 0; j < sc->drefs_count; j++) {
7249 av_freep(&sc->drefs[j].path);
7250 av_freep(&sc->drefs[j].dir);
7252 av_freep(&sc->drefs);
7254 sc->drefs_count = 0;
7256 if (!sc->pb_is_copied)
7257 ff_format_io_close(s, &sc->pb);
7260 av_freep(&sc->chunk_offsets);
7261 av_freep(&sc->stsc_data);
7262 av_freep(&sc->sample_sizes);
7263 av_freep(&sc->keyframes);
7264 av_freep(&sc->stts_data);
7265 av_freep(&sc->sdtp_data);
7266 av_freep(&sc->stps_data);
7267 av_freep(&sc->elst_data);
7268 av_freep(&sc->rap_group);
7269 av_freep(&sc->display_matrix);
7270 av_freep(&sc->index_ranges);
7273 for (j = 0; j < sc->stsd_count; j++)
7274 av_free(sc->extradata[j]);
7275 av_freep(&sc->extradata);
7276 av_freep(&sc->extradata_size);
7278 mov_free_encryption_index(&sc->cenc.encryption_index);
7279 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7280 av_aes_ctr_free(sc->cenc.aes_ctr);
7282 av_freep(&sc->stereo3d);
7283 av_freep(&sc->spherical);
7284 av_freep(&sc->mastering);
7285 av_freep(&sc->coll);
7288 if (mov->dv_demux) {
7289 avformat_free_context(mov->dv_fctx);
7290 mov->dv_fctx = NULL;
7293 if (mov->meta_keys) {
7294 for (i = 1; i < mov->meta_keys_count; i++) {
7295 av_freep(&mov->meta_keys[i]);
7297 av_freep(&mov->meta_keys);
7300 av_freep(&mov->trex_data);
7301 av_freep(&mov->bitrates);
7303 for (i = 0; i < mov->frag_index.nb_items; i++) {
7304 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7305 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7306 mov_free_encryption_index(&frag[j].encryption_index);
7308 av_freep(&mov->frag_index.item[i].stream_info);
7310 av_freep(&mov->frag_index.item);
7312 av_freep(&mov->aes_decrypt);
7313 av_freep(&mov->chapter_tracks);
7318 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7322 for (i = 0; i < s->nb_streams; i++) {
7323 AVStream *st = s->streams[i];
7324 MOVStreamContext *sc = st->priv_data;
7326 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7327 sc->timecode_track == tmcd_id)
7333 /* look for a tmcd track not referenced by any video track, and export it globally */
7334 static void export_orphan_timecode(AVFormatContext *s)
7338 for (i = 0; i < s->nb_streams; i++) {
7339 AVStream *st = s->streams[i];
7341 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7342 !tmcd_is_referenced(s, i + 1)) {
7343 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7345 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7352 static int read_tfra(MOVContext *mov, AVIOContext *f)
7354 int version, fieldlength, i, j;
7355 int64_t pos = avio_tell(f);
7356 uint32_t size = avio_rb32(f);
7357 unsigned track_id, item_count;
7359 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7362 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7364 version = avio_r8(f);
7366 track_id = avio_rb32(f);
7367 fieldlength = avio_rb32(f);
7368 item_count = avio_rb32(f);
7369 for (i = 0; i < item_count; i++) {
7370 int64_t time, offset;
7372 MOVFragmentStreamInfo * frag_stream_info;
7375 return AVERROR_INVALIDDATA;
7379 time = avio_rb64(f);
7380 offset = avio_rb64(f);
7382 time = avio_rb32(f);
7383 offset = avio_rb32(f);
7386 // The first sample of each stream in a fragment is always a random
7387 // access sample. So it's entry in the tfra can be used as the
7388 // initial PTS of the fragment.
7389 index = update_frag_index(mov, offset);
7390 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7391 if (frag_stream_info &&
7392 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7393 frag_stream_info->first_tfra_pts = time;
7395 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7397 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7399 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7403 avio_seek(f, pos + size, SEEK_SET);
7407 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7409 int64_t stream_size = avio_size(f);
7410 int64_t original_pos = avio_tell(f);
7414 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7418 mfra_size = avio_rb32(f);
7419 if (mfra_size < 0 || mfra_size > stream_size) {
7420 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7423 if ((seek_ret = avio_seek(f, -mfra_size, SEEK_CUR)) < 0) {
7427 if (avio_rb32(f) != mfra_size) {
7428 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7431 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7432 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7435 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7437 ret = read_tfra(c, f);
7443 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7445 av_log(c->fc, AV_LOG_ERROR,
7446 "failed to seek back after looking for mfra\n");
7452 static int mov_read_header(AVFormatContext *s)
7454 MOVContext *mov = s->priv_data;
7455 AVIOContext *pb = s->pb;
7457 MOVAtom atom = { AV_RL32("root") };
7460 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7461 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7462 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7463 return AVERROR(EINVAL);
7467 mov->trak_index = -1;
7468 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7469 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7470 atom.size = avio_size(pb);
7472 atom.size = INT64_MAX;
7474 /* check MOV header */
7476 if (mov->moov_retry)
7477 avio_seek(pb, 0, SEEK_SET);
7478 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7479 av_log(s, AV_LOG_ERROR, "error reading header\n");
7483 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7484 if (!mov->found_moov) {
7485 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7487 return AVERROR_INVALIDDATA;
7489 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7491 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7492 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7493 mov_read_chapters(s);
7494 for (i = 0; i < s->nb_streams; i++)
7495 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7496 mov_read_timecode_track(s, s->streams[i]);
7497 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7498 mov_read_rtmd_track(s, s->streams[i]);
7502 /* copy timecode metadata from tmcd tracks to the related video streams */
7503 for (i = 0; i < s->nb_streams; i++) {
7504 AVStream *st = s->streams[i];
7505 MOVStreamContext *sc = st->priv_data;
7506 if (sc->timecode_track > 0) {
7507 AVDictionaryEntry *tcr;
7508 int tmcd_st_id = -1;
7510 for (j = 0; j < s->nb_streams; j++)
7511 if (s->streams[j]->id == sc->timecode_track)
7514 if (tmcd_st_id < 0 || tmcd_st_id == i)
7516 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7518 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7521 export_orphan_timecode(s);
7523 for (i = 0; i < s->nb_streams; i++) {
7524 AVStream *st = s->streams[i];
7525 MOVStreamContext *sc = st->priv_data;
7526 fix_timescale(mov, sc);
7527 if(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7528 st->skip_samples = sc->start_pad;
7530 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7531 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7532 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7533 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7534 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7535 st->codecpar->width = sc->width;
7536 st->codecpar->height = sc->height;
7538 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7539 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7543 if (mov->handbrake_version &&
7544 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7545 st->codecpar->codec_id == AV_CODEC_ID_MP3
7547 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7548 st->need_parsing = AVSTREAM_PARSE_FULL;
7552 if (mov->trex_data) {
7553 for (i = 0; i < s->nb_streams; i++) {
7554 AVStream *st = s->streams[i];
7555 MOVStreamContext *sc = st->priv_data;
7556 if (st->duration > 0) {
7557 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7558 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7559 sc->data_size, sc->time_scale);
7561 return AVERROR_INVALIDDATA;
7563 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7568 if (mov->use_mfra_for > 0) {
7569 for (i = 0; i < s->nb_streams; i++) {
7570 AVStream *st = s->streams[i];
7571 MOVStreamContext *sc = st->priv_data;
7572 if (sc->duration_for_fps > 0) {
7573 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7574 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7575 sc->data_size, sc->time_scale);
7577 return AVERROR_INVALIDDATA;
7579 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7580 sc->duration_for_fps;
7585 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7586 if (mov->bitrates[i]) {
7587 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7591 ff_rfps_calculate(s);
7593 for (i = 0; i < s->nb_streams; i++) {
7594 AVStream *st = s->streams[i];
7595 MOVStreamContext *sc = st->priv_data;
7597 switch (st->codecpar->codec_type) {
7598 case AVMEDIA_TYPE_AUDIO:
7599 err = ff_replaygain_export(st, s->metadata);
7605 case AVMEDIA_TYPE_VIDEO:
7606 if (sc->display_matrix) {
7607 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7608 sizeof(int32_t) * 9);
7612 sc->display_matrix = NULL;
7615 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7616 (uint8_t *)sc->stereo3d,
7617 sizeof(*sc->stereo3d));
7621 sc->stereo3d = NULL;
7623 if (sc->spherical) {
7624 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7625 (uint8_t *)sc->spherical,
7626 sc->spherical_size);
7630 sc->spherical = NULL;
7632 if (sc->mastering) {
7633 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7634 (uint8_t *)sc->mastering,
7635 sizeof(*sc->mastering));
7639 sc->mastering = NULL;
7642 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7643 (uint8_t *)sc->coll,
7653 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7655 for (i = 0; i < mov->frag_index.nb_items; i++)
7656 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7657 mov->frag_index.item[i].headers_read = 1;
7662 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7664 AVIndexEntry *sample = NULL;
7665 int64_t best_dts = INT64_MAX;
7667 for (i = 0; i < s->nb_streams; i++) {
7668 AVStream *avst = s->streams[i];
7669 MOVStreamContext *msc = avst->priv_data;
7670 if (msc->pb && msc->current_sample < avst->nb_index_entries) {
7671 AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample];
7672 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7673 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7674 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7675 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7676 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb &&
7677 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7678 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7679 sample = current_sample;
7688 static int should_retry(AVIOContext *pb, int error_code) {
7689 if (error_code == AVERROR_EOF || avio_feof(pb))
7695 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7698 MOVContext *mov = s->priv_data;
7700 if (index >= 0 && index < mov->frag_index.nb_items)
7701 target = mov->frag_index.item[index].moof_offset;
7702 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7703 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7704 return AVERROR_INVALIDDATA;
7707 mov->next_root_atom = 0;
7708 if (index < 0 || index >= mov->frag_index.nb_items)
7709 index = search_frag_moof_offset(&mov->frag_index, target);
7710 if (index < mov->frag_index.nb_items) {
7711 if (index + 1 < mov->frag_index.nb_items)
7712 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7713 if (mov->frag_index.item[index].headers_read)
7715 mov->frag_index.item[index].headers_read = 1;
7718 mov->found_mdat = 0;
7720 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7723 if (avio_feof(s->pb))
7725 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7730 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7732 uint8_t *side, *extradata;
7735 /* Save the current index. */
7736 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7738 /* Notify the decoder that extradata changed. */
7739 extradata_size = sc->extradata_size[sc->last_stsd_index];
7740 extradata = sc->extradata[sc->last_stsd_index];
7741 if (extradata_size > 0 && extradata) {
7742 side = av_packet_new_side_data(pkt,
7743 AV_PKT_DATA_NEW_EXTRADATA,
7746 return AVERROR(ENOMEM);
7747 memcpy(side, extradata, extradata_size);
7753 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7755 MOVContext *mov = s->priv_data;
7756 MOVStreamContext *sc;
7757 AVIndexEntry *sample;
7758 AVStream *st = NULL;
7759 int64_t current_index;
7763 sample = mov_find_next_sample(s, &st);
7764 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7765 if (!mov->next_root_atom)
7767 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7772 /* must be done just before reading, to avoid infinite loop on sample */
7773 current_index = sc->current_index;
7774 mov_current_sample_inc(sc);
7776 if (mov->next_root_atom) {
7777 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7778 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7781 if (st->discard != AVDISCARD_ALL) {
7782 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7783 if (ret64 != sample->pos) {
7784 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7785 sc->ffindex, sample->pos);
7786 if (should_retry(sc->pb, ret64)) {
7787 mov_current_sample_dec(sc);
7789 return AVERROR_INVALIDDATA;
7792 if( st->discard == AVDISCARD_NONKEY && 0==(sample->flags & AVINDEX_KEYFRAME) ) {
7793 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7797 ret = av_get_packet(sc->pb, pkt, sample->size);
7799 if (should_retry(sc->pb, ret)) {
7800 mov_current_sample_dec(sc);
7804 if (sc->has_palette) {
7807 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7809 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7811 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7812 sc->has_palette = 0;
7815 #if CONFIG_DV_DEMUXER
7816 if (mov->dv_demux && sc->dv_audio_container) {
7817 avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7818 av_freep(&pkt->data);
7820 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7825 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7826 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7827 st->need_parsing = AVSTREAM_PARSE_FULL;
7831 pkt->stream_index = sc->ffindex;
7832 pkt->dts = sample->timestamp;
7833 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7834 pkt->flags |= AV_PKT_FLAG_DISCARD;
7836 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7837 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
7838 /* update ctts context */
7840 if (sc->ctts_index < sc->ctts_count &&
7841 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
7843 sc->ctts_sample = 0;
7846 int64_t next_dts = (sc->current_sample < st->nb_index_entries) ?
7847 st->index_entries[sc->current_sample].timestamp : st->duration;
7849 if (next_dts >= pkt->dts)
7850 pkt->duration = next_dts - pkt->dts;
7851 pkt->pts = pkt->dts;
7853 if (st->discard == AVDISCARD_ALL)
7855 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
7856 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
7857 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
7858 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
7860 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
7861 pkt->pos = sample->pos;
7863 /* Multiple stsd handling. */
7864 if (sc->stsc_data) {
7865 /* Keep track of the stsc index for the given sample, then check
7866 * if the stsd index is different from the last used one. */
7868 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
7869 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
7871 sc->stsc_sample = 0;
7872 /* Do not check indexes after a switch. */
7873 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
7874 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
7875 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
7876 ret = mov_change_extradata(sc, pkt);
7883 aax_filter(pkt->data, pkt->size, mov);
7885 ret = cenc_filter(mov, st, sc, pkt, current_index);
7887 av_packet_unref(pkt);
7894 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
7896 MOVContext *mov = s->priv_data;
7899 if (!mov->frag_index.complete)
7902 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
7905 if (!mov->frag_index.item[index].headers_read)
7906 return mov_switch_root(s, -1, index);
7907 if (index + 1 < mov->frag_index.nb_items)
7908 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7913 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
7915 MOVStreamContext *sc = st->priv_data;
7916 int sample, time_sample, ret;
7919 // Here we consider timestamp to be PTS, hence try to offset it so that we
7920 // can search over the DTS timeline.
7921 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
7923 ret = mov_seek_fragment(s, st, timestamp);
7927 sample = av_index_search_timestamp(st, timestamp, flags);
7928 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
7929 if (sample < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp)
7931 if (sample < 0) /* not sure what to do */
7932 return AVERROR_INVALIDDATA;
7933 mov_current_sample_set(sc, sample);
7934 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
7935 /* adjust ctts index */
7936 if (sc->ctts_data) {
7938 for (i = 0; i < sc->ctts_count; i++) {
7939 int next = time_sample + sc->ctts_data[i].count;
7940 if (next > sc->current_sample) {
7942 sc->ctts_sample = sc->current_sample - time_sample;
7949 /* adjust stsd index */
7950 if (sc->chunk_count) {
7952 for (i = 0; i < sc->stsc_count; i++) {
7953 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
7954 if (next > sc->current_sample) {
7956 sc->stsc_sample = sc->current_sample - time_sample;
7959 av_assert0(next == (int)next);
7967 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
7969 MOVContext *mc = s->priv_data;
7974 if (stream_index >= s->nb_streams)
7975 return AVERROR_INVALIDDATA;
7977 st = s->streams[stream_index];
7978 sample = mov_seek_stream(s, st, sample_time, flags);
7982 if (mc->seek_individually) {
7983 /* adjust seek timestamp to found sample timestamp */
7984 int64_t seek_timestamp = st->index_entries[sample].timestamp;
7986 for (i = 0; i < s->nb_streams; i++) {
7988 MOVStreamContext *sc = s->streams[i]->priv_data;
7990 st->skip_samples = (sample_time <= 0) ? sc->start_pad : 0;
7992 if (stream_index == i)
7995 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
7996 mov_seek_stream(s, st, timestamp, flags);
7999 for (i = 0; i < s->nb_streams; i++) {
8000 MOVStreamContext *sc;
8003 mov_current_sample_set(sc, 0);
8006 MOVStreamContext *sc;
8007 AVIndexEntry *entry = mov_find_next_sample(s, &st);
8009 return AVERROR_INVALIDDATA;
8011 if (sc->ffindex == stream_index && sc->current_sample == sample)
8013 mov_current_sample_inc(sc);
8019 #define OFFSET(x) offsetof(MOVContext, x)
8020 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
8021 static const AVOption mov_options[] = {
8022 {"use_absolute_path",
8023 "allow using absolute path when opening alias, this is a possible security issue",
8024 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
8026 {"seek_streams_individually",
8027 "Seek each stream individually to the closest point",
8028 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
8030 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
8032 {"advanced_editlist",
8033 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
8034 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
8036 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8039 "use mfra for fragment timestamps",
8040 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8041 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8043 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8044 FLAGS, "use_mfra_for" },
8045 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8046 FLAGS, "use_mfra_for" },
8047 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8048 FLAGS, "use_mfra_for" },
8049 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8050 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8051 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8052 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8053 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8054 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8055 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8056 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8057 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8058 .flags = AV_OPT_FLAG_DECODING_PARAM },
8059 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8060 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8061 {.i64 = 0}, 0, 1, FLAGS },
8066 static const AVClass mov_class = {
8067 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8068 .item_name = av_default_item_name,
8069 .option = mov_options,
8070 .version = LIBAVUTIL_VERSION_INT,
8073 AVInputFormat ff_mov_demuxer = {
8074 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8075 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8076 .priv_class = &mov_class,
8077 .priv_data_size = sizeof(MOVContext),
8078 .extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
8079 .read_probe = mov_probe,
8080 .read_header = mov_read_header,
8081 .read_packet = mov_read_packet,
8082 .read_close = mov_read_close,
8083 .read_seek = mov_read_seek,
8084 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,