3 * Copyright (c) 2001 Fabrice Bellard
4 * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
6 * first version by Francois Revol <revol@free.fr>
7 * seek function by Gael Chardon <gael.dev@4now.net>
9 * This file is part of FFmpeg.
11 * FFmpeg is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * FFmpeg is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with FFmpeg; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30 #include "libavutil/attributes.h"
31 #include "libavutil/channel_layout.h"
32 #include "libavutil/internal.h"
33 #include "libavutil/intreadwrite.h"
34 #include "libavutil/intfloat.h"
35 #include "libavutil/mathematics.h"
36 #include "libavutil/time_internal.h"
37 #include "libavutil/avassert.h"
38 #include "libavutil/avstring.h"
39 #include "libavutil/dict.h"
40 #include "libavutil/display.h"
41 #include "libavutil/opt.h"
42 #include "libavutil/aes.h"
43 #include "libavutil/aes_ctr.h"
44 #include "libavutil/pixdesc.h"
45 #include "libavutil/sha.h"
46 #include "libavutil/spherical.h"
47 #include "libavutil/stereo3d.h"
48 #include "libavutil/timecode.h"
49 #include "libavcodec/ac3tab.h"
50 #include "libavcodec/flac.h"
51 #include "libavcodec/mpegaudiodecheader.h"
52 #include "libavcodec/mlp_parse.h"
55 #include "avio_internal.h"
58 #include "libavcodec/get_bits.h"
61 #include "replaygain.h"
67 #include "qtpalette.h"
69 /* those functions parse an atom */
70 /* links atom IDs to parse functions */
71 typedef struct MOVParseTableEntry {
73 int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
76 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
77 static int mov_read_mfra(MOVContext *c, AVIOContext *f);
78 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
79 int count, int duration);
81 static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb,
82 unsigned len, const char *key)
86 short current, total = 0;
87 avio_rb16(pb); // unknown
88 current = avio_rb16(pb);
90 total = avio_rb16(pb);
92 snprintf(buf, sizeof(buf), "%d", current);
94 snprintf(buf, sizeof(buf), "%d/%d", current, total);
95 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
96 av_dict_set(&c->fc->metadata, key, buf, 0);
101 static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb,
102 unsigned len, const char *key)
104 /* bypass padding bytes */
109 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
110 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
115 static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb,
116 unsigned len, const char *key)
118 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
119 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
124 static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb,
125 unsigned len, const char *key)
129 avio_r8(pb); // unknown
132 if (genre < 1 || genre > ID3v1_GENRE_MAX)
134 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
135 av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
140 static const uint32_t mac_to_unicode[128] = {
141 0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
142 0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
143 0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
144 0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
145 0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
146 0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
147 0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
148 0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
149 0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
150 0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
151 0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
152 0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
153 0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
154 0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
155 0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
156 0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
159 static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len,
160 char *dst, int dstlen)
163 char *end = dst+dstlen-1;
166 for (i = 0; i < len; i++) {
167 uint8_t t, c = avio_r8(pb);
175 PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
181 static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
185 MOVStreamContext *sc;
190 case 0xd: id = AV_CODEC_ID_MJPEG; break;
191 case 0xe: id = AV_CODEC_ID_PNG; break;
192 case 0x1b: id = AV_CODEC_ID_BMP; break;
194 av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
199 st = avformat_new_stream(c->fc, NULL);
201 return AVERROR(ENOMEM);
202 sc = av_mallocz(sizeof(*sc));
204 return AVERROR(ENOMEM);
207 ret = av_get_packet(pb, &pkt, len);
211 if (pkt.size >= 8 && id != AV_CODEC_ID_BMP) {
212 if (AV_RB64(pkt.data) == 0x89504e470d0a1a0a) {
213 id = AV_CODEC_ID_PNG;
215 id = AV_CODEC_ID_MJPEG;
219 st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
221 st->attached_pic = pkt;
222 st->attached_pic.stream_index = st->index;
223 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
225 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
226 st->codecpar->codec_id = id;
232 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
234 char language[4] = { 0 };
235 char buf[200], place[100];
236 uint16_t langcode = 0;
237 double longitude, latitude, altitude;
238 const char *key = "location";
240 if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
241 av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
242 return AVERROR_INVALIDDATA;
245 avio_skip(pb, 4); // version+flags
246 langcode = avio_rb16(pb);
247 ff_mov_lang_to_iso639(langcode, language);
250 len -= avio_get_str(pb, len, place, sizeof(place));
252 av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
253 return AVERROR_INVALIDDATA;
255 avio_skip(pb, 1); // role
259 av_log(c->fc, AV_LOG_ERROR,
260 "loci too short (%u bytes left, need at least %d)\n", len, 12);
261 return AVERROR_INVALIDDATA;
263 longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
264 latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
265 altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
267 // Try to output in the same format as the ?xyz field
268 snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
270 av_strlcatf(buf, sizeof(buf), "%+f", altitude);
271 av_strlcatf(buf, sizeof(buf), "/%s", place);
273 if (*language && strcmp(language, "und")) {
275 snprintf(key2, sizeof(key2), "%s-%s", key, language);
276 av_dict_set(&c->fc->metadata, key2, buf, 0);
278 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
279 return av_dict_set(&c->fc->metadata, key, buf, 0);
282 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
288 if (c->ignore_chapters)
291 n_hmmt = avio_rb32(pb);
292 for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
293 int moment_time = avio_rb32(pb);
294 avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
299 static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
302 char key2[32], language[4] = {0};
304 const char *key = NULL;
305 uint16_t langcode = 0;
306 uint32_t data_type = 0, str_size, str_size_alloc;
307 int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
312 case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
313 case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
314 case MKTAG( 'X','M','P','_'):
315 if (c->export_xmp) { key = "xmp"; raw = 1; } break;
316 case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
317 case MKTAG( 'a','k','I','D'): key = "account_type";
318 parse = mov_metadata_int8_no_padding; break;
319 case MKTAG( 'a','p','I','D'): key = "account_id"; break;
320 case MKTAG( 'c','a','t','g'): key = "category"; break;
321 case MKTAG( 'c','p','i','l'): key = "compilation";
322 parse = mov_metadata_int8_no_padding; break;
323 case MKTAG( 'c','p','r','t'): key = "copyright"; break;
324 case MKTAG( 'd','e','s','c'): key = "description"; break;
325 case MKTAG( 'd','i','s','k'): key = "disc";
326 parse = mov_metadata_track_or_disc_number; break;
327 case MKTAG( 'e','g','i','d'): key = "episode_uid";
328 parse = mov_metadata_int8_no_padding; break;
329 case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
330 case MKTAG( 'g','n','r','e'): key = "genre";
331 parse = mov_metadata_gnre; break;
332 case MKTAG( 'h','d','v','d'): key = "hd_video";
333 parse = mov_metadata_int8_no_padding; break;
334 case MKTAG( 'H','M','M','T'):
335 return mov_metadata_hmmt(c, pb, atom.size);
336 case MKTAG( 'k','e','y','w'): key = "keywords"; break;
337 case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
338 case MKTAG( 'l','o','c','i'):
339 return mov_metadata_loci(c, pb, atom.size);
340 case MKTAG( 'm','a','n','u'): key = "make"; break;
341 case MKTAG( 'm','o','d','l'): key = "model"; break;
342 case MKTAG( 'p','c','s','t'): key = "podcast";
343 parse = mov_metadata_int8_no_padding; break;
344 case MKTAG( 'p','g','a','p'): key = "gapless_playback";
345 parse = mov_metadata_int8_no_padding; break;
346 case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
347 case MKTAG( 'r','t','n','g'): key = "rating";
348 parse = mov_metadata_int8_no_padding; break;
349 case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
350 case MKTAG( 's','o','a','l'): key = "sort_album"; break;
351 case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
352 case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
353 case MKTAG( 's','o','n','m'): key = "sort_name"; break;
354 case MKTAG( 's','o','s','n'): key = "sort_show"; break;
355 case MKTAG( 's','t','i','k'): key = "media_type";
356 parse = mov_metadata_int8_no_padding; break;
357 case MKTAG( 't','r','k','n'): key = "track";
358 parse = mov_metadata_track_or_disc_number; break;
359 case MKTAG( 't','v','e','n'): key = "episode_id"; break;
360 case MKTAG( 't','v','e','s'): key = "episode_sort";
361 parse = mov_metadata_int8_bypass_padding; break;
362 case MKTAG( 't','v','n','n'): key = "network"; break;
363 case MKTAG( 't','v','s','h'): key = "show"; break;
364 case MKTAG( 't','v','s','n'): key = "season_number";
365 parse = mov_metadata_int8_bypass_padding; break;
366 case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
367 case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
368 case MKTAG(0xa9,'a','l','b'): key = "album"; break;
369 case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
370 case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
371 case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
372 case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
373 case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
374 case MKTAG(0xa9,'d','a','y'): key = "date"; break;
375 case MKTAG(0xa9,'d','i','r'): key = "director"; break;
376 case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
377 case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
378 case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
379 case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
380 case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
381 case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
382 case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
383 case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
384 case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
385 case MKTAG(0xa9,'m','a','k'): key = "make"; break;
386 case MKTAG(0xa9,'m','o','d'): key = "model"; break;
387 case MKTAG(0xa9,'n','a','m'): key = "title"; break;
388 case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
389 case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
390 case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
391 case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
392 case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
393 case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
394 case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
395 case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
396 case MKTAG(0xa9,'t','r','k'): key = "track"; break;
397 case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
398 case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
399 case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
400 case MKTAG(0xa9,'x','y','z'): key = "location"; break;
403 if (c->itunes_metadata && atom.size > 8) {
404 int data_size = avio_rb32(pb);
405 int tag = avio_rl32(pb);
406 if (tag == MKTAG('d','a','t','a') && data_size <= atom.size) {
407 data_type = avio_rb32(pb); // type
408 avio_rb32(pb); // unknown
409 str_size = data_size - 16;
412 if (atom.type == MKTAG('c', 'o', 'v', 'r')) {
413 int ret = mov_read_covr(c, pb, data_type, str_size);
415 av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
418 atom.size -= str_size;
422 } else if (!key && c->found_hdlr_mdta && c->meta_keys) {
423 uint32_t index = AV_RB32(&atom.type);
424 if (index < c->meta_keys_count && index > 0) {
425 key = c->meta_keys[index];
427 av_log(c->fc, AV_LOG_WARNING,
428 "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
429 index, c->meta_keys_count);
433 } else if (atom.size > 4 && key && !c->itunes_metadata && !raw) {
434 str_size = avio_rb16(pb); // string length
435 if (str_size > atom.size) {
437 avio_seek(pb, -2, SEEK_CUR);
438 av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
441 langcode = avio_rb16(pb);
442 ff_mov_lang_to_iso639(langcode, language);
445 str_size = atom.size;
447 if (c->export_all && !key) {
448 snprintf(tmp_key, 5, "%.4s", (char*)&atom.type);
454 if (atom.size < 0 || str_size >= INT_MAX/2)
455 return AVERROR_INVALIDDATA;
457 // Allocates enough space if data_type is a int32 or float32 number, otherwise
458 // worst-case requirement for output string in case of utf8 coded input
459 num = (data_type >= 21 && data_type <= 23);
460 str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
461 str = av_mallocz(str_size_alloc);
463 return AVERROR(ENOMEM);
466 parse(c, pb, str_size, key);
468 if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
469 mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
470 } else if (data_type == 21) { // BE signed integer, variable size
473 val = (int8_t)avio_r8(pb);
474 else if (str_size == 2)
475 val = (int16_t)avio_rb16(pb);
476 else if (str_size == 3)
477 val = ((int32_t)(avio_rb24(pb)<<8))>>8;
478 else if (str_size == 4)
479 val = (int32_t)avio_rb32(pb);
480 if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
481 av_log(c->fc, AV_LOG_ERROR,
482 "Failed to store the number (%d) in string.\n", val);
484 return AVERROR_INVALIDDATA;
486 } else if (data_type == 22) { // BE unsigned integer, variable size
487 unsigned int val = 0;
490 else if (str_size == 2)
492 else if (str_size == 3)
494 else if (str_size == 4)
496 if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
497 av_log(c->fc, AV_LOG_ERROR,
498 "Failed to store the number (%u) in string.\n", val);
500 return AVERROR_INVALIDDATA;
502 } else if (data_type == 23 && str_size >= 4) { // BE float32
503 float val = av_int2float(avio_rb32(pb));
504 if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
505 av_log(c->fc, AV_LOG_ERROR,
506 "Failed to store the float32 number (%f) in string.\n", val);
508 return AVERROR_INVALIDDATA;
511 int ret = ffio_read_size(pb, str, str_size);
518 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
519 av_dict_set(&c->fc->metadata, key, str, 0);
520 if (*language && strcmp(language, "und")) {
521 snprintf(key2, sizeof(key2), "%s-%s", key, language);
522 av_dict_set(&c->fc->metadata, key2, str, 0);
524 if (!strcmp(key, "encoder")) {
525 int major, minor, micro;
526 if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, µ) == 3) {
527 c->handbrake_version = 1000000*major + 1000*minor + micro;
536 static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
539 int i, nb_chapters, str_len, version;
543 if (c->ignore_chapters)
546 if ((atom.size -= 5) < 0)
549 version = avio_r8(pb);
552 avio_rb32(pb); // ???
553 nb_chapters = avio_r8(pb);
555 for (i = 0; i < nb_chapters; i++) {
559 start = avio_rb64(pb);
560 str_len = avio_r8(pb);
562 if ((atom.size -= 9+str_len) < 0)
565 ret = ffio_read_size(pb, str, str_len);
569 avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
574 #define MIN_DATA_ENTRY_BOX_SIZE 12
575 static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
578 MOVStreamContext *sc;
581 if (c->fc->nb_streams < 1)
583 st = c->fc->streams[c->fc->nb_streams-1];
586 avio_rb32(pb); // version + flags
587 entries = avio_rb32(pb);
589 entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
590 entries >= UINT_MAX / sizeof(*sc->drefs))
591 return AVERROR_INVALIDDATA;
595 sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
597 return AVERROR(ENOMEM);
598 sc->drefs_count = entries;
600 for (i = 0; i < entries; i++) {
601 MOVDref *dref = &sc->drefs[i];
602 uint32_t size = avio_rb32(pb);
603 int64_t next = avio_tell(pb) + size - 4;
606 return AVERROR_INVALIDDATA;
608 dref->type = avio_rl32(pb);
609 avio_rb32(pb); // version + flags
611 if (dref->type == MKTAG('a','l','i','s') && size > 150) {
612 /* macintosh alias record */
613 uint16_t volume_len, len;
619 volume_len = avio_r8(pb);
620 volume_len = FFMIN(volume_len, 27);
621 ret = ffio_read_size(pb, dref->volume, 27);
624 dref->volume[volume_len] = 0;
625 av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
630 len = FFMIN(len, 63);
631 ret = ffio_read_size(pb, dref->filename, 63);
634 dref->filename[len] = 0;
635 av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
639 /* read next level up_from_alias/down_to_target */
640 dref->nlvl_from = avio_rb16(pb);
641 dref->nlvl_to = avio_rb16(pb);
642 av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
643 dref->nlvl_from, dref->nlvl_to);
647 for (type = 0; type != -1 && avio_tell(pb) < next; ) {
650 type = avio_rb16(pb);
652 av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
655 if (type == 2) { // absolute path
657 dref->path = av_mallocz(len+1);
659 return AVERROR(ENOMEM);
661 ret = ffio_read_size(pb, dref->path, len);
663 av_freep(&dref->path);
666 if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
668 memmove(dref->path, dref->path+volume_len, len);
671 // trim string of any ending zeros
672 for (j = len - 1; j >= 0; j--) {
673 if (dref->path[j] == 0)
678 for (j = 0; j < len; j++)
679 if (dref->path[j] == ':' || dref->path[j] == 0)
681 av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
682 } else if (type == 0) { // directory name
684 dref->dir = av_malloc(len+1);
686 return AVERROR(ENOMEM);
688 ret = ffio_read_size(pb, dref->dir, len);
690 av_freep(&dref->dir);
694 for (j = 0; j < len; j++)
695 if (dref->dir[j] == ':')
697 av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
702 av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
707 avio_seek(pb, next, SEEK_SET);
712 static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
721 avio_r8(pb); /* version */
722 avio_rb24(pb); /* flags */
725 ctype = avio_rl32(pb);
726 type = avio_rl32(pb); /* component subtype */
728 av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
729 av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
731 if (c->trak_index < 0) { // meta not inside a trak
732 if (type == MKTAG('m','d','t','a')) {
733 c->found_hdlr_mdta = 1;
738 st = c->fc->streams[c->fc->nb_streams-1];
740 if (type == MKTAG('v','i','d','e'))
741 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
742 else if (type == MKTAG('s','o','u','n'))
743 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
744 else if (type == MKTAG('m','1','a',' '))
745 st->codecpar->codec_id = AV_CODEC_ID_MP2;
746 else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
747 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
749 avio_rb32(pb); /* component manufacture */
750 avio_rb32(pb); /* component flags */
751 avio_rb32(pb); /* component flags mask */
753 title_size = atom.size - 24;
754 if (title_size > 0) {
755 if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
756 return AVERROR_INVALIDDATA;
757 title_str = av_malloc(title_size + 1); /* Add null terminator */
759 return AVERROR(ENOMEM);
761 ret = ffio_read_size(pb, title_str, title_size);
763 av_freep(&title_str);
766 title_str[title_size] = 0;
768 int off = (!c->isom && title_str[0] == title_size - 1);
769 // flag added so as to not set stream handler name if already set from mdia->hdlr
770 av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
772 av_freep(&title_str);
778 static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
780 return ff_mov_read_esds(c->fc, pb);
783 static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
786 enum AVAudioServiceType *ast;
787 int ac3info, acmod, lfeon, bsmod;
789 if (c->fc->nb_streams < 1)
791 st = c->fc->streams[c->fc->nb_streams-1];
793 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
796 return AVERROR(ENOMEM);
798 ac3info = avio_rb24(pb);
799 bsmod = (ac3info >> 14) & 0x7;
800 acmod = (ac3info >> 11) & 0x7;
801 lfeon = (ac3info >> 10) & 0x1;
802 st->codecpar->channels = ((int[]){2,1,2,3,3,4,4,5})[acmod] + lfeon;
803 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
805 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
807 if (st->codecpar->channels > 1 && bsmod == 0x7)
808 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
810 #if FF_API_LAVF_AVCTX
811 FF_DISABLE_DEPRECATION_WARNINGS
812 st->codec->audio_service_type = *ast;
813 FF_ENABLE_DEPRECATION_WARNINGS
819 static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
822 enum AVAudioServiceType *ast;
823 int eac3info, acmod, lfeon, bsmod;
825 if (c->fc->nb_streams < 1)
827 st = c->fc->streams[c->fc->nb_streams-1];
829 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
832 return AVERROR(ENOMEM);
834 /* No need to parse fields for additional independent substreams and its
835 * associated dependent substreams since libavcodec's E-AC-3 decoder
836 * does not support them yet. */
837 avio_rb16(pb); /* data_rate and num_ind_sub */
838 eac3info = avio_rb24(pb);
839 bsmod = (eac3info >> 12) & 0x1f;
840 acmod = (eac3info >> 9) & 0x7;
841 lfeon = (eac3info >> 8) & 0x1;
842 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
844 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
845 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
847 if (st->codecpar->channels > 1 && bsmod == 0x7)
848 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
850 #if FF_API_LAVF_AVCTX
851 FF_DISABLE_DEPRECATION_WARNINGS
852 st->codec->audio_service_type = *ast;
853 FF_ENABLE_DEPRECATION_WARNINGS
859 static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
861 const uint32_t ddts_size = 20;
864 uint32_t frame_duration_code = 0;
865 uint32_t channel_layout_code = 0;
868 buf = av_malloc(ddts_size + AV_INPUT_BUFFER_PADDING_SIZE);
870 return AVERROR(ENOMEM);
872 if (avio_read(pb, buf, ddts_size) < ddts_size) {
874 return AVERROR_INVALIDDATA;
877 init_get_bits(&gb, buf, 8*ddts_size);
879 if (c->fc->nb_streams < 1) {
883 st = c->fc->streams[c->fc->nb_streams-1];
885 st->codecpar->sample_rate = get_bits_long(&gb, 32);
886 if (st->codecpar->sample_rate <= 0) {
887 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
889 return AVERROR_INVALIDDATA;
891 skip_bits_long(&gb, 32); /* max bitrate */
892 st->codecpar->bit_rate = get_bits_long(&gb, 32);
893 st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
894 frame_duration_code = get_bits(&gb, 2);
895 skip_bits(&gb, 30); /* various fields */
896 channel_layout_code = get_bits(&gb, 16);
898 st->codecpar->frame_size =
899 (frame_duration_code == 0) ? 512 :
900 (frame_duration_code == 1) ? 1024 :
901 (frame_duration_code == 2) ? 2048 :
902 (frame_duration_code == 3) ? 4096 : 0;
904 if (channel_layout_code > 0xff) {
905 av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout");
907 st->codecpar->channel_layout =
908 ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
909 ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
910 ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
911 ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
912 ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
913 ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0);
915 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
921 static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
925 if (c->fc->nb_streams < 1)
927 st = c->fc->streams[c->fc->nb_streams-1];
932 /* skip version and flags */
935 ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
940 static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
945 if (c->fc->nb_streams < 1)
947 st = c->fc->streams[c->fc->nb_streams-1];
949 if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
950 av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
955 static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
957 const int num = avio_rb32(pb);
958 const int den = avio_rb32(pb);
961 if (c->fc->nb_streams < 1)
963 st = c->fc->streams[c->fc->nb_streams-1];
965 if ((st->sample_aspect_ratio.den != 1 || st->sample_aspect_ratio.num) && // default
966 (den != st->sample_aspect_ratio.den || num != st->sample_aspect_ratio.num)) {
967 av_log(c->fc, AV_LOG_WARNING,
968 "sample aspect ratio already set to %d:%d, ignoring 'pasp' atom (%d:%d)\n",
969 st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
971 } else if (den != 0) {
972 av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den,
978 /* this atom contains actual media data */
979 static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
981 if (atom.size == 0) /* wrong one (MP4) */
984 return 0; /* now go for moov */
987 #define DRM_BLOB_SIZE 56
989 static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
991 uint8_t intermediate_key[20];
992 uint8_t intermediate_iv[20];
995 uint8_t file_checksum[20];
996 uint8_t calculated_checksum[20];
1000 uint8_t *activation_bytes = c->activation_bytes;
1001 uint8_t *fixed_key = c->audible_fixed_key;
1005 sha = av_sha_alloc();
1007 return AVERROR(ENOMEM);
1008 c->aes_decrypt = av_aes_alloc();
1009 if (!c->aes_decrypt) {
1010 ret = AVERROR(ENOMEM);
1014 /* drm blob processing */
1015 avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1016 avio_read(pb, input, DRM_BLOB_SIZE);
1017 avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1018 avio_read(pb, file_checksum, 20);
1020 av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == "); // required by external tools
1021 for (i = 0; i < 20; i++)
1022 av_log(c->fc, AV_LOG_INFO, "%02x", file_checksum[i]);
1023 av_log(c->fc, AV_LOG_INFO, "\n");
1025 /* verify activation data */
1026 if (!activation_bytes) {
1027 av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1028 ret = 0; /* allow ffprobe to continue working on .aax files */
1031 if (c->activation_bytes_size != 4) {
1032 av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1033 ret = AVERROR(EINVAL);
1037 /* verify fixed key */
1038 if (c->audible_fixed_key_size != 16) {
1039 av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1040 ret = AVERROR(EINVAL);
1044 /* AAX (and AAX+) key derivation */
1045 av_sha_init(sha, 160);
1046 av_sha_update(sha, fixed_key, 16);
1047 av_sha_update(sha, activation_bytes, 4);
1048 av_sha_final(sha, intermediate_key);
1049 av_sha_init(sha, 160);
1050 av_sha_update(sha, fixed_key, 16);
1051 av_sha_update(sha, intermediate_key, 20);
1052 av_sha_update(sha, activation_bytes, 4);
1053 av_sha_final(sha, intermediate_iv);
1054 av_sha_init(sha, 160);
1055 av_sha_update(sha, intermediate_key, 16);
1056 av_sha_update(sha, intermediate_iv, 16);
1057 av_sha_final(sha, calculated_checksum);
1058 if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1059 av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1060 ret = AVERROR_INVALIDDATA;
1063 av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1064 av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1065 for (i = 0; i < 4; i++) {
1066 // file data (in output) is stored in big-endian mode
1067 if (activation_bytes[i] != output[3 - i]) { // critical error
1068 av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1069 ret = AVERROR_INVALIDDATA;
1073 memcpy(c->file_key, output + 8, 16);
1074 memcpy(input, output + 26, 16);
1075 av_sha_init(sha, 160);
1076 av_sha_update(sha, input, 16);
1077 av_sha_update(sha, c->file_key, 16);
1078 av_sha_update(sha, fixed_key, 16);
1079 av_sha_final(sha, c->file_iv);
1087 // Audible AAX (and AAX+) bytestream decryption
1088 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1091 unsigned char iv[16];
1093 memcpy(iv, c->file_iv, 16); // iv is overwritten
1094 blocks = size >> 4; // trailing bytes are not encrypted!
1095 av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1096 av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1101 /* read major brand, minor version and compatible brands and store them as metadata */
1102 static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1105 int comp_brand_size;
1106 char* comp_brands_str;
1107 uint8_t type[5] = {0};
1108 int ret = ffio_read_size(pb, type, 4);
1112 if (strcmp(type, "qt "))
1114 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1115 av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1116 minor_ver = avio_rb32(pb); /* minor version */
1117 av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1119 comp_brand_size = atom.size - 8;
1120 if (comp_brand_size < 0)
1121 return AVERROR_INVALIDDATA;
1122 comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1123 if (!comp_brands_str)
1124 return AVERROR(ENOMEM);
1126 ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1128 av_freep(&comp_brands_str);
1131 comp_brands_str[comp_brand_size] = 0;
1132 av_dict_set(&c->fc->metadata, "compatible_brands", comp_brands_str, 0);
1133 av_freep(&comp_brands_str);
1138 /* this atom should contain all header atoms */
1139 static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1143 if (c->found_moov) {
1144 av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1145 avio_skip(pb, atom.size);
1149 if ((ret = mov_read_default(c, pb, atom)) < 0)
1151 /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1152 /* so we don't parse the whole file if over a network */
1154 return 0; /* now go for mdat */
1157 static MOVFragmentStreamInfo * get_frag_stream_info(
1158 MOVFragmentIndex *frag_index,
1163 MOVFragmentIndexItem * item;
1165 if (index < 0 || index >= frag_index->nb_items)
1167 item = &frag_index->item[index];
1168 for (i = 0; i < item->nb_stream_info; i++)
1169 if (item->stream_info[i].id == id)
1170 return &item->stream_info[i];
1172 // This shouldn't happen
1176 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1179 MOVFragmentIndexItem * item;
1181 if (frag_index->current < 0 ||
1182 frag_index->current >= frag_index->nb_items)
1185 item = &frag_index->item[frag_index->current];
1186 for (i = 0; i < item->nb_stream_info; i++)
1187 if (item->stream_info[i].id == id) {
1192 // id not found. This shouldn't happen.
1196 static MOVFragmentStreamInfo * get_current_frag_stream_info(
1197 MOVFragmentIndex *frag_index)
1199 MOVFragmentIndexItem *item;
1200 if (frag_index->current < 0 ||
1201 frag_index->current >= frag_index->nb_items)
1204 item = &frag_index->item[frag_index->current];
1205 if (item->current >= 0 && item->current < item->nb_stream_info)
1206 return &item->stream_info[item->current];
1208 // This shouldn't happen
1212 static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
1215 int64_t moof_offset;
1217 // Optimize for appending new entries
1218 if (!frag_index->nb_items ||
1219 frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1220 return frag_index->nb_items;
1223 b = frag_index->nb_items;
1227 moof_offset = frag_index->item[m].moof_offset;
1228 if (moof_offset >= offset)
1230 if (moof_offset <= offset)
1236 static int64_t get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
1238 av_assert0(frag_stream_info);
1239 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1240 return frag_stream_info->sidx_pts;
1241 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1242 return frag_stream_info->first_tfra_pts;
1243 return frag_stream_info->tfdt_dts;
1246 static int64_t get_frag_time(MOVFragmentIndex *frag_index,
1247 int index, int track_id)
1249 MOVFragmentStreamInfo * frag_stream_info;
1253 if (track_id >= 0) {
1254 frag_stream_info = get_frag_stream_info(frag_index, index, track_id);
1255 return frag_stream_info->sidx_pts;
1258 for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1259 frag_stream_info = &frag_index->item[index].stream_info[i];
1260 timestamp = get_stream_info_time(frag_stream_info);
1261 if (timestamp != AV_NOPTS_VALUE)
1264 return AV_NOPTS_VALUE;
1267 static int search_frag_timestamp(MOVFragmentIndex *frag_index,
1268 AVStream *st, int64_t timestamp)
1275 // If the stream is referenced by any sidx, limit the search
1276 // to fragments that referenced this stream in the sidx
1277 MOVStreamContext *sc = st->priv_data;
1283 b = frag_index->nb_items;
1286 m0 = m = (a + b) >> 1;
1289 (frag_time = get_frag_time(frag_index, m, id)) == AV_NOPTS_VALUE)
1292 if (m < b && frag_time <= timestamp)
1301 static int update_frag_index(MOVContext *c, int64_t offset)
1304 MOVFragmentIndexItem * item;
1305 MOVFragmentStreamInfo * frag_stream_info;
1307 // If moof_offset already exists in frag_index, return index to it
1308 index = search_frag_moof_offset(&c->frag_index, offset);
1309 if (index < c->frag_index.nb_items &&
1310 c->frag_index.item[index].moof_offset == offset)
1313 // offset is not yet in frag index.
1314 // Insert new item at index (sorted by moof offset)
1315 item = av_fast_realloc(c->frag_index.item,
1316 &c->frag_index.allocated_size,
1317 (c->frag_index.nb_items + 1) *
1318 sizeof(*c->frag_index.item));
1321 c->frag_index.item = item;
1323 frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1324 sizeof(*item->stream_info));
1325 if (!frag_stream_info)
1328 for (i = 0; i < c->fc->nb_streams; i++) {
1329 // Avoid building frag index if streams lack track id.
1330 if (c->fc->streams[i]->id < 0)
1331 return AVERROR_INVALIDDATA;
1333 frag_stream_info[i].id = c->fc->streams[i]->id;
1334 frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1335 frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1336 frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1337 frag_stream_info[i].index_entry = -1;
1338 frag_stream_info[i].encryption_index = NULL;
1341 if (index < c->frag_index.nb_items)
1342 memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1343 (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1345 item = &c->frag_index.item[index];
1346 item->headers_read = 0;
1348 item->nb_stream_info = c->fc->nb_streams;
1349 item->moof_offset = offset;
1350 item->stream_info = frag_stream_info;
1351 c->frag_index.nb_items++;
1356 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1357 int id, int entries)
1360 MOVFragmentStreamInfo * frag_stream_info;
1364 for (i = index; i < frag_index->nb_items; i++) {
1365 frag_stream_info = get_frag_stream_info(frag_index, i, id);
1366 if (frag_stream_info && frag_stream_info->index_entry >= 0)
1367 frag_stream_info->index_entry += entries;
1371 static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1373 // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1374 c->fragment.found_tfhd = 0;
1376 if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1377 c->has_looked_for_mfra = 1;
1378 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1380 av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1382 if ((ret = mov_read_mfra(c, pb)) < 0) {
1383 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1384 "read the mfra (may be a live ismv)\n");
1387 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1388 "seekable, can not look for mfra\n");
1391 c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1392 av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1393 c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1394 return mov_read_default(c, pb, atom);
1397 static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time, void *logctx)
1400 if(time >= 2082844800)
1401 time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1403 if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1404 av_log(logctx, AV_LOG_DEBUG, "creation_time is not representable\n");
1408 avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1412 static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1415 MOVStreamContext *sc;
1417 char language[4] = {0};
1419 int64_t creation_time;
1421 if (c->fc->nb_streams < 1)
1423 st = c->fc->streams[c->fc->nb_streams-1];
1426 if (sc->time_scale) {
1427 av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1428 return AVERROR_INVALIDDATA;
1431 version = avio_r8(pb);
1433 avpriv_request_sample(c->fc, "Version %d", version);
1434 return AVERROR_PATCHWELCOME;
1436 avio_rb24(pb); /* flags */
1438 creation_time = avio_rb64(pb);
1441 creation_time = avio_rb32(pb);
1442 avio_rb32(pb); /* modification time */
1444 mov_metadata_creation_time(&st->metadata, creation_time, c->fc);
1446 sc->time_scale = avio_rb32(pb);
1447 if (sc->time_scale <= 0) {
1448 av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1451 st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1453 lang = avio_rb16(pb); /* language */
1454 if (ff_mov_lang_to_iso639(lang, language))
1455 av_dict_set(&st->metadata, "language", language, 0);
1456 avio_rb16(pb); /* quality */
1461 static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1464 int64_t creation_time;
1465 int version = avio_r8(pb); /* version */
1466 avio_rb24(pb); /* flags */
1469 creation_time = avio_rb64(pb);
1472 creation_time = avio_rb32(pb);
1473 avio_rb32(pb); /* modification time */
1475 mov_metadata_creation_time(&c->fc->metadata, creation_time, c->fc);
1476 c->time_scale = avio_rb32(pb); /* time scale */
1477 if (c->time_scale <= 0) {
1478 av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1481 av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1483 c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1484 // set the AVCodecContext duration because the duration of individual tracks
1485 // may be inaccurate
1486 if (c->time_scale > 0 && !c->trex_data)
1487 c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale);
1488 avio_rb32(pb); /* preferred scale */
1490 avio_rb16(pb); /* preferred volume */
1492 avio_skip(pb, 10); /* reserved */
1494 /* movie display matrix, store it in main context and use it later on */
1495 for (i = 0; i < 3; i++) {
1496 c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1497 c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1498 c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1501 avio_rb32(pb); /* preview time */
1502 avio_rb32(pb); /* preview duration */
1503 avio_rb32(pb); /* poster time */
1504 avio_rb32(pb); /* selection time */
1505 avio_rb32(pb); /* selection duration */
1506 avio_rb32(pb); /* current time */
1507 avio_rb32(pb); /* next track ID */
1512 static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1517 if (c->fc->nb_streams < 1)
1519 st = c->fc->streams[c->fc->nb_streams-1];
1521 little_endian = avio_rb16(pb) & 0xFF;
1522 av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1523 if (little_endian == 1) {
1524 switch (st->codecpar->codec_id) {
1525 case AV_CODEC_ID_PCM_S24BE:
1526 st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE;
1528 case AV_CODEC_ID_PCM_S32BE:
1529 st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE;
1531 case AV_CODEC_ID_PCM_F32BE:
1532 st->codecpar->codec_id = AV_CODEC_ID_PCM_F32LE;
1534 case AV_CODEC_ID_PCM_F64BE:
1535 st->codecpar->codec_id = AV_CODEC_ID_PCM_F64LE;
1544 static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1547 char color_parameter_type[5] = { 0 };
1548 uint16_t color_primaries, color_trc, color_matrix;
1551 if (c->fc->nb_streams < 1)
1553 st = c->fc->streams[c->fc->nb_streams - 1];
1555 ret = ffio_read_size(pb, color_parameter_type, 4);
1558 if (strncmp(color_parameter_type, "nclx", 4) &&
1559 strncmp(color_parameter_type, "nclc", 4)) {
1560 av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
1561 color_parameter_type);
1565 color_primaries = avio_rb16(pb);
1566 color_trc = avio_rb16(pb);
1567 color_matrix = avio_rb16(pb);
1569 av_log(c->fc, AV_LOG_TRACE,
1570 "%s: pri %d trc %d matrix %d",
1571 color_parameter_type, color_primaries, color_trc, color_matrix);
1573 if (!strncmp(color_parameter_type, "nclx", 4)) {
1574 uint8_t color_range = avio_r8(pb) >> 7;
1575 av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
1577 st->codecpar->color_range = AVCOL_RANGE_JPEG;
1579 st->codecpar->color_range = AVCOL_RANGE_MPEG;
1582 if (!av_color_primaries_name(color_primaries))
1583 color_primaries = AVCOL_PRI_UNSPECIFIED;
1584 if (!av_color_transfer_name(color_trc))
1585 color_trc = AVCOL_TRC_UNSPECIFIED;
1586 if (!av_color_space_name(color_matrix))
1587 color_matrix = AVCOL_SPC_UNSPECIFIED;
1589 st->codecpar->color_primaries = color_primaries;
1590 st->codecpar->color_trc = color_trc;
1591 st->codecpar->color_space = color_matrix;
1592 av_log(c->fc, AV_LOG_TRACE, "\n");
1597 static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1600 unsigned mov_field_order;
1601 enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
1603 if (c->fc->nb_streams < 1) // will happen with jp2 files
1605 st = c->fc->streams[c->fc->nb_streams-1];
1607 return AVERROR_INVALIDDATA;
1608 mov_field_order = avio_rb16(pb);
1609 if ((mov_field_order & 0xFF00) == 0x0100)
1610 decoded_field_order = AV_FIELD_PROGRESSIVE;
1611 else if ((mov_field_order & 0xFF00) == 0x0200) {
1612 switch (mov_field_order & 0xFF) {
1613 case 0x01: decoded_field_order = AV_FIELD_TT;
1615 case 0x06: decoded_field_order = AV_FIELD_BB;
1617 case 0x09: decoded_field_order = AV_FIELD_TB;
1619 case 0x0E: decoded_field_order = AV_FIELD_BT;
1623 if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
1624 av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
1626 st->codecpar->field_order = decoded_field_order;
1631 static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
1634 uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
1635 if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
1636 return AVERROR_INVALIDDATA;
1637 if ((err = av_reallocp(&par->extradata, size)) < 0) {
1638 par->extradata_size = 0;
1641 par->extradata_size = size - AV_INPUT_BUFFER_PADDING_SIZE;
1645 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
1646 static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1647 AVCodecParameters *par, uint8_t *buf)
1649 int64_t result = atom.size;
1652 AV_WB32(buf , atom.size + 8);
1653 AV_WL32(buf + 4, atom.type);
1654 err = ffio_read_size(pb, buf + 8, atom.size);
1656 par->extradata_size -= atom.size;
1658 } else if (err < atom.size) {
1659 av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
1660 par->extradata_size -= atom.size - err;
1663 memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1667 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
1668 static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1669 enum AVCodecID codec_id)
1672 uint64_t original_size;
1675 if (c->fc->nb_streams < 1) // will happen with jp2 files
1677 st = c->fc->streams[c->fc->nb_streams-1];
1679 if (st->codecpar->codec_id != codec_id)
1680 return 0; /* unexpected codec_id - don't mess with extradata */
1682 original_size = st->codecpar->extradata_size;
1683 err = mov_realloc_extradata(st->codecpar, atom);
1687 err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
1690 return 0; // Note: this is the original behavior to ignore truncation.
1693 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
1694 static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1696 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
1699 static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1701 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS);
1704 static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1706 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
1709 static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1711 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
1714 static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1716 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
1718 ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
1722 static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1724 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
1726 if (!ret && c->fc->nb_streams >= 1) {
1727 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1728 if (par->extradata_size >= 40) {
1729 par->height = AV_RB16(&par->extradata[36]);
1730 par->width = AV_RB16(&par->extradata[38]);
1736 static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1738 if (c->fc->nb_streams >= 1) {
1739 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1740 if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
1741 par->codec_id == AV_CODEC_ID_H264 &&
1745 cid = avio_rb16(pb);
1746 /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
1747 if (cid == 0xd4d || cid == 0xd4e)
1750 } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
1751 par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
1752 par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
1756 num = avio_rb32(pb);
1757 den = avio_rb32(pb);
1758 if (num <= 0 || den <= 0)
1760 switch (avio_rb32(pb)) {
1762 if (den >= INT_MAX / 2)
1766 c->fc->streams[c->fc->nb_streams-1]->display_aspect_ratio.num = num;
1767 c->fc->streams[c->fc->nb_streams-1]->display_aspect_ratio.den = den;
1774 return mov_read_avid(c, pb, atom);
1777 static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1781 uint64_t original_size;
1782 if (c->fc->nb_streams >= 1) {
1783 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1784 if (par->codec_id == AV_CODEC_ID_H264)
1786 if (atom.size == 16) {
1787 original_size = par->extradata_size;
1788 ret = mov_realloc_extradata(par, atom);
1790 length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
1791 if (length == atom.size) {
1792 const uint8_t range_value = par->extradata[original_size + 19];
1793 switch (range_value) {
1795 par->color_range = AVCOL_RANGE_MPEG;
1798 par->color_range = AVCOL_RANGE_JPEG;
1801 av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
1804 ff_dlog(c->fc, "color_range: %d\n", par->color_range);
1806 /* For some reason the whole atom was not added to the extradata */
1807 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
1810 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
1813 av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
1820 static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1822 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
1825 static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1830 if (c->fc->nb_streams < 1)
1832 st = c->fc->streams[c->fc->nb_streams-1];
1834 if ((uint64_t)atom.size > (1<<30))
1835 return AVERROR_INVALIDDATA;
1837 if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
1838 st->codecpar->codec_id == AV_CODEC_ID_QDMC ||
1839 st->codecpar->codec_id == AV_CODEC_ID_SPEEX) {
1840 // pass all frma atom to codec, needed at least for QDMC and QDM2
1841 av_freep(&st->codecpar->extradata);
1842 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1845 } else if (atom.size > 8) { /* to read frma, esds atoms */
1846 if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
1848 ret = ffio_ensure_seekback(pb, 8);
1851 buffer = avio_rb64(pb);
1853 if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
1854 && buffer >> 32 <= atom.size
1855 && buffer >> 32 >= 8) {
1858 } else if (!st->codecpar->extradata_size) {
1859 #define ALAC_EXTRADATA_SIZE 36
1860 st->codecpar->extradata = av_mallocz(ALAC_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
1861 if (!st->codecpar->extradata)
1862 return AVERROR(ENOMEM);
1863 st->codecpar->extradata_size = ALAC_EXTRADATA_SIZE;
1864 AV_WB32(st->codecpar->extradata , ALAC_EXTRADATA_SIZE);
1865 AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
1866 AV_WB64(st->codecpar->extradata + 12, buffer);
1867 avio_read(pb, st->codecpar->extradata + 20, 16);
1868 avio_skip(pb, atom.size - 24);
1872 if ((ret = mov_read_default(c, pb, atom)) < 0)
1875 avio_skip(pb, atom.size);
1880 * This function reads atom content and puts data in extradata without tag
1881 * nor size unlike mov_read_extradata.
1883 static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1888 if (c->fc->nb_streams < 1)
1890 st = c->fc->streams[c->fc->nb_streams-1];
1892 if ((uint64_t)atom.size > (1<<30))
1893 return AVERROR_INVALIDDATA;
1895 if (atom.size >= 10) {
1896 // Broken files created by legacy versions of libavformat will
1897 // wrap a whole fiel atom inside of a glbl atom.
1898 unsigned size = avio_rb32(pb);
1899 unsigned type = avio_rl32(pb);
1900 avio_seek(pb, -8, SEEK_CUR);
1901 if (type == MKTAG('f','i','e','l') && size == atom.size)
1902 return mov_read_default(c, pb, atom);
1904 if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
1905 av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
1908 av_freep(&st->codecpar->extradata);
1909 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1912 if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
1913 /* HEVC-based Dolby Vision derived from hvc1.
1914 Happens to match with an identifier
1915 previously utilized for DV. Thus, if we have
1916 the hvcC extradata box available as specified,
1917 set codec to HEVC */
1918 st->codecpar->codec_id = AV_CODEC_ID_HEVC;
1923 static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1926 uint8_t profile_level;
1929 if (c->fc->nb_streams < 1)
1931 st = c->fc->streams[c->fc->nb_streams-1];
1933 if (atom.size >= (1<<28) || atom.size < 7)
1934 return AVERROR_INVALIDDATA;
1936 profile_level = avio_r8(pb);
1937 if ((profile_level & 0xf0) != 0xc0)
1940 avio_seek(pb, 6, SEEK_CUR);
1941 av_freep(&st->codecpar->extradata);
1942 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
1950 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
1951 * but can have extradata appended at the end after the 40 bytes belonging
1954 static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1959 if (c->fc->nb_streams < 1)
1961 if (atom.size <= 40)
1963 st = c->fc->streams[c->fc->nb_streams-1];
1965 if ((uint64_t)atom.size > (1<<30))
1966 return AVERROR_INVALIDDATA;
1969 av_freep(&st->codecpar->extradata);
1970 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
1977 static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1980 MOVStreamContext *sc;
1981 unsigned int i, entries;
1983 if (c->fc->nb_streams < 1)
1985 st = c->fc->streams[c->fc->nb_streams-1];
1988 avio_r8(pb); /* version */
1989 avio_rb24(pb); /* flags */
1991 entries = avio_rb32(pb);
1996 if (sc->chunk_offsets)
1997 av_log(c->fc, AV_LOG_WARNING, "Duplicated STCO atom\n");
1998 av_free(sc->chunk_offsets);
1999 sc->chunk_count = 0;
2000 sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2001 if (!sc->chunk_offsets)
2002 return AVERROR(ENOMEM);
2003 sc->chunk_count = entries;
2005 if (atom.type == MKTAG('s','t','c','o'))
2006 for (i = 0; i < entries && !pb->eof_reached; i++)
2007 sc->chunk_offsets[i] = avio_rb32(pb);
2008 else if (atom.type == MKTAG('c','o','6','4'))
2009 for (i = 0; i < entries && !pb->eof_reached; i++)
2010 sc->chunk_offsets[i] = avio_rb64(pb);
2012 return AVERROR_INVALIDDATA;
2014 sc->chunk_count = i;
2016 if (pb->eof_reached) {
2017 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2024 static int mov_codec_id(AVStream *st, uint32_t format)
2026 int id = ff_codec_get_id(ff_codec_movaudio_tags, format);
2029 ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2030 (format & 0xFFFF) == 'T' + ('S' << 8)))
2031 id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format) & 0xFFFF);
2033 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2034 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2035 } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2036 /* skip old ASF MPEG-4 tag */
2037 format && format != MKTAG('m','p','4','s')) {
2038 id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2040 id = ff_codec_get_id(ff_codec_bmp_tags, format);
2042 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
2043 else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2044 (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE &&
2045 st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2046 id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
2048 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
2050 id = ff_codec_get_id(ff_codec_movdata_tags, format);
2054 st->codecpar->codec_tag = format;
2059 static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
2060 AVStream *st, MOVStreamContext *sc)
2062 uint8_t codec_name[32] = { 0 };
2066 /* The first 16 bytes of the video sample description are already
2067 * read in ff_mov_read_stsd_entries() */
2068 stsd_start = avio_tell(pb) - 16;
2070 avio_rb16(pb); /* version */
2071 avio_rb16(pb); /* revision level */
2072 avio_rb32(pb); /* vendor */
2073 avio_rb32(pb); /* temporal quality */
2074 avio_rb32(pb); /* spatial quality */
2076 st->codecpar->width = avio_rb16(pb); /* width */
2077 st->codecpar->height = avio_rb16(pb); /* height */
2079 avio_rb32(pb); /* horiz resolution */
2080 avio_rb32(pb); /* vert resolution */
2081 avio_rb32(pb); /* data size, always 0 */
2082 avio_rb16(pb); /* frames per samples */
2084 len = avio_r8(pb); /* codec name, pascal string */
2087 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2089 avio_skip(pb, 31 - len);
2092 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2094 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2095 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2096 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2097 st->codecpar->width &= ~1;
2098 st->codecpar->height &= ~1;
2100 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2101 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2102 !strncmp(codec_name, "Sorenson H263", 13))
2103 st->codecpar->codec_id = AV_CODEC_ID_FLV1;
2105 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2107 avio_seek(pb, stsd_start, SEEK_SET);
2109 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2110 st->codecpar->bits_per_coded_sample &= 0x1F;
2111 sc->has_palette = 1;
2115 static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
2116 AVStream *st, MOVStreamContext *sc)
2118 int bits_per_sample, flags;
2119 uint16_t version = avio_rb16(pb);
2120 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2122 avio_rb16(pb); /* revision level */
2123 avio_rb32(pb); /* vendor */
2125 st->codecpar->channels = avio_rb16(pb); /* channel count */
2126 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2127 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", st->codecpar->channels);
2129 sc->audio_cid = avio_rb16(pb);
2130 avio_rb16(pb); /* packet size = 0 */
2132 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2134 // Read QT version 1 fields. In version 0 these do not exist.
2135 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2137 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2138 (sc->stsd_version == 0 && version > 0)) {
2140 sc->samples_per_frame = avio_rb32(pb);
2141 avio_rb32(pb); /* bytes per packet */
2142 sc->bytes_per_frame = avio_rb32(pb);
2143 avio_rb32(pb); /* bytes per sample */
2144 } else if (version == 2) {
2145 avio_rb32(pb); /* sizeof struct only */
2146 st->codecpar->sample_rate = av_int2double(avio_rb64(pb));
2147 st->codecpar->channels = avio_rb32(pb);
2148 avio_rb32(pb); /* always 0x7F000000 */
2149 st->codecpar->bits_per_coded_sample = avio_rb32(pb);
2151 flags = avio_rb32(pb); /* lpcm format specific flag */
2152 sc->bytes_per_frame = avio_rb32(pb);
2153 sc->samples_per_frame = avio_rb32(pb);
2154 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2155 st->codecpar->codec_id =
2156 ff_mov_get_lpcm_codec_id(st->codecpar->bits_per_coded_sample,
2159 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2160 /* can't correctly handle variable sized packet as audio unit */
2161 switch (st->codecpar->codec_id) {
2162 case AV_CODEC_ID_MP2:
2163 case AV_CODEC_ID_MP3:
2164 st->need_parsing = AVSTREAM_PARSE_FULL;
2170 if (sc->format == 0) {
2171 if (st->codecpar->bits_per_coded_sample == 8)
2172 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2173 else if (st->codecpar->bits_per_coded_sample == 16)
2174 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2177 switch (st->codecpar->codec_id) {
2178 case AV_CODEC_ID_PCM_S8:
2179 case AV_CODEC_ID_PCM_U8:
2180 if (st->codecpar->bits_per_coded_sample == 16)
2181 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16BE;
2183 case AV_CODEC_ID_PCM_S16LE:
2184 case AV_CODEC_ID_PCM_S16BE:
2185 if (st->codecpar->bits_per_coded_sample == 8)
2186 st->codecpar->codec_id = AV_CODEC_ID_PCM_S8;
2187 else if (st->codecpar->bits_per_coded_sample == 24)
2188 st->codecpar->codec_id =
2189 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2190 AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
2191 else if (st->codecpar->bits_per_coded_sample == 32)
2192 st->codecpar->codec_id =
2193 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2194 AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
2196 /* set values for old format before stsd version 1 appeared */
2197 case AV_CODEC_ID_MACE3:
2198 sc->samples_per_frame = 6;
2199 sc->bytes_per_frame = 2 * st->codecpar->channels;
2201 case AV_CODEC_ID_MACE6:
2202 sc->samples_per_frame = 6;
2203 sc->bytes_per_frame = 1 * st->codecpar->channels;
2205 case AV_CODEC_ID_ADPCM_IMA_QT:
2206 sc->samples_per_frame = 64;
2207 sc->bytes_per_frame = 34 * st->codecpar->channels;
2209 case AV_CODEC_ID_GSM:
2210 sc->samples_per_frame = 160;
2211 sc->bytes_per_frame = 33;
2217 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2218 if (bits_per_sample) {
2219 st->codecpar->bits_per_coded_sample = bits_per_sample;
2220 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->channels;
2224 static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
2225 AVStream *st, MOVStreamContext *sc,
2228 // ttxt stsd contains display flags, justification, background
2229 // color, fonts, and default styles, so fake an atom to read it
2230 MOVAtom fake_atom = { .size = size };
2231 // mp4s contains a regular esds atom
2232 if (st->codecpar->codec_tag != AV_RL32("mp4s"))
2233 mov_read_glbl(c, pb, fake_atom);
2234 st->codecpar->width = sc->width;
2235 st->codecpar->height = sc->height;
2238 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2243 y = (ycbcr >> 16) & 0xFF;
2244 cr = (ycbcr >> 8) & 0xFF;
2247 b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
2248 g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
2249 r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
2251 return (r << 16) | (g << 8) | b;
2254 static int mov_rewrite_dvd_sub_extradata(AVStream *st)
2256 char buf[256] = {0};
2257 uint8_t *src = st->codecpar->extradata;
2260 if (st->codecpar->extradata_size != 64)
2263 if (st->codecpar->width > 0 && st->codecpar->height > 0)
2264 snprintf(buf, sizeof(buf), "size: %dx%d\n",
2265 st->codecpar->width, st->codecpar->height);
2266 av_strlcat(buf, "palette: ", sizeof(buf));
2268 for (i = 0; i < 16; i++) {
2269 uint32_t yuv = AV_RB32(src + i * 4);
2270 uint32_t rgba = yuv_to_rgba(yuv);
2272 av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2275 if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2278 av_freep(&st->codecpar->extradata);
2279 st->codecpar->extradata_size = 0;
2280 st->codecpar->extradata = av_mallocz(strlen(buf) + AV_INPUT_BUFFER_PADDING_SIZE);
2281 if (!st->codecpar->extradata)
2282 return AVERROR(ENOMEM);
2283 st->codecpar->extradata_size = strlen(buf);
2284 memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2289 static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
2290 AVStream *st, MOVStreamContext *sc,
2295 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2296 if ((int)size != size)
2297 return AVERROR(ENOMEM);
2299 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2303 MOVStreamContext *tmcd_ctx = st->priv_data;
2305 val = AV_RB32(st->codecpar->extradata + 4);
2306 tmcd_ctx->tmcd_flags = val;
2307 st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2308 st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2309 #if FF_API_LAVF_AVCTX
2310 FF_DISABLE_DEPRECATION_WARNINGS
2311 st->codec->time_base = av_inv_q(st->avg_frame_rate);
2312 FF_ENABLE_DEPRECATION_WARNINGS
2314 /* adjust for per frame dur in counter mode */
2315 if (tmcd_ctx->tmcd_flags & 0x0008) {
2316 int timescale = AV_RB32(st->codecpar->extradata + 8);
2317 int framedur = AV_RB32(st->codecpar->extradata + 12);
2318 st->avg_frame_rate.num *= timescale;
2319 st->avg_frame_rate.den *= framedur;
2320 #if FF_API_LAVF_AVCTX
2321 FF_DISABLE_DEPRECATION_WARNINGS
2322 st->codec->time_base.den *= timescale;
2323 st->codec->time_base.num *= framedur;
2324 FF_ENABLE_DEPRECATION_WARNINGS
2328 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2329 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2330 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2331 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2332 if (str_size > 0 && size >= (int)str_size + 26) {
2333 char *reel_name = av_malloc(str_size + 1);
2335 return AVERROR(ENOMEM);
2336 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2337 reel_name[str_size] = 0; /* Add null terminator */
2338 /* don't add reel_name if emtpy string */
2339 if (*reel_name == 0) {
2342 av_dict_set(&st->metadata, "reel_name", reel_name, AV_DICT_DONT_STRDUP_VAL);
2349 /* other codec type, just skip (rtp, mp4s ...) */
2350 avio_skip(pb, size);
2355 static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
2356 AVStream *st, MOVStreamContext *sc)
2358 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2359 !st->codecpar->sample_rate && sc->time_scale > 1)
2360 st->codecpar->sample_rate = sc->time_scale;
2362 /* special codec parameters handling */
2363 switch (st->codecpar->codec_id) {
2364 #if CONFIG_DV_DEMUXER
2365 case AV_CODEC_ID_DVAUDIO:
2366 c->dv_fctx = avformat_alloc_context();
2368 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2369 return AVERROR(ENOMEM);
2371 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2373 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2374 return AVERROR(ENOMEM);
2376 sc->dv_audio_container = 1;
2377 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
2380 /* no ifdef since parameters are always those */
2381 case AV_CODEC_ID_QCELP:
2382 st->codecpar->channels = 1;
2383 // force sample rate for qcelp when not stored in mov
2384 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2385 st->codecpar->sample_rate = 8000;
2386 // FIXME: Why is the following needed for some files?
2387 sc->samples_per_frame = 160;
2388 if (!sc->bytes_per_frame)
2389 sc->bytes_per_frame = 35;
2391 case AV_CODEC_ID_AMR_NB:
2392 st->codecpar->channels = 1;
2393 /* force sample rate for amr, stsd in 3gp does not store sample rate */
2394 st->codecpar->sample_rate = 8000;
2396 case AV_CODEC_ID_AMR_WB:
2397 st->codecpar->channels = 1;
2398 st->codecpar->sample_rate = 16000;
2400 case AV_CODEC_ID_MP2:
2401 case AV_CODEC_ID_MP3:
2402 /* force type after stsd for m1a hdlr */
2403 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2405 case AV_CODEC_ID_GSM:
2406 case AV_CODEC_ID_ADPCM_MS:
2407 case AV_CODEC_ID_ADPCM_IMA_WAV:
2408 case AV_CODEC_ID_ILBC:
2409 case AV_CODEC_ID_MACE3:
2410 case AV_CODEC_ID_MACE6:
2411 case AV_CODEC_ID_QDM2:
2412 st->codecpar->block_align = sc->bytes_per_frame;
2414 case AV_CODEC_ID_ALAC:
2415 if (st->codecpar->extradata_size == 36) {
2416 st->codecpar->channels = AV_RB8 (st->codecpar->extradata + 21);
2417 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2420 case AV_CODEC_ID_AC3:
2421 case AV_CODEC_ID_EAC3:
2422 case AV_CODEC_ID_MPEG1VIDEO:
2423 case AV_CODEC_ID_VC1:
2424 case AV_CODEC_ID_VP8:
2425 case AV_CODEC_ID_VP9:
2426 st->need_parsing = AVSTREAM_PARSE_FULL;
2434 static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
2435 int codec_tag, int format,
2438 int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2441 (codec_tag != format &&
2442 // AVID 1:1 samples with differing data format and codec tag exist
2443 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
2444 // prores is allowed to have differing data format and codec tag
2445 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
2447 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
2448 (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id
2449 : codec_tag != MKTAG('j','p','e','g')))) {
2450 /* Multiple fourcc, we skip JPEG. This is not correct, we should
2451 * export it as a separate AVStream but this needs a few changes
2452 * in the MOV demuxer, patch welcome. */
2454 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
2455 avio_skip(pb, size);
2462 int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
2465 MOVStreamContext *sc;
2466 int pseudo_stream_id;
2468 av_assert0 (c->fc->nb_streams >= 1);
2469 st = c->fc->streams[c->fc->nb_streams-1];
2472 for (pseudo_stream_id = 0;
2473 pseudo_stream_id < entries && !pb->eof_reached;
2474 pseudo_stream_id++) {
2475 //Parsing Sample description table
2477 int ret, dref_id = 1;
2478 MOVAtom a = { AV_RL32("stsd") };
2479 int64_t start_pos = avio_tell(pb);
2480 int64_t size = avio_rb32(pb); /* size */
2481 uint32_t format = avio_rl32(pb); /* data format */
2484 avio_rb32(pb); /* reserved */
2485 avio_rb16(pb); /* reserved */
2486 dref_id = avio_rb16(pb);
2487 } else if (size <= 7) {
2488 av_log(c->fc, AV_LOG_ERROR,
2489 "invalid size %"PRId64" in stsd\n", size);
2490 return AVERROR_INVALIDDATA;
2493 if (mov_skip_multiple_stsd(c, pb, st->codecpar->codec_tag, format,
2494 size - (avio_tell(pb) - start_pos))) {
2499 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
2500 sc->dref_id= dref_id;
2501 sc->format = format;
2503 id = mov_codec_id(st, format);
2505 av_log(c->fc, AV_LOG_TRACE,
2506 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
2507 av_fourcc2str(format), st->codecpar->codec_type);
2509 st->codecpar->codec_id = id;
2510 if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) {
2511 mov_parse_stsd_video(c, pb, st, sc);
2512 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
2513 mov_parse_stsd_audio(c, pb, st, sc);
2514 if (st->codecpar->sample_rate < 0) {
2515 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
2516 return AVERROR_INVALIDDATA;
2518 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
2519 mov_parse_stsd_subtitle(c, pb, st, sc,
2520 size - (avio_tell(pb) - start_pos));
2522 ret = mov_parse_stsd_data(c, pb, st, sc,
2523 size - (avio_tell(pb) - start_pos));
2527 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
2528 a.size = size - (avio_tell(pb) - start_pos);
2530 if ((ret = mov_read_default(c, pb, a)) < 0)
2532 } else if (a.size > 0)
2533 avio_skip(pb, a.size);
2535 if (sc->extradata && st->codecpar->extradata) {
2536 int extra_size = st->codecpar->extradata_size;
2538 /* Move the current stream extradata to the stream context one. */
2539 sc->extradata_size[pseudo_stream_id] = extra_size;
2540 sc->extradata[pseudo_stream_id] = av_malloc(extra_size + AV_INPUT_BUFFER_PADDING_SIZE);
2541 if (!sc->extradata[pseudo_stream_id])
2542 return AVERROR(ENOMEM);
2543 memcpy(sc->extradata[pseudo_stream_id], st->codecpar->extradata, extra_size);
2544 av_freep(&st->codecpar->extradata);
2545 st->codecpar->extradata_size = 0;
2550 if (pb->eof_reached) {
2551 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
2558 static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2561 MOVStreamContext *sc;
2564 if (c->fc->nb_streams < 1)
2566 st = c->fc->streams[c->fc->nb_streams - 1];
2569 sc->stsd_version = avio_r8(pb);
2570 avio_rb24(pb); /* flags */
2571 entries = avio_rb32(pb);
2573 /* Each entry contains a size (4 bytes) and format (4 bytes). */
2574 if (entries <= 0 || entries > atom.size / 8) {
2575 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
2576 return AVERROR_INVALIDDATA;
2579 if (sc->extradata) {
2580 av_log(c->fc, AV_LOG_ERROR,
2581 "Duplicate stsd found in this track.\n");
2582 return AVERROR_INVALIDDATA;
2585 /* Prepare space for hosting multiple extradata. */
2586 sc->extradata = av_mallocz_array(entries, sizeof(*sc->extradata));
2588 return AVERROR(ENOMEM);
2590 sc->extradata_size = av_mallocz_array(entries, sizeof(*sc->extradata_size));
2591 if (!sc->extradata_size) {
2592 ret = AVERROR(ENOMEM);
2596 ret = ff_mov_read_stsd_entries(c, pb, entries);
2600 /* Restore back the primary extradata. */
2601 av_freep(&st->codecpar->extradata);
2602 st->codecpar->extradata_size = sc->extradata_size[0];
2603 if (sc->extradata_size[0]) {
2604 st->codecpar->extradata = av_mallocz(sc->extradata_size[0] + AV_INPUT_BUFFER_PADDING_SIZE);
2605 if (!st->codecpar->extradata)
2606 return AVERROR(ENOMEM);
2607 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
2610 return mov_finalize_stsd_codec(c, pb, st, sc);
2612 if (sc->extradata) {
2614 for (j = 0; j < sc->stsd_count; j++)
2615 av_freep(&sc->extradata[j]);
2618 av_freep(&sc->extradata);
2619 av_freep(&sc->extradata_size);
2623 static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2626 MOVStreamContext *sc;
2627 unsigned int i, entries;
2629 if (c->fc->nb_streams < 1)
2631 st = c->fc->streams[c->fc->nb_streams-1];
2634 avio_r8(pb); /* version */
2635 avio_rb24(pb); /* flags */
2637 entries = avio_rb32(pb);
2638 if ((uint64_t)entries * 12 + 4 > atom.size)
2639 return AVERROR_INVALIDDATA;
2641 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
2646 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSC atom\n");
2647 av_free(sc->stsc_data);
2649 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
2651 return AVERROR(ENOMEM);
2653 for (i = 0; i < entries && !pb->eof_reached; i++) {
2654 sc->stsc_data[i].first = avio_rb32(pb);
2655 sc->stsc_data[i].count = avio_rb32(pb);
2656 sc->stsc_data[i].id = avio_rb32(pb);
2660 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
2661 int64_t first_min = i + 1;
2662 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
2663 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
2664 sc->stsc_data[i].first < first_min ||
2665 sc->stsc_data[i].count < 1 ||
2666 sc->stsc_data[i].id < 1) {
2667 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);
2668 if (i+1 >= sc->stsc_count) {
2669 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
2670 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
2671 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
2672 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
2673 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
2676 av_assert0(sc->stsc_data[i+1].first >= 2);
2677 // We replace this entry by the next valid
2678 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
2679 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
2680 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
2684 if (pb->eof_reached) {
2685 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
2692 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
2694 return index < count - 1;
2697 /* Compute the samples value for the stsc entry at the given index. */
2698 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
2702 if (mov_stsc_index_valid(index, sc->stsc_count))
2703 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
2705 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
2706 av_assert0(sc->stsc_data[index].first <= sc->chunk_count);
2707 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
2710 return sc->stsc_data[index].count * (int64_t)chunk_count;
2713 static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2716 MOVStreamContext *sc;
2717 unsigned i, entries;
2719 if (c->fc->nb_streams < 1)
2721 st = c->fc->streams[c->fc->nb_streams-1];
2724 avio_rb32(pb); // version + flags
2726 entries = avio_rb32(pb);
2728 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
2729 av_free(sc->stps_data);
2731 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
2733 return AVERROR(ENOMEM);
2735 for (i = 0; i < entries && !pb->eof_reached; i++) {
2736 sc->stps_data[i] = avio_rb32(pb);
2741 if (pb->eof_reached) {
2742 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
2749 static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2752 MOVStreamContext *sc;
2753 unsigned int i, entries;
2755 if (c->fc->nb_streams < 1)
2757 st = c->fc->streams[c->fc->nb_streams-1];
2760 avio_r8(pb); /* version */
2761 avio_rb24(pb); /* flags */
2763 entries = avio_rb32(pb);
2765 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
2769 sc->keyframe_absent = 1;
2770 if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
2771 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2775 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
2776 if (entries >= UINT_MAX / sizeof(int))
2777 return AVERROR_INVALIDDATA;
2778 av_freep(&sc->keyframes);
2779 sc->keyframe_count = 0;
2780 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
2782 return AVERROR(ENOMEM);
2784 for (i = 0; i < entries && !pb->eof_reached; i++) {
2785 sc->keyframes[i] = avio_rb32(pb);
2788 sc->keyframe_count = i;
2790 if (pb->eof_reached) {
2791 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
2798 static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2801 MOVStreamContext *sc;
2802 unsigned int i, entries, sample_size, field_size, num_bytes;
2807 if (c->fc->nb_streams < 1)
2809 st = c->fc->streams[c->fc->nb_streams-1];
2812 avio_r8(pb); /* version */
2813 avio_rb24(pb); /* flags */
2815 if (atom.type == MKTAG('s','t','s','z')) {
2816 sample_size = avio_rb32(pb);
2817 if (!sc->sample_size) /* do not overwrite value computed in stsd */
2818 sc->sample_size = sample_size;
2819 sc->stsz_sample_size = sample_size;
2823 avio_rb24(pb); /* reserved */
2824 field_size = avio_r8(pb);
2826 entries = avio_rb32(pb);
2828 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
2830 sc->sample_count = entries;
2834 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
2835 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
2836 return AVERROR_INVALIDDATA;
2841 if (entries >= (UINT_MAX - 4) / field_size)
2842 return AVERROR_INVALIDDATA;
2843 if (sc->sample_sizes)
2844 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
2845 av_free(sc->sample_sizes);
2846 sc->sample_count = 0;
2847 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
2848 if (!sc->sample_sizes)
2849 return AVERROR(ENOMEM);
2851 num_bytes = (entries*field_size+4)>>3;
2853 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
2855 av_freep(&sc->sample_sizes);
2856 return AVERROR(ENOMEM);
2859 ret = ffio_read_size(pb, buf, num_bytes);
2861 av_freep(&sc->sample_sizes);
2863 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
2867 init_get_bits(&gb, buf, 8*num_bytes);
2869 for (i = 0; i < entries && !pb->eof_reached; i++) {
2870 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
2871 sc->data_size += sc->sample_sizes[i];
2874 sc->sample_count = i;
2878 if (pb->eof_reached) {
2879 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSZ atom\n");
2886 static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2889 MOVStreamContext *sc;
2890 unsigned int i, entries, alloc_size = 0;
2892 int64_t total_sample_count=0;
2894 if (c->fc->nb_streams < 1)
2896 st = c->fc->streams[c->fc->nb_streams-1];
2899 avio_r8(pb); /* version */
2900 avio_rb24(pb); /* flags */
2901 entries = avio_rb32(pb);
2903 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
2904 c->fc->nb_streams-1, entries);
2907 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
2908 av_freep(&sc->stts_data);
2910 if (entries >= INT_MAX / sizeof(*sc->stts_data))
2911 return AVERROR(ENOMEM);
2913 for (i = 0; i < entries && !pb->eof_reached; i++) {
2914 int sample_duration;
2915 unsigned int sample_count;
2916 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
2917 MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
2918 min_entries * sizeof(*sc->stts_data));
2920 av_freep(&sc->stts_data);
2922 return AVERROR(ENOMEM);
2924 sc->stts_count = min_entries;
2925 sc->stts_data = stts_data;
2927 sample_count=avio_rb32(pb);
2928 sample_duration = avio_rb32(pb);
2930 sc->stts_data[i].count= sample_count;
2931 sc->stts_data[i].duration= sample_duration;
2933 av_log(c->fc, AV_LOG_TRACE, "sample_count=%d, sample_duration=%d\n",
2934 sample_count, sample_duration);
2936 duration+=(int64_t)sample_duration*(uint64_t)sample_count;
2937 total_sample_count+=sample_count;
2943 duration <= INT64_MAX - sc->duration_for_fps &&
2944 total_sample_count <= INT_MAX - sc->nb_frames_for_fps
2946 sc->duration_for_fps += duration;
2947 sc->nb_frames_for_fps += total_sample_count;
2950 if (pb->eof_reached) {
2951 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
2955 st->nb_frames= total_sample_count;
2957 st->duration= FFMIN(st->duration, duration);
2958 sc->track_end = duration;
2962 static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2965 MOVStreamContext *sc;
2968 if (c->fc->nb_streams < 1)
2970 st = c->fc->streams[c->fc->nb_streams - 1];
2973 avio_r8(pb); /* version */
2974 avio_rb24(pb); /* flags */
2975 entries = atom.size - 4;
2977 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
2978 c->fc->nb_streams - 1, entries);
2981 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
2982 av_freep(&sc->sdtp_data);
2985 sc->sdtp_data = av_mallocz(entries);
2987 return AVERROR(ENOMEM);
2989 for (i = 0; i < entries && !pb->eof_reached; i++)
2990 sc->sdtp_data[i] = avio_r8(pb);
2996 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
2999 if (duration == INT_MIN) {
3000 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3003 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3007 static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3010 MOVStreamContext *sc;
3011 unsigned int i, entries, ctts_count = 0;
3013 if (c->fc->nb_streams < 1)
3015 st = c->fc->streams[c->fc->nb_streams-1];
3018 avio_r8(pb); /* version */
3019 avio_rb24(pb); /* flags */
3020 entries = avio_rb32(pb);
3022 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3026 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3027 return AVERROR_INVALIDDATA;
3028 av_freep(&sc->ctts_data);
3029 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3031 return AVERROR(ENOMEM);
3033 for (i = 0; i < entries && !pb->eof_reached; i++) {
3034 int count =avio_rb32(pb);
3035 int duration =avio_rb32(pb);
3038 av_log(c->fc, AV_LOG_TRACE,
3039 "ignoring CTTS entry with count=%d duration=%d\n",
3044 add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3047 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3050 if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3051 av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3052 av_freep(&sc->ctts_data);
3058 mov_update_dts_shift(sc, duration, c->fc);
3061 sc->ctts_count = ctts_count;
3063 if (pb->eof_reached) {
3064 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3068 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3073 static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3076 MOVStreamContext *sc;
3077 unsigned int i, entries;
3079 uint32_t grouping_type;
3081 if (c->fc->nb_streams < 1)
3083 st = c->fc->streams[c->fc->nb_streams-1];
3086 version = avio_r8(pb); /* version */
3087 avio_rb24(pb); /* flags */
3088 grouping_type = avio_rl32(pb);
3089 if (grouping_type != MKTAG( 'r','a','p',' '))
3090 return 0; /* only support 'rap ' grouping */
3092 avio_rb32(pb); /* grouping_type_parameter */
3094 entries = avio_rb32(pb);
3098 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP atom\n");
3099 av_free(sc->rap_group);
3100 sc->rap_group_count = 0;
3101 sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group));
3103 return AVERROR(ENOMEM);
3105 for (i = 0; i < entries && !pb->eof_reached; i++) {
3106 sc->rap_group[i].count = avio_rb32(pb); /* sample_count */
3107 sc->rap_group[i].index = avio_rb32(pb); /* group_description_index */
3110 sc->rap_group_count = i;
3112 if (pb->eof_reached) {
3113 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3121 * Get ith edit list entry (media time, duration).
3123 static int get_edit_list_entry(MOVContext *mov,
3124 const MOVStreamContext *msc,
3125 unsigned int edit_list_index,
3126 int64_t *edit_list_media_time,
3127 int64_t *edit_list_duration,
3128 int64_t global_timescale)
3130 if (edit_list_index == msc->elst_count) {
3133 *edit_list_media_time = msc->elst_data[edit_list_index].time;
3134 *edit_list_duration = msc->elst_data[edit_list_index].duration;
3136 /* duration is in global timescale units;convert to msc timescale */
3137 if (global_timescale == 0) {
3138 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3141 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3147 * Find the closest previous frame to the timestamp_pts, in e_old index
3148 * entries. Searching for just any frame / just key frames can be controlled by
3149 * last argument 'flag'.
3150 * Note that if ctts_data is not NULL, we will always search for a key frame
3151 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3152 * return the first frame of the video.
3154 * Here the timestamp_pts is considered to be a presentation timestamp and
3155 * the timestamp of index entries are considered to be decoding timestamps.
3157 * Returns 0 if successful in finding a frame, else returns -1.
3158 * Places the found index corresponding output arg.
3160 * If ctts_old is not NULL, then refines the searched entry by searching
3161 * backwards from the found timestamp, to find the frame with correct PTS.
3163 * Places the found ctts_index and ctts_sample in corresponding output args.
3165 static int find_prev_closest_index(AVStream *st,
3166 AVIndexEntry *e_old,
3170 int64_t timestamp_pts,
3173 int64_t* ctts_index,
3174 int64_t* ctts_sample)
3176 MOVStreamContext *msc = st->priv_data;
3177 AVIndexEntry *e_keep = st->index_entries;
3178 int nb_keep = st->nb_index_entries;
3180 int64_t index_ctts_count;
3184 // If dts_shift > 0, then all the index timestamps will have to be offset by
3185 // at least dts_shift amount to obtain PTS.
3186 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3187 if (msc->dts_shift > 0) {
3188 timestamp_pts -= msc->dts_shift;
3191 st->index_entries = e_old;
3192 st->nb_index_entries = nb_old;
3193 *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3195 // Keep going backwards in the index entries until the timestamp is the same.
3197 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3199 if ((flag & AVSEEK_FLAG_ANY) ||
3200 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3206 // If we have CTTS then refine the search, by searching backwards over PTS
3207 // computed by adding corresponding CTTS durations to index timestamps.
3208 if (ctts_data && *index >= 0) {
3209 av_assert0(ctts_index);
3210 av_assert0(ctts_sample);
3211 // Find out the ctts_index for the found frame.
3214 for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3215 if (*ctts_index < ctts_count) {
3217 if (ctts_data[*ctts_index].count == *ctts_sample) {
3224 while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3225 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3226 // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3227 // compensated by dts_shift above.
3228 if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3229 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3234 if (*ctts_sample == 0) {
3236 if (*ctts_index >= 0)
3237 *ctts_sample = ctts_data[*ctts_index].count - 1;
3244 /* restore AVStream state*/
3245 st->index_entries = e_keep;
3246 st->nb_index_entries = nb_keep;
3247 return *index >= 0 ? 0 : -1;
3251 * Add index entry with the given values, to the end of st->index_entries.
3252 * Returns the new size st->index_entries if successful, else returns -1.
3254 * This function is similar to ff_add_index_entry in libavformat/utils.c
3255 * except that here we are always unconditionally adding an index entry to
3256 * the end, instead of searching the entries list and skipping the add if
3257 * there is an existing entry with the same timestamp.
3258 * This is needed because the mov_fix_index calls this func with the same
3259 * unincremented timestamp for successive discarded frames.
3261 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3262 int size, int distance, int flags)
3264 AVIndexEntry *entries, *ie;
3266 const size_t min_size_needed = (st->nb_index_entries + 1) * sizeof(AVIndexEntry);
3268 // Double the allocation each time, to lower memory fragmentation.
3269 // Another difference from ff_add_index_entry function.
3270 const size_t requested_size =
3271 min_size_needed > st->index_entries_allocated_size ?
3272 FFMAX(min_size_needed, 2 * st->index_entries_allocated_size) :
3275 if((unsigned)st->nb_index_entries + 1 >= UINT_MAX / sizeof(AVIndexEntry))
3278 entries = av_fast_realloc(st->index_entries,
3279 &st->index_entries_allocated_size,
3284 st->index_entries= entries;
3286 index= st->nb_index_entries++;
3287 ie= &entries[index];
3290 ie->timestamp = timestamp;
3291 ie->min_distance= distance;
3298 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3299 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3301 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3302 int64_t* frame_duration_buffer,
3303 int frame_duration_buffer_size) {
3305 av_assert0(end_index >= 0 && end_index <= st->nb_index_entries);
3306 for (i = 0; i < frame_duration_buffer_size; i++) {
3307 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3308 st->index_entries[end_index - 1 - i].timestamp = end_ts;
3313 * Append a new ctts entry to ctts_data.
3314 * Returns the new ctts_count if successful, else returns -1.
3316 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3317 int count, int duration)
3319 MOVStts *ctts_buf_new;
3320 const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVStts);
3321 const size_t requested_size =
3322 min_size_needed > *allocated_size ?
3323 FFMAX(min_size_needed, 2 * (*allocated_size)) :
3326 if((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
3329 ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3334 *ctts_data = ctts_buf_new;
3336 ctts_buf_new[*ctts_count].count = count;
3337 ctts_buf_new[*ctts_count].duration = duration;
3339 *ctts_count = (*ctts_count) + 1;
3343 #define MAX_REORDER_DELAY 16
3344 static void mov_estimate_video_delay(MOVContext *c, AVStream* st) {
3345 MOVStreamContext *msc = st->priv_data;
3348 int ctts_sample = 0;
3349 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3351 int j, r, num_swaps;
3353 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3354 pts_buf[j] = INT64_MIN;
3356 if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3357 st->codecpar->codec_id == AV_CODEC_ID_H264) {
3358 st->codecpar->video_delay = 0;
3359 for(ind = 0; ind < st->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3360 // Point j to the last elem of the buffer and insert the current pts there.
3362 buf_start = (buf_start + 1);
3363 if (buf_start == MAX_REORDER_DELAY + 1)
3366 pts_buf[j] = st->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3368 // The timestamps that are already in the sorted buffer, and are greater than the
3369 // current pts, are exactly the timestamps that need to be buffered to output PTS
3370 // in correct sorted order.
3371 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3372 // can be computed as the maximum no. of swaps any particular timestamp needs to
3373 // go through, to keep this buffer in sorted order.
3375 while (j != buf_start) {
3377 if (r < 0) r = MAX_REORDER_DELAY;
3378 if (pts_buf[j] < pts_buf[r]) {
3379 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3386 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3389 if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3394 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3395 st->codecpar->video_delay, st->index);
3399 static void mov_current_sample_inc(MOVStreamContext *sc)
3401 sc->current_sample++;
3402 sc->current_index++;
3403 if (sc->index_ranges &&
3404 sc->current_index >= sc->current_index_range->end &&
3405 sc->current_index_range->end) {
3406 sc->current_index_range++;
3407 sc->current_index = sc->current_index_range->start;
3411 static void mov_current_sample_dec(MOVStreamContext *sc)
3413 sc->current_sample--;
3414 sc->current_index--;
3415 if (sc->index_ranges &&
3416 sc->current_index < sc->current_index_range->start &&
3417 sc->current_index_range > sc->index_ranges) {
3418 sc->current_index_range--;
3419 sc->current_index = sc->current_index_range->end - 1;
3423 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3427 sc->current_sample = current_sample;
3428 sc->current_index = current_sample;
3429 if (!sc->index_ranges) {
3433 for (sc->current_index_range = sc->index_ranges;
3434 sc->current_index_range->end;
3435 sc->current_index_range++) {
3436 range_size = sc->current_index_range->end - sc->current_index_range->start;
3437 if (range_size > current_sample) {
3438 sc->current_index = sc->current_index_range->start + current_sample;
3441 current_sample -= range_size;
3446 * Fix st->index_entries, so that it contains only the entries (and the entries
3447 * which are needed to decode them) that fall in the edit list time ranges.
3448 * Also fixes the timestamps of the index entries to match the timeline
3449 * specified the edit lists.
3451 static void mov_fix_index(MOVContext *mov, AVStream *st)
3453 MOVStreamContext *msc = st->priv_data;
3454 AVIndexEntry *e_old = st->index_entries;
3455 int nb_old = st->nb_index_entries;
3456 const AVIndexEntry *e_old_end = e_old + nb_old;
3457 const AVIndexEntry *current = NULL;
3458 MOVStts *ctts_data_old = msc->ctts_data;
3459 int64_t ctts_index_old = 0;
3460 int64_t ctts_sample_old = 0;
3461 int64_t ctts_count_old = msc->ctts_count;
3462 int64_t edit_list_media_time = 0;
3463 int64_t edit_list_duration = 0;
3464 int64_t frame_duration = 0;
3465 int64_t edit_list_dts_counter = 0;
3466 int64_t edit_list_dts_entry_end = 0;
3467 int64_t edit_list_start_ctts_sample = 0;
3469 int64_t curr_ctts = 0;
3470 int64_t empty_edits_sum_duration = 0;
3471 int64_t edit_list_index = 0;
3474 int64_t start_dts = 0;
3475 int64_t edit_list_start_encountered = 0;
3476 int64_t search_timestamp = 0;
3477 int64_t* frame_duration_buffer = NULL;
3478 int num_discarded_begin = 0;
3479 int first_non_zero_audio_edit = -1;
3480 int packet_skip_samples = 0;
3481 MOVIndexRange *current_index_range;
3483 int found_keyframe_after_edit = 0;
3484 int found_non_empty_edit = 0;
3486 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
3490 // allocate the index ranges array
3491 msc->index_ranges = av_malloc((msc->elst_count + 1) * sizeof(msc->index_ranges[0]));
3492 if (!msc->index_ranges) {
3493 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
3496 msc->current_index_range = msc->index_ranges;
3497 current_index_range = msc->index_ranges - 1;
3499 // Clean AVStream from traces of old index
3500 st->index_entries = NULL;
3501 st->index_entries_allocated_size = 0;
3502 st->nb_index_entries = 0;
3504 // Clean ctts fields of MOVStreamContext
3505 msc->ctts_data = NULL;
3506 msc->ctts_count = 0;
3507 msc->ctts_index = 0;
3508 msc->ctts_sample = 0;
3509 msc->ctts_allocated_size = 0;
3511 // Reinitialize min_corrected_pts so that it can be computed again.
3512 msc->min_corrected_pts = -1;
3514 // If the dts_shift is positive (in case of negative ctts values in mov),
3515 // then negate the DTS by dts_shift
3516 if (msc->dts_shift > 0) {
3517 edit_list_dts_entry_end -= msc->dts_shift;
3518 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
3521 start_dts = edit_list_dts_entry_end;
3523 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
3524 &edit_list_duration, mov->time_scale)) {
3525 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
3526 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
3528 edit_list_dts_counter = edit_list_dts_entry_end;
3529 edit_list_dts_entry_end += edit_list_duration;
3530 num_discarded_begin = 0;
3531 if (!found_non_empty_edit && edit_list_media_time == -1) {
3532 empty_edits_sum_duration += edit_list_duration;
3535 found_non_empty_edit = 1;
3537 // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
3538 // according to the edit list below.
3539 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3540 if (first_non_zero_audio_edit < 0) {
3541 first_non_zero_audio_edit = 1;
3543 first_non_zero_audio_edit = 0;
3546 if (first_non_zero_audio_edit > 0)
3547 st->skip_samples = msc->start_pad = 0;
3550 // While reordering frame index according to edit list we must handle properly
3551 // the scenario when edit list entry starts from none key frame.
3552 // We find closest previous key frame and preserve it and consequent frames in index.
3553 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
3554 search_timestamp = edit_list_media_time;
3555 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3556 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
3557 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
3558 // edit_list_media_time to cover the decoder delay.
3559 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
3562 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
3563 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3564 av_log(mov->fc, AV_LOG_WARNING,
3565 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
3566 st->index, edit_list_index, search_timestamp);
3567 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
3568 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3569 av_log(mov->fc, AV_LOG_WARNING,
3570 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
3571 st->index, edit_list_index, search_timestamp);
3574 ctts_sample_old = 0;
3577 current = e_old + index;
3578 edit_list_start_ctts_sample = ctts_sample_old;
3580 // Iterate over index and arrange it according to edit list
3581 edit_list_start_encountered = 0;
3582 found_keyframe_after_edit = 0;
3583 for (; current < e_old_end; current++, index++) {
3584 // check if frame outside edit list mark it for discard
3585 frame_duration = (current + 1 < e_old_end) ?
3586 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
3588 flags = current->flags;
3590 // frames (pts) before or after edit list
3591 curr_cts = current->timestamp + msc->dts_shift;
3594 if (ctts_data_old && ctts_index_old < ctts_count_old) {
3595 curr_ctts = ctts_data_old[ctts_index_old].duration;
3596 av_log(mov->fc, AV_LOG_DEBUG, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
3597 curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
3598 curr_cts += curr_ctts;
3600 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
3601 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3602 &msc->ctts_allocated_size,
3603 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3604 ctts_data_old[ctts_index_old].duration) == -1) {
3605 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3607 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3608 ctts_data_old[ctts_index_old].duration);
3612 ctts_sample_old = 0;
3613 edit_list_start_ctts_sample = 0;
3617 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
3618 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
3619 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
3620 first_non_zero_audio_edit > 0) {
3621 packet_skip_samples = edit_list_media_time - curr_cts;
3622 st->skip_samples += packet_skip_samples;
3624 // Shift the index entry timestamp by packet_skip_samples to be correct.
3625 edit_list_dts_counter -= packet_skip_samples;
3626 if (edit_list_start_encountered == 0) {
3627 edit_list_start_encountered = 1;
3628 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
3629 // discarded packets.
3630 if (frame_duration_buffer) {
3631 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3632 frame_duration_buffer, num_discarded_begin);
3633 av_freep(&frame_duration_buffer);
3637 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
3639 flags |= AVINDEX_DISCARD_FRAME;
3640 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
3642 if (edit_list_start_encountered == 0) {
3643 num_discarded_begin++;
3644 frame_duration_buffer = av_realloc(frame_duration_buffer,
3645 num_discarded_begin * sizeof(int64_t));
3646 if (!frame_duration_buffer) {
3647 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
3650 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
3652 // Increment skip_samples for the first non-zero audio edit list
3653 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3654 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
3655 st->skip_samples += frame_duration;
3660 if (msc->min_corrected_pts < 0) {
3661 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
3663 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
3665 if (edit_list_start_encountered == 0) {
3666 edit_list_start_encountered = 1;
3667 // Make timestamps strictly monotonically increasing by rewriting timestamps for
3668 // discarded packets.
3669 if (frame_duration_buffer) {
3670 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3671 frame_duration_buffer, num_discarded_begin);
3672 av_freep(&frame_duration_buffer);
3677 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
3678 current->min_distance, flags) == -1) {
3679 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
3683 // Update the index ranges array
3684 if (current_index_range < msc->index_ranges || index != current_index_range->end) {
3685 current_index_range++;
3686 current_index_range->start = index;
3688 current_index_range->end = index + 1;
3690 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
3691 if (edit_list_start_encountered > 0) {
3692 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
3695 // Break when found first key frame after edit entry completion
3696 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
3697 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
3698 if (ctts_data_old) {
3699 // If we have CTTS and this is the first keyframe after edit elist,
3700 // wait for one more, because there might be trailing B-frames after this I-frame
3701 // that do belong to the edit.
3702 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
3703 found_keyframe_after_edit = 1;
3706 if (ctts_sample_old != 0) {
3707 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3708 &msc->ctts_allocated_size,
3709 ctts_sample_old - edit_list_start_ctts_sample,
3710 ctts_data_old[ctts_index_old].duration) == -1) {
3711 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3712 ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
3713 ctts_data_old[ctts_index_old].duration);
3722 // If there are empty edits, then msc->min_corrected_pts might be positive
3723 // intentionally. So we subtract the sum duration of emtpy edits here.
3724 msc->min_corrected_pts -= empty_edits_sum_duration;
3726 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
3727 // dts by that amount to make the first pts zero.
3728 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
3729 if (msc->min_corrected_pts > 0) {
3730 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
3731 for (i = 0; i < st->nb_index_entries; ++i) {
3732 st->index_entries[i].timestamp -= msc->min_corrected_pts;
3736 // Start time should be equal to zero or the duration of any empty edits.
3737 st->start_time = empty_edits_sum_duration;
3739 // Update av stream length, if it ends up shorter than the track's media duration
3740 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
3741 msc->start_pad = st->skip_samples;
3743 // Free the old index and the old CTTS structures
3745 av_free(ctts_data_old);
3746 av_freep(&frame_duration_buffer);
3748 // Null terminate the index ranges array
3749 current_index_range++;
3750 current_index_range->start = 0;
3751 current_index_range->end = 0;
3752 msc->current_index = msc->index_ranges[0].start;
3755 static void mov_build_index(MOVContext *mov, AVStream *st)
3757 MOVStreamContext *sc = st->priv_data;
3758 int64_t current_offset;
3759 int64_t current_dts = 0;
3760 unsigned int stts_index = 0;
3761 unsigned int stsc_index = 0;
3762 unsigned int stss_index = 0;
3763 unsigned int stps_index = 0;
3765 uint64_t stream_size = 0;
3766 MOVStts *ctts_data_old = sc->ctts_data;
3767 unsigned int ctts_count_old = sc->ctts_count;
3769 if (sc->elst_count) {
3770 int i, edit_start_index = 0, multiple_edits = 0;
3771 int64_t empty_duration = 0; // empty duration of the first edit list entry
3772 int64_t start_time = 0; // start time of the media
3774 for (i = 0; i < sc->elst_count; i++) {
3775 const MOVElst *e = &sc->elst_data[i];
3776 if (i == 0 && e->time == -1) {
3777 /* if empty, the first entry is the start time of the stream
3778 * relative to the presentation itself */
3779 empty_duration = e->duration;
3780 edit_start_index = 1;
3781 } else if (i == edit_start_index && e->time >= 0) {
3782 start_time = e->time;
3788 if (multiple_edits && !mov->advanced_editlist)
3789 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
3790 "Use -advanced_editlist to correctly decode otherwise "
3791 "a/v desync might occur\n");
3793 /* adjust first dts according to edit list */
3794 if ((empty_duration || start_time) && mov->time_scale > 0) {
3796 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
3797 sc->time_offset = start_time - empty_duration;
3798 sc->min_corrected_pts = start_time;
3799 if (!mov->advanced_editlist)
3800 current_dts = -sc->time_offset;
3803 if (!multiple_edits && !mov->advanced_editlist &&
3804 st->codecpar->codec_id == AV_CODEC_ID_AAC && start_time > 0)
3805 sc->start_pad = start_time;
3808 /* only use old uncompressed audio chunk demuxing when stts specifies it */
3809 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3810 sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
3811 unsigned int current_sample = 0;
3812 unsigned int stts_sample = 0;
3813 unsigned int sample_size;
3814 unsigned int distance = 0;
3815 unsigned int rap_group_index = 0;
3816 unsigned int rap_group_sample = 0;
3817 int64_t last_dts = 0;
3818 int64_t dts_correction = 0;
3819 int rap_group_present = sc->rap_group_count && sc->rap_group;
3820 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
3822 current_dts -= sc->dts_shift;
3823 last_dts = current_dts;
3825 if (!sc->sample_count || st->nb_index_entries)
3827 if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
3829 if (av_reallocp_array(&st->index_entries,
3830 st->nb_index_entries + sc->sample_count,
3831 sizeof(*st->index_entries)) < 0) {
3832 st->nb_index_entries = 0;
3835 st->index_entries_allocated_size = (st->nb_index_entries + sc->sample_count) * sizeof(*st->index_entries);
3837 if (ctts_data_old) {
3838 // Expand ctts entries such that we have a 1-1 mapping with samples
3839 if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
3842 sc->ctts_allocated_size = 0;
3843 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size,
3844 sc->sample_count * sizeof(*sc->ctts_data));
3845 if (!sc->ctts_data) {
3846 av_free(ctts_data_old);
3850 memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
3852 for (i = 0; i < ctts_count_old &&
3853 sc->ctts_count < sc->sample_count; i++)
3854 for (j = 0; j < ctts_data_old[i].count &&
3855 sc->ctts_count < sc->sample_count; j++)
3856 add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
3857 &sc->ctts_allocated_size, 1,
3858 ctts_data_old[i].duration);
3859 av_free(ctts_data_old);
3862 for (i = 0; i < sc->chunk_count; i++) {
3863 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
3864 current_offset = sc->chunk_offsets[i];
3865 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3866 i + 1 == sc->stsc_data[stsc_index + 1].first)
3869 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
3870 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
3871 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
3872 sc->stsz_sample_size = sc->sample_size;
3874 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
3875 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
3876 sc->stsz_sample_size = sc->sample_size;
3879 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
3881 if (current_sample >= sc->sample_count) {
3882 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
3886 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
3888 if (stss_index + 1 < sc->keyframe_count)
3890 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
3892 if (stps_index + 1 < sc->stps_count)
3895 if (rap_group_present && rap_group_index < sc->rap_group_count) {
3896 if (sc->rap_group[rap_group_index].index > 0)
3898 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
3899 rap_group_sample = 0;
3903 if (sc->keyframe_absent
3905 && !rap_group_present
3906 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
3910 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
3911 if (sc->pseudo_stream_id == -1 ||
3912 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
3914 if (sample_size > 0x3FFFFFFF) {
3915 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
3918 e = &st->index_entries[st->nb_index_entries++];
3919 e->pos = current_offset;
3920 e->timestamp = current_dts;
3921 e->size = sample_size;
3922 e->min_distance = distance;
3923 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
3924 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
3925 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
3926 current_offset, current_dts, sample_size, distance, keyframe);
3927 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries < 100)
3928 ff_rfps_add_frame(mov->fc, st, current_dts);
3931 current_offset += sample_size;
3932 stream_size += sample_size;
3934 /* A negative sample duration is invalid based on the spec,
3935 * but some samples need it to correct the DTS. */
3936 if (sc->stts_data[stts_index].duration < 0) {
3937 av_log(mov->fc, AV_LOG_WARNING,
3938 "Invalid SampleDelta %d in STTS, at %d st:%d\n",
3939 sc->stts_data[stts_index].duration, stts_index,
3941 dts_correction += sc->stts_data[stts_index].duration - 1;
3942 sc->stts_data[stts_index].duration = 1;
3944 current_dts += sc->stts_data[stts_index].duration;
3945 if (!dts_correction || current_dts + dts_correction > last_dts) {
3946 current_dts += dts_correction;
3949 /* Avoid creating non-monotonous DTS */
3950 dts_correction += current_dts - last_dts - 1;
3951 current_dts = last_dts + 1;
3953 last_dts = current_dts;
3957 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
3963 if (st->duration > 0)
3964 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
3966 unsigned chunk_samples, total = 0;
3968 if (!sc->chunk_count)
3971 // compute total chunk count
3972 for (i = 0; i < sc->stsc_count; i++) {
3973 unsigned count, chunk_count;
3975 chunk_samples = sc->stsc_data[i].count;
3976 if (i != sc->stsc_count - 1 &&
3977 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
3978 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
3982 if (sc->samples_per_frame >= 160) { // gsm
3983 count = chunk_samples / sc->samples_per_frame;
3984 } else if (sc->samples_per_frame > 1) {
3985 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
3986 count = (chunk_samples+samples-1) / samples;
3988 count = (chunk_samples+1023) / 1024;
3991 if (mov_stsc_index_valid(i, sc->stsc_count))
3992 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
3994 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
3995 total += chunk_count * count;
3998 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
3999 if (total >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
4001 if (av_reallocp_array(&st->index_entries,
4002 st->nb_index_entries + total,
4003 sizeof(*st->index_entries)) < 0) {
4004 st->nb_index_entries = 0;
4007 st->index_entries_allocated_size = (st->nb_index_entries + total) * sizeof(*st->index_entries);
4010 for (i = 0; i < sc->chunk_count; i++) {
4011 current_offset = sc->chunk_offsets[i];
4012 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4013 i + 1 == sc->stsc_data[stsc_index + 1].first)
4015 chunk_samples = sc->stsc_data[stsc_index].count;
4017 while (chunk_samples > 0) {
4019 unsigned size, samples;
4021 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4022 avpriv_request_sample(mov->fc,
4023 "Zero bytes per frame, but %d samples per frame",
4024 sc->samples_per_frame);
4028 if (sc->samples_per_frame >= 160) { // gsm
4029 samples = sc->samples_per_frame;
4030 size = sc->bytes_per_frame;
4032 if (sc->samples_per_frame > 1) {
4033 samples = FFMIN((1024 / sc->samples_per_frame)*
4034 sc->samples_per_frame, chunk_samples);
4035 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
4037 samples = FFMIN(1024, chunk_samples);
4038 size = samples * sc->sample_size;
4042 if (st->nb_index_entries >= total) {
4043 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4046 if (size > 0x3FFFFFFF) {
4047 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4050 e = &st->index_entries[st->nb_index_entries++];
4051 e->pos = current_offset;
4052 e->timestamp = current_dts;
4054 e->min_distance = 0;
4055 e->flags = AVINDEX_KEYFRAME;
4056 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4057 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4060 current_offset += size;
4061 current_dts += samples;
4062 chunk_samples -= samples;
4067 if (!mov->ignore_editlist && mov->advanced_editlist) {
4068 // Fix index according to edit lists.
4069 mov_fix_index(mov, st);
4072 // Update start time of the stream.
4073 if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries > 0) {
4074 st->start_time = st->index_entries[0].timestamp + sc->dts_shift;
4075 if (sc->ctts_data) {
4076 st->start_time += sc->ctts_data[0].duration;
4080 mov_estimate_video_delay(mov, st);
4083 static int test_same_origin(const char *src, const char *ref) {
4093 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4094 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4096 if (strlen(src) == 0) {
4098 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4099 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4100 strlen(src_host) + 1 >= sizeof(src_host) ||
4101 strlen(ref_host) + 1 >= sizeof(ref_host)) {
4103 } else if (strcmp(src_proto, ref_proto) ||
4104 strcmp(src_auth, ref_auth) ||
4105 strcmp(src_host, ref_host) ||
4106 src_port != ref_port) {
4112 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4114 /* try relative path, we do not try the absolute because it can leak information about our
4115 system to an attacker */
4116 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4117 char filename[1025];
4118 const char *src_path;
4121 /* find a source dir */
4122 src_path = strrchr(src, '/');
4128 /* find a next level down to target */
4129 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4130 if (ref->path[l] == '/') {
4131 if (i == ref->nlvl_to - 1)
4137 /* compose filename if next level down to target was found */
4138 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4139 memcpy(filename, src, src_path - src);
4140 filename[src_path - src] = 0;
4142 for (i = 1; i < ref->nlvl_from; i++)
4143 av_strlcat(filename, "../", sizeof(filename));
4145 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4146 if (!c->use_absolute_path) {
4147 int same_origin = test_same_origin(src, filename);
4150 av_log(c->fc, AV_LOG_ERROR,
4151 "Reference with mismatching origin, %s not tried for security reasons, "
4152 "set demuxer option use_absolute_path to allow it anyway\n",
4154 return AVERROR(ENOENT);
4157 if(strstr(ref->path + l + 1, "..") ||
4158 strstr(ref->path + l + 1, ":") ||
4159 (ref->nlvl_from > 1 && same_origin < 0) ||
4160 (filename[0] == '/' && src_path == src))
4161 return AVERROR(ENOENT);
4164 if (strlen(filename) + 1 == sizeof(filename))
4165 return AVERROR(ENOENT);
4166 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4169 } else if (c->use_absolute_path) {
4170 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4171 "this is a possible security issue\n");
4172 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4175 av_log(c->fc, AV_LOG_ERROR,
4176 "Absolute path %s not tried for security reasons, "
4177 "set demuxer option use_absolute_path to allow absolute paths\n",
4181 return AVERROR(ENOENT);
4184 static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
4186 if (sc->time_scale <= 0) {
4187 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4188 sc->time_scale = c->time_scale;
4189 if (sc->time_scale <= 0)
4194 static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4197 MOVStreamContext *sc;
4200 st = avformat_new_stream(c->fc, NULL);
4201 if (!st) return AVERROR(ENOMEM);
4203 sc = av_mallocz(sizeof(MOVStreamContext));
4204 if (!sc) return AVERROR(ENOMEM);
4207 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
4208 sc->ffindex = st->index;
4209 c->trak_index = st->index;
4211 if ((ret = mov_read_default(c, pb, atom)) < 0)
4216 // Here stsc refers to a chunk not described in stco. This is technically invalid,
4217 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4218 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4220 av_freep(&sc->stsc_data);
4224 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4225 (!sc->sample_size && !sc->sample_count))) ||
4226 (!sc->chunk_count && sc->sample_count)) {
4227 av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4231 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4232 av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4234 return AVERROR_INVALIDDATA;
4237 fix_timescale(c, sc);
4239 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4241 mov_build_index(c, st);
4243 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4244 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4245 if (c->enable_drefs) {
4246 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4247 av_log(c->fc, AV_LOG_ERROR,
4248 "stream %d, error opening alias: path='%s', dir='%s', "
4249 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4250 st->index, dref->path, dref->dir, dref->filename,
4251 dref->volume, dref->nlvl_from, dref->nlvl_to);
4253 av_log(c->fc, AV_LOG_WARNING,
4254 "Skipped opening external track: "
4255 "stream %d, alias: path='%s', dir='%s', "
4256 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4257 "Set enable_drefs to allow this.\n",
4258 st->index, dref->path, dref->dir, dref->filename,
4259 dref->volume, dref->nlvl_from, dref->nlvl_to);
4263 sc->pb_is_copied = 1;
4266 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4267 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4268 sc->height && sc->width &&
4269 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4270 st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4271 ((double)st->codecpar->width * sc->height), INT_MAX);
4274 #if FF_API_R_FRAME_RATE
4275 if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4276 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
4277 sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4281 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4282 if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4283 TAG_IS_AVCI(st->codecpar->codec_tag)) {
4284 ret = ff_generate_avci_extradata(st);
4289 switch (st->codecpar->codec_id) {
4290 #if CONFIG_H261_DECODER
4291 case AV_CODEC_ID_H261:
4293 #if CONFIG_H263_DECODER
4294 case AV_CODEC_ID_H263:
4296 #if CONFIG_MPEG4_DECODER
4297 case AV_CODEC_ID_MPEG4:
4299 st->codecpar->width = 0; /* let decoder init width/height */
4300 st->codecpar->height= 0;
4304 // If the duration of the mp3 packets is not constant, then they could need a parser
4305 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4306 && sc->stts_count > 3
4307 && sc->stts_count*10 > st->nb_frames
4308 && sc->time_scale == st->codecpar->sample_rate) {
4309 st->need_parsing = AVSTREAM_PARSE_FULL;
4311 /* Do not need those anymore. */
4312 av_freep(&sc->chunk_offsets);
4313 av_freep(&sc->sample_sizes);
4314 av_freep(&sc->keyframes);
4315 av_freep(&sc->stts_data);
4316 av_freep(&sc->stps_data);
4317 av_freep(&sc->elst_data);
4318 av_freep(&sc->rap_group);
4323 static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4326 c->itunes_metadata = 1;
4327 ret = mov_read_default(c, pb, atom);
4328 c->itunes_metadata = 0;
4332 static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4341 count = avio_rb32(pb);
4342 if (count > UINT_MAX / sizeof(*c->meta_keys) - 1) {
4343 av_log(c->fc, AV_LOG_ERROR,
4344 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
4345 return AVERROR_INVALIDDATA;
4348 c->meta_keys_count = count + 1;
4349 c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
4351 return AVERROR(ENOMEM);
4353 for (i = 1; i <= count; ++i) {
4354 uint32_t key_size = avio_rb32(pb);
4355 uint32_t type = avio_rl32(pb);
4357 av_log(c->fc, AV_LOG_ERROR,
4358 "The key# %"PRIu32" in meta has invalid size:"
4359 "%"PRIu32"\n", i, key_size);
4360 return AVERROR_INVALIDDATA;
4363 if (type != MKTAG('m','d','t','a')) {
4364 avio_skip(pb, key_size);
4366 c->meta_keys[i] = av_mallocz(key_size + 1);
4367 if (!c->meta_keys[i])
4368 return AVERROR(ENOMEM);
4369 avio_read(pb, c->meta_keys[i], key_size);
4375 static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4377 int64_t end = avio_tell(pb) + atom.size;
4378 uint8_t *key = NULL, *val = NULL, *mean = NULL;
4382 MOVStreamContext *sc;
4384 if (c->fc->nb_streams < 1)
4386 st = c->fc->streams[c->fc->nb_streams-1];
4389 for (i = 0; i < 3; i++) {
4393 if (end - avio_tell(pb) <= 12)
4396 len = avio_rb32(pb);
4397 tag = avio_rl32(pb);
4398 avio_skip(pb, 4); // flags
4400 if (len < 12 || len - 12 > end - avio_tell(pb))
4404 if (tag == MKTAG('m', 'e', 'a', 'n'))
4406 else if (tag == MKTAG('n', 'a', 'm', 'e'))
4408 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
4415 *p = av_malloc(len + 1);
4417 ret = AVERROR(ENOMEM);
4420 ret = ffio_read_size(pb, *p, len);
4428 if (mean && key && val) {
4429 if (strcmp(key, "iTunSMPB") == 0) {
4430 int priming, remainder, samples;
4431 if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
4432 if(priming>0 && priming<16384)
4433 sc->start_pad = priming;
4436 if (strcmp(key, "cdec") != 0) {
4437 av_dict_set(&c->fc->metadata, key, val,
4438 AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
4442 av_log(c->fc, AV_LOG_VERBOSE,
4443 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
4446 avio_seek(pb, end, SEEK_SET);
4453 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4455 while (atom.size > 8) {
4459 tag = avio_rl32(pb);
4461 if (tag == MKTAG('h','d','l','r')) {
4462 avio_seek(pb, -8, SEEK_CUR);
4464 return mov_read_default(c, pb, atom);
4470 // return 1 when matrix is identity, 0 otherwise
4471 #define IS_MATRIX_IDENT(matrix) \
4472 ( (matrix)[0][0] == (1 << 16) && \
4473 (matrix)[1][1] == (1 << 16) && \
4474 (matrix)[2][2] == (1 << 30) && \
4475 !(matrix)[0][1] && !(matrix)[0][2] && \
4476 !(matrix)[1][0] && !(matrix)[1][2] && \
4477 !(matrix)[2][0] && !(matrix)[2][1])
4479 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4484 int display_matrix[3][3];
4485 int res_display_matrix[3][3] = { { 0 } };
4487 MOVStreamContext *sc;
4491 if (c->fc->nb_streams < 1)
4493 st = c->fc->streams[c->fc->nb_streams-1];
4496 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4497 // avoids corrupting AVStreams mapped to an earlier tkhd.
4499 return AVERROR_INVALIDDATA;
4501 version = avio_r8(pb);
4502 flags = avio_rb24(pb);
4503 st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
4509 avio_rb32(pb); /* creation time */
4510 avio_rb32(pb); /* modification time */
4512 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4513 avio_rb32(pb); /* reserved */
4515 /* highlevel (considering edits) duration in movie timebase */
4516 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4517 avio_rb32(pb); /* reserved */
4518 avio_rb32(pb); /* reserved */
4520 avio_rb16(pb); /* layer */
4521 avio_rb16(pb); /* alternate group */
4522 avio_rb16(pb); /* volume */
4523 avio_rb16(pb); /* reserved */
4525 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4526 // they're kept in fixed point format through all calculations
4527 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4528 // side data, but the scale factor is not needed to calculate aspect ratio
4529 for (i = 0; i < 3; i++) {
4530 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
4531 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
4532 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
4535 width = avio_rb32(pb); // 16.16 fixed point track width
4536 height = avio_rb32(pb); // 16.16 fixed point track height
4537 sc->width = width >> 16;
4538 sc->height = height >> 16;
4540 // apply the moov display matrix (after the tkhd one)
4541 for (i = 0; i < 3; i++) {
4542 const int sh[3] = { 16, 16, 30 };
4543 for (j = 0; j < 3; j++) {
4544 for (e = 0; e < 3; e++) {
4545 res_display_matrix[i][j] +=
4546 ((int64_t) display_matrix[i][e] *
4547 c->movie_display_matrix[e][j]) >> sh[e];
4552 // save the matrix when it is not the default identity
4553 if (!IS_MATRIX_IDENT(res_display_matrix)) {
4556 av_freep(&sc->display_matrix);
4557 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4558 if (!sc->display_matrix)
4559 return AVERROR(ENOMEM);
4561 for (i = 0; i < 3; i++)
4562 for (j = 0; j < 3; j++)
4563 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4565 #if FF_API_OLD_ROTATE_API
4566 rotate = av_display_rotation_get(sc->display_matrix);
4567 if (!isnan(rotate)) {
4568 char rotate_buf[64];
4570 if (rotate < 0) // for backward compatibility
4572 snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate);
4573 av_dict_set(&st->metadata, "rotate", rotate_buf, 0);
4578 // transform the display width/height according to the matrix
4579 // to keep the same scale, use [width height 1<<16]
4580 if (width && height && sc->display_matrix) {
4581 double disp_transform[2];
4583 for (i = 0; i < 2; i++)
4584 disp_transform[i] = hypot(sc->display_matrix[0 + i],
4585 sc->display_matrix[3 + i]);
4587 if (disp_transform[0] > 0 && disp_transform[1] > 0 &&
4588 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4589 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4590 st->sample_aspect_ratio = av_d2q(
4591 disp_transform[0] / disp_transform[1],
4597 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4599 MOVFragment *frag = &c->fragment;
4600 MOVTrackExt *trex = NULL;
4601 int flags, track_id, i;
4603 avio_r8(pb); /* version */
4604 flags = avio_rb24(pb);
4606 track_id = avio_rb32(pb);
4608 return AVERROR_INVALIDDATA;
4609 for (i = 0; i < c->trex_count; i++)
4610 if (c->trex_data[i].track_id == track_id) {
4611 trex = &c->trex_data[i];
4615 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4618 c->fragment.found_tfhd = 1;
4619 frag->track_id = track_id;
4620 set_frag_stream(&c->frag_index, track_id);
4622 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4623 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4624 frag->moof_offset : frag->implicit_offset;
4625 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4627 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4628 avio_rb32(pb) : trex->duration;
4629 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4630 avio_rb32(pb) : trex->size;
4631 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4632 avio_rb32(pb) : trex->flags;
4633 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4638 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4643 num = atom.size / 4;
4644 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4645 return AVERROR(ENOMEM);
4647 av_free(c->chapter_tracks);
4648 c->chapter_tracks = new_tracks;
4649 c->nb_chapter_tracks = num;
4651 for (i = 0; i < num && !pb->eof_reached; i++)
4652 c->chapter_tracks[i] = avio_rb32(pb);
4657 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4662 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4663 return AVERROR_INVALIDDATA;
4664 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4665 sizeof(*c->trex_data))) < 0) {
4670 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4672 trex = &c->trex_data[c->trex_count++];
4673 avio_r8(pb); /* version */
4674 avio_rb24(pb); /* flags */
4675 trex->track_id = avio_rb32(pb);
4676 trex->stsd_id = avio_rb32(pb);
4677 trex->duration = avio_rb32(pb);
4678 trex->size = avio_rb32(pb);
4679 trex->flags = avio_rb32(pb);
4683 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4685 MOVFragment *frag = &c->fragment;
4686 AVStream *st = NULL;
4687 MOVStreamContext *sc;
4689 MOVFragmentStreamInfo * frag_stream_info;
4690 int64_t base_media_decode_time;
4692 for (i = 0; i < c->fc->nb_streams; i++) {
4693 if (c->fc->streams[i]->id == frag->track_id) {
4694 st = c->fc->streams[i];
4699 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4703 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4705 version = avio_r8(pb);
4706 avio_rb24(pb); /* flags */
4708 base_media_decode_time = avio_rb64(pb);
4710 base_media_decode_time = avio_rb32(pb);
4713 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4714 if (frag_stream_info)
4715 frag_stream_info->tfdt_dts = base_media_decode_time;
4716 sc->track_end = base_media_decode_time;
4721 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4723 MOVFragment *frag = &c->fragment;
4724 AVStream *st = NULL;
4725 MOVStreamContext *sc;
4728 int64_t dts, pts = AV_NOPTS_VALUE;
4729 int data_offset = 0;
4730 unsigned entries, first_sample_flags = frag->flags;
4731 int flags, distance, i;
4732 int64_t prev_dts = AV_NOPTS_VALUE;
4733 int next_frag_index = -1, index_entry_pos;
4734 size_t requested_size;
4735 size_t old_ctts_allocated_size;
4736 AVIndexEntry *new_entries;
4737 MOVFragmentStreamInfo * frag_stream_info;
4739 if (!frag->found_tfhd) {
4740 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4741 return AVERROR_INVALIDDATA;
4744 for (i = 0; i < c->fc->nb_streams; i++) {
4745 if (c->fc->streams[i]->id == frag->track_id) {
4746 st = c->fc->streams[i];
4751 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4755 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4758 // Find the next frag_index index that has a valid index_entry for
4759 // the current track_id.
4761 // A valid index_entry means the trun for the fragment was read
4762 // and it's samples are in index_entries at the given position.
4763 // New index entries will be inserted before the index_entry found.
4764 index_entry_pos = st->nb_index_entries;
4765 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4766 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4767 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4768 next_frag_index = i;
4769 index_entry_pos = frag_stream_info->index_entry;
4773 av_assert0(index_entry_pos <= st->nb_index_entries);
4775 avio_r8(pb); /* version */
4776 flags = avio_rb24(pb);
4777 entries = avio_rb32(pb);
4778 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4780 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4781 return AVERROR_INVALIDDATA;
4782 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4783 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4785 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4786 if (frag_stream_info)
4788 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4789 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4790 pts = frag_stream_info->first_tfra_pts;
4791 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4792 ", using it for pts\n", pts);
4793 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4794 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4795 // pts = frag_stream_info->sidx_pts;
4796 dts = frag_stream_info->sidx_pts - sc->time_offset;
4797 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4798 ", using it for pts\n", pts);
4799 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4800 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4801 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4802 ", using it for dts\n", dts);
4804 dts = sc->track_end - sc->time_offset;
4805 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4806 ", using it for dts\n", dts);
4809 dts = sc->track_end - sc->time_offset;
4810 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4811 ", using it for dts\n", dts);
4813 offset = frag->base_data_offset + data_offset;
4815 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4817 // realloc space for new index entries
4818 if((uint64_t)st->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4819 entries = UINT_MAX / sizeof(AVIndexEntry) - st->nb_index_entries;
4820 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4825 requested_size = (st->nb_index_entries + entries) * sizeof(AVIndexEntry);
4826 new_entries = av_fast_realloc(st->index_entries,
4827 &st->index_entries_allocated_size,
4830 return AVERROR(ENOMEM);
4831 st->index_entries= new_entries;
4833 requested_size = (st->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4834 old_ctts_allocated_size = sc->ctts_allocated_size;
4835 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4838 return AVERROR(ENOMEM);
4839 sc->ctts_data = ctts_data;
4841 // In case there were samples without ctts entries, ensure they get
4842 // zero valued entries. This ensures clips which mix boxes with and
4843 // without ctts entries don't pickup uninitialized data.
4844 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4845 sc->ctts_allocated_size - old_ctts_allocated_size);
4847 if (index_entry_pos < st->nb_index_entries) {
4848 // Make hole in index_entries and ctts_data for new samples
4849 memmove(st->index_entries + index_entry_pos + entries,
4850 st->index_entries + index_entry_pos,
4851 sizeof(*st->index_entries) *
4852 (st->nb_index_entries - index_entry_pos));
4853 memmove(sc->ctts_data + index_entry_pos + entries,
4854 sc->ctts_data + index_entry_pos,
4855 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4856 if (index_entry_pos < sc->current_sample) {
4857 sc->current_sample += entries;
4861 st->nb_index_entries += entries;
4862 sc->ctts_count = st->nb_index_entries;
4864 // Record the index_entry position in frag_index of this fragment
4865 if (frag_stream_info)
4866 frag_stream_info->index_entry = index_entry_pos;
4868 if (index_entry_pos > 0)
4869 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4871 for (i = 0; i < entries && !pb->eof_reached; i++) {
4872 unsigned sample_size = frag->size;
4873 int sample_flags = i ? frag->flags : first_sample_flags;
4874 unsigned sample_duration = frag->duration;
4875 unsigned ctts_duration = 0;
4877 int index_entry_flags = 0;
4879 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4880 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4881 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4882 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4884 mov_update_dts_shift(sc, ctts_duration, c->fc);
4885 if (pts != AV_NOPTS_VALUE) {
4886 dts = pts - sc->dts_shift;
4887 if (flags & MOV_TRUN_SAMPLE_CTS) {
4888 dts -= ctts_duration;
4890 dts -= sc->time_offset;
4892 av_log(c->fc, AV_LOG_DEBUG,
4893 "pts %"PRId64" calculated dts %"PRId64
4894 " sc->dts_shift %d ctts.duration %d"
4895 " sc->time_offset %"PRId64
4896 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4898 sc->dts_shift, ctts_duration,
4899 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4900 pts = AV_NOPTS_VALUE;
4903 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4907 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4908 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4911 index_entry_flags |= AVINDEX_KEYFRAME;
4913 // Fragments can overlap in time. Discard overlapping frames after
4915 if (prev_dts >= dts)
4916 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4918 st->index_entries[index_entry_pos].pos = offset;
4919 st->index_entries[index_entry_pos].timestamp = dts;
4920 st->index_entries[index_entry_pos].size= sample_size;
4921 st->index_entries[index_entry_pos].min_distance= distance;
4922 st->index_entries[index_entry_pos].flags = index_entry_flags;
4924 sc->ctts_data[index_entry_pos].count = 1;
4925 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4928 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4929 "size %u, distance %d, keyframe %d\n", st->index,
4930 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4932 dts += sample_duration;
4933 offset += sample_size;
4934 sc->data_size += sample_size;
4936 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4937 1 <= INT_MAX - sc->nb_frames_for_fps
4939 sc->duration_for_fps += sample_duration;
4940 sc->nb_frames_for_fps ++;
4944 // EOF found before reading all entries. Fix the hole this would
4945 // leave in index_entries and ctts_data
4946 int gap = entries - i;
4947 memmove(st->index_entries + index_entry_pos,
4948 st->index_entries + index_entry_pos + gap,
4949 sizeof(*st->index_entries) *
4950 (st->nb_index_entries - (index_entry_pos + gap)));
4951 memmove(sc->ctts_data + index_entry_pos,
4952 sc->ctts_data + index_entry_pos + gap,
4953 sizeof(*sc->ctts_data) *
4954 (sc->ctts_count - (index_entry_pos + gap)));
4956 st->nb_index_entries -= gap;
4957 sc->ctts_count -= gap;
4958 if (index_entry_pos < sc->current_sample) {
4959 sc->current_sample -= gap;
4964 // The end of this new fragment may overlap in time with the start
4965 // of the next fragment in index_entries. Mark the samples in the next
4966 // fragment that overlap with AVINDEX_DISCARD_FRAME
4967 prev_dts = AV_NOPTS_VALUE;
4968 if (index_entry_pos > 0)
4969 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4970 for (i = index_entry_pos; i < st->nb_index_entries; i++) {
4971 if (prev_dts < st->index_entries[i].timestamp)
4973 st->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
4976 // If a hole was created to insert the new index_entries into,
4977 // the index_entry recorded for all subsequent moof must
4978 // be incremented by the number of entries inserted.
4979 fix_frag_index_entries(&c->frag_index, next_frag_index,
4980 frag->track_id, entries);
4982 if (pb->eof_reached) {
4983 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
4987 frag->implicit_offset = offset;
4989 sc->track_end = dts + sc->time_offset;
4990 if (st->duration < sc->track_end)
4991 st->duration = sc->track_end;
4996 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4998 int64_t offset = avio_tell(pb) + atom.size, pts, timestamp;
5000 unsigned i, j, track_id, item_count;
5001 AVStream *st = NULL;
5002 AVStream *ref_st = NULL;
5003 MOVStreamContext *sc, *ref_sc = NULL;
5004 AVRational timescale;
5006 version = avio_r8(pb);
5008 avpriv_request_sample(c->fc, "sidx version %u", version);
5012 avio_rb24(pb); // flags
5014 track_id = avio_rb32(pb); // Reference ID
5015 for (i = 0; i < c->fc->nb_streams; i++) {
5016 if (c->fc->streams[i]->id == track_id) {
5017 st = c->fc->streams[i];
5022 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5028 timescale = av_make_q(1, avio_rb32(pb));
5030 if (timescale.den <= 0) {
5031 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5032 return AVERROR_INVALIDDATA;
5036 pts = avio_rb32(pb);
5037 offset += avio_rb32(pb);
5039 pts = avio_rb64(pb);
5040 offset += avio_rb64(pb);
5043 avio_rb16(pb); // reserved
5045 item_count = avio_rb16(pb);
5047 for (i = 0; i < item_count; i++) {
5049 MOVFragmentStreamInfo * frag_stream_info;
5050 uint32_t size = avio_rb32(pb);
5051 uint32_t duration = avio_rb32(pb);
5052 if (size & 0x80000000) {
5053 avpriv_request_sample(c->fc, "sidx reference_type 1");
5054 return AVERROR_PATCHWELCOME;
5056 avio_rb32(pb); // sap_flags
5057 timestamp = av_rescale_q(pts, timescale, st->time_base);
5059 index = update_frag_index(c, offset);
5060 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5061 if (frag_stream_info)
5062 frag_stream_info->sidx_pts = timestamp;
5068 st->duration = sc->track_end = pts;
5072 if (offset == avio_size(pb)) {
5073 // Find first entry in fragment index that came from an sidx.
5074 // This will pretty much always be the first entry.
5075 for (i = 0; i < c->frag_index.nb_items; i++) {
5076 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5077 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5078 MOVFragmentStreamInfo * si;
5079 si = &item->stream_info[j];
5080 if (si->sidx_pts != AV_NOPTS_VALUE) {
5081 ref_st = c->fc->streams[j];
5082 ref_sc = ref_st->priv_data;
5087 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5088 st = c->fc->streams[i];
5090 if (!sc->has_sidx) {
5091 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5095 c->frag_index.complete = 1;
5101 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5102 /* like the files created with Adobe Premiere 5.0, for samples see */
5103 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5104 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5109 return 0; /* continue */
5110 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5111 avio_skip(pb, atom.size - 4);
5114 atom.type = avio_rl32(pb);
5116 if (atom.type != MKTAG('m','d','a','t')) {
5117 avio_skip(pb, atom.size);
5120 err = mov_read_mdat(c, pb, atom);
5124 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5129 uint8_t *moov_data; /* uncompressed data */
5130 long cmov_len, moov_len;
5133 avio_rb32(pb); /* dcom atom */
5134 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5135 return AVERROR_INVALIDDATA;
5136 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5137 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5138 return AVERROR_INVALIDDATA;
5140 avio_rb32(pb); /* cmvd atom */
5141 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5142 return AVERROR_INVALIDDATA;
5143 moov_len = avio_rb32(pb); /* uncompressed size */
5144 cmov_len = atom.size - 6 * 4;
5146 cmov_data = av_malloc(cmov_len);
5148 return AVERROR(ENOMEM);
5149 moov_data = av_malloc(moov_len);
5152 return AVERROR(ENOMEM);
5154 ret = ffio_read_size(pb, cmov_data, cmov_len);
5156 goto free_and_return;
5158 ret = AVERROR_INVALIDDATA;
5159 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5160 goto free_and_return;
5161 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5162 goto free_and_return;
5163 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5164 atom.type = MKTAG('m','o','o','v');
5165 atom.size = moov_len;
5166 ret = mov_read_default(c, &ctx, atom);
5172 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5173 return AVERROR(ENOSYS);
5177 /* edit list atom */
5178 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5180 MOVStreamContext *sc;
5181 int i, edit_count, version;
5182 int64_t elst_entry_size;
5184 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5186 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5188 version = avio_r8(pb); /* version */
5189 avio_rb24(pb); /* flags */
5190 edit_count = avio_rb32(pb); /* entries */
5193 elst_entry_size = version == 1 ? 20 : 12;
5194 if (atom.size != edit_count * elst_entry_size) {
5195 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5196 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5197 edit_count, atom.size + 8);
5198 return AVERROR_INVALIDDATA;
5200 edit_count = atom.size / elst_entry_size;
5201 if (edit_count * elst_entry_size != atom.size) {
5202 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.", atom.size, edit_count);
5210 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5211 av_free(sc->elst_data);
5213 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5215 return AVERROR(ENOMEM);
5217 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5218 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5219 MOVElst *e = &sc->elst_data[i];
5222 e->duration = avio_rb64(pb);
5223 e->time = avio_rb64(pb);
5226 e->duration = avio_rb32(pb); /* segment duration */
5227 e->time = (int32_t)avio_rb32(pb); /* media time */
5230 e->rate = avio_rb32(pb) / 65536.0;
5232 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5233 e->duration, e->time, e->rate);
5235 if (e->time < 0 && e->time != -1 &&
5236 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5237 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5238 c->fc->nb_streams-1, i, e->time);
5239 return AVERROR_INVALIDDATA;
5247 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5249 MOVStreamContext *sc;
5251 if (c->fc->nb_streams < 1)
5252 return AVERROR_INVALIDDATA;
5253 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5254 sc->timecode_track = avio_rb32(pb);
5258 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5263 if (c->fc->nb_streams < 1)
5265 st = c->fc->streams[c->fc->nb_streams - 1];
5267 if (atom.size < 4) {
5268 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5269 return AVERROR_INVALIDDATA;
5272 /* For now, propagate only the OBUs, if any. Once libavcodec is
5273 updated to handle isobmff style extradata this can be removed. */
5279 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5286 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5289 int version, color_range, color_primaries, color_trc, color_space;
5291 if (c->fc->nb_streams < 1)
5293 st = c->fc->streams[c->fc->nb_streams - 1];
5295 if (atom.size < 5) {
5296 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5297 return AVERROR_INVALIDDATA;
5300 version = avio_r8(pb);
5302 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5305 avio_skip(pb, 3); /* flags */
5307 avio_skip(pb, 2); /* profile + level */
5308 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5309 color_primaries = avio_r8(pb);
5310 color_trc = avio_r8(pb);
5311 color_space = avio_r8(pb);
5312 if (avio_rb16(pb)) /* codecIntializationDataSize */
5313 return AVERROR_INVALIDDATA;
5315 if (!av_color_primaries_name(color_primaries))
5316 color_primaries = AVCOL_PRI_UNSPECIFIED;
5317 if (!av_color_transfer_name(color_trc))
5318 color_trc = AVCOL_TRC_UNSPECIFIED;
5319 if (!av_color_space_name(color_space))
5320 color_space = AVCOL_SPC_UNSPECIFIED;
5322 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5323 st->codecpar->color_primaries = color_primaries;
5324 st->codecpar->color_trc = color_trc;
5325 st->codecpar->color_space = color_space;
5330 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5332 MOVStreamContext *sc;
5335 if (c->fc->nb_streams < 1)
5336 return AVERROR_INVALIDDATA;
5338 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5340 if (atom.size < 5) {
5341 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5342 return AVERROR_INVALIDDATA;
5345 version = avio_r8(pb);
5347 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5350 avio_skip(pb, 3); /* flags */
5352 sc->mastering = av_mastering_display_metadata_alloc();
5354 return AVERROR(ENOMEM);
5356 for (i = 0; i < 3; i++) {
5357 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5358 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5360 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5361 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5363 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5364 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5366 sc->mastering->has_primaries = 1;
5367 sc->mastering->has_luminance = 1;
5372 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5374 MOVStreamContext *sc;
5375 const int mapping[3] = {1, 2, 0};
5376 const int chroma_den = 50000;
5377 const int luma_den = 10000;
5380 if (c->fc->nb_streams < 1)
5381 return AVERROR_INVALIDDATA;
5383 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5385 if (atom.size < 24) {
5386 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5387 return AVERROR_INVALIDDATA;
5390 sc->mastering = av_mastering_display_metadata_alloc();
5392 return AVERROR(ENOMEM);
5394 for (i = 0; i < 3; i++) {
5395 const int j = mapping[i];
5396 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5397 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5399 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5400 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5402 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5403 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5405 sc->mastering->has_luminance = 1;
5406 sc->mastering->has_primaries = 1;
5411 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5413 MOVStreamContext *sc;
5416 if (c->fc->nb_streams < 1)
5417 return AVERROR_INVALIDDATA;
5419 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5421 if (atom.size < 5) {
5422 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5423 return AVERROR_INVALIDDATA;
5426 version = avio_r8(pb);
5428 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5431 avio_skip(pb, 3); /* flags */
5433 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5435 return AVERROR(ENOMEM);
5437 sc->coll->MaxCLL = avio_rb16(pb);
5438 sc->coll->MaxFALL = avio_rb16(pb);
5443 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5445 MOVStreamContext *sc;
5447 if (c->fc->nb_streams < 1)
5448 return AVERROR_INVALIDDATA;
5450 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5452 if (atom.size < 4) {
5453 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5454 return AVERROR_INVALIDDATA;
5457 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5459 return AVERROR(ENOMEM);
5461 sc->coll->MaxCLL = avio_rb16(pb);
5462 sc->coll->MaxFALL = avio_rb16(pb);
5467 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5470 MOVStreamContext *sc;
5471 enum AVStereo3DType type;
5474 if (c->fc->nb_streams < 1)
5477 st = c->fc->streams[c->fc->nb_streams - 1];
5480 if (atom.size < 5) {
5481 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5482 return AVERROR_INVALIDDATA;
5484 avio_skip(pb, 4); /* version + flags */
5489 type = AV_STEREO3D_2D;
5492 type = AV_STEREO3D_TOPBOTTOM;
5495 type = AV_STEREO3D_SIDEBYSIDE;
5498 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5502 sc->stereo3d = av_stereo3d_alloc();
5504 return AVERROR(ENOMEM);
5506 sc->stereo3d->type = type;
5510 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5513 MOVStreamContext *sc;
5514 int size, version, layout;
5515 int32_t yaw, pitch, roll;
5516 uint32_t l = 0, t = 0, r = 0, b = 0;
5517 uint32_t tag, padding = 0;
5518 enum AVSphericalProjection projection;
5520 if (c->fc->nb_streams < 1)
5523 st = c->fc->streams[c->fc->nb_streams - 1];
5526 if (atom.size < 8) {
5527 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5528 return AVERROR_INVALIDDATA;
5531 size = avio_rb32(pb);
5532 if (size <= 12 || size > atom.size)
5533 return AVERROR_INVALIDDATA;
5535 tag = avio_rl32(pb);
5536 if (tag != MKTAG('s','v','h','d')) {
5537 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5540 version = avio_r8(pb);
5542 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5546 avio_skip(pb, 3); /* flags */
5547 avio_skip(pb, size - 12); /* metadata_source */
5549 size = avio_rb32(pb);
5550 if (size > atom.size)
5551 return AVERROR_INVALIDDATA;
5553 tag = avio_rl32(pb);
5554 if (tag != MKTAG('p','r','o','j')) {
5555 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5559 size = avio_rb32(pb);
5560 if (size > atom.size)
5561 return AVERROR_INVALIDDATA;
5563 tag = avio_rl32(pb);
5564 if (tag != MKTAG('p','r','h','d')) {
5565 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5568 version = avio_r8(pb);
5570 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5574 avio_skip(pb, 3); /* flags */
5576 /* 16.16 fixed point */
5577 yaw = avio_rb32(pb);
5578 pitch = avio_rb32(pb);
5579 roll = avio_rb32(pb);
5581 size = avio_rb32(pb);
5582 if (size > atom.size)
5583 return AVERROR_INVALIDDATA;
5585 tag = avio_rl32(pb);
5586 version = avio_r8(pb);
5588 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5592 avio_skip(pb, 3); /* flags */
5594 case MKTAG('c','b','m','p'):
5595 layout = avio_rb32(pb);
5597 av_log(c->fc, AV_LOG_WARNING,
5598 "Unsupported cubemap layout %d\n", layout);
5601 projection = AV_SPHERICAL_CUBEMAP;
5602 padding = avio_rb32(pb);
5604 case MKTAG('e','q','u','i'):
5610 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5611 av_log(c->fc, AV_LOG_ERROR,
5612 "Invalid bounding rectangle coordinates "
5613 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5614 return AVERROR_INVALIDDATA;
5617 if (l || t || r || b)
5618 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5620 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5623 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5627 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5629 return AVERROR(ENOMEM);
5631 sc->spherical->projection = projection;
5633 sc->spherical->yaw = yaw;
5634 sc->spherical->pitch = pitch;
5635 sc->spherical->roll = roll;
5637 sc->spherical->padding = padding;
5639 sc->spherical->bound_left = l;
5640 sc->spherical->bound_top = t;
5641 sc->spherical->bound_right = r;
5642 sc->spherical->bound_bottom = b;
5647 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5650 uint8_t *buffer = av_malloc(len + 1);
5654 return AVERROR(ENOMEM);
5657 ret = ffio_read_size(pb, buffer, len);
5661 /* Check for mandatory keys and values, try to support XML as best-effort */
5662 if (!sc->spherical &&
5663 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5664 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5665 av_stristr(val, "true") &&
5666 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5667 av_stristr(val, "true") &&
5668 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5669 av_stristr(val, "equirectangular")) {
5670 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5674 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5676 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5677 enum AVStereo3DType mode;
5679 if (av_stristr(buffer, "left-right"))
5680 mode = AV_STEREO3D_SIDEBYSIDE;
5681 else if (av_stristr(buffer, "top-bottom"))
5682 mode = AV_STEREO3D_TOPBOTTOM;
5684 mode = AV_STEREO3D_2D;
5686 sc->stereo3d = av_stereo3d_alloc();
5690 sc->stereo3d->type = mode;
5694 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5696 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5697 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5699 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5700 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5702 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5710 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5713 MOVStreamContext *sc;
5716 static const uint8_t uuid_isml_manifest[] = {
5717 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5718 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5720 static const uint8_t uuid_xmp[] = {
5721 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5722 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5724 static const uint8_t uuid_spherical[] = {
5725 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5726 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5729 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5730 return AVERROR_INVALIDDATA;
5732 if (c->fc->nb_streams < 1)
5734 st = c->fc->streams[c->fc->nb_streams - 1];
5737 ret = avio_read(pb, uuid, sizeof(uuid));
5740 } else if (ret != sizeof(uuid)) {
5741 return AVERROR_INVALIDDATA;
5743 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5744 uint8_t *buffer, *ptr;
5746 size_t len = atom.size - sizeof(uuid);
5749 return AVERROR_INVALIDDATA;
5751 ret = avio_skip(pb, 4); // zeroes
5754 buffer = av_mallocz(len + 1);
5756 return AVERROR(ENOMEM);
5758 ret = avio_read(pb, buffer, len);
5762 } else if (ret != len) {
5764 return AVERROR_INVALIDDATA;
5768 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5769 ptr += sizeof("systemBitrate=\"") - 1;
5770 c->bitrates_count++;
5771 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5773 c->bitrates_count = 0;
5775 return AVERROR(ENOMEM);
5778 ret = strtol(ptr, &endptr, 10);
5779 if (ret < 0 || errno || *endptr != '"') {
5780 c->bitrates[c->bitrates_count - 1] = 0;
5782 c->bitrates[c->bitrates_count - 1] = ret;
5787 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5789 size_t len = atom.size - sizeof(uuid);
5790 if (c->export_xmp) {
5791 buffer = av_mallocz(len + 1);
5793 return AVERROR(ENOMEM);
5795 ret = avio_read(pb, buffer, len);
5799 } else if (ret != len) {
5801 return AVERROR_INVALIDDATA;
5804 av_dict_set(&c->fc->metadata, "xmp", buffer, 0);
5807 // skip all uuid atom, which makes it fast for long uuid-xmp file
5808 ret = avio_skip(pb, len);
5812 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5813 size_t len = atom.size - sizeof(uuid);
5814 ret = mov_parse_uuid_spherical(sc, pb, len);
5818 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5824 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5827 uint8_t content[16];
5832 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5838 && !memcmp(content, "Anevia\x1A\x1A", 8)
5839 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5840 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5846 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5848 uint32_t format = avio_rl32(pb);
5849 MOVStreamContext *sc;
5853 if (c->fc->nb_streams < 1)
5855 st = c->fc->streams[c->fc->nb_streams - 1];
5860 case MKTAG('e','n','c','v'): // encrypted video
5861 case MKTAG('e','n','c','a'): // encrypted audio
5862 id = mov_codec_id(st, format);
5863 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5864 st->codecpar->codec_id != id) {
5865 av_log(c->fc, AV_LOG_WARNING,
5866 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5867 (char*)&format, st->codecpar->codec_id);
5871 st->codecpar->codec_id = id;
5872 sc->format = format;
5876 if (format != sc->format) {
5877 av_log(c->fc, AV_LOG_WARNING,
5878 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5879 (char*)&format, (char*)&sc->format);
5888 * Gets the current encryption info and associated current stream context. If
5889 * we are parsing a track fragment, this will return the specific encryption
5890 * info for this fragment; otherwise this will return the global encryption
5891 * info for the current stream.
5893 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5895 MOVFragmentStreamInfo *frag_stream_info;
5899 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5900 if (frag_stream_info) {
5901 for (i = 0; i < c->fc->nb_streams; i++) {
5902 if (c->fc->streams[i]->id == frag_stream_info->id) {
5903 st = c->fc->streams[i];
5907 if (i == c->fc->nb_streams)
5909 *sc = st->priv_data;
5911 if (!frag_stream_info->encryption_index) {
5912 // If this stream isn't encrypted, don't create the index.
5913 if (!(*sc)->cenc.default_encrypted_sample)
5915 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5916 if (!frag_stream_info->encryption_index)
5917 return AVERROR(ENOMEM);
5919 *encryption_index = frag_stream_info->encryption_index;
5922 // No current track fragment, using stream level encryption info.
5924 if (c->fc->nb_streams < 1)
5926 st = c->fc->streams[c->fc->nb_streams - 1];
5927 *sc = st->priv_data;
5929 if (!(*sc)->cenc.encryption_index) {
5930 // If this stream isn't encrypted, don't create the index.
5931 if (!(*sc)->cenc.default_encrypted_sample)
5933 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5934 if (!(*sc)->cenc.encryption_index)
5935 return AVERROR(ENOMEM);
5938 *encryption_index = (*sc)->cenc.encryption_index;
5943 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
5946 unsigned int subsample_count;
5947 AVSubsampleEncryptionInfo *subsamples;
5949 if (!sc->cenc.default_encrypted_sample) {
5950 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
5951 return AVERROR_INVALIDDATA;
5954 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
5956 return AVERROR(ENOMEM);
5958 if (sc->cenc.per_sample_iv_size != 0) {
5959 if (avio_read(pb, (*sample)->iv, sc->cenc.per_sample_iv_size) != sc->cenc.per_sample_iv_size) {
5960 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
5961 av_encryption_info_free(*sample);
5963 return AVERROR_INVALIDDATA;
5967 if (use_subsamples) {
5968 subsample_count = avio_rb16(pb);
5969 av_free((*sample)->subsamples);
5970 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
5971 if (!(*sample)->subsamples) {
5972 av_encryption_info_free(*sample);
5974 return AVERROR(ENOMEM);
5977 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
5978 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
5979 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
5982 if (pb->eof_reached) {
5983 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
5984 av_encryption_info_free(*sample);
5986 return AVERROR_INVALIDDATA;
5988 (*sample)->subsample_count = subsample_count;
5994 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5996 AVEncryptionInfo **encrypted_samples;
5997 MOVEncryptionIndex *encryption_index;
5998 MOVStreamContext *sc;
5999 int use_subsamples, ret;
6000 unsigned int sample_count, i, alloc_size = 0;
6002 ret = get_current_encryption_info(c, &encryption_index, &sc);
6006 if (encryption_index->nb_encrypted_samples) {
6007 // This can happen if we have both saio/saiz and senc atoms.
6008 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6012 avio_r8(pb); /* version */
6013 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6015 sample_count = avio_rb32(pb);
6016 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6017 return AVERROR(ENOMEM);
6019 for (i = 0; i < sample_count; i++) {
6020 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6021 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6022 min_samples * sizeof(*encrypted_samples));
6023 if (encrypted_samples) {
6024 encryption_index->encrypted_samples = encrypted_samples;
6026 ret = mov_read_sample_encryption_info(
6027 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6029 ret = AVERROR(ENOMEM);
6031 if (pb->eof_reached) {
6032 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6033 ret = AVERROR_INVALIDDATA;
6038 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6039 av_freep(&encryption_index->encrypted_samples);
6043 encryption_index->nb_encrypted_samples = sample_count;
6048 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6050 AVEncryptionInfo **sample, **encrypted_samples;
6052 size_t sample_count, sample_info_size, i;
6054 unsigned int alloc_size = 0;
6056 if (encryption_index->nb_encrypted_samples)
6058 sample_count = encryption_index->auxiliary_info_sample_count;
6059 if (encryption_index->auxiliary_offsets_count != 1) {
6060 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6061 return AVERROR_PATCHWELCOME;
6063 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6064 return AVERROR(ENOMEM);
6066 prev_pos = avio_tell(pb);
6067 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6068 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6069 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6073 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6074 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6075 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6076 min_samples * sizeof(*encrypted_samples));
6077 if (!encrypted_samples) {
6078 ret = AVERROR(ENOMEM);
6081 encryption_index->encrypted_samples = encrypted_samples;
6083 sample = &encryption_index->encrypted_samples[i];
6084 sample_info_size = encryption_index->auxiliary_info_default_size
6085 ? encryption_index->auxiliary_info_default_size
6086 : encryption_index->auxiliary_info_sizes[i];
6088 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6092 if (pb->eof_reached) {
6093 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6094 ret = AVERROR_INVALIDDATA;
6096 encryption_index->nb_encrypted_samples = sample_count;
6100 avio_seek(pb, prev_pos, SEEK_SET);
6102 for (; i > 0; i--) {
6103 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6105 av_freep(&encryption_index->encrypted_samples);
6111 * Tries to read the given number of bytes from the stream and puts it in a
6112 * newly allocated buffer. This reads in small chunks to avoid allocating large
6113 * memory if the file contains an invalid/malicious size value.
6115 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6117 const unsigned int block_size = 1024 * 1024;
6118 uint8_t *buffer = NULL;
6119 unsigned int alloc_size = 0, offset = 0;
6120 while (offset < size) {
6121 unsigned int new_size =
6122 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6123 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6124 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6127 return AVERROR(ENOMEM);
6129 buffer = new_buffer;
6131 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6133 return AVERROR_INVALIDDATA;
6142 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6144 MOVEncryptionIndex *encryption_index;
6145 MOVStreamContext *sc;
6147 unsigned int sample_count, aux_info_type, aux_info_param;
6149 ret = get_current_encryption_info(c, &encryption_index, &sc);
6153 if (encryption_index->nb_encrypted_samples) {
6154 // This can happen if we have both saio/saiz and senc atoms.
6155 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6159 if (encryption_index->auxiliary_info_sample_count) {
6160 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6161 return AVERROR_INVALIDDATA;
6164 avio_r8(pb); /* version */
6165 if (avio_rb24(pb) & 0x01) { /* flags */
6166 aux_info_type = avio_rb32(pb);
6167 aux_info_param = avio_rb32(pb);
6168 if (sc->cenc.default_encrypted_sample) {
6169 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6170 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6173 if (aux_info_param != 0) {
6174 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6178 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6179 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6180 aux_info_type == MKBETAG('c','e','n','s') ||
6181 aux_info_type == MKBETAG('c','b','c','1') ||
6182 aux_info_type == MKBETAG('c','b','c','s')) &&
6183 aux_info_param == 0) {
6184 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6185 return AVERROR_INVALIDDATA;
6190 } else if (!sc->cenc.default_encrypted_sample) {
6191 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6195 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6196 sample_count = avio_rb32(pb);
6197 encryption_index->auxiliary_info_sample_count = sample_count;
6199 if (encryption_index->auxiliary_info_default_size == 0) {
6200 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6202 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6207 if (encryption_index->auxiliary_offsets_count) {
6208 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6214 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6216 uint64_t *auxiliary_offsets;
6217 MOVEncryptionIndex *encryption_index;
6218 MOVStreamContext *sc;
6220 unsigned int version, entry_count, aux_info_type, aux_info_param;
6221 unsigned int alloc_size = 0;
6223 ret = get_current_encryption_info(c, &encryption_index, &sc);
6227 if (encryption_index->nb_encrypted_samples) {
6228 // This can happen if we have both saio/saiz and senc atoms.
6229 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6233 if (encryption_index->auxiliary_offsets_count) {
6234 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6235 return AVERROR_INVALIDDATA;
6238 version = avio_r8(pb); /* version */
6239 if (avio_rb24(pb) & 0x01) { /* flags */
6240 aux_info_type = avio_rb32(pb);
6241 aux_info_param = avio_rb32(pb);
6242 if (sc->cenc.default_encrypted_sample) {
6243 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6244 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6247 if (aux_info_param != 0) {
6248 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6252 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6253 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6254 aux_info_type == MKBETAG('c','e','n','s') ||
6255 aux_info_type == MKBETAG('c','b','c','1') ||
6256 aux_info_type == MKBETAG('c','b','c','s')) &&
6257 aux_info_param == 0) {
6258 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6259 return AVERROR_INVALIDDATA;
6264 } else if (!sc->cenc.default_encrypted_sample) {
6265 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6269 entry_count = avio_rb32(pb);
6270 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6271 return AVERROR(ENOMEM);
6273 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6274 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6275 auxiliary_offsets = av_fast_realloc(
6276 encryption_index->auxiliary_offsets, &alloc_size,
6277 min_offsets * sizeof(*auxiliary_offsets));
6278 if (!auxiliary_offsets) {
6279 av_freep(&encryption_index->auxiliary_offsets);
6280 return AVERROR(ENOMEM);
6282 encryption_index->auxiliary_offsets = auxiliary_offsets;
6285 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6287 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6289 if (c->frag_index.current >= 0) {
6290 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6294 if (pb->eof_reached) {
6295 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6296 av_freep(&encryption_index->auxiliary_offsets);
6297 return AVERROR_INVALIDDATA;
6300 encryption_index->auxiliary_offsets_count = entry_count;
6302 if (encryption_index->auxiliary_info_sample_count) {
6303 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6309 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6311 AVEncryptionInitInfo *info, *old_init_info;
6314 uint8_t *side_data, *extra_data, *old_side_data;
6315 size_t side_data_size;
6316 int ret = 0, old_side_data_size;
6317 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6319 if (c->fc->nb_streams < 1)
6321 st = c->fc->streams[c->fc->nb_streams-1];
6323 version = avio_r8(pb); /* version */
6324 avio_rb24(pb); /* flags */
6326 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6327 /* key_id_size */ 16, /* data_size */ 0);
6329 return AVERROR(ENOMEM);
6331 if (avio_read(pb, info->system_id, 16) != 16) {
6332 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6333 ret = AVERROR_INVALIDDATA;
6338 kid_count = avio_rb32(pb);
6339 if (kid_count >= INT_MAX / sizeof(*key_ids))
6340 return AVERROR(ENOMEM);
6342 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6343 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6344 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6345 min_kid_count * sizeof(*key_ids));
6347 ret = AVERROR(ENOMEM);
6350 info->key_ids = key_ids;
6352 info->key_ids[i] = av_mallocz(16);
6353 if (!info->key_ids[i]) {
6354 ret = AVERROR(ENOMEM);
6357 info->num_key_ids = i + 1;
6359 if (avio_read(pb, info->key_ids[i], 16) != 16) {
6360 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6361 ret = AVERROR_INVALIDDATA;
6366 if (pb->eof_reached) {
6367 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6368 ret = AVERROR_INVALIDDATA;
6373 extra_data_size = avio_rb32(pb);
6374 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6378 av_freep(&info->data); // malloc(0) may still allocate something.
6379 info->data = extra_data;
6380 info->data_size = extra_data_size;
6382 // If there is existing initialization data, append to the list.
6383 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6384 if (old_side_data) {
6385 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6386 if (old_init_info) {
6387 // Append to the end of the list.
6388 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6394 info = old_init_info;
6396 // Assume existing side-data will be valid, so the only error we could get is OOM.
6397 ret = AVERROR(ENOMEM);
6402 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6404 ret = AVERROR(ENOMEM);
6407 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6408 side_data, side_data_size);
6413 av_encryption_init_info_free(info);
6417 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6420 MOVStreamContext *sc;
6422 if (c->fc->nb_streams < 1)
6424 st = c->fc->streams[c->fc->nb_streams-1];
6427 if (sc->pseudo_stream_id != 0) {
6428 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6429 return AVERROR_PATCHWELCOME;
6433 return AVERROR_INVALIDDATA;
6435 avio_rb32(pb); /* version and flags */
6437 if (!sc->cenc.default_encrypted_sample) {
6438 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6439 if (!sc->cenc.default_encrypted_sample) {
6440 return AVERROR(ENOMEM);
6444 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6448 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6451 MOVStreamContext *sc;
6452 unsigned int version, pattern, is_protected, iv_size;
6454 if (c->fc->nb_streams < 1)
6456 st = c->fc->streams[c->fc->nb_streams-1];
6459 if (sc->pseudo_stream_id != 0) {
6460 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6461 return AVERROR_PATCHWELCOME;
6464 if (!sc->cenc.default_encrypted_sample) {
6465 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6466 if (!sc->cenc.default_encrypted_sample) {
6467 return AVERROR(ENOMEM);
6472 return AVERROR_INVALIDDATA;
6474 version = avio_r8(pb); /* version */
6475 avio_rb24(pb); /* flags */
6477 avio_r8(pb); /* reserved */
6478 pattern = avio_r8(pb);
6481 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6482 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6485 is_protected = avio_r8(pb);
6486 if (is_protected && !sc->cenc.encryption_index) {
6487 // The whole stream should be by-default encrypted.
6488 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6489 if (!sc->cenc.encryption_index)
6490 return AVERROR(ENOMEM);
6492 sc->cenc.per_sample_iv_size = avio_r8(pb);
6493 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6494 sc->cenc.per_sample_iv_size != 16) {
6495 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6496 return AVERROR_INVALIDDATA;
6498 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6499 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6500 return AVERROR_INVALIDDATA;
6503 if (is_protected && !sc->cenc.per_sample_iv_size) {
6504 iv_size = avio_r8(pb);
6505 if (iv_size != 8 && iv_size != 16) {
6506 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6507 return AVERROR_INVALIDDATA;
6510 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6511 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6512 return AVERROR_INVALIDDATA;
6519 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6522 int last, type, size, ret;
6525 if (c->fc->nb_streams < 1)
6527 st = c->fc->streams[c->fc->nb_streams-1];
6529 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6530 return AVERROR_INVALIDDATA;
6532 /* Check FlacSpecificBox version. */
6533 if (avio_r8(pb) != 0)
6534 return AVERROR_INVALIDDATA;
6536 avio_rb24(pb); /* Flags */
6538 avio_read(pb, buf, sizeof(buf));
6539 flac_parse_block_header(buf, &last, &type, &size);
6541 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6542 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6543 return AVERROR_INVALIDDATA;
6546 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6551 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6556 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6560 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6561 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6562 return AVERROR_PATCHWELCOME;
6565 if (!sc->cenc.aes_ctr) {
6566 /* initialize the cipher */
6567 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6568 if (!sc->cenc.aes_ctr) {
6569 return AVERROR(ENOMEM);
6572 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6578 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6580 if (!sample->subsample_count)
6582 /* decrypt the whole packet */
6583 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6587 for (i = 0; i < sample->subsample_count; i++)
6589 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6590 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6591 return AVERROR_INVALIDDATA;
6594 /* skip the clear bytes */
6595 input += sample->subsamples[i].bytes_of_clear_data;
6596 size -= sample->subsamples[i].bytes_of_clear_data;
6598 /* decrypt the encrypted bytes */
6599 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6600 input += sample->subsamples[i].bytes_of_protected_data;
6601 size -= sample->subsamples[i].bytes_of_protected_data;
6605 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6606 return AVERROR_INVALIDDATA;
6612 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6614 MOVFragmentStreamInfo *frag_stream_info;
6615 MOVEncryptionIndex *encryption_index;
6616 AVEncryptionInfo *encrypted_sample;
6617 int encrypted_index, ret;
6619 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6620 encrypted_index = current_index;
6621 encryption_index = NULL;
6622 if (frag_stream_info) {
6623 // Note this only supports encryption info in the first sample descriptor.
6624 if (mov->fragment.stsd_id == 1) {
6625 if (frag_stream_info->encryption_index) {
6626 encrypted_index = current_index - frag_stream_info->index_entry;
6627 encryption_index = frag_stream_info->encryption_index;
6629 encryption_index = sc->cenc.encryption_index;
6633 encryption_index = sc->cenc.encryption_index;
6636 if (encryption_index) {
6637 if (encryption_index->auxiliary_info_sample_count &&
6638 !encryption_index->nb_encrypted_samples) {
6639 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6640 return AVERROR_INVALIDDATA;
6642 if (encryption_index->auxiliary_offsets_count &&
6643 !encryption_index->nb_encrypted_samples) {
6644 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6645 return AVERROR_INVALIDDATA;
6648 if (!encryption_index->nb_encrypted_samples) {
6649 // Full-sample encryption with default settings.
6650 encrypted_sample = sc->cenc.default_encrypted_sample;
6651 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6652 // Per-sample setting override.
6653 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6655 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6656 return AVERROR_INVALIDDATA;
6659 if (mov->decryption_key) {
6660 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6663 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6665 return AVERROR(ENOMEM);
6666 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6676 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6678 const int OPUS_SEEK_PREROLL_MS = 80;
6683 if (c->fc->nb_streams < 1)
6685 st = c->fc->streams[c->fc->nb_streams-1];
6687 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6688 return AVERROR_INVALIDDATA;
6690 /* Check OpusSpecificBox version. */
6691 if (avio_r8(pb) != 0) {
6692 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6693 return AVERROR_INVALIDDATA;
6696 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6697 size = atom.size + 8;
6699 if (ff_alloc_extradata(st->codecpar, size))
6700 return AVERROR(ENOMEM);
6702 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6703 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6704 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6705 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6707 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6708 little-endian; aside from the preceeding magic and version they're
6709 otherwise currently identical. Data after output gain at offset 16
6710 doesn't need to be bytewapped. */
6711 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6712 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6713 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6714 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6716 st->codecpar->initial_padding = pre_skip;
6717 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6718 (AVRational){1, 1000},
6719 (AVRational){1, 48000});
6724 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6727 unsigned format_info;
6728 int channel_assignment, channel_assignment1, channel_assignment2;
6731 if (c->fc->nb_streams < 1)
6733 st = c->fc->streams[c->fc->nb_streams-1];
6736 return AVERROR_INVALIDDATA;
6738 format_info = avio_rb32(pb);
6740 ratebits = (format_info >> 28) & 0xF;
6741 channel_assignment1 = (format_info >> 15) & 0x1F;
6742 channel_assignment2 = format_info & 0x1FFF;
6743 if (channel_assignment2)
6744 channel_assignment = channel_assignment2;
6746 channel_assignment = channel_assignment1;
6748 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6749 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6750 st->codecpar->channels = truehd_channels(channel_assignment);
6751 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6756 static const MOVParseTableEntry mov_default_parse_table[] = {
6757 { MKTAG('A','C','L','R'), mov_read_aclr },
6758 { MKTAG('A','P','R','G'), mov_read_avid },
6759 { MKTAG('A','A','L','P'), mov_read_avid },
6760 { MKTAG('A','R','E','S'), mov_read_ares },
6761 { MKTAG('a','v','s','s'), mov_read_avss },
6762 { MKTAG('a','v','1','C'), mov_read_av1c },
6763 { MKTAG('c','h','p','l'), mov_read_chpl },
6764 { MKTAG('c','o','6','4'), mov_read_stco },
6765 { MKTAG('c','o','l','r'), mov_read_colr },
6766 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6767 { MKTAG('d','i','n','f'), mov_read_default },
6768 { MKTAG('D','p','x','E'), mov_read_dpxe },
6769 { MKTAG('d','r','e','f'), mov_read_dref },
6770 { MKTAG('e','d','t','s'), mov_read_default },
6771 { MKTAG('e','l','s','t'), mov_read_elst },
6772 { MKTAG('e','n','d','a'), mov_read_enda },
6773 { MKTAG('f','i','e','l'), mov_read_fiel },
6774 { MKTAG('a','d','r','m'), mov_read_adrm },
6775 { MKTAG('f','t','y','p'), mov_read_ftyp },
6776 { MKTAG('g','l','b','l'), mov_read_glbl },
6777 { MKTAG('h','d','l','r'), mov_read_hdlr },
6778 { MKTAG('i','l','s','t'), mov_read_ilst },
6779 { MKTAG('j','p','2','h'), mov_read_jp2h },
6780 { MKTAG('m','d','a','t'), mov_read_mdat },
6781 { MKTAG('m','d','h','d'), mov_read_mdhd },
6782 { MKTAG('m','d','i','a'), mov_read_default },
6783 { MKTAG('m','e','t','a'), mov_read_meta },
6784 { MKTAG('m','i','n','f'), mov_read_default },
6785 { MKTAG('m','o','o','f'), mov_read_moof },
6786 { MKTAG('m','o','o','v'), mov_read_moov },
6787 { MKTAG('m','v','e','x'), mov_read_default },
6788 { MKTAG('m','v','h','d'), mov_read_mvhd },
6789 { MKTAG('S','M','I',' '), mov_read_svq3 },
6790 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6791 { MKTAG('a','v','c','C'), mov_read_glbl },
6792 { MKTAG('p','a','s','p'), mov_read_pasp },
6793 { MKTAG('s','i','d','x'), mov_read_sidx },
6794 { MKTAG('s','t','b','l'), mov_read_default },
6795 { MKTAG('s','t','c','o'), mov_read_stco },
6796 { MKTAG('s','t','p','s'), mov_read_stps },
6797 { MKTAG('s','t','r','f'), mov_read_strf },
6798 { MKTAG('s','t','s','c'), mov_read_stsc },
6799 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6800 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6801 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6802 { MKTAG('s','t','t','s'), mov_read_stts },
6803 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6804 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
6805 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6806 { MKTAG('t','f','d','t'), mov_read_tfdt },
6807 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6808 { MKTAG('t','r','a','k'), mov_read_trak },
6809 { MKTAG('t','r','a','f'), mov_read_default },
6810 { MKTAG('t','r','e','f'), mov_read_default },
6811 { MKTAG('t','m','c','d'), mov_read_tmcd },
6812 { MKTAG('c','h','a','p'), mov_read_chap },
6813 { MKTAG('t','r','e','x'), mov_read_trex },
6814 { MKTAG('t','r','u','n'), mov_read_trun },
6815 { MKTAG('u','d','t','a'), mov_read_default },
6816 { MKTAG('w','a','v','e'), mov_read_wave },
6817 { MKTAG('e','s','d','s'), mov_read_esds },
6818 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6819 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6820 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6821 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6822 { MKTAG('w','f','e','x'), mov_read_wfex },
6823 { MKTAG('c','m','o','v'), mov_read_cmov },
6824 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6825 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6826 { MKTAG('s','b','g','p'), mov_read_sbgp },
6827 { MKTAG('h','v','c','C'), mov_read_glbl },
6828 { MKTAG('u','u','i','d'), mov_read_uuid },
6829 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6830 { MKTAG('f','r','e','e'), mov_read_free },
6831 { MKTAG('-','-','-','-'), mov_read_custom },
6832 { MKTAG('s','i','n','f'), mov_read_default },
6833 { MKTAG('f','r','m','a'), mov_read_frma },
6834 { MKTAG('s','e','n','c'), mov_read_senc },
6835 { MKTAG('s','a','i','z'), mov_read_saiz },
6836 { MKTAG('s','a','i','o'), mov_read_saio },
6837 { MKTAG('p','s','s','h'), mov_read_pssh },
6838 { MKTAG('s','c','h','m'), mov_read_schm },
6839 { MKTAG('s','c','h','i'), mov_read_default },
6840 { MKTAG('t','e','n','c'), mov_read_tenc },
6841 { MKTAG('d','f','L','a'), mov_read_dfla },
6842 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6843 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6844 { MKTAG('d','O','p','s'), mov_read_dops },
6845 { MKTAG('d','m','l','p'), mov_read_dmlp },
6846 { MKTAG('S','m','D','m'), mov_read_smdm },
6847 { MKTAG('C','o','L','L'), mov_read_coll },
6848 { MKTAG('v','p','c','C'), mov_read_vpcc },
6849 { MKTAG('m','d','c','v'), mov_read_mdcv },
6850 { MKTAG('c','l','l','i'), mov_read_clli },
6854 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6856 int64_t total_size = 0;
6860 if (c->atom_depth > 10) {
6861 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6862 return AVERROR_INVALIDDATA;
6867 atom.size = INT64_MAX;
6868 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6869 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
6872 if (atom.size >= 8) {
6873 a.size = avio_rb32(pb);
6874 a.type = avio_rl32(pb);
6875 if (a.type == MKTAG('f','r','e','e') &&
6877 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT &&
6880 uint32_t *type = (uint32_t *)buf + 1;
6881 if (avio_read(pb, buf, 8) != 8)
6882 return AVERROR_INVALIDDATA;
6883 avio_seek(pb, -8, SEEK_CUR);
6884 if (*type == MKTAG('m','v','h','d') ||
6885 *type == MKTAG('c','m','o','v')) {
6886 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free atom.\n");
6887 a.type = MKTAG('m','o','o','v');
6890 if (atom.type != MKTAG('r','o','o','t') &&
6891 atom.type != MKTAG('m','o','o','v'))
6893 if (a.type == MKTAG('t','r','a','k') || a.type == MKTAG('m','d','a','t'))
6895 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
6902 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
6903 a.size = avio_rb64(pb) - 8;
6907 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
6908 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
6910 a.size = atom.size - total_size + 8;
6915 a.size = FFMIN(a.size, atom.size - total_size);
6917 for (i = 0; mov_default_parse_table[i].type; i++)
6918 if (mov_default_parse_table[i].type == a.type) {
6919 parse = mov_default_parse_table[i].parse;
6923 // container is user data
6924 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
6925 atom.type == MKTAG('i','l','s','t')))
6926 parse = mov_read_udta_string;
6928 // Supports parsing the QuickTime Metadata Keys.
6929 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
6930 if (!parse && c->found_hdlr_mdta &&
6931 atom.type == MKTAG('m','e','t','a') &&
6932 a.type == MKTAG('k','e','y','s')) {
6933 parse = mov_read_keys;
6936 if (!parse) { /* skip leaf atoms data */
6937 avio_skip(pb, a.size);
6939 int64_t start_pos = avio_tell(pb);
6941 int err = parse(c, pb, a);
6946 if (c->found_moov && c->found_mdat &&
6947 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
6948 start_pos + a.size == avio_size(pb))) {
6949 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
6950 c->next_root_atom = start_pos + a.size;
6954 left = a.size - avio_tell(pb) + start_pos;
6955 if (left > 0) /* skip garbage at atom end */
6956 avio_skip(pb, left);
6957 else if (left < 0) {
6958 av_log(c->fc, AV_LOG_WARNING,
6959 "overread end of atom '%.4s' by %"PRId64" bytes\n",
6960 (char*)&a.type, -left);
6961 avio_seek(pb, left, SEEK_CUR);
6965 total_size += a.size;
6968 if (total_size < atom.size && atom.size < 0x7ffff)
6969 avio_skip(pb, atom.size - total_size);
6975 static int mov_probe(const AVProbeData *p)
6980 int moov_offset = -1;
6982 /* check file header */
6985 /* ignore invalid offset */
6986 if ((offset + 8) > (unsigned int)p->buf_size)
6988 tag = AV_RL32(p->buf + offset + 4);
6990 /* check for obvious tags */
6991 case MKTAG('m','o','o','v'):
6992 moov_offset = offset + 4;
6993 case MKTAG('m','d','a','t'):
6994 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
6995 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
6996 case MKTAG('f','t','y','p'):
6997 if (AV_RB32(p->buf+offset) < 8 &&
6998 (AV_RB32(p->buf+offset) != 1 ||
6999 offset + 12 > (unsigned int)p->buf_size ||
7000 AV_RB64(p->buf+offset + 8) == 0)) {
7001 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7002 } else if (tag == MKTAG('f','t','y','p') &&
7003 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
7004 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
7006 score = FFMAX(score, 5);
7008 score = AVPROBE_SCORE_MAX;
7010 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7012 /* those are more common words, so rate then a bit less */
7013 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
7014 case MKTAG('w','i','d','e'):
7015 case MKTAG('f','r','e','e'):
7016 case MKTAG('j','u','n','k'):
7017 case MKTAG('p','i','c','t'):
7018 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
7019 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7021 case MKTAG(0x82,0x82,0x7f,0x7d):
7022 case MKTAG('s','k','i','p'):
7023 case MKTAG('u','u','i','d'):
7024 case MKTAG('p','r','f','l'):
7025 /* if we only find those cause probedata is too small at least rate them */
7026 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7027 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7030 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7033 if(score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
7034 /* moov atom in the header - we should make sure that this is not a
7035 * MOV-packed MPEG-PS */
7036 offset = moov_offset;
7038 while(offset < (p->buf_size - 16)){ /* Sufficient space */
7039 /* We found an actual hdlr atom */
7040 if(AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7041 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7042 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')){
7043 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7044 /* We found a media handler reference atom describing an
7045 * MPEG-PS-in-MOV, return a
7046 * low score to force expanding the probe window until
7047 * mpegps_probe finds what it needs */
7058 // must be done after parsing all trak because there's no order requirement
7059 static void mov_read_chapters(AVFormatContext *s)
7061 MOVContext *mov = s->priv_data;
7063 MOVStreamContext *sc;
7068 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7069 chapter_track = mov->chapter_tracks[j];
7071 for (i = 0; i < s->nb_streams; i++)
7072 if (s->streams[i]->id == chapter_track) {
7077 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7082 cur_pos = avio_tell(sc->pb);
7084 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7085 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7086 if (st->nb_index_entries) {
7087 // Retrieve the first frame, if possible
7089 AVIndexEntry *sample = &st->index_entries[0];
7090 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7091 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7095 if (av_get_packet(sc->pb, &pkt, sample->size) < 0)
7098 st->attached_pic = pkt;
7099 st->attached_pic.stream_index = st->index;
7100 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
7103 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7104 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7105 st->discard = AVDISCARD_ALL;
7106 for (i = 0; i < st->nb_index_entries; i++) {
7107 AVIndexEntry *sample = &st->index_entries[i];
7108 int64_t end = i+1 < st->nb_index_entries ? st->index_entries[i+1].timestamp : st->duration;
7113 if (end < sample->timestamp) {
7114 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7115 end = AV_NOPTS_VALUE;
7118 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7119 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7123 // the first two bytes are the length of the title
7124 len = avio_rb16(sc->pb);
7125 if (len > sample->size-2)
7127 title_len = 2*len + 1;
7128 if (!(title = av_mallocz(title_len)))
7131 // The samples could theoretically be in any encoding if there's an encd
7132 // atom following, but in practice are only utf-8 or utf-16, distinguished
7133 // instead by the presence of a BOM
7137 ch = avio_rb16(sc->pb);
7139 avio_get_str16be(sc->pb, len, title, title_len);
7140 else if (ch == 0xfffe)
7141 avio_get_str16le(sc->pb, len, title, title_len);
7144 if (len == 1 || len == 2)
7147 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7151 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7156 avio_seek(sc->pb, cur_pos, SEEK_SET);
7160 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7161 uint32_t value, int flags)
7164 char buf[AV_TIMECODE_STR_SIZE];
7165 AVRational rate = st->avg_frame_rate;
7166 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7169 av_dict_set(&st->metadata, "timecode",
7170 av_timecode_make_string(&tc, buf, value), 0);
7174 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7176 MOVStreamContext *sc = st->priv_data;
7177 char buf[AV_TIMECODE_STR_SIZE];
7178 int64_t cur_pos = avio_tell(sc->pb);
7179 int hh, mm, ss, ff, drop;
7181 if (!st->nb_index_entries)
7184 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7185 avio_skip(s->pb, 13);
7186 hh = avio_r8(s->pb);
7187 mm = avio_r8(s->pb);
7188 ss = avio_r8(s->pb);
7189 drop = avio_r8(s->pb);
7190 ff = avio_r8(s->pb);
7191 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7192 hh, mm, ss, drop ? ';' : ':', ff);
7193 av_dict_set(&st->metadata, "timecode", buf, 0);
7195 avio_seek(sc->pb, cur_pos, SEEK_SET);
7199 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7201 MOVStreamContext *sc = st->priv_data;
7203 int64_t cur_pos = avio_tell(sc->pb);
7206 if (!st->nb_index_entries)
7209 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7210 value = avio_rb32(s->pb);
7212 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7213 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7214 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7216 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7217 * not the case) and thus assume "frame number format" instead of QT one.
7218 * No sample with tmcd track can be found with a QT timecode at the moment,
7219 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7221 parse_timecode_in_framenum_format(s, st, value, flags);
7223 avio_seek(sc->pb, cur_pos, SEEK_SET);
7227 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7229 if (!index || !*index) return;
7230 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7231 av_encryption_info_free((*index)->encrypted_samples[i]);
7233 av_freep(&(*index)->encrypted_samples);
7234 av_freep(&(*index)->auxiliary_info_sizes);
7235 av_freep(&(*index)->auxiliary_offsets);
7239 static int mov_read_close(AVFormatContext *s)
7241 MOVContext *mov = s->priv_data;
7244 for (i = 0; i < s->nb_streams; i++) {
7245 AVStream *st = s->streams[i];
7246 MOVStreamContext *sc = st->priv_data;
7251 av_freep(&sc->ctts_data);
7252 for (j = 0; j < sc->drefs_count; j++) {
7253 av_freep(&sc->drefs[j].path);
7254 av_freep(&sc->drefs[j].dir);
7256 av_freep(&sc->drefs);
7258 sc->drefs_count = 0;
7260 if (!sc->pb_is_copied)
7261 ff_format_io_close(s, &sc->pb);
7264 av_freep(&sc->chunk_offsets);
7265 av_freep(&sc->stsc_data);
7266 av_freep(&sc->sample_sizes);
7267 av_freep(&sc->keyframes);
7268 av_freep(&sc->stts_data);
7269 av_freep(&sc->sdtp_data);
7270 av_freep(&sc->stps_data);
7271 av_freep(&sc->elst_data);
7272 av_freep(&sc->rap_group);
7273 av_freep(&sc->display_matrix);
7274 av_freep(&sc->index_ranges);
7277 for (j = 0; j < sc->stsd_count; j++)
7278 av_free(sc->extradata[j]);
7279 av_freep(&sc->extradata);
7280 av_freep(&sc->extradata_size);
7282 mov_free_encryption_index(&sc->cenc.encryption_index);
7283 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7284 av_aes_ctr_free(sc->cenc.aes_ctr);
7286 av_freep(&sc->stereo3d);
7287 av_freep(&sc->spherical);
7288 av_freep(&sc->mastering);
7289 av_freep(&sc->coll);
7292 if (mov->dv_demux) {
7293 avformat_free_context(mov->dv_fctx);
7294 mov->dv_fctx = NULL;
7297 if (mov->meta_keys) {
7298 for (i = 1; i < mov->meta_keys_count; i++) {
7299 av_freep(&mov->meta_keys[i]);
7301 av_freep(&mov->meta_keys);
7304 av_freep(&mov->trex_data);
7305 av_freep(&mov->bitrates);
7307 for (i = 0; i < mov->frag_index.nb_items; i++) {
7308 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7309 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7310 mov_free_encryption_index(&frag[j].encryption_index);
7312 av_freep(&mov->frag_index.item[i].stream_info);
7314 av_freep(&mov->frag_index.item);
7316 av_freep(&mov->aes_decrypt);
7317 av_freep(&mov->chapter_tracks);
7322 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7326 for (i = 0; i < s->nb_streams; i++) {
7327 AVStream *st = s->streams[i];
7328 MOVStreamContext *sc = st->priv_data;
7330 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7331 sc->timecode_track == tmcd_id)
7337 /* look for a tmcd track not referenced by any video track, and export it globally */
7338 static void export_orphan_timecode(AVFormatContext *s)
7342 for (i = 0; i < s->nb_streams; i++) {
7343 AVStream *st = s->streams[i];
7345 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7346 !tmcd_is_referenced(s, i + 1)) {
7347 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7349 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7356 static int read_tfra(MOVContext *mov, AVIOContext *f)
7358 int version, fieldlength, i, j;
7359 int64_t pos = avio_tell(f);
7360 uint32_t size = avio_rb32(f);
7361 unsigned track_id, item_count;
7363 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7366 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7368 version = avio_r8(f);
7370 track_id = avio_rb32(f);
7371 fieldlength = avio_rb32(f);
7372 item_count = avio_rb32(f);
7373 for (i = 0; i < item_count; i++) {
7374 int64_t time, offset;
7376 MOVFragmentStreamInfo * frag_stream_info;
7379 return AVERROR_INVALIDDATA;
7383 time = avio_rb64(f);
7384 offset = avio_rb64(f);
7386 time = avio_rb32(f);
7387 offset = avio_rb32(f);
7390 // The first sample of each stream in a fragment is always a random
7391 // access sample. So it's entry in the tfra can be used as the
7392 // initial PTS of the fragment.
7393 index = update_frag_index(mov, offset);
7394 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7395 if (frag_stream_info &&
7396 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7397 frag_stream_info->first_tfra_pts = time;
7399 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7401 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7403 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7407 avio_seek(f, pos + size, SEEK_SET);
7411 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7413 int64_t stream_size = avio_size(f);
7414 int64_t original_pos = avio_tell(f);
7418 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7422 mfra_size = avio_rb32(f);
7423 if (mfra_size < 0 || mfra_size > stream_size) {
7424 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7427 if ((seek_ret = avio_seek(f, -mfra_size, SEEK_CUR)) < 0) {
7431 if (avio_rb32(f) != mfra_size) {
7432 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7435 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7436 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7439 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7441 ret = read_tfra(c, f);
7447 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7449 av_log(c->fc, AV_LOG_ERROR,
7450 "failed to seek back after looking for mfra\n");
7456 static int mov_read_header(AVFormatContext *s)
7458 MOVContext *mov = s->priv_data;
7459 AVIOContext *pb = s->pb;
7461 MOVAtom atom = { AV_RL32("root") };
7464 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7465 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7466 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7467 return AVERROR(EINVAL);
7471 mov->trak_index = -1;
7472 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7473 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7474 atom.size = avio_size(pb);
7476 atom.size = INT64_MAX;
7478 /* check MOV header */
7480 if (mov->moov_retry)
7481 avio_seek(pb, 0, SEEK_SET);
7482 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7483 av_log(s, AV_LOG_ERROR, "error reading header\n");
7487 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7488 if (!mov->found_moov) {
7489 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7491 return AVERROR_INVALIDDATA;
7493 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7495 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7496 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7497 mov_read_chapters(s);
7498 for (i = 0; i < s->nb_streams; i++)
7499 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7500 mov_read_timecode_track(s, s->streams[i]);
7501 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7502 mov_read_rtmd_track(s, s->streams[i]);
7506 /* copy timecode metadata from tmcd tracks to the related video streams */
7507 for (i = 0; i < s->nb_streams; i++) {
7508 AVStream *st = s->streams[i];
7509 MOVStreamContext *sc = st->priv_data;
7510 if (sc->timecode_track > 0) {
7511 AVDictionaryEntry *tcr;
7512 int tmcd_st_id = -1;
7514 for (j = 0; j < s->nb_streams; j++)
7515 if (s->streams[j]->id == sc->timecode_track)
7518 if (tmcd_st_id < 0 || tmcd_st_id == i)
7520 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7522 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7525 export_orphan_timecode(s);
7527 for (i = 0; i < s->nb_streams; i++) {
7528 AVStream *st = s->streams[i];
7529 MOVStreamContext *sc = st->priv_data;
7530 fix_timescale(mov, sc);
7531 if(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7532 st->skip_samples = sc->start_pad;
7534 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7535 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7536 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7537 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7538 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7539 st->codecpar->width = sc->width;
7540 st->codecpar->height = sc->height;
7542 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7543 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7547 if (mov->handbrake_version &&
7548 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7549 st->codecpar->codec_id == AV_CODEC_ID_MP3
7551 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7552 st->need_parsing = AVSTREAM_PARSE_FULL;
7556 if (mov->trex_data) {
7557 for (i = 0; i < s->nb_streams; i++) {
7558 AVStream *st = s->streams[i];
7559 MOVStreamContext *sc = st->priv_data;
7560 if (st->duration > 0) {
7561 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7562 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7563 sc->data_size, sc->time_scale);
7565 return AVERROR_INVALIDDATA;
7567 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7572 if (mov->use_mfra_for > 0) {
7573 for (i = 0; i < s->nb_streams; i++) {
7574 AVStream *st = s->streams[i];
7575 MOVStreamContext *sc = st->priv_data;
7576 if (sc->duration_for_fps > 0) {
7577 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7578 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7579 sc->data_size, sc->time_scale);
7581 return AVERROR_INVALIDDATA;
7583 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7584 sc->duration_for_fps;
7589 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7590 if (mov->bitrates[i]) {
7591 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7595 ff_rfps_calculate(s);
7597 for (i = 0; i < s->nb_streams; i++) {
7598 AVStream *st = s->streams[i];
7599 MOVStreamContext *sc = st->priv_data;
7601 switch (st->codecpar->codec_type) {
7602 case AVMEDIA_TYPE_AUDIO:
7603 err = ff_replaygain_export(st, s->metadata);
7609 case AVMEDIA_TYPE_VIDEO:
7610 if (sc->display_matrix) {
7611 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7612 sizeof(int32_t) * 9);
7616 sc->display_matrix = NULL;
7619 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7620 (uint8_t *)sc->stereo3d,
7621 sizeof(*sc->stereo3d));
7625 sc->stereo3d = NULL;
7627 if (sc->spherical) {
7628 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7629 (uint8_t *)sc->spherical,
7630 sc->spherical_size);
7634 sc->spherical = NULL;
7636 if (sc->mastering) {
7637 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7638 (uint8_t *)sc->mastering,
7639 sizeof(*sc->mastering));
7643 sc->mastering = NULL;
7646 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7647 (uint8_t *)sc->coll,
7657 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7659 for (i = 0; i < mov->frag_index.nb_items; i++)
7660 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7661 mov->frag_index.item[i].headers_read = 1;
7666 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7668 AVIndexEntry *sample = NULL;
7669 int64_t best_dts = INT64_MAX;
7671 for (i = 0; i < s->nb_streams; i++) {
7672 AVStream *avst = s->streams[i];
7673 MOVStreamContext *msc = avst->priv_data;
7674 if (msc->pb && msc->current_sample < avst->nb_index_entries) {
7675 AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample];
7676 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7677 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7678 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7679 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7680 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb &&
7681 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7682 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7683 sample = current_sample;
7692 static int should_retry(AVIOContext *pb, int error_code) {
7693 if (error_code == AVERROR_EOF || avio_feof(pb))
7699 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7702 MOVContext *mov = s->priv_data;
7704 if (index >= 0 && index < mov->frag_index.nb_items)
7705 target = mov->frag_index.item[index].moof_offset;
7706 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7707 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7708 return AVERROR_INVALIDDATA;
7711 mov->next_root_atom = 0;
7712 if (index < 0 || index >= mov->frag_index.nb_items)
7713 index = search_frag_moof_offset(&mov->frag_index, target);
7714 if (index < mov->frag_index.nb_items) {
7715 if (index + 1 < mov->frag_index.nb_items)
7716 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7717 if (mov->frag_index.item[index].headers_read)
7719 mov->frag_index.item[index].headers_read = 1;
7722 mov->found_mdat = 0;
7724 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7727 if (avio_feof(s->pb))
7729 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7734 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7736 uint8_t *side, *extradata;
7739 /* Save the current index. */
7740 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7742 /* Notify the decoder that extradata changed. */
7743 extradata_size = sc->extradata_size[sc->last_stsd_index];
7744 extradata = sc->extradata[sc->last_stsd_index];
7745 if (extradata_size > 0 && extradata) {
7746 side = av_packet_new_side_data(pkt,
7747 AV_PKT_DATA_NEW_EXTRADATA,
7750 return AVERROR(ENOMEM);
7751 memcpy(side, extradata, extradata_size);
7757 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7759 MOVContext *mov = s->priv_data;
7760 MOVStreamContext *sc;
7761 AVIndexEntry *sample;
7762 AVStream *st = NULL;
7763 int64_t current_index;
7767 sample = mov_find_next_sample(s, &st);
7768 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7769 if (!mov->next_root_atom)
7771 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7776 /* must be done just before reading, to avoid infinite loop on sample */
7777 current_index = sc->current_index;
7778 mov_current_sample_inc(sc);
7780 if (mov->next_root_atom) {
7781 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7782 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7785 if (st->discard != AVDISCARD_ALL) {
7786 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7787 if (ret64 != sample->pos) {
7788 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7789 sc->ffindex, sample->pos);
7790 if (should_retry(sc->pb, ret64)) {
7791 mov_current_sample_dec(sc);
7793 return AVERROR_INVALIDDATA;
7796 if( st->discard == AVDISCARD_NONKEY && 0==(sample->flags & AVINDEX_KEYFRAME) ) {
7797 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7801 ret = av_get_packet(sc->pb, pkt, sample->size);
7803 if (should_retry(sc->pb, ret)) {
7804 mov_current_sample_dec(sc);
7808 if (sc->has_palette) {
7811 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7813 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7815 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7816 sc->has_palette = 0;
7819 #if CONFIG_DV_DEMUXER
7820 if (mov->dv_demux && sc->dv_audio_container) {
7821 avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7822 av_freep(&pkt->data);
7824 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7829 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7830 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7831 st->need_parsing = AVSTREAM_PARSE_FULL;
7835 pkt->stream_index = sc->ffindex;
7836 pkt->dts = sample->timestamp;
7837 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7838 pkt->flags |= AV_PKT_FLAG_DISCARD;
7840 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7841 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
7842 /* update ctts context */
7844 if (sc->ctts_index < sc->ctts_count &&
7845 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
7847 sc->ctts_sample = 0;
7850 int64_t next_dts = (sc->current_sample < st->nb_index_entries) ?
7851 st->index_entries[sc->current_sample].timestamp : st->duration;
7853 if (next_dts >= pkt->dts)
7854 pkt->duration = next_dts - pkt->dts;
7855 pkt->pts = pkt->dts;
7857 if (st->discard == AVDISCARD_ALL)
7859 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
7860 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
7861 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
7862 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
7864 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
7865 pkt->pos = sample->pos;
7867 /* Multiple stsd handling. */
7868 if (sc->stsc_data) {
7869 /* Keep track of the stsc index for the given sample, then check
7870 * if the stsd index is different from the last used one. */
7872 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
7873 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
7875 sc->stsc_sample = 0;
7876 /* Do not check indexes after a switch. */
7877 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
7878 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
7879 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
7880 ret = mov_change_extradata(sc, pkt);
7887 aax_filter(pkt->data, pkt->size, mov);
7889 ret = cenc_filter(mov, st, sc, pkt, current_index);
7891 av_packet_unref(pkt);
7898 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
7900 MOVContext *mov = s->priv_data;
7903 if (!mov->frag_index.complete)
7906 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
7909 if (!mov->frag_index.item[index].headers_read)
7910 return mov_switch_root(s, -1, index);
7911 if (index + 1 < mov->frag_index.nb_items)
7912 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7917 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
7919 MOVStreamContext *sc = st->priv_data;
7920 int sample, time_sample, ret;
7923 // Here we consider timestamp to be PTS, hence try to offset it so that we
7924 // can search over the DTS timeline.
7925 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
7927 ret = mov_seek_fragment(s, st, timestamp);
7931 sample = av_index_search_timestamp(st, timestamp, flags);
7932 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
7933 if (sample < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp)
7935 if (sample < 0) /* not sure what to do */
7936 return AVERROR_INVALIDDATA;
7937 mov_current_sample_set(sc, sample);
7938 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
7939 /* adjust ctts index */
7940 if (sc->ctts_data) {
7942 for (i = 0; i < sc->ctts_count; i++) {
7943 int next = time_sample + sc->ctts_data[i].count;
7944 if (next > sc->current_sample) {
7946 sc->ctts_sample = sc->current_sample - time_sample;
7953 /* adjust stsd index */
7954 if (sc->chunk_count) {
7956 for (i = 0; i < sc->stsc_count; i++) {
7957 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
7958 if (next > sc->current_sample) {
7960 sc->stsc_sample = sc->current_sample - time_sample;
7963 av_assert0(next == (int)next);
7971 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
7973 MOVContext *mc = s->priv_data;
7978 if (stream_index >= s->nb_streams)
7979 return AVERROR_INVALIDDATA;
7981 st = s->streams[stream_index];
7982 sample = mov_seek_stream(s, st, sample_time, flags);
7986 if (mc->seek_individually) {
7987 /* adjust seek timestamp to found sample timestamp */
7988 int64_t seek_timestamp = st->index_entries[sample].timestamp;
7990 for (i = 0; i < s->nb_streams; i++) {
7992 MOVStreamContext *sc = s->streams[i]->priv_data;
7994 st->skip_samples = (sample_time <= 0) ? sc->start_pad : 0;
7996 if (stream_index == i)
7999 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
8000 mov_seek_stream(s, st, timestamp, flags);
8003 for (i = 0; i < s->nb_streams; i++) {
8004 MOVStreamContext *sc;
8007 mov_current_sample_set(sc, 0);
8010 MOVStreamContext *sc;
8011 AVIndexEntry *entry = mov_find_next_sample(s, &st);
8013 return AVERROR_INVALIDDATA;
8015 if (sc->ffindex == stream_index && sc->current_sample == sample)
8017 mov_current_sample_inc(sc);
8023 #define OFFSET(x) offsetof(MOVContext, x)
8024 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
8025 static const AVOption mov_options[] = {
8026 {"use_absolute_path",
8027 "allow using absolute path when opening alias, this is a possible security issue",
8028 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
8030 {"seek_streams_individually",
8031 "Seek each stream individually to the closest point",
8032 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
8034 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
8036 {"advanced_editlist",
8037 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
8038 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
8040 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8043 "use mfra for fragment timestamps",
8044 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8045 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8047 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8048 FLAGS, "use_mfra_for" },
8049 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8050 FLAGS, "use_mfra_for" },
8051 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8052 FLAGS, "use_mfra_for" },
8053 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8054 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8055 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8056 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8057 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8058 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8059 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8060 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8061 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8062 .flags = AV_OPT_FLAG_DECODING_PARAM },
8063 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8064 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8065 {.i64 = 0}, 0, 1, FLAGS },
8070 static const AVClass mov_class = {
8071 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8072 .item_name = av_default_item_name,
8073 .option = mov_options,
8074 .version = LIBAVUTIL_VERSION_INT,
8077 AVInputFormat ff_mov_demuxer = {
8078 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8079 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8080 .priv_class = &mov_class,
8081 .priv_data_size = sizeof(MOVContext),
8082 .extensions = "mov,mp4,m4a,3gp,3g2,mj2",
8083 .read_probe = mov_probe,
8084 .read_header = mov_read_header,
8085 .read_packet = mov_read_packet,
8086 .read_close = mov_read_close,
8087 .read_seek = mov_read_seek,
8088 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,