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"
54 #include "avio_internal.h"
57 #include "libavcodec/get_bits.h"
60 #include "replaygain.h"
66 #include "qtpalette.h"
68 /* those functions parse an atom */
69 /* links atom IDs to parse functions */
70 typedef struct MOVParseTableEntry {
72 int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
75 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
76 static int mov_read_mfra(MOVContext *c, AVIOContext *f);
77 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
78 int count, int duration);
80 static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb,
81 unsigned len, const char *key)
85 short current, total = 0;
86 avio_rb16(pb); // unknown
87 current = avio_rb16(pb);
89 total = avio_rb16(pb);
91 snprintf(buf, sizeof(buf), "%d", current);
93 snprintf(buf, sizeof(buf), "%d/%d", current, total);
94 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
95 av_dict_set(&c->fc->metadata, key, buf, 0);
100 static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb,
101 unsigned len, const char *key)
103 /* bypass padding bytes */
108 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
109 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
114 static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb,
115 unsigned len, const char *key)
117 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
118 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
123 static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb,
124 unsigned len, const char *key)
128 avio_r8(pb); // unknown
131 if (genre < 1 || genre > ID3v1_GENRE_MAX)
133 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
134 av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
139 static const uint32_t mac_to_unicode[128] = {
140 0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
141 0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
142 0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
143 0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
144 0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
145 0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
146 0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
147 0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
148 0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
149 0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
150 0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
151 0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
152 0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
153 0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
154 0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
155 0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
158 static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len,
159 char *dst, int dstlen)
162 char *end = dst+dstlen-1;
165 for (i = 0; i < len; i++) {
166 uint8_t t, c = avio_r8(pb);
174 PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
180 static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
184 MOVStreamContext *sc;
189 case 0xd: id = AV_CODEC_ID_MJPEG; break;
190 case 0xe: id = AV_CODEC_ID_PNG; break;
191 case 0x1b: id = AV_CODEC_ID_BMP; break;
193 av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
198 st = avformat_new_stream(c->fc, NULL);
200 return AVERROR(ENOMEM);
201 sc = av_mallocz(sizeof(*sc));
203 return AVERROR(ENOMEM);
206 ret = av_get_packet(pb, &pkt, len);
210 if (pkt.size >= 8 && id != AV_CODEC_ID_BMP) {
211 if (AV_RB64(pkt.data) == 0x89504e470d0a1a0a) {
212 id = AV_CODEC_ID_PNG;
214 id = AV_CODEC_ID_MJPEG;
218 st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
220 st->attached_pic = pkt;
221 st->attached_pic.stream_index = st->index;
222 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
224 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
225 st->codecpar->codec_id = id;
231 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
233 char language[4] = { 0 };
234 char buf[200], place[100];
235 uint16_t langcode = 0;
236 double longitude, latitude, altitude;
237 const char *key = "location";
239 if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
240 av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
241 return AVERROR_INVALIDDATA;
244 avio_skip(pb, 4); // version+flags
245 langcode = avio_rb16(pb);
246 ff_mov_lang_to_iso639(langcode, language);
249 len -= avio_get_str(pb, len, place, sizeof(place));
251 av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
252 return AVERROR_INVALIDDATA;
254 avio_skip(pb, 1); // role
258 av_log(c->fc, AV_LOG_ERROR,
259 "loci too short (%u bytes left, need at least %d)\n", len, 12);
260 return AVERROR_INVALIDDATA;
262 longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
263 latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
264 altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
266 // Try to output in the same format as the ?xyz field
267 snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
269 av_strlcatf(buf, sizeof(buf), "%+f", altitude);
270 av_strlcatf(buf, sizeof(buf), "/%s", place);
272 if (*language && strcmp(language, "und")) {
274 snprintf(key2, sizeof(key2), "%s-%s", key, language);
275 av_dict_set(&c->fc->metadata, key2, buf, 0);
277 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
278 return av_dict_set(&c->fc->metadata, key, buf, 0);
281 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
287 if (c->ignore_chapters)
290 n_hmmt = avio_rb32(pb);
291 for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
292 int moment_time = avio_rb32(pb);
293 avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
298 static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
301 char key2[32], language[4] = {0};
303 const char *key = NULL;
304 uint16_t langcode = 0;
305 uint32_t data_type = 0, str_size, str_size_alloc;
306 int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
311 case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
312 case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
313 case MKTAG( 'X','M','P','_'):
314 if (c->export_xmp) { key = "xmp"; raw = 1; } break;
315 case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
316 case MKTAG( 'a','k','I','D'): key = "account_type";
317 parse = mov_metadata_int8_no_padding; break;
318 case MKTAG( 'a','p','I','D'): key = "account_id"; break;
319 case MKTAG( 'c','a','t','g'): key = "category"; break;
320 case MKTAG( 'c','p','i','l'): key = "compilation";
321 parse = mov_metadata_int8_no_padding; break;
322 case MKTAG( 'c','p','r','t'): key = "copyright"; break;
323 case MKTAG( 'd','e','s','c'): key = "description"; break;
324 case MKTAG( 'd','i','s','k'): key = "disc";
325 parse = mov_metadata_track_or_disc_number; break;
326 case MKTAG( 'e','g','i','d'): key = "episode_uid";
327 parse = mov_metadata_int8_no_padding; break;
328 case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
329 case MKTAG( 'g','n','r','e'): key = "genre";
330 parse = mov_metadata_gnre; break;
331 case MKTAG( 'h','d','v','d'): key = "hd_video";
332 parse = mov_metadata_int8_no_padding; break;
333 case MKTAG( 'H','M','M','T'):
334 return mov_metadata_hmmt(c, pb, atom.size);
335 case MKTAG( 'k','e','y','w'): key = "keywords"; break;
336 case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
337 case MKTAG( 'l','o','c','i'):
338 return mov_metadata_loci(c, pb, atom.size);
339 case MKTAG( 'm','a','n','u'): key = "make"; break;
340 case MKTAG( 'm','o','d','l'): key = "model"; break;
341 case MKTAG( 'p','c','s','t'): key = "podcast";
342 parse = mov_metadata_int8_no_padding; break;
343 case MKTAG( 'p','g','a','p'): key = "gapless_playback";
344 parse = mov_metadata_int8_no_padding; break;
345 case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
346 case MKTAG( 'r','t','n','g'): key = "rating";
347 parse = mov_metadata_int8_no_padding; break;
348 case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
349 case MKTAG( 's','o','a','l'): key = "sort_album"; break;
350 case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
351 case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
352 case MKTAG( 's','o','n','m'): key = "sort_name"; break;
353 case MKTAG( 's','o','s','n'): key = "sort_show"; break;
354 case MKTAG( 's','t','i','k'): key = "media_type";
355 parse = mov_metadata_int8_no_padding; break;
356 case MKTAG( 't','r','k','n'): key = "track";
357 parse = mov_metadata_track_or_disc_number; break;
358 case MKTAG( 't','v','e','n'): key = "episode_id"; break;
359 case MKTAG( 't','v','e','s'): key = "episode_sort";
360 parse = mov_metadata_int8_bypass_padding; break;
361 case MKTAG( 't','v','n','n'): key = "network"; break;
362 case MKTAG( 't','v','s','h'): key = "show"; break;
363 case MKTAG( 't','v','s','n'): key = "season_number";
364 parse = mov_metadata_int8_bypass_padding; break;
365 case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
366 case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
367 case MKTAG(0xa9,'a','l','b'): key = "album"; break;
368 case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
369 case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
370 case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
371 case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
372 case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
373 case MKTAG(0xa9,'d','a','y'): key = "date"; break;
374 case MKTAG(0xa9,'d','i','r'): key = "director"; break;
375 case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
376 case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
377 case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
378 case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
379 case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
380 case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
381 case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
382 case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
383 case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
384 case MKTAG(0xa9,'m','a','k'): key = "make"; break;
385 case MKTAG(0xa9,'m','o','d'): key = "model"; break;
386 case MKTAG(0xa9,'n','a','m'): key = "title"; break;
387 case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
388 case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
389 case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
390 case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
391 case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
392 case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
393 case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
394 case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
395 case MKTAG(0xa9,'t','r','k'): key = "track"; break;
396 case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
397 case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
398 case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
399 case MKTAG(0xa9,'x','y','z'): key = "location"; break;
402 if (c->itunes_metadata && atom.size > 8) {
403 int data_size = avio_rb32(pb);
404 int tag = avio_rl32(pb);
405 if (tag == MKTAG('d','a','t','a') && data_size <= atom.size) {
406 data_type = avio_rb32(pb); // type
407 avio_rb32(pb); // unknown
408 str_size = data_size - 16;
411 if (atom.type == MKTAG('c', 'o', 'v', 'r')) {
412 int ret = mov_read_covr(c, pb, data_type, str_size);
414 av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
417 atom.size -= str_size;
421 } else if (!key && c->found_hdlr_mdta && c->meta_keys) {
422 uint32_t index = AV_RB32(&atom.type);
423 if (index < c->meta_keys_count && index > 0) {
424 key = c->meta_keys[index];
426 av_log(c->fc, AV_LOG_WARNING,
427 "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
428 index, c->meta_keys_count);
432 } else if (atom.size > 4 && key && !c->itunes_metadata && !raw) {
433 str_size = avio_rb16(pb); // string length
434 if (str_size > atom.size) {
436 avio_seek(pb, -2, SEEK_CUR);
437 av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
440 langcode = avio_rb16(pb);
441 ff_mov_lang_to_iso639(langcode, language);
444 str_size = atom.size;
446 if (c->export_all && !key) {
447 snprintf(tmp_key, 5, "%.4s", (char*)&atom.type);
453 if (atom.size < 0 || str_size >= INT_MAX/2)
454 return AVERROR_INVALIDDATA;
456 // Allocates enough space if data_type is a int32 or float32 number, otherwise
457 // worst-case requirement for output string in case of utf8 coded input
458 num = (data_type >= 21 && data_type <= 23);
459 str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
460 str = av_mallocz(str_size_alloc);
462 return AVERROR(ENOMEM);
465 parse(c, pb, str_size, key);
467 if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
468 mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
469 } else if (data_type == 21) { // BE signed integer, variable size
472 val = (int8_t)avio_r8(pb);
473 else if (str_size == 2)
474 val = (int16_t)avio_rb16(pb);
475 else if (str_size == 3)
476 val = ((int32_t)(avio_rb24(pb)<<8))>>8;
477 else if (str_size == 4)
478 val = (int32_t)avio_rb32(pb);
479 if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
480 av_log(c->fc, AV_LOG_ERROR,
481 "Failed to store the number (%d) in string.\n", val);
483 return AVERROR_INVALIDDATA;
485 } else if (data_type == 22) { // BE unsigned integer, variable size
486 unsigned int val = 0;
489 else if (str_size == 2)
491 else if (str_size == 3)
493 else if (str_size == 4)
495 if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
496 av_log(c->fc, AV_LOG_ERROR,
497 "Failed to store the number (%u) in string.\n", val);
499 return AVERROR_INVALIDDATA;
501 } else if (data_type == 23 && str_size >= 4) { // BE float32
502 float val = av_int2float(avio_rb32(pb));
503 if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
504 av_log(c->fc, AV_LOG_ERROR,
505 "Failed to store the float32 number (%f) in string.\n", val);
507 return AVERROR_INVALIDDATA;
510 int ret = ffio_read_size(pb, str, str_size);
517 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
518 av_dict_set(&c->fc->metadata, key, str, 0);
519 if (*language && strcmp(language, "und")) {
520 snprintf(key2, sizeof(key2), "%s-%s", key, language);
521 av_dict_set(&c->fc->metadata, key2, str, 0);
523 if (!strcmp(key, "encoder")) {
524 int major, minor, micro;
525 if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, µ) == 3) {
526 c->handbrake_version = 1000000*major + 1000*minor + micro;
535 static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
538 int i, nb_chapters, str_len, version;
542 if (c->ignore_chapters)
545 if ((atom.size -= 5) < 0)
548 version = avio_r8(pb);
551 avio_rb32(pb); // ???
552 nb_chapters = avio_r8(pb);
554 for (i = 0; i < nb_chapters; i++) {
558 start = avio_rb64(pb);
559 str_len = avio_r8(pb);
561 if ((atom.size -= 9+str_len) < 0)
564 ret = ffio_read_size(pb, str, str_len);
568 avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
573 #define MIN_DATA_ENTRY_BOX_SIZE 12
574 static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
577 MOVStreamContext *sc;
580 if (c->fc->nb_streams < 1)
582 st = c->fc->streams[c->fc->nb_streams-1];
585 avio_rb32(pb); // version + flags
586 entries = avio_rb32(pb);
588 entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
589 entries >= UINT_MAX / sizeof(*sc->drefs))
590 return AVERROR_INVALIDDATA;
594 sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
596 return AVERROR(ENOMEM);
597 sc->drefs_count = entries;
599 for (i = 0; i < entries; i++) {
600 MOVDref *dref = &sc->drefs[i];
601 uint32_t size = avio_rb32(pb);
602 int64_t next = avio_tell(pb) + size - 4;
605 return AVERROR_INVALIDDATA;
607 dref->type = avio_rl32(pb);
608 avio_rb32(pb); // version + flags
610 if (dref->type == MKTAG('a','l','i','s') && size > 150) {
611 /* macintosh alias record */
612 uint16_t volume_len, len;
618 volume_len = avio_r8(pb);
619 volume_len = FFMIN(volume_len, 27);
620 ret = ffio_read_size(pb, dref->volume, 27);
623 dref->volume[volume_len] = 0;
624 av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
629 len = FFMIN(len, 63);
630 ret = ffio_read_size(pb, dref->filename, 63);
633 dref->filename[len] = 0;
634 av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
638 /* read next level up_from_alias/down_to_target */
639 dref->nlvl_from = avio_rb16(pb);
640 dref->nlvl_to = avio_rb16(pb);
641 av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
642 dref->nlvl_from, dref->nlvl_to);
646 for (type = 0; type != -1 && avio_tell(pb) < next; ) {
649 type = avio_rb16(pb);
651 av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
654 if (type == 2) { // absolute path
656 dref->path = av_mallocz(len+1);
658 return AVERROR(ENOMEM);
660 ret = ffio_read_size(pb, dref->path, len);
662 av_freep(&dref->path);
665 if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
667 memmove(dref->path, dref->path+volume_len, len);
670 // trim string of any ending zeros
671 for (j = len - 1; j >= 0; j--) {
672 if (dref->path[j] == 0)
677 for (j = 0; j < len; j++)
678 if (dref->path[j] == ':' || dref->path[j] == 0)
680 av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
681 } else if (type == 0) { // directory name
683 dref->dir = av_malloc(len+1);
685 return AVERROR(ENOMEM);
687 ret = ffio_read_size(pb, dref->dir, len);
689 av_freep(&dref->dir);
693 for (j = 0; j < len; j++)
694 if (dref->dir[j] == ':')
696 av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
701 av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
706 avio_seek(pb, next, SEEK_SET);
711 static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
720 avio_r8(pb); /* version */
721 avio_rb24(pb); /* flags */
724 ctype = avio_rl32(pb);
725 type = avio_rl32(pb); /* component subtype */
727 av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
728 av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
730 if (c->trak_index < 0) { // meta not inside a trak
731 if (type == MKTAG('m','d','t','a')) {
732 c->found_hdlr_mdta = 1;
737 st = c->fc->streams[c->fc->nb_streams-1];
739 if (type == MKTAG('v','i','d','e'))
740 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
741 else if (type == MKTAG('s','o','u','n'))
742 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
743 else if (type == MKTAG('m','1','a',' '))
744 st->codecpar->codec_id = AV_CODEC_ID_MP2;
745 else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
746 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
748 avio_rb32(pb); /* component manufacture */
749 avio_rb32(pb); /* component flags */
750 avio_rb32(pb); /* component flags mask */
752 title_size = atom.size - 24;
753 if (title_size > 0) {
754 if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
755 return AVERROR_INVALIDDATA;
756 title_str = av_malloc(title_size + 1); /* Add null terminator */
758 return AVERROR(ENOMEM);
760 ret = ffio_read_size(pb, title_str, title_size);
762 av_freep(&title_str);
765 title_str[title_size] = 0;
767 int off = (!c->isom && title_str[0] == title_size - 1);
768 // flag added so as to not set stream handler name if already set from mdia->hdlr
769 av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
771 av_freep(&title_str);
777 static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
779 return ff_mov_read_esds(c->fc, pb);
782 static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
785 enum AVAudioServiceType *ast;
786 int ac3info, acmod, lfeon, bsmod;
788 if (c->fc->nb_streams < 1)
790 st = c->fc->streams[c->fc->nb_streams-1];
792 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
795 return AVERROR(ENOMEM);
797 ac3info = avio_rb24(pb);
798 bsmod = (ac3info >> 14) & 0x7;
799 acmod = (ac3info >> 11) & 0x7;
800 lfeon = (ac3info >> 10) & 0x1;
801 st->codecpar->channels = ((int[]){2,1,2,3,3,4,4,5})[acmod] + lfeon;
802 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
804 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
806 if (st->codecpar->channels > 1 && bsmod == 0x7)
807 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
809 #if FF_API_LAVF_AVCTX
810 FF_DISABLE_DEPRECATION_WARNINGS
811 st->codec->audio_service_type = *ast;
812 FF_ENABLE_DEPRECATION_WARNINGS
818 static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
821 enum AVAudioServiceType *ast;
822 int eac3info, acmod, lfeon, bsmod;
824 if (c->fc->nb_streams < 1)
826 st = c->fc->streams[c->fc->nb_streams-1];
828 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
831 return AVERROR(ENOMEM);
833 /* No need to parse fields for additional independent substreams and its
834 * associated dependent substreams since libavcodec's E-AC-3 decoder
835 * does not support them yet. */
836 avio_rb16(pb); /* data_rate and num_ind_sub */
837 eac3info = avio_rb24(pb);
838 bsmod = (eac3info >> 12) & 0x1f;
839 acmod = (eac3info >> 9) & 0x7;
840 lfeon = (eac3info >> 8) & 0x1;
841 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
843 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
844 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
846 if (st->codecpar->channels > 1 && bsmod == 0x7)
847 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
849 #if FF_API_LAVF_AVCTX
850 FF_DISABLE_DEPRECATION_WARNINGS
851 st->codec->audio_service_type = *ast;
852 FF_ENABLE_DEPRECATION_WARNINGS
858 static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
860 const uint32_t ddts_size = 20;
863 uint32_t frame_duration_code = 0;
864 uint32_t channel_layout_code = 0;
867 buf = av_malloc(ddts_size + AV_INPUT_BUFFER_PADDING_SIZE);
869 return AVERROR(ENOMEM);
871 if (avio_read(pb, buf, ddts_size) < ddts_size) {
873 return AVERROR_INVALIDDATA;
876 init_get_bits(&gb, buf, 8*ddts_size);
878 if (c->fc->nb_streams < 1) {
882 st = c->fc->streams[c->fc->nb_streams-1];
884 st->codecpar->sample_rate = get_bits_long(&gb, 32);
885 if (st->codecpar->sample_rate <= 0) {
886 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
888 return AVERROR_INVALIDDATA;
890 skip_bits_long(&gb, 32); /* max bitrate */
891 st->codecpar->bit_rate = get_bits_long(&gb, 32);
892 st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
893 frame_duration_code = get_bits(&gb, 2);
894 skip_bits(&gb, 30); /* various fields */
895 channel_layout_code = get_bits(&gb, 16);
897 st->codecpar->frame_size =
898 (frame_duration_code == 0) ? 512 :
899 (frame_duration_code == 1) ? 1024 :
900 (frame_duration_code == 2) ? 2048 :
901 (frame_duration_code == 3) ? 4096 : 0;
903 if (channel_layout_code > 0xff) {
904 av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout");
906 st->codecpar->channel_layout =
907 ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
908 ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
909 ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
910 ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
911 ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
912 ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0);
914 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
920 static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
924 if (c->fc->nb_streams < 1)
926 st = c->fc->streams[c->fc->nb_streams-1];
931 /* skip version and flags */
934 ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
939 static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
944 if (c->fc->nb_streams < 1)
946 st = c->fc->streams[c->fc->nb_streams-1];
948 if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
949 av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
954 static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
956 const int num = avio_rb32(pb);
957 const int den = avio_rb32(pb);
960 if (c->fc->nb_streams < 1)
962 st = c->fc->streams[c->fc->nb_streams-1];
964 if ((st->sample_aspect_ratio.den != 1 || st->sample_aspect_ratio.num) && // default
965 (den != st->sample_aspect_ratio.den || num != st->sample_aspect_ratio.num)) {
966 av_log(c->fc, AV_LOG_WARNING,
967 "sample aspect ratio already set to %d:%d, ignoring 'pasp' atom (%d:%d)\n",
968 st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
970 } else if (den != 0) {
971 av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den,
977 /* this atom contains actual media data */
978 static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
980 if (atom.size == 0) /* wrong one (MP4) */
983 return 0; /* now go for moov */
986 #define DRM_BLOB_SIZE 56
988 static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
990 uint8_t intermediate_key[20];
991 uint8_t intermediate_iv[20];
994 uint8_t file_checksum[20];
995 uint8_t calculated_checksum[20];
999 uint8_t *activation_bytes = c->activation_bytes;
1000 uint8_t *fixed_key = c->audible_fixed_key;
1004 sha = av_sha_alloc();
1006 return AVERROR(ENOMEM);
1007 c->aes_decrypt = av_aes_alloc();
1008 if (!c->aes_decrypt) {
1009 ret = AVERROR(ENOMEM);
1013 /* drm blob processing */
1014 avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1015 avio_read(pb, input, DRM_BLOB_SIZE);
1016 avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1017 avio_read(pb, file_checksum, 20);
1019 av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == "); // required by external tools
1020 for (i = 0; i < 20; i++)
1021 av_log(c->fc, AV_LOG_INFO, "%02x", file_checksum[i]);
1022 av_log(c->fc, AV_LOG_INFO, "\n");
1024 /* verify activation data */
1025 if (!activation_bytes) {
1026 av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1027 ret = 0; /* allow ffprobe to continue working on .aax files */
1030 if (c->activation_bytes_size != 4) {
1031 av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1032 ret = AVERROR(EINVAL);
1036 /* verify fixed key */
1037 if (c->audible_fixed_key_size != 16) {
1038 av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1039 ret = AVERROR(EINVAL);
1043 /* AAX (and AAX+) key derivation */
1044 av_sha_init(sha, 160);
1045 av_sha_update(sha, fixed_key, 16);
1046 av_sha_update(sha, activation_bytes, 4);
1047 av_sha_final(sha, intermediate_key);
1048 av_sha_init(sha, 160);
1049 av_sha_update(sha, fixed_key, 16);
1050 av_sha_update(sha, intermediate_key, 20);
1051 av_sha_update(sha, activation_bytes, 4);
1052 av_sha_final(sha, intermediate_iv);
1053 av_sha_init(sha, 160);
1054 av_sha_update(sha, intermediate_key, 16);
1055 av_sha_update(sha, intermediate_iv, 16);
1056 av_sha_final(sha, calculated_checksum);
1057 if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1058 av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1059 ret = AVERROR_INVALIDDATA;
1062 av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1063 av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1064 for (i = 0; i < 4; i++) {
1065 // file data (in output) is stored in big-endian mode
1066 if (activation_bytes[i] != output[3 - i]) { // critical error
1067 av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1068 ret = AVERROR_INVALIDDATA;
1072 memcpy(c->file_key, output + 8, 16);
1073 memcpy(input, output + 26, 16);
1074 av_sha_init(sha, 160);
1075 av_sha_update(sha, input, 16);
1076 av_sha_update(sha, c->file_key, 16);
1077 av_sha_update(sha, fixed_key, 16);
1078 av_sha_final(sha, c->file_iv);
1086 // Audible AAX (and AAX+) bytestream decryption
1087 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1090 unsigned char iv[16];
1092 memcpy(iv, c->file_iv, 16); // iv is overwritten
1093 blocks = size >> 4; // trailing bytes are not encrypted!
1094 av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1095 av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1100 /* read major brand, minor version and compatible brands and store them as metadata */
1101 static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1104 int comp_brand_size;
1105 char* comp_brands_str;
1106 uint8_t type[5] = {0};
1107 int ret = ffio_read_size(pb, type, 4);
1111 if (strcmp(type, "qt "))
1113 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1114 av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1115 minor_ver = avio_rb32(pb); /* minor version */
1116 av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1118 comp_brand_size = atom.size - 8;
1119 if (comp_brand_size < 0)
1120 return AVERROR_INVALIDDATA;
1121 comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1122 if (!comp_brands_str)
1123 return AVERROR(ENOMEM);
1125 ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1127 av_freep(&comp_brands_str);
1130 comp_brands_str[comp_brand_size] = 0;
1131 av_dict_set(&c->fc->metadata, "compatible_brands", comp_brands_str, 0);
1132 av_freep(&comp_brands_str);
1137 /* this atom should contain all header atoms */
1138 static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1142 if (c->found_moov) {
1143 av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1144 avio_skip(pb, atom.size);
1148 if ((ret = mov_read_default(c, pb, atom)) < 0)
1150 /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1151 /* so we don't parse the whole file if over a network */
1153 return 0; /* now go for mdat */
1156 static MOVFragmentStreamInfo * get_frag_stream_info(
1157 MOVFragmentIndex *frag_index,
1162 MOVFragmentIndexItem * item;
1164 if (index < 0 || index >= frag_index->nb_items)
1166 item = &frag_index->item[index];
1167 for (i = 0; i < item->nb_stream_info; i++)
1168 if (item->stream_info[i].id == id)
1169 return &item->stream_info[i];
1171 // This shouldn't happen
1175 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1178 MOVFragmentIndexItem * item;
1180 if (frag_index->current < 0 ||
1181 frag_index->current >= frag_index->nb_items)
1184 item = &frag_index->item[frag_index->current];
1185 for (i = 0; i < item->nb_stream_info; i++)
1186 if (item->stream_info[i].id == id) {
1191 // id not found. This shouldn't happen.
1195 static MOVFragmentStreamInfo * get_current_frag_stream_info(
1196 MOVFragmentIndex *frag_index)
1198 MOVFragmentIndexItem *item;
1199 if (frag_index->current < 0 ||
1200 frag_index->current >= frag_index->nb_items)
1203 item = &frag_index->item[frag_index->current];
1204 if (item->current >= 0 && item->current < item->nb_stream_info)
1205 return &item->stream_info[item->current];
1207 // This shouldn't happen
1211 static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
1214 int64_t moof_offset;
1216 // Optimize for appending new entries
1217 if (!frag_index->nb_items ||
1218 frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1219 return frag_index->nb_items;
1222 b = frag_index->nb_items;
1226 moof_offset = frag_index->item[m].moof_offset;
1227 if (moof_offset >= offset)
1229 if (moof_offset <= offset)
1235 static int64_t get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
1237 av_assert0(frag_stream_info);
1238 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1239 return frag_stream_info->sidx_pts;
1240 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1241 return frag_stream_info->first_tfra_pts;
1242 return frag_stream_info->tfdt_dts;
1245 static int64_t get_frag_time(MOVFragmentIndex *frag_index,
1246 int index, int track_id)
1248 MOVFragmentStreamInfo * frag_stream_info;
1252 if (track_id >= 0) {
1253 frag_stream_info = get_frag_stream_info(frag_index, index, track_id);
1254 return frag_stream_info->sidx_pts;
1257 for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1258 frag_stream_info = &frag_index->item[index].stream_info[i];
1259 timestamp = get_stream_info_time(frag_stream_info);
1260 if (timestamp != AV_NOPTS_VALUE)
1263 return AV_NOPTS_VALUE;
1266 static int search_frag_timestamp(MOVFragmentIndex *frag_index,
1267 AVStream *st, int64_t timestamp)
1274 // If the stream is referenced by any sidx, limit the search
1275 // to fragments that referenced this stream in the sidx
1276 MOVStreamContext *sc = st->priv_data;
1282 b = frag_index->nb_items;
1285 m0 = m = (a + b) >> 1;
1288 (frag_time = get_frag_time(frag_index, m, id)) == AV_NOPTS_VALUE)
1291 if (m < b && frag_time <= timestamp)
1300 static int update_frag_index(MOVContext *c, int64_t offset)
1303 MOVFragmentIndexItem * item;
1304 MOVFragmentStreamInfo * frag_stream_info;
1306 // If moof_offset already exists in frag_index, return index to it
1307 index = search_frag_moof_offset(&c->frag_index, offset);
1308 if (index < c->frag_index.nb_items &&
1309 c->frag_index.item[index].moof_offset == offset)
1312 // offset is not yet in frag index.
1313 // Insert new item at index (sorted by moof offset)
1314 item = av_fast_realloc(c->frag_index.item,
1315 &c->frag_index.allocated_size,
1316 (c->frag_index.nb_items + 1) *
1317 sizeof(*c->frag_index.item));
1320 c->frag_index.item = item;
1322 frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1323 sizeof(*item->stream_info));
1324 if (!frag_stream_info)
1327 for (i = 0; i < c->fc->nb_streams; i++) {
1328 // Avoid building frag index if streams lack track id.
1329 if (c->fc->streams[i]->id < 0)
1330 return AVERROR_INVALIDDATA;
1332 frag_stream_info[i].id = c->fc->streams[i]->id;
1333 frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1334 frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1335 frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1336 frag_stream_info[i].index_entry = -1;
1337 frag_stream_info[i].encryption_index = NULL;
1340 if (index < c->frag_index.nb_items)
1341 memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1342 (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1344 item = &c->frag_index.item[index];
1345 item->headers_read = 0;
1347 item->nb_stream_info = c->fc->nb_streams;
1348 item->moof_offset = offset;
1349 item->stream_info = frag_stream_info;
1350 c->frag_index.nb_items++;
1355 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1356 int id, int entries)
1359 MOVFragmentStreamInfo * frag_stream_info;
1363 for (i = index; i < frag_index->nb_items; i++) {
1364 frag_stream_info = get_frag_stream_info(frag_index, i, id);
1365 if (frag_stream_info && frag_stream_info->index_entry >= 0)
1366 frag_stream_info->index_entry += entries;
1370 static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1372 // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1373 c->fragment.found_tfhd = 0;
1375 if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1376 c->has_looked_for_mfra = 1;
1377 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1379 av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1381 if ((ret = mov_read_mfra(c, pb)) < 0) {
1382 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1383 "read the mfra (may be a live ismv)\n");
1386 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1387 "seekable, can not look for mfra\n");
1390 c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1391 av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1392 c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1393 return mov_read_default(c, pb, atom);
1396 static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time)
1399 if(time >= 2082844800)
1400 time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1402 if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1403 av_log(NULL, AV_LOG_DEBUG, "creation_time is not representable\n");
1407 avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1411 static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1414 MOVStreamContext *sc;
1416 char language[4] = {0};
1418 int64_t creation_time;
1420 if (c->fc->nb_streams < 1)
1422 st = c->fc->streams[c->fc->nb_streams-1];
1425 if (sc->time_scale) {
1426 av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1427 return AVERROR_INVALIDDATA;
1430 version = avio_r8(pb);
1432 avpriv_request_sample(c->fc, "Version %d", version);
1433 return AVERROR_PATCHWELCOME;
1435 avio_rb24(pb); /* flags */
1437 creation_time = avio_rb64(pb);
1440 creation_time = avio_rb32(pb);
1441 avio_rb32(pb); /* modification time */
1443 mov_metadata_creation_time(&st->metadata, creation_time);
1445 sc->time_scale = avio_rb32(pb);
1446 if (sc->time_scale <= 0) {
1447 av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1450 st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1452 lang = avio_rb16(pb); /* language */
1453 if (ff_mov_lang_to_iso639(lang, language))
1454 av_dict_set(&st->metadata, "language", language, 0);
1455 avio_rb16(pb); /* quality */
1460 static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1463 int64_t creation_time;
1464 int version = avio_r8(pb); /* version */
1465 avio_rb24(pb); /* flags */
1468 creation_time = avio_rb64(pb);
1471 creation_time = avio_rb32(pb);
1472 avio_rb32(pb); /* modification time */
1474 mov_metadata_creation_time(&c->fc->metadata, creation_time);
1475 c->time_scale = avio_rb32(pb); /* time scale */
1476 if (c->time_scale <= 0) {
1477 av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1480 av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1482 c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1483 // set the AVCodecContext duration because the duration of individual tracks
1484 // may be inaccurate
1485 if (c->time_scale > 0 && !c->trex_data)
1486 c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale);
1487 avio_rb32(pb); /* preferred scale */
1489 avio_rb16(pb); /* preferred volume */
1491 avio_skip(pb, 10); /* reserved */
1493 /* movie display matrix, store it in main context and use it later on */
1494 for (i = 0; i < 3; i++) {
1495 c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1496 c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1497 c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1500 avio_rb32(pb); /* preview time */
1501 avio_rb32(pb); /* preview duration */
1502 avio_rb32(pb); /* poster time */
1503 avio_rb32(pb); /* selection time */
1504 avio_rb32(pb); /* selection duration */
1505 avio_rb32(pb); /* current time */
1506 avio_rb32(pb); /* next track ID */
1511 static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1516 if (c->fc->nb_streams < 1)
1518 st = c->fc->streams[c->fc->nb_streams-1];
1520 little_endian = avio_rb16(pb) & 0xFF;
1521 av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1522 if (little_endian == 1) {
1523 switch (st->codecpar->codec_id) {
1524 case AV_CODEC_ID_PCM_S24BE:
1525 st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE;
1527 case AV_CODEC_ID_PCM_S32BE:
1528 st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE;
1530 case AV_CODEC_ID_PCM_F32BE:
1531 st->codecpar->codec_id = AV_CODEC_ID_PCM_F32LE;
1533 case AV_CODEC_ID_PCM_F64BE:
1534 st->codecpar->codec_id = AV_CODEC_ID_PCM_F64LE;
1543 static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1546 char color_parameter_type[5] = { 0 };
1547 uint16_t color_primaries, color_trc, color_matrix;
1550 if (c->fc->nb_streams < 1)
1552 st = c->fc->streams[c->fc->nb_streams - 1];
1554 ret = ffio_read_size(pb, color_parameter_type, 4);
1557 if (strncmp(color_parameter_type, "nclx", 4) &&
1558 strncmp(color_parameter_type, "nclc", 4)) {
1559 av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
1560 color_parameter_type);
1564 color_primaries = avio_rb16(pb);
1565 color_trc = avio_rb16(pb);
1566 color_matrix = avio_rb16(pb);
1568 av_log(c->fc, AV_LOG_TRACE,
1569 "%s: pri %d trc %d matrix %d",
1570 color_parameter_type, color_primaries, color_trc, color_matrix);
1572 if (!strncmp(color_parameter_type, "nclx", 4)) {
1573 uint8_t color_range = avio_r8(pb) >> 7;
1574 av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
1576 st->codecpar->color_range = AVCOL_RANGE_JPEG;
1578 st->codecpar->color_range = AVCOL_RANGE_MPEG;
1581 if (!av_color_primaries_name(color_primaries))
1582 color_primaries = AVCOL_PRI_UNSPECIFIED;
1583 if (!av_color_transfer_name(color_trc))
1584 color_trc = AVCOL_TRC_UNSPECIFIED;
1585 if (!av_color_space_name(color_matrix))
1586 color_matrix = AVCOL_SPC_UNSPECIFIED;
1588 st->codecpar->color_primaries = color_primaries;
1589 st->codecpar->color_trc = color_trc;
1590 st->codecpar->color_space = color_matrix;
1591 av_log(c->fc, AV_LOG_TRACE, "\n");
1596 static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1599 unsigned mov_field_order;
1600 enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
1602 if (c->fc->nb_streams < 1) // will happen with jp2 files
1604 st = c->fc->streams[c->fc->nb_streams-1];
1606 return AVERROR_INVALIDDATA;
1607 mov_field_order = avio_rb16(pb);
1608 if ((mov_field_order & 0xFF00) == 0x0100)
1609 decoded_field_order = AV_FIELD_PROGRESSIVE;
1610 else if ((mov_field_order & 0xFF00) == 0x0200) {
1611 switch (mov_field_order & 0xFF) {
1612 case 0x01: decoded_field_order = AV_FIELD_TT;
1614 case 0x06: decoded_field_order = AV_FIELD_BB;
1616 case 0x09: decoded_field_order = AV_FIELD_TB;
1618 case 0x0E: decoded_field_order = AV_FIELD_BT;
1622 if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
1623 av_log(NULL, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
1625 st->codecpar->field_order = decoded_field_order;
1630 static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
1633 uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
1634 if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
1635 return AVERROR_INVALIDDATA;
1636 if ((err = av_reallocp(&par->extradata, size)) < 0) {
1637 par->extradata_size = 0;
1640 par->extradata_size = size - AV_INPUT_BUFFER_PADDING_SIZE;
1644 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
1645 static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1646 AVCodecParameters *par, uint8_t *buf)
1648 int64_t result = atom.size;
1651 AV_WB32(buf , atom.size + 8);
1652 AV_WL32(buf + 4, atom.type);
1653 err = ffio_read_size(pb, buf + 8, atom.size);
1655 par->extradata_size -= atom.size;
1657 } else if (err < atom.size) {
1658 av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
1659 par->extradata_size -= atom.size - err;
1662 memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1666 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
1667 static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1668 enum AVCodecID codec_id)
1671 uint64_t original_size;
1674 if (c->fc->nb_streams < 1) // will happen with jp2 files
1676 st = c->fc->streams[c->fc->nb_streams-1];
1678 if (st->codecpar->codec_id != codec_id)
1679 return 0; /* unexpected codec_id - don't mess with extradata */
1681 original_size = st->codecpar->extradata_size;
1682 err = mov_realloc_extradata(st->codecpar, atom);
1686 err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
1689 return 0; // Note: this is the original behavior to ignore truncation.
1692 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
1693 static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1695 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
1698 static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1700 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS);
1703 static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1705 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
1708 static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1710 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
1713 static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1715 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
1717 ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
1721 static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1723 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
1725 if (!ret && c->fc->nb_streams >= 1) {
1726 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1727 if (par->extradata_size >= 40) {
1728 par->height = AV_RB16(&par->extradata[36]);
1729 par->width = AV_RB16(&par->extradata[38]);
1735 static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1737 if (c->fc->nb_streams >= 1) {
1738 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1739 if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
1740 par->codec_id == AV_CODEC_ID_H264 &&
1744 cid = avio_rb16(pb);
1745 /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
1746 if (cid == 0xd4d || cid == 0xd4e)
1749 } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
1750 par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
1751 par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
1755 num = avio_rb32(pb);
1756 den = avio_rb32(pb);
1757 if (num <= 0 || den <= 0)
1759 switch (avio_rb32(pb)) {
1761 if (den >= INT_MAX / 2)
1765 c->fc->streams[c->fc->nb_streams-1]->display_aspect_ratio.num = num;
1766 c->fc->streams[c->fc->nb_streams-1]->display_aspect_ratio.den = den;
1773 return mov_read_avid(c, pb, atom);
1776 static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1780 uint64_t original_size;
1781 if (c->fc->nb_streams >= 1) {
1782 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1783 if (par->codec_id == AV_CODEC_ID_H264)
1785 if (atom.size == 16) {
1786 original_size = par->extradata_size;
1787 ret = mov_realloc_extradata(par, atom);
1789 length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
1790 if (length == atom.size) {
1791 const uint8_t range_value = par->extradata[original_size + 19];
1792 switch (range_value) {
1794 par->color_range = AVCOL_RANGE_MPEG;
1797 par->color_range = AVCOL_RANGE_JPEG;
1800 av_log(c, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
1803 ff_dlog(c, "color_range: %d\n", par->color_range);
1805 /* For some reason the whole atom was not added to the extradata */
1806 av_log(c, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
1809 av_log(c, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
1812 av_log(c, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
1819 static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1821 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
1824 static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1829 if (c->fc->nb_streams < 1)
1831 st = c->fc->streams[c->fc->nb_streams-1];
1833 if ((uint64_t)atom.size > (1<<30))
1834 return AVERROR_INVALIDDATA;
1836 if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
1837 st->codecpar->codec_id == AV_CODEC_ID_QDMC ||
1838 st->codecpar->codec_id == AV_CODEC_ID_SPEEX) {
1839 // pass all frma atom to codec, needed at least for QDMC and QDM2
1840 av_freep(&st->codecpar->extradata);
1841 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1844 } else if (atom.size > 8) { /* to read frma, esds atoms */
1845 if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
1847 ret = ffio_ensure_seekback(pb, 8);
1850 buffer = avio_rb64(pb);
1852 if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
1853 && buffer >> 32 <= atom.size
1854 && buffer >> 32 >= 8) {
1857 } else if (!st->codecpar->extradata_size) {
1858 #define ALAC_EXTRADATA_SIZE 36
1859 st->codecpar->extradata = av_mallocz(ALAC_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
1860 if (!st->codecpar->extradata)
1861 return AVERROR(ENOMEM);
1862 st->codecpar->extradata_size = ALAC_EXTRADATA_SIZE;
1863 AV_WB32(st->codecpar->extradata , ALAC_EXTRADATA_SIZE);
1864 AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
1865 AV_WB64(st->codecpar->extradata + 12, buffer);
1866 avio_read(pb, st->codecpar->extradata + 20, 16);
1867 avio_skip(pb, atom.size - 24);
1871 if ((ret = mov_read_default(c, pb, atom)) < 0)
1874 avio_skip(pb, atom.size);
1879 * This function reads atom content and puts data in extradata without tag
1880 * nor size unlike mov_read_extradata.
1882 static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1887 if (c->fc->nb_streams < 1)
1889 st = c->fc->streams[c->fc->nb_streams-1];
1891 if ((uint64_t)atom.size > (1<<30))
1892 return AVERROR_INVALIDDATA;
1894 if (atom.size >= 10) {
1895 // Broken files created by legacy versions of libavformat will
1896 // wrap a whole fiel atom inside of a glbl atom.
1897 unsigned size = avio_rb32(pb);
1898 unsigned type = avio_rl32(pb);
1899 avio_seek(pb, -8, SEEK_CUR);
1900 if (type == MKTAG('f','i','e','l') && size == atom.size)
1901 return mov_read_default(c, pb, atom);
1903 if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
1904 av_log(c, AV_LOG_WARNING, "ignoring multiple glbl\n");
1907 av_freep(&st->codecpar->extradata);
1908 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1911 if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
1912 /* HEVC-based Dolby Vision derived from hvc1.
1913 Happens to match with an identifier
1914 previously utilized for DV. Thus, if we have
1915 the hvcC extradata box available as specified,
1916 set codec to HEVC */
1917 st->codecpar->codec_id = AV_CODEC_ID_HEVC;
1922 static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1925 uint8_t profile_level;
1928 if (c->fc->nb_streams < 1)
1930 st = c->fc->streams[c->fc->nb_streams-1];
1932 if (atom.size >= (1<<28) || atom.size < 7)
1933 return AVERROR_INVALIDDATA;
1935 profile_level = avio_r8(pb);
1936 if ((profile_level & 0xf0) != 0xc0)
1939 avio_seek(pb, 6, SEEK_CUR);
1940 av_freep(&st->codecpar->extradata);
1941 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
1949 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
1950 * but can have extradata appended at the end after the 40 bytes belonging
1953 static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1958 if (c->fc->nb_streams < 1)
1960 if (atom.size <= 40)
1962 st = c->fc->streams[c->fc->nb_streams-1];
1964 if ((uint64_t)atom.size > (1<<30))
1965 return AVERROR_INVALIDDATA;
1968 av_freep(&st->codecpar->extradata);
1969 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
1976 static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1979 MOVStreamContext *sc;
1980 unsigned int i, entries;
1982 if (c->fc->nb_streams < 1)
1984 st = c->fc->streams[c->fc->nb_streams-1];
1987 avio_r8(pb); /* version */
1988 avio_rb24(pb); /* flags */
1990 entries = avio_rb32(pb);
1995 if (sc->chunk_offsets)
1996 av_log(c->fc, AV_LOG_WARNING, "Duplicated STCO atom\n");
1997 av_free(sc->chunk_offsets);
1998 sc->chunk_count = 0;
1999 sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2000 if (!sc->chunk_offsets)
2001 return AVERROR(ENOMEM);
2002 sc->chunk_count = entries;
2004 if (atom.type == MKTAG('s','t','c','o'))
2005 for (i = 0; i < entries && !pb->eof_reached; i++)
2006 sc->chunk_offsets[i] = avio_rb32(pb);
2007 else if (atom.type == MKTAG('c','o','6','4'))
2008 for (i = 0; i < entries && !pb->eof_reached; i++)
2009 sc->chunk_offsets[i] = avio_rb64(pb);
2011 return AVERROR_INVALIDDATA;
2013 sc->chunk_count = i;
2015 if (pb->eof_reached) {
2016 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2023 static int mov_codec_id(AVStream *st, uint32_t format)
2025 int id = ff_codec_get_id(ff_codec_movaudio_tags, format);
2028 ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2029 (format & 0xFFFF) == 'T' + ('S' << 8)))
2030 id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format) & 0xFFFF);
2032 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2033 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2034 } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2035 /* skip old ASF MPEG-4 tag */
2036 format && format != MKTAG('m','p','4','s')) {
2037 id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2039 id = ff_codec_get_id(ff_codec_bmp_tags, format);
2041 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
2042 else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2043 (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE &&
2044 st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2045 id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
2047 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
2049 id = ff_codec_get_id(ff_codec_movdata_tags, format);
2053 st->codecpar->codec_tag = format;
2058 static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
2059 AVStream *st, MOVStreamContext *sc)
2061 uint8_t codec_name[32] = { 0 };
2065 /* The first 16 bytes of the video sample description are already
2066 * read in ff_mov_read_stsd_entries() */
2067 stsd_start = avio_tell(pb) - 16;
2069 avio_rb16(pb); /* version */
2070 avio_rb16(pb); /* revision level */
2071 avio_rb32(pb); /* vendor */
2072 avio_rb32(pb); /* temporal quality */
2073 avio_rb32(pb); /* spatial quality */
2075 st->codecpar->width = avio_rb16(pb); /* width */
2076 st->codecpar->height = avio_rb16(pb); /* height */
2078 avio_rb32(pb); /* horiz resolution */
2079 avio_rb32(pb); /* vert resolution */
2080 avio_rb32(pb); /* data size, always 0 */
2081 avio_rb16(pb); /* frames per samples */
2083 len = avio_r8(pb); /* codec name, pascal string */
2086 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2088 avio_skip(pb, 31 - len);
2091 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2093 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2094 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2095 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2096 st->codecpar->width &= ~1;
2097 st->codecpar->height &= ~1;
2099 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2100 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2101 !strncmp(codec_name, "Sorenson H263", 13))
2102 st->codecpar->codec_id = AV_CODEC_ID_FLV1;
2104 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2106 avio_seek(pb, stsd_start, SEEK_SET);
2108 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2109 st->codecpar->bits_per_coded_sample &= 0x1F;
2110 sc->has_palette = 1;
2114 static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
2115 AVStream *st, MOVStreamContext *sc)
2117 int bits_per_sample, flags;
2118 uint16_t version = avio_rb16(pb);
2119 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2121 avio_rb16(pb); /* revision level */
2122 avio_rb32(pb); /* vendor */
2124 st->codecpar->channels = avio_rb16(pb); /* channel count */
2125 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2126 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", st->codecpar->channels);
2128 sc->audio_cid = avio_rb16(pb);
2129 avio_rb16(pb); /* packet size = 0 */
2131 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2133 // Read QT version 1 fields. In version 0 these do not exist.
2134 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2136 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2137 (sc->stsd_version == 0 && version > 0)) {
2139 sc->samples_per_frame = avio_rb32(pb);
2140 avio_rb32(pb); /* bytes per packet */
2141 sc->bytes_per_frame = avio_rb32(pb);
2142 avio_rb32(pb); /* bytes per sample */
2143 } else if (version == 2) {
2144 avio_rb32(pb); /* sizeof struct only */
2145 st->codecpar->sample_rate = av_int2double(avio_rb64(pb));
2146 st->codecpar->channels = avio_rb32(pb);
2147 avio_rb32(pb); /* always 0x7F000000 */
2148 st->codecpar->bits_per_coded_sample = avio_rb32(pb);
2150 flags = avio_rb32(pb); /* lpcm format specific flag */
2151 sc->bytes_per_frame = avio_rb32(pb);
2152 sc->samples_per_frame = avio_rb32(pb);
2153 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2154 st->codecpar->codec_id =
2155 ff_mov_get_lpcm_codec_id(st->codecpar->bits_per_coded_sample,
2158 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2159 /* can't correctly handle variable sized packet as audio unit */
2160 switch (st->codecpar->codec_id) {
2161 case AV_CODEC_ID_MP2:
2162 case AV_CODEC_ID_MP3:
2163 st->need_parsing = AVSTREAM_PARSE_FULL;
2169 if (sc->format == 0) {
2170 if (st->codecpar->bits_per_coded_sample == 8)
2171 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2172 else if (st->codecpar->bits_per_coded_sample == 16)
2173 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2176 switch (st->codecpar->codec_id) {
2177 case AV_CODEC_ID_PCM_S8:
2178 case AV_CODEC_ID_PCM_U8:
2179 if (st->codecpar->bits_per_coded_sample == 16)
2180 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16BE;
2182 case AV_CODEC_ID_PCM_S16LE:
2183 case AV_CODEC_ID_PCM_S16BE:
2184 if (st->codecpar->bits_per_coded_sample == 8)
2185 st->codecpar->codec_id = AV_CODEC_ID_PCM_S8;
2186 else if (st->codecpar->bits_per_coded_sample == 24)
2187 st->codecpar->codec_id =
2188 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2189 AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
2190 else if (st->codecpar->bits_per_coded_sample == 32)
2191 st->codecpar->codec_id =
2192 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2193 AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
2195 /* set values for old format before stsd version 1 appeared */
2196 case AV_CODEC_ID_MACE3:
2197 sc->samples_per_frame = 6;
2198 sc->bytes_per_frame = 2 * st->codecpar->channels;
2200 case AV_CODEC_ID_MACE6:
2201 sc->samples_per_frame = 6;
2202 sc->bytes_per_frame = 1 * st->codecpar->channels;
2204 case AV_CODEC_ID_ADPCM_IMA_QT:
2205 sc->samples_per_frame = 64;
2206 sc->bytes_per_frame = 34 * st->codecpar->channels;
2208 case AV_CODEC_ID_GSM:
2209 sc->samples_per_frame = 160;
2210 sc->bytes_per_frame = 33;
2216 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2217 if (bits_per_sample) {
2218 st->codecpar->bits_per_coded_sample = bits_per_sample;
2219 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->channels;
2223 static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
2224 AVStream *st, MOVStreamContext *sc,
2227 // ttxt stsd contains display flags, justification, background
2228 // color, fonts, and default styles, so fake an atom to read it
2229 MOVAtom fake_atom = { .size = size };
2230 // mp4s contains a regular esds atom
2231 if (st->codecpar->codec_tag != AV_RL32("mp4s"))
2232 mov_read_glbl(c, pb, fake_atom);
2233 st->codecpar->width = sc->width;
2234 st->codecpar->height = sc->height;
2237 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2242 y = (ycbcr >> 16) & 0xFF;
2243 cr = (ycbcr >> 8) & 0xFF;
2246 b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
2247 g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
2248 r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
2250 return (r << 16) | (g << 8) | b;
2253 static int mov_rewrite_dvd_sub_extradata(AVStream *st)
2255 char buf[256] = {0};
2256 uint8_t *src = st->codecpar->extradata;
2259 if (st->codecpar->extradata_size != 64)
2262 if (st->codecpar->width > 0 && st->codecpar->height > 0)
2263 snprintf(buf, sizeof(buf), "size: %dx%d\n",
2264 st->codecpar->width, st->codecpar->height);
2265 av_strlcat(buf, "palette: ", sizeof(buf));
2267 for (i = 0; i < 16; i++) {
2268 uint32_t yuv = AV_RB32(src + i * 4);
2269 uint32_t rgba = yuv_to_rgba(yuv);
2271 av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2274 if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2277 av_freep(&st->codecpar->extradata);
2278 st->codecpar->extradata_size = 0;
2279 st->codecpar->extradata = av_mallocz(strlen(buf) + AV_INPUT_BUFFER_PADDING_SIZE);
2280 if (!st->codecpar->extradata)
2281 return AVERROR(ENOMEM);
2282 st->codecpar->extradata_size = strlen(buf);
2283 memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2288 static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
2289 AVStream *st, MOVStreamContext *sc,
2294 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2295 if ((int)size != size)
2296 return AVERROR(ENOMEM);
2298 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2302 MOVStreamContext *tmcd_ctx = st->priv_data;
2304 val = AV_RB32(st->codecpar->extradata + 4);
2305 tmcd_ctx->tmcd_flags = val;
2306 st->avg_frame_rate.num = st->codecpar->extradata[16]; /* number of frame */
2307 st->avg_frame_rate.den = 1;
2308 #if FF_API_LAVF_AVCTX
2309 FF_DISABLE_DEPRECATION_WARNINGS
2310 st->codec->time_base = av_inv_q(st->avg_frame_rate);
2311 FF_ENABLE_DEPRECATION_WARNINGS
2313 /* adjust for per frame dur in counter mode */
2314 if (tmcd_ctx->tmcd_flags & 0x0008) {
2315 int timescale = AV_RB32(st->codecpar->extradata + 8);
2316 int framedur = AV_RB32(st->codecpar->extradata + 12);
2317 st->avg_frame_rate.num *= timescale;
2318 st->avg_frame_rate.den *= framedur;
2319 #if FF_API_LAVF_AVCTX
2320 FF_DISABLE_DEPRECATION_WARNINGS
2321 st->codec->time_base.den *= timescale;
2322 st->codec->time_base.num *= framedur;
2323 FF_ENABLE_DEPRECATION_WARNINGS
2327 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2328 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2329 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2330 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2331 if (str_size > 0 && size >= (int)str_size + 26) {
2332 char *reel_name = av_malloc(str_size + 1);
2334 return AVERROR(ENOMEM);
2335 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2336 reel_name[str_size] = 0; /* Add null terminator */
2337 /* don't add reel_name if emtpy string */
2338 if (*reel_name == 0) {
2341 av_dict_set(&st->metadata, "reel_name", reel_name, AV_DICT_DONT_STRDUP_VAL);
2348 /* other codec type, just skip (rtp, mp4s ...) */
2349 avio_skip(pb, size);
2354 static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
2355 AVStream *st, MOVStreamContext *sc)
2357 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2358 !st->codecpar->sample_rate && sc->time_scale > 1)
2359 st->codecpar->sample_rate = sc->time_scale;
2361 /* special codec parameters handling */
2362 switch (st->codecpar->codec_id) {
2363 #if CONFIG_DV_DEMUXER
2364 case AV_CODEC_ID_DVAUDIO:
2365 c->dv_fctx = avformat_alloc_context();
2367 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2368 return AVERROR(ENOMEM);
2370 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2372 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2373 return AVERROR(ENOMEM);
2375 sc->dv_audio_container = 1;
2376 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
2379 /* no ifdef since parameters are always those */
2380 case AV_CODEC_ID_QCELP:
2381 st->codecpar->channels = 1;
2382 // force sample rate for qcelp when not stored in mov
2383 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2384 st->codecpar->sample_rate = 8000;
2385 // FIXME: Why is the following needed for some files?
2386 sc->samples_per_frame = 160;
2387 if (!sc->bytes_per_frame)
2388 sc->bytes_per_frame = 35;
2390 case AV_CODEC_ID_AMR_NB:
2391 st->codecpar->channels = 1;
2392 /* force sample rate for amr, stsd in 3gp does not store sample rate */
2393 st->codecpar->sample_rate = 8000;
2395 case AV_CODEC_ID_AMR_WB:
2396 st->codecpar->channels = 1;
2397 st->codecpar->sample_rate = 16000;
2399 case AV_CODEC_ID_MP2:
2400 case AV_CODEC_ID_MP3:
2401 /* force type after stsd for m1a hdlr */
2402 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2404 case AV_CODEC_ID_GSM:
2405 case AV_CODEC_ID_ADPCM_MS:
2406 case AV_CODEC_ID_ADPCM_IMA_WAV:
2407 case AV_CODEC_ID_ILBC:
2408 case AV_CODEC_ID_MACE3:
2409 case AV_CODEC_ID_MACE6:
2410 case AV_CODEC_ID_QDM2:
2411 st->codecpar->block_align = sc->bytes_per_frame;
2413 case AV_CODEC_ID_ALAC:
2414 if (st->codecpar->extradata_size == 36) {
2415 st->codecpar->channels = AV_RB8 (st->codecpar->extradata + 21);
2416 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2419 case AV_CODEC_ID_AC3:
2420 case AV_CODEC_ID_EAC3:
2421 case AV_CODEC_ID_MPEG1VIDEO:
2422 case AV_CODEC_ID_VC1:
2423 case AV_CODEC_ID_VP8:
2424 case AV_CODEC_ID_VP9:
2425 st->need_parsing = AVSTREAM_PARSE_FULL;
2433 static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
2434 int codec_tag, int format,
2437 int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2440 (codec_tag != format &&
2441 // AVID 1:1 samples with differing data format and codec tag exist
2442 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
2443 // prores is allowed to have differing data format and codec tag
2444 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
2446 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
2447 (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id
2448 : codec_tag != MKTAG('j','p','e','g')))) {
2449 /* Multiple fourcc, we skip JPEG. This is not correct, we should
2450 * export it as a separate AVStream but this needs a few changes
2451 * in the MOV demuxer, patch welcome. */
2453 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
2454 avio_skip(pb, size);
2461 int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
2464 MOVStreamContext *sc;
2465 int pseudo_stream_id;
2467 av_assert0 (c->fc->nb_streams >= 1);
2468 st = c->fc->streams[c->fc->nb_streams-1];
2471 for (pseudo_stream_id = 0;
2472 pseudo_stream_id < entries && !pb->eof_reached;
2473 pseudo_stream_id++) {
2474 //Parsing Sample description table
2476 int ret, dref_id = 1;
2477 MOVAtom a = { AV_RL32("stsd") };
2478 int64_t start_pos = avio_tell(pb);
2479 int64_t size = avio_rb32(pb); /* size */
2480 uint32_t format = avio_rl32(pb); /* data format */
2483 avio_rb32(pb); /* reserved */
2484 avio_rb16(pb); /* reserved */
2485 dref_id = avio_rb16(pb);
2486 } else if (size <= 7) {
2487 av_log(c->fc, AV_LOG_ERROR,
2488 "invalid size %"PRId64" in stsd\n", size);
2489 return AVERROR_INVALIDDATA;
2492 if (mov_skip_multiple_stsd(c, pb, st->codecpar->codec_tag, format,
2493 size - (avio_tell(pb) - start_pos))) {
2498 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
2499 sc->dref_id= dref_id;
2500 sc->format = format;
2502 id = mov_codec_id(st, format);
2504 av_log(c->fc, AV_LOG_TRACE,
2505 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
2506 av_fourcc2str(format), st->codecpar->codec_type);
2508 st->codecpar->codec_id = id;
2509 if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) {
2510 mov_parse_stsd_video(c, pb, st, sc);
2511 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
2512 mov_parse_stsd_audio(c, pb, st, sc);
2513 if (st->codecpar->sample_rate < 0) {
2514 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
2515 return AVERROR_INVALIDDATA;
2517 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
2518 mov_parse_stsd_subtitle(c, pb, st, sc,
2519 size - (avio_tell(pb) - start_pos));
2521 ret = mov_parse_stsd_data(c, pb, st, sc,
2522 size - (avio_tell(pb) - start_pos));
2526 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
2527 a.size = size - (avio_tell(pb) - start_pos);
2529 if ((ret = mov_read_default(c, pb, a)) < 0)
2531 } else if (a.size > 0)
2532 avio_skip(pb, a.size);
2534 if (sc->extradata && st->codecpar->extradata) {
2535 int extra_size = st->codecpar->extradata_size;
2537 /* Move the current stream extradata to the stream context one. */
2538 sc->extradata_size[pseudo_stream_id] = extra_size;
2539 sc->extradata[pseudo_stream_id] = av_malloc(extra_size + AV_INPUT_BUFFER_PADDING_SIZE);
2540 if (!sc->extradata[pseudo_stream_id])
2541 return AVERROR(ENOMEM);
2542 memcpy(sc->extradata[pseudo_stream_id], st->codecpar->extradata, extra_size);
2543 av_freep(&st->codecpar->extradata);
2544 st->codecpar->extradata_size = 0;
2549 if (pb->eof_reached) {
2550 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
2557 static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2560 MOVStreamContext *sc;
2563 if (c->fc->nb_streams < 1)
2565 st = c->fc->streams[c->fc->nb_streams - 1];
2568 sc->stsd_version = avio_r8(pb);
2569 avio_rb24(pb); /* flags */
2570 entries = avio_rb32(pb);
2572 /* Each entry contains a size (4 bytes) and format (4 bytes). */
2573 if (entries <= 0 || entries > atom.size / 8) {
2574 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
2575 return AVERROR_INVALIDDATA;
2578 if (sc->extradata) {
2579 av_log(c->fc, AV_LOG_ERROR,
2580 "Duplicate stsd found in this track.\n");
2581 return AVERROR_INVALIDDATA;
2584 /* Prepare space for hosting multiple extradata. */
2585 sc->extradata = av_mallocz_array(entries, sizeof(*sc->extradata));
2587 return AVERROR(ENOMEM);
2589 sc->extradata_size = av_mallocz_array(entries, sizeof(*sc->extradata_size));
2590 if (!sc->extradata_size) {
2591 ret = AVERROR(ENOMEM);
2595 ret = ff_mov_read_stsd_entries(c, pb, entries);
2599 /* Restore back the primary extradata. */
2600 av_freep(&st->codecpar->extradata);
2601 st->codecpar->extradata_size = sc->extradata_size[0];
2602 if (sc->extradata_size[0]) {
2603 st->codecpar->extradata = av_mallocz(sc->extradata_size[0] + AV_INPUT_BUFFER_PADDING_SIZE);
2604 if (!st->codecpar->extradata)
2605 return AVERROR(ENOMEM);
2606 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
2609 return mov_finalize_stsd_codec(c, pb, st, sc);
2611 if (sc->extradata) {
2613 for (j = 0; j < sc->stsd_count; j++)
2614 av_freep(&sc->extradata[j]);
2617 av_freep(&sc->extradata);
2618 av_freep(&sc->extradata_size);
2622 static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2625 MOVStreamContext *sc;
2626 unsigned int i, entries;
2628 if (c->fc->nb_streams < 1)
2630 st = c->fc->streams[c->fc->nb_streams-1];
2633 avio_r8(pb); /* version */
2634 avio_rb24(pb); /* flags */
2636 entries = avio_rb32(pb);
2637 if ((uint64_t)entries * 12 + 4 > atom.size)
2638 return AVERROR_INVALIDDATA;
2640 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
2645 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSC atom\n");
2646 av_free(sc->stsc_data);
2648 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
2650 return AVERROR(ENOMEM);
2652 for (i = 0; i < entries && !pb->eof_reached; i++) {
2653 sc->stsc_data[i].first = avio_rb32(pb);
2654 sc->stsc_data[i].count = avio_rb32(pb);
2655 sc->stsc_data[i].id = avio_rb32(pb);
2659 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
2660 int64_t first_min = i + 1;
2661 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
2662 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
2663 sc->stsc_data[i].first < first_min ||
2664 sc->stsc_data[i].count < 1 ||
2665 sc->stsc_data[i].id < 1) {
2666 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);
2667 if (i+1 >= sc->stsc_count) {
2668 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
2669 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
2670 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
2671 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
2672 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
2675 av_assert0(sc->stsc_data[i+1].first >= 2);
2676 // We replace this entry by the next valid
2677 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
2678 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
2679 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
2683 if (pb->eof_reached) {
2684 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
2691 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
2693 return index < count - 1;
2696 /* Compute the samples value for the stsc entry at the given index. */
2697 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
2701 if (mov_stsc_index_valid(index, sc->stsc_count))
2702 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
2704 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
2705 av_assert0(sc->stsc_data[index].first <= sc->chunk_count);
2706 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
2709 return sc->stsc_data[index].count * (int64_t)chunk_count;
2712 static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2715 MOVStreamContext *sc;
2716 unsigned i, entries;
2718 if (c->fc->nb_streams < 1)
2720 st = c->fc->streams[c->fc->nb_streams-1];
2723 avio_rb32(pb); // version + flags
2725 entries = avio_rb32(pb);
2727 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
2728 av_free(sc->stps_data);
2730 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
2732 return AVERROR(ENOMEM);
2734 for (i = 0; i < entries && !pb->eof_reached; i++) {
2735 sc->stps_data[i] = avio_rb32(pb);
2740 if (pb->eof_reached) {
2741 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
2748 static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2751 MOVStreamContext *sc;
2752 unsigned int i, entries;
2754 if (c->fc->nb_streams < 1)
2756 st = c->fc->streams[c->fc->nb_streams-1];
2759 avio_r8(pb); /* version */
2760 avio_rb24(pb); /* flags */
2762 entries = avio_rb32(pb);
2764 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
2768 sc->keyframe_absent = 1;
2769 if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
2770 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2774 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
2775 if (entries >= UINT_MAX / sizeof(int))
2776 return AVERROR_INVALIDDATA;
2777 av_freep(&sc->keyframes);
2778 sc->keyframe_count = 0;
2779 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
2781 return AVERROR(ENOMEM);
2783 for (i = 0; i < entries && !pb->eof_reached; i++) {
2784 sc->keyframes[i] = avio_rb32(pb);
2787 sc->keyframe_count = i;
2789 if (pb->eof_reached) {
2790 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
2797 static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2800 MOVStreamContext *sc;
2801 unsigned int i, entries, sample_size, field_size, num_bytes;
2806 if (c->fc->nb_streams < 1)
2808 st = c->fc->streams[c->fc->nb_streams-1];
2811 avio_r8(pb); /* version */
2812 avio_rb24(pb); /* flags */
2814 if (atom.type == MKTAG('s','t','s','z')) {
2815 sample_size = avio_rb32(pb);
2816 if (!sc->sample_size) /* do not overwrite value computed in stsd */
2817 sc->sample_size = sample_size;
2818 sc->stsz_sample_size = sample_size;
2822 avio_rb24(pb); /* reserved */
2823 field_size = avio_r8(pb);
2825 entries = avio_rb32(pb);
2827 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
2829 sc->sample_count = entries;
2833 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
2834 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
2835 return AVERROR_INVALIDDATA;
2840 if (entries >= (UINT_MAX - 4) / field_size)
2841 return AVERROR_INVALIDDATA;
2842 if (sc->sample_sizes)
2843 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
2844 av_free(sc->sample_sizes);
2845 sc->sample_count = 0;
2846 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
2847 if (!sc->sample_sizes)
2848 return AVERROR(ENOMEM);
2850 num_bytes = (entries*field_size+4)>>3;
2852 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
2854 av_freep(&sc->sample_sizes);
2855 return AVERROR(ENOMEM);
2858 ret = ffio_read_size(pb, buf, num_bytes);
2860 av_freep(&sc->sample_sizes);
2862 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
2866 init_get_bits(&gb, buf, 8*num_bytes);
2868 for (i = 0; i < entries && !pb->eof_reached; i++) {
2869 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
2870 sc->data_size += sc->sample_sizes[i];
2873 sc->sample_count = i;
2877 if (pb->eof_reached) {
2878 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSZ atom\n");
2885 static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2888 MOVStreamContext *sc;
2889 unsigned int i, entries, alloc_size = 0;
2891 int64_t total_sample_count=0;
2893 if (c->fc->nb_streams < 1)
2895 st = c->fc->streams[c->fc->nb_streams-1];
2898 avio_r8(pb); /* version */
2899 avio_rb24(pb); /* flags */
2900 entries = avio_rb32(pb);
2902 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
2903 c->fc->nb_streams-1, entries);
2906 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
2907 av_freep(&sc->stts_data);
2909 if (entries >= INT_MAX / sizeof(*sc->stts_data))
2910 return AVERROR(ENOMEM);
2912 for (i = 0; i < entries && !pb->eof_reached; i++) {
2913 int sample_duration;
2914 unsigned int sample_count;
2915 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
2916 MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
2917 min_entries * sizeof(*sc->stts_data));
2919 av_freep(&sc->stts_data);
2921 return AVERROR(ENOMEM);
2923 sc->stts_count = min_entries;
2924 sc->stts_data = stts_data;
2926 sample_count=avio_rb32(pb);
2927 sample_duration = avio_rb32(pb);
2929 sc->stts_data[i].count= sample_count;
2930 sc->stts_data[i].duration= sample_duration;
2932 av_log(c->fc, AV_LOG_TRACE, "sample_count=%d, sample_duration=%d\n",
2933 sample_count, sample_duration);
2935 duration+=(int64_t)sample_duration*(uint64_t)sample_count;
2936 total_sample_count+=sample_count;
2942 duration <= INT64_MAX - sc->duration_for_fps &&
2943 total_sample_count <= INT_MAX - sc->nb_frames_for_fps
2945 sc->duration_for_fps += duration;
2946 sc->nb_frames_for_fps += total_sample_count;
2949 if (pb->eof_reached) {
2950 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
2954 st->nb_frames= total_sample_count;
2956 st->duration= FFMIN(st->duration, duration);
2957 sc->track_end = duration;
2961 static void mov_update_dts_shift(MOVStreamContext *sc, int duration)
2964 if (duration == INT_MIN) {
2965 av_log(NULL, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
2968 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
2972 static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2975 MOVStreamContext *sc;
2976 unsigned int i, entries, ctts_count = 0;
2978 if (c->fc->nb_streams < 1)
2980 st = c->fc->streams[c->fc->nb_streams-1];
2983 avio_r8(pb); /* version */
2984 avio_rb24(pb); /* flags */
2985 entries = avio_rb32(pb);
2987 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
2991 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
2992 return AVERROR_INVALIDDATA;
2993 av_freep(&sc->ctts_data);
2994 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
2996 return AVERROR(ENOMEM);
2998 for (i = 0; i < entries && !pb->eof_reached; i++) {
2999 int count =avio_rb32(pb);
3000 int duration =avio_rb32(pb);
3003 av_log(c->fc, AV_LOG_TRACE,
3004 "ignoring CTTS entry with count=%d duration=%d\n",
3009 add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3012 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3015 if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3016 av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3017 av_freep(&sc->ctts_data);
3023 mov_update_dts_shift(sc, duration);
3026 sc->ctts_count = ctts_count;
3028 if (pb->eof_reached) {
3029 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3033 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3038 static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3041 MOVStreamContext *sc;
3042 unsigned int i, entries;
3044 uint32_t grouping_type;
3046 if (c->fc->nb_streams < 1)
3048 st = c->fc->streams[c->fc->nb_streams-1];
3051 version = avio_r8(pb); /* version */
3052 avio_rb24(pb); /* flags */
3053 grouping_type = avio_rl32(pb);
3054 if (grouping_type != MKTAG( 'r','a','p',' '))
3055 return 0; /* only support 'rap ' grouping */
3057 avio_rb32(pb); /* grouping_type_parameter */
3059 entries = avio_rb32(pb);
3063 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP atom\n");
3064 av_free(sc->rap_group);
3065 sc->rap_group_count = 0;
3066 sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group));
3068 return AVERROR(ENOMEM);
3070 for (i = 0; i < entries && !pb->eof_reached; i++) {
3071 sc->rap_group[i].count = avio_rb32(pb); /* sample_count */
3072 sc->rap_group[i].index = avio_rb32(pb); /* group_description_index */
3075 sc->rap_group_count = i;
3077 if (pb->eof_reached) {
3078 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3086 * Get ith edit list entry (media time, duration).
3088 static int get_edit_list_entry(MOVContext *mov,
3089 const MOVStreamContext *msc,
3090 unsigned int edit_list_index,
3091 int64_t *edit_list_media_time,
3092 int64_t *edit_list_duration,
3093 int64_t global_timescale)
3095 if (edit_list_index == msc->elst_count) {
3098 *edit_list_media_time = msc->elst_data[edit_list_index].time;
3099 *edit_list_duration = msc->elst_data[edit_list_index].duration;
3101 /* duration is in global timescale units;convert to msc timescale */
3102 if (global_timescale == 0) {
3103 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3106 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3112 * Find the closest previous frame to the timestamp_pts, in e_old index
3113 * entries. Searching for just any frame / just key frames can be controlled by
3114 * last argument 'flag'.
3115 * Note that if ctts_data is not NULL, we will always search for a key frame
3116 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3117 * return the first frame of the video.
3119 * Here the timestamp_pts is considered to be a presentation timestamp and
3120 * the timestamp of index entries are considered to be decoding timestamps.
3122 * Returns 0 if successful in finding a frame, else returns -1.
3123 * Places the found index corresponding output arg.
3125 * If ctts_old is not NULL, then refines the searched entry by searching
3126 * backwards from the found timestamp, to find the frame with correct PTS.
3128 * Places the found ctts_index and ctts_sample in corresponding output args.
3130 static int find_prev_closest_index(AVStream *st,
3131 AVIndexEntry *e_old,
3135 int64_t timestamp_pts,
3138 int64_t* ctts_index,
3139 int64_t* ctts_sample)
3141 MOVStreamContext *msc = st->priv_data;
3142 AVIndexEntry *e_keep = st->index_entries;
3143 int nb_keep = st->nb_index_entries;
3145 int64_t index_ctts_count;
3149 // If dts_shift > 0, then all the index timestamps will have to be offset by
3150 // at least dts_shift amount to obtain PTS.
3151 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3152 if (msc->dts_shift > 0) {
3153 timestamp_pts -= msc->dts_shift;
3156 st->index_entries = e_old;
3157 st->nb_index_entries = nb_old;
3158 *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3160 // Keep going backwards in the index entries until the timestamp is the same.
3162 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3164 if ((flag & AVSEEK_FLAG_ANY) ||
3165 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3171 // If we have CTTS then refine the search, by searching backwards over PTS
3172 // computed by adding corresponding CTTS durations to index timestamps.
3173 if (ctts_data && *index >= 0) {
3174 av_assert0(ctts_index);
3175 av_assert0(ctts_sample);
3176 // Find out the ctts_index for the found frame.
3179 for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3180 if (*ctts_index < ctts_count) {
3182 if (ctts_data[*ctts_index].count == *ctts_sample) {
3189 while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3190 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3191 // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3192 // compensated by dts_shift above.
3193 if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3194 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3199 if (*ctts_sample == 0) {
3201 if (*ctts_index >= 0)
3202 *ctts_sample = ctts_data[*ctts_index].count - 1;
3209 /* restore AVStream state*/
3210 st->index_entries = e_keep;
3211 st->nb_index_entries = nb_keep;
3212 return *index >= 0 ? 0 : -1;
3216 * Add index entry with the given values, to the end of st->index_entries.
3217 * Returns the new size st->index_entries if successful, else returns -1.
3219 * This function is similar to ff_add_index_entry in libavformat/utils.c
3220 * except that here we are always unconditionally adding an index entry to
3221 * the end, instead of searching the entries list and skipping the add if
3222 * there is an existing entry with the same timestamp.
3223 * This is needed because the mov_fix_index calls this func with the same
3224 * unincremented timestamp for successive discarded frames.
3226 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3227 int size, int distance, int flags)
3229 AVIndexEntry *entries, *ie;
3231 const size_t min_size_needed = (st->nb_index_entries + 1) * sizeof(AVIndexEntry);
3233 // Double the allocation each time, to lower memory fragmentation.
3234 // Another difference from ff_add_index_entry function.
3235 const size_t requested_size =
3236 min_size_needed > st->index_entries_allocated_size ?
3237 FFMAX(min_size_needed, 2 * st->index_entries_allocated_size) :
3240 if((unsigned)st->nb_index_entries + 1 >= UINT_MAX / sizeof(AVIndexEntry))
3243 entries = av_fast_realloc(st->index_entries,
3244 &st->index_entries_allocated_size,
3249 st->index_entries= entries;
3251 index= st->nb_index_entries++;
3252 ie= &entries[index];
3255 ie->timestamp = timestamp;
3256 ie->min_distance= distance;
3263 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3264 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3266 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3267 int64_t* frame_duration_buffer,
3268 int frame_duration_buffer_size) {
3270 av_assert0(end_index >= 0 && end_index <= st->nb_index_entries);
3271 for (i = 0; i < frame_duration_buffer_size; i++) {
3272 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3273 st->index_entries[end_index - 1 - i].timestamp = end_ts;
3278 * Append a new ctts entry to ctts_data.
3279 * Returns the new ctts_count if successful, else returns -1.
3281 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3282 int count, int duration)
3284 MOVStts *ctts_buf_new;
3285 const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVStts);
3286 const size_t requested_size =
3287 min_size_needed > *allocated_size ?
3288 FFMAX(min_size_needed, 2 * (*allocated_size)) :
3291 if((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
3294 ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3299 *ctts_data = ctts_buf_new;
3301 ctts_buf_new[*ctts_count].count = count;
3302 ctts_buf_new[*ctts_count].duration = duration;
3304 *ctts_count = (*ctts_count) + 1;
3308 #define MAX_REORDER_DELAY 16
3309 static void mov_estimate_video_delay(MOVContext *c, AVStream* st) {
3310 MOVStreamContext *msc = st->priv_data;
3313 int ctts_sample = 0;
3314 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3316 int j, r, num_swaps;
3318 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3319 pts_buf[j] = INT64_MIN;
3321 if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3322 st->codecpar->codec_id == AV_CODEC_ID_H264) {
3323 st->codecpar->video_delay = 0;
3324 for(ind = 0; ind < st->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3325 // Point j to the last elem of the buffer and insert the current pts there.
3327 buf_start = (buf_start + 1);
3328 if (buf_start == MAX_REORDER_DELAY + 1)
3331 pts_buf[j] = st->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3333 // The timestamps that are already in the sorted buffer, and are greater than the
3334 // current pts, are exactly the timestamps that need to be buffered to output PTS
3335 // in correct sorted order.
3336 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3337 // can be computed as the maximum no. of swaps any particular timestamp needs to
3338 // go through, to keep this buffer in sorted order.
3340 while (j != buf_start) {
3342 if (r < 0) r = MAX_REORDER_DELAY;
3343 if (pts_buf[j] < pts_buf[r]) {
3344 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3351 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3354 if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3359 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3360 st->codecpar->video_delay, st->index);
3364 static void mov_current_sample_inc(MOVStreamContext *sc)
3366 sc->current_sample++;
3367 sc->current_index++;
3368 if (sc->index_ranges &&
3369 sc->current_index >= sc->current_index_range->end &&
3370 sc->current_index_range->end) {
3371 sc->current_index_range++;
3372 sc->current_index = sc->current_index_range->start;
3376 static void mov_current_sample_dec(MOVStreamContext *sc)
3378 sc->current_sample--;
3379 sc->current_index--;
3380 if (sc->index_ranges &&
3381 sc->current_index < sc->current_index_range->start &&
3382 sc->current_index_range > sc->index_ranges) {
3383 sc->current_index_range--;
3384 sc->current_index = sc->current_index_range->end - 1;
3388 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3392 sc->current_sample = current_sample;
3393 sc->current_index = current_sample;
3394 if (!sc->index_ranges) {
3398 for (sc->current_index_range = sc->index_ranges;
3399 sc->current_index_range->end;
3400 sc->current_index_range++) {
3401 range_size = sc->current_index_range->end - sc->current_index_range->start;
3402 if (range_size > current_sample) {
3403 sc->current_index = sc->current_index_range->start + current_sample;
3406 current_sample -= range_size;
3411 * Fix st->index_entries, so that it contains only the entries (and the entries
3412 * which are needed to decode them) that fall in the edit list time ranges.
3413 * Also fixes the timestamps of the index entries to match the timeline
3414 * specified the edit lists.
3416 static void mov_fix_index(MOVContext *mov, AVStream *st)
3418 MOVStreamContext *msc = st->priv_data;
3419 AVIndexEntry *e_old = st->index_entries;
3420 int nb_old = st->nb_index_entries;
3421 const AVIndexEntry *e_old_end = e_old + nb_old;
3422 const AVIndexEntry *current = NULL;
3423 MOVStts *ctts_data_old = msc->ctts_data;
3424 int64_t ctts_index_old = 0;
3425 int64_t ctts_sample_old = 0;
3426 int64_t ctts_count_old = msc->ctts_count;
3427 int64_t edit_list_media_time = 0;
3428 int64_t edit_list_duration = 0;
3429 int64_t frame_duration = 0;
3430 int64_t edit_list_dts_counter = 0;
3431 int64_t edit_list_dts_entry_end = 0;
3432 int64_t edit_list_start_ctts_sample = 0;
3434 int64_t curr_ctts = 0;
3435 int64_t empty_edits_sum_duration = 0;
3436 int64_t edit_list_index = 0;
3439 int64_t start_dts = 0;
3440 int64_t edit_list_start_encountered = 0;
3441 int64_t search_timestamp = 0;
3442 int64_t* frame_duration_buffer = NULL;
3443 int num_discarded_begin = 0;
3444 int first_non_zero_audio_edit = -1;
3445 int packet_skip_samples = 0;
3446 MOVIndexRange *current_index_range;
3448 int found_keyframe_after_edit = 0;
3449 int found_non_empty_edit = 0;
3451 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
3455 // allocate the index ranges array
3456 msc->index_ranges = av_malloc((msc->elst_count + 1) * sizeof(msc->index_ranges[0]));
3457 if (!msc->index_ranges) {
3458 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
3461 msc->current_index_range = msc->index_ranges;
3462 current_index_range = msc->index_ranges - 1;
3464 // Clean AVStream from traces of old index
3465 st->index_entries = NULL;
3466 st->index_entries_allocated_size = 0;
3467 st->nb_index_entries = 0;
3469 // Clean ctts fields of MOVStreamContext
3470 msc->ctts_data = NULL;
3471 msc->ctts_count = 0;
3472 msc->ctts_index = 0;
3473 msc->ctts_sample = 0;
3474 msc->ctts_allocated_size = 0;
3476 // Reinitialize min_corrected_pts so that it can be computed again.
3477 msc->min_corrected_pts = -1;
3479 // If the dts_shift is positive (in case of negative ctts values in mov),
3480 // then negate the DTS by dts_shift
3481 if (msc->dts_shift > 0) {
3482 edit_list_dts_entry_end -= msc->dts_shift;
3483 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
3486 start_dts = edit_list_dts_entry_end;
3488 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
3489 &edit_list_duration, mov->time_scale)) {
3490 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
3491 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
3493 edit_list_dts_counter = edit_list_dts_entry_end;
3494 edit_list_dts_entry_end += edit_list_duration;
3495 num_discarded_begin = 0;
3496 if (!found_non_empty_edit && edit_list_media_time == -1) {
3497 empty_edits_sum_duration += edit_list_duration;
3500 found_non_empty_edit = 1;
3502 // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
3503 // according to the edit list below.
3504 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3505 if (first_non_zero_audio_edit < 0) {
3506 first_non_zero_audio_edit = 1;
3508 first_non_zero_audio_edit = 0;
3511 if (first_non_zero_audio_edit > 0)
3512 st->skip_samples = msc->start_pad = 0;
3515 // While reordering frame index according to edit list we must handle properly
3516 // the scenario when edit list entry starts from none key frame.
3517 // We find closest previous key frame and preserve it and consequent frames in index.
3518 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
3519 search_timestamp = edit_list_media_time;
3520 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3521 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
3522 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
3523 // edit_list_media_time to cover the decoder delay.
3524 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
3527 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
3528 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3529 av_log(mov->fc, AV_LOG_WARNING,
3530 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
3531 st->index, edit_list_index, search_timestamp);
3532 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
3533 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3534 av_log(mov->fc, AV_LOG_WARNING,
3535 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
3536 st->index, edit_list_index, search_timestamp);
3539 ctts_sample_old = 0;
3542 current = e_old + index;
3543 edit_list_start_ctts_sample = ctts_sample_old;
3545 // Iterate over index and arrange it according to edit list
3546 edit_list_start_encountered = 0;
3547 found_keyframe_after_edit = 0;
3548 for (; current < e_old_end; current++, index++) {
3549 // check if frame outside edit list mark it for discard
3550 frame_duration = (current + 1 < e_old_end) ?
3551 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
3553 flags = current->flags;
3555 // frames (pts) before or after edit list
3556 curr_cts = current->timestamp + msc->dts_shift;
3559 if (ctts_data_old && ctts_index_old < ctts_count_old) {
3560 curr_ctts = ctts_data_old[ctts_index_old].duration;
3561 av_log(mov->fc, AV_LOG_DEBUG, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
3562 curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
3563 curr_cts += curr_ctts;
3565 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
3566 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3567 &msc->ctts_allocated_size,
3568 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3569 ctts_data_old[ctts_index_old].duration) == -1) {
3570 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3572 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3573 ctts_data_old[ctts_index_old].duration);
3577 ctts_sample_old = 0;
3578 edit_list_start_ctts_sample = 0;
3582 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
3583 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
3584 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
3585 first_non_zero_audio_edit > 0) {
3586 packet_skip_samples = edit_list_media_time - curr_cts;
3587 st->skip_samples += packet_skip_samples;
3589 // Shift the index entry timestamp by packet_skip_samples to be correct.
3590 edit_list_dts_counter -= packet_skip_samples;
3591 if (edit_list_start_encountered == 0) {
3592 edit_list_start_encountered = 1;
3593 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
3594 // discarded packets.
3595 if (frame_duration_buffer) {
3596 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3597 frame_duration_buffer, num_discarded_begin);
3598 av_freep(&frame_duration_buffer);
3602 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
3604 flags |= AVINDEX_DISCARD_FRAME;
3605 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
3607 if (edit_list_start_encountered == 0) {
3608 num_discarded_begin++;
3609 frame_duration_buffer = av_realloc(frame_duration_buffer,
3610 num_discarded_begin * sizeof(int64_t));
3611 if (!frame_duration_buffer) {
3612 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
3615 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
3617 // Increment skip_samples for the first non-zero audio edit list
3618 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3619 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
3620 st->skip_samples += frame_duration;
3625 if (msc->min_corrected_pts < 0) {
3626 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
3628 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
3630 if (edit_list_start_encountered == 0) {
3631 edit_list_start_encountered = 1;
3632 // Make timestamps strictly monotonically increasing by rewriting timestamps for
3633 // discarded packets.
3634 if (frame_duration_buffer) {
3635 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3636 frame_duration_buffer, num_discarded_begin);
3637 av_freep(&frame_duration_buffer);
3642 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
3643 current->min_distance, flags) == -1) {
3644 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
3648 // Update the index ranges array
3649 if (current_index_range < msc->index_ranges || index != current_index_range->end) {
3650 current_index_range++;
3651 current_index_range->start = index;
3653 current_index_range->end = index + 1;
3655 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
3656 if (edit_list_start_encountered > 0) {
3657 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
3660 // Break when found first key frame after edit entry completion
3661 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
3662 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
3663 if (ctts_data_old) {
3664 // If we have CTTS and this is the first keyframe after edit elist,
3665 // wait for one more, because there might be trailing B-frames after this I-frame
3666 // that do belong to the edit.
3667 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
3668 found_keyframe_after_edit = 1;
3671 if (ctts_sample_old != 0) {
3672 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3673 &msc->ctts_allocated_size,
3674 ctts_sample_old - edit_list_start_ctts_sample,
3675 ctts_data_old[ctts_index_old].duration) == -1) {
3676 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3677 ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
3678 ctts_data_old[ctts_index_old].duration);
3687 // If there are empty edits, then msc->min_corrected_pts might be positive
3688 // intentionally. So we subtract the sum duration of emtpy edits here.
3689 msc->min_corrected_pts -= empty_edits_sum_duration;
3691 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
3692 // dts by that amount to make the first pts zero.
3693 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
3694 if (msc->min_corrected_pts > 0) {
3695 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
3696 for (i = 0; i < st->nb_index_entries; ++i) {
3697 st->index_entries[i].timestamp -= msc->min_corrected_pts;
3701 // Start time should be equal to zero or the duration of any empty edits.
3702 st->start_time = empty_edits_sum_duration;
3704 // Update av stream length, if it ends up shorter than the track's media duration
3705 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
3706 msc->start_pad = st->skip_samples;
3708 // Free the old index and the old CTTS structures
3710 av_free(ctts_data_old);
3711 av_freep(&frame_duration_buffer);
3713 // Null terminate the index ranges array
3714 current_index_range++;
3715 current_index_range->start = 0;
3716 current_index_range->end = 0;
3717 msc->current_index = msc->index_ranges[0].start;
3720 static void mov_build_index(MOVContext *mov, AVStream *st)
3722 MOVStreamContext *sc = st->priv_data;
3723 int64_t current_offset;
3724 int64_t current_dts = 0;
3725 unsigned int stts_index = 0;
3726 unsigned int stsc_index = 0;
3727 unsigned int stss_index = 0;
3728 unsigned int stps_index = 0;
3730 uint64_t stream_size = 0;
3731 MOVStts *ctts_data_old = sc->ctts_data;
3732 unsigned int ctts_count_old = sc->ctts_count;
3734 if (sc->elst_count) {
3735 int i, edit_start_index = 0, multiple_edits = 0;
3736 int64_t empty_duration = 0; // empty duration of the first edit list entry
3737 int64_t start_time = 0; // start time of the media
3739 for (i = 0; i < sc->elst_count; i++) {
3740 const MOVElst *e = &sc->elst_data[i];
3741 if (i == 0 && e->time == -1) {
3742 /* if empty, the first entry is the start time of the stream
3743 * relative to the presentation itself */
3744 empty_duration = e->duration;
3745 edit_start_index = 1;
3746 } else if (i == edit_start_index && e->time >= 0) {
3747 start_time = e->time;
3753 if (multiple_edits && !mov->advanced_editlist)
3754 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
3755 "Use -advanced_editlist to correctly decode otherwise "
3756 "a/v desync might occur\n");
3758 /* adjust first dts according to edit list */
3759 if ((empty_duration || start_time) && mov->time_scale > 0) {
3761 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
3762 sc->time_offset = start_time - empty_duration;
3763 sc->min_corrected_pts = start_time;
3764 if (!mov->advanced_editlist)
3765 current_dts = -sc->time_offset;
3768 if (!multiple_edits && !mov->advanced_editlist &&
3769 st->codecpar->codec_id == AV_CODEC_ID_AAC && start_time > 0)
3770 sc->start_pad = start_time;
3773 /* only use old uncompressed audio chunk demuxing when stts specifies it */
3774 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3775 sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
3776 unsigned int current_sample = 0;
3777 unsigned int stts_sample = 0;
3778 unsigned int sample_size;
3779 unsigned int distance = 0;
3780 unsigned int rap_group_index = 0;
3781 unsigned int rap_group_sample = 0;
3782 int64_t last_dts = 0;
3783 int64_t dts_correction = 0;
3784 int rap_group_present = sc->rap_group_count && sc->rap_group;
3785 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
3787 current_dts -= sc->dts_shift;
3788 last_dts = current_dts;
3790 if (!sc->sample_count || st->nb_index_entries)
3792 if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
3794 if (av_reallocp_array(&st->index_entries,
3795 st->nb_index_entries + sc->sample_count,
3796 sizeof(*st->index_entries)) < 0) {
3797 st->nb_index_entries = 0;
3800 st->index_entries_allocated_size = (st->nb_index_entries + sc->sample_count) * sizeof(*st->index_entries);
3802 if (ctts_data_old) {
3803 // Expand ctts entries such that we have a 1-1 mapping with samples
3804 if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
3807 sc->ctts_allocated_size = 0;
3808 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size,
3809 sc->sample_count * sizeof(*sc->ctts_data));
3810 if (!sc->ctts_data) {
3811 av_free(ctts_data_old);
3815 memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
3817 for (i = 0; i < ctts_count_old &&
3818 sc->ctts_count < sc->sample_count; i++)
3819 for (j = 0; j < ctts_data_old[i].count &&
3820 sc->ctts_count < sc->sample_count; j++)
3821 add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
3822 &sc->ctts_allocated_size, 1,
3823 ctts_data_old[i].duration);
3824 av_free(ctts_data_old);
3827 for (i = 0; i < sc->chunk_count; i++) {
3828 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
3829 current_offset = sc->chunk_offsets[i];
3830 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3831 i + 1 == sc->stsc_data[stsc_index + 1].first)
3834 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
3835 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
3836 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
3837 sc->stsz_sample_size = sc->sample_size;
3839 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
3840 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
3841 sc->stsz_sample_size = sc->sample_size;
3844 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
3846 if (current_sample >= sc->sample_count) {
3847 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
3851 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
3853 if (stss_index + 1 < sc->keyframe_count)
3855 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
3857 if (stps_index + 1 < sc->stps_count)
3860 if (rap_group_present && rap_group_index < sc->rap_group_count) {
3861 if (sc->rap_group[rap_group_index].index > 0)
3863 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
3864 rap_group_sample = 0;
3868 if (sc->keyframe_absent
3870 && !rap_group_present
3871 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
3875 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
3876 if (sc->pseudo_stream_id == -1 ||
3877 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
3879 if (sample_size > 0x3FFFFFFF) {
3880 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
3883 e = &st->index_entries[st->nb_index_entries++];
3884 e->pos = current_offset;
3885 e->timestamp = current_dts;
3886 e->size = sample_size;
3887 e->min_distance = distance;
3888 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
3889 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
3890 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
3891 current_offset, current_dts, sample_size, distance, keyframe);
3892 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries < 100)
3893 ff_rfps_add_frame(mov->fc, st, current_dts);
3896 current_offset += sample_size;
3897 stream_size += sample_size;
3899 /* A negative sample duration is invalid based on the spec,
3900 * but some samples need it to correct the DTS. */
3901 if (sc->stts_data[stts_index].duration < 0) {
3902 av_log(mov->fc, AV_LOG_WARNING,
3903 "Invalid SampleDelta %d in STTS, at %d st:%d\n",
3904 sc->stts_data[stts_index].duration, stts_index,
3906 dts_correction += sc->stts_data[stts_index].duration - 1;
3907 sc->stts_data[stts_index].duration = 1;
3909 current_dts += sc->stts_data[stts_index].duration;
3910 if (!dts_correction || current_dts + dts_correction > last_dts) {
3911 current_dts += dts_correction;
3914 /* Avoid creating non-monotonous DTS */
3915 dts_correction += current_dts - last_dts - 1;
3916 current_dts = last_dts + 1;
3918 last_dts = current_dts;
3922 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
3928 if (st->duration > 0)
3929 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
3931 unsigned chunk_samples, total = 0;
3933 if (!sc->chunk_count)
3936 // compute total chunk count
3937 for (i = 0; i < sc->stsc_count; i++) {
3938 unsigned count, chunk_count;
3940 chunk_samples = sc->stsc_data[i].count;
3941 if (i != sc->stsc_count - 1 &&
3942 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
3943 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
3947 if (sc->samples_per_frame >= 160) { // gsm
3948 count = chunk_samples / sc->samples_per_frame;
3949 } else if (sc->samples_per_frame > 1) {
3950 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
3951 count = (chunk_samples+samples-1) / samples;
3953 count = (chunk_samples+1023) / 1024;
3956 if (mov_stsc_index_valid(i, sc->stsc_count))
3957 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
3959 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
3960 total += chunk_count * count;
3963 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
3964 if (total >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
3966 if (av_reallocp_array(&st->index_entries,
3967 st->nb_index_entries + total,
3968 sizeof(*st->index_entries)) < 0) {
3969 st->nb_index_entries = 0;
3972 st->index_entries_allocated_size = (st->nb_index_entries + total) * sizeof(*st->index_entries);
3975 for (i = 0; i < sc->chunk_count; i++) {
3976 current_offset = sc->chunk_offsets[i];
3977 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3978 i + 1 == sc->stsc_data[stsc_index + 1].first)
3980 chunk_samples = sc->stsc_data[stsc_index].count;
3982 while (chunk_samples > 0) {
3984 unsigned size, samples;
3986 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
3987 avpriv_request_sample(mov->fc,
3988 "Zero bytes per frame, but %d samples per frame",
3989 sc->samples_per_frame);
3993 if (sc->samples_per_frame >= 160) { // gsm
3994 samples = sc->samples_per_frame;
3995 size = sc->bytes_per_frame;
3997 if (sc->samples_per_frame > 1) {
3998 samples = FFMIN((1024 / sc->samples_per_frame)*
3999 sc->samples_per_frame, chunk_samples);
4000 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
4002 samples = FFMIN(1024, chunk_samples);
4003 size = samples * sc->sample_size;
4007 if (st->nb_index_entries >= total) {
4008 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4011 if (size > 0x3FFFFFFF) {
4012 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4015 e = &st->index_entries[st->nb_index_entries++];
4016 e->pos = current_offset;
4017 e->timestamp = current_dts;
4019 e->min_distance = 0;
4020 e->flags = AVINDEX_KEYFRAME;
4021 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4022 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4025 current_offset += size;
4026 current_dts += samples;
4027 chunk_samples -= samples;
4032 if (!mov->ignore_editlist && mov->advanced_editlist) {
4033 // Fix index according to edit lists.
4034 mov_fix_index(mov, st);
4037 // Update start time of the stream.
4038 if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries > 0) {
4039 st->start_time = st->index_entries[0].timestamp + sc->dts_shift;
4040 if (sc->ctts_data) {
4041 st->start_time += sc->ctts_data[0].duration;
4045 mov_estimate_video_delay(mov, st);
4048 static int test_same_origin(const char *src, const char *ref) {
4058 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4059 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4061 if (strlen(src) == 0) {
4063 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4064 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4065 strlen(src_host) + 1 >= sizeof(src_host) ||
4066 strlen(ref_host) + 1 >= sizeof(ref_host)) {
4068 } else if (strcmp(src_proto, ref_proto) ||
4069 strcmp(src_auth, ref_auth) ||
4070 strcmp(src_host, ref_host) ||
4071 src_port != ref_port) {
4077 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4079 /* try relative path, we do not try the absolute because it can leak information about our
4080 system to an attacker */
4081 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4082 char filename[1025];
4083 const char *src_path;
4086 /* find a source dir */
4087 src_path = strrchr(src, '/');
4093 /* find a next level down to target */
4094 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4095 if (ref->path[l] == '/') {
4096 if (i == ref->nlvl_to - 1)
4102 /* compose filename if next level down to target was found */
4103 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4104 memcpy(filename, src, src_path - src);
4105 filename[src_path - src] = 0;
4107 for (i = 1; i < ref->nlvl_from; i++)
4108 av_strlcat(filename, "../", sizeof(filename));
4110 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4111 if (!c->use_absolute_path) {
4112 int same_origin = test_same_origin(src, filename);
4115 av_log(c->fc, AV_LOG_ERROR,
4116 "Reference with mismatching origin, %s not tried for security reasons, "
4117 "set demuxer option use_absolute_path to allow it anyway\n",
4119 return AVERROR(ENOENT);
4122 if(strstr(ref->path + l + 1, "..") ||
4123 strstr(ref->path + l + 1, ":") ||
4124 (ref->nlvl_from > 1 && same_origin < 0) ||
4125 (filename[0] == '/' && src_path == src))
4126 return AVERROR(ENOENT);
4129 if (strlen(filename) + 1 == sizeof(filename))
4130 return AVERROR(ENOENT);
4131 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4134 } else if (c->use_absolute_path) {
4135 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4136 "this is a possible security issue\n");
4137 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4140 av_log(c->fc, AV_LOG_ERROR,
4141 "Absolute path %s not tried for security reasons, "
4142 "set demuxer option use_absolute_path to allow absolute paths\n",
4146 return AVERROR(ENOENT);
4149 static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
4151 if (sc->time_scale <= 0) {
4152 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4153 sc->time_scale = c->time_scale;
4154 if (sc->time_scale <= 0)
4159 static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4162 MOVStreamContext *sc;
4165 st = avformat_new_stream(c->fc, NULL);
4166 if (!st) return AVERROR(ENOMEM);
4168 sc = av_mallocz(sizeof(MOVStreamContext));
4169 if (!sc) return AVERROR(ENOMEM);
4172 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
4173 sc->ffindex = st->index;
4174 c->trak_index = st->index;
4176 if ((ret = mov_read_default(c, pb, atom)) < 0)
4181 // Here stsc refers to a chunk not described in stco. This is technically invalid,
4182 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4183 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4185 av_freep(&sc->stsc_data);
4189 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4190 (!sc->sample_size && !sc->sample_count))) ||
4191 (!sc->chunk_count && sc->sample_count)) {
4192 av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4196 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4197 av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4199 return AVERROR_INVALIDDATA;
4202 fix_timescale(c, sc);
4204 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4206 mov_build_index(c, st);
4208 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4209 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4210 if (c->enable_drefs) {
4211 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4212 av_log(c->fc, AV_LOG_ERROR,
4213 "stream %d, error opening alias: path='%s', dir='%s', "
4214 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4215 st->index, dref->path, dref->dir, dref->filename,
4216 dref->volume, dref->nlvl_from, dref->nlvl_to);
4218 av_log(c->fc, AV_LOG_WARNING,
4219 "Skipped opening external track: "
4220 "stream %d, alias: path='%s', dir='%s', "
4221 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4222 "Set enable_drefs to allow this.\n",
4223 st->index, dref->path, dref->dir, dref->filename,
4224 dref->volume, dref->nlvl_from, dref->nlvl_to);
4228 sc->pb_is_copied = 1;
4231 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4232 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4233 sc->height && sc->width &&
4234 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4235 st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4236 ((double)st->codecpar->width * sc->height), INT_MAX);
4239 #if FF_API_R_FRAME_RATE
4240 if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4241 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
4242 sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4246 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4247 if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4248 TAG_IS_AVCI(st->codecpar->codec_tag)) {
4249 ret = ff_generate_avci_extradata(st);
4254 switch (st->codecpar->codec_id) {
4255 #if CONFIG_H261_DECODER
4256 case AV_CODEC_ID_H261:
4258 #if CONFIG_H263_DECODER
4259 case AV_CODEC_ID_H263:
4261 #if CONFIG_MPEG4_DECODER
4262 case AV_CODEC_ID_MPEG4:
4264 st->codecpar->width = 0; /* let decoder init width/height */
4265 st->codecpar->height= 0;
4269 // If the duration of the mp3 packets is not constant, then they could need a parser
4270 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4271 && sc->stts_count > 3
4272 && sc->stts_count*10 > st->nb_frames
4273 && sc->time_scale == st->codecpar->sample_rate) {
4274 st->need_parsing = AVSTREAM_PARSE_FULL;
4276 /* Do not need those anymore. */
4277 av_freep(&sc->chunk_offsets);
4278 av_freep(&sc->sample_sizes);
4279 av_freep(&sc->keyframes);
4280 av_freep(&sc->stts_data);
4281 av_freep(&sc->stps_data);
4282 av_freep(&sc->elst_data);
4283 av_freep(&sc->rap_group);
4288 static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4291 c->itunes_metadata = 1;
4292 ret = mov_read_default(c, pb, atom);
4293 c->itunes_metadata = 0;
4297 static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4306 count = avio_rb32(pb);
4307 if (count > UINT_MAX / sizeof(*c->meta_keys) - 1) {
4308 av_log(c->fc, AV_LOG_ERROR,
4309 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
4310 return AVERROR_INVALIDDATA;
4313 c->meta_keys_count = count + 1;
4314 c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
4316 return AVERROR(ENOMEM);
4318 for (i = 1; i <= count; ++i) {
4319 uint32_t key_size = avio_rb32(pb);
4320 uint32_t type = avio_rl32(pb);
4322 av_log(c->fc, AV_LOG_ERROR,
4323 "The key# %"PRIu32" in meta has invalid size:"
4324 "%"PRIu32"\n", i, key_size);
4325 return AVERROR_INVALIDDATA;
4328 if (type != MKTAG('m','d','t','a')) {
4329 avio_skip(pb, key_size);
4331 c->meta_keys[i] = av_mallocz(key_size + 1);
4332 if (!c->meta_keys[i])
4333 return AVERROR(ENOMEM);
4334 avio_read(pb, c->meta_keys[i], key_size);
4340 static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4342 int64_t end = avio_tell(pb) + atom.size;
4343 uint8_t *key = NULL, *val = NULL, *mean = NULL;
4347 MOVStreamContext *sc;
4349 if (c->fc->nb_streams < 1)
4351 st = c->fc->streams[c->fc->nb_streams-1];
4354 for (i = 0; i < 3; i++) {
4358 if (end - avio_tell(pb) <= 12)
4361 len = avio_rb32(pb);
4362 tag = avio_rl32(pb);
4363 avio_skip(pb, 4); // flags
4365 if (len < 12 || len - 12 > end - avio_tell(pb))
4369 if (tag == MKTAG('m', 'e', 'a', 'n'))
4371 else if (tag == MKTAG('n', 'a', 'm', 'e'))
4373 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
4380 *p = av_malloc(len + 1);
4382 ret = AVERROR(ENOMEM);
4385 ret = ffio_read_size(pb, *p, len);
4393 if (mean && key && val) {
4394 if (strcmp(key, "iTunSMPB") == 0) {
4395 int priming, remainder, samples;
4396 if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
4397 if(priming>0 && priming<16384)
4398 sc->start_pad = priming;
4401 if (strcmp(key, "cdec") != 0) {
4402 av_dict_set(&c->fc->metadata, key, val,
4403 AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
4407 av_log(c->fc, AV_LOG_VERBOSE,
4408 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
4411 avio_seek(pb, end, SEEK_SET);
4418 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4420 while (atom.size > 8) {
4421 uint32_t tag = avio_rl32(pb);
4423 if (tag == MKTAG('h','d','l','r')) {
4424 avio_seek(pb, -8, SEEK_CUR);
4426 return mov_read_default(c, pb, atom);
4432 // return 1 when matrix is identity, 0 otherwise
4433 #define IS_MATRIX_IDENT(matrix) \
4434 ( (matrix)[0][0] == (1 << 16) && \
4435 (matrix)[1][1] == (1 << 16) && \
4436 (matrix)[2][2] == (1 << 30) && \
4437 !(matrix)[0][1] && !(matrix)[0][2] && \
4438 !(matrix)[1][0] && !(matrix)[1][2] && \
4439 !(matrix)[2][0] && !(matrix)[2][1])
4441 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4446 int display_matrix[3][3];
4447 int res_display_matrix[3][3] = { { 0 } };
4449 MOVStreamContext *sc;
4453 if (c->fc->nb_streams < 1)
4455 st = c->fc->streams[c->fc->nb_streams-1];
4458 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4459 // avoids corrupting AVStreams mapped to an earlier tkhd.
4461 return AVERROR_INVALIDDATA;
4463 version = avio_r8(pb);
4464 flags = avio_rb24(pb);
4465 st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
4471 avio_rb32(pb); /* creation time */
4472 avio_rb32(pb); /* modification time */
4474 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4475 avio_rb32(pb); /* reserved */
4477 /* highlevel (considering edits) duration in movie timebase */
4478 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4479 avio_rb32(pb); /* reserved */
4480 avio_rb32(pb); /* reserved */
4482 avio_rb16(pb); /* layer */
4483 avio_rb16(pb); /* alternate group */
4484 avio_rb16(pb); /* volume */
4485 avio_rb16(pb); /* reserved */
4487 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4488 // they're kept in fixed point format through all calculations
4489 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4490 // side data, but the scale factor is not needed to calculate aspect ratio
4491 for (i = 0; i < 3; i++) {
4492 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
4493 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
4494 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
4497 width = avio_rb32(pb); // 16.16 fixed point track width
4498 height = avio_rb32(pb); // 16.16 fixed point track height
4499 sc->width = width >> 16;
4500 sc->height = height >> 16;
4502 // apply the moov display matrix (after the tkhd one)
4503 for (i = 0; i < 3; i++) {
4504 const int sh[3] = { 16, 16, 30 };
4505 for (j = 0; j < 3; j++) {
4506 for (e = 0; e < 3; e++) {
4507 res_display_matrix[i][j] +=
4508 ((int64_t) display_matrix[i][e] *
4509 c->movie_display_matrix[e][j]) >> sh[e];
4514 // save the matrix when it is not the default identity
4515 if (!IS_MATRIX_IDENT(res_display_matrix)) {
4518 av_freep(&sc->display_matrix);
4519 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4520 if (!sc->display_matrix)
4521 return AVERROR(ENOMEM);
4523 for (i = 0; i < 3; i++)
4524 for (j = 0; j < 3; j++)
4525 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4527 #if FF_API_OLD_ROTATE_API
4528 rotate = av_display_rotation_get(sc->display_matrix);
4529 if (!isnan(rotate)) {
4530 char rotate_buf[64];
4532 if (rotate < 0) // for backward compatibility
4534 snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate);
4535 av_dict_set(&st->metadata, "rotate", rotate_buf, 0);
4540 // transform the display width/height according to the matrix
4541 // to keep the same scale, use [width height 1<<16]
4542 if (width && height && sc->display_matrix) {
4543 double disp_transform[2];
4545 for (i = 0; i < 2; i++)
4546 disp_transform[i] = hypot(sc->display_matrix[0 + i],
4547 sc->display_matrix[3 + i]);
4549 if (disp_transform[0] > 0 && disp_transform[1] > 0 &&
4550 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4551 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4552 st->sample_aspect_ratio = av_d2q(
4553 disp_transform[0] / disp_transform[1],
4559 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4561 MOVFragment *frag = &c->fragment;
4562 MOVTrackExt *trex = NULL;
4563 int flags, track_id, i;
4565 avio_r8(pb); /* version */
4566 flags = avio_rb24(pb);
4568 track_id = avio_rb32(pb);
4570 return AVERROR_INVALIDDATA;
4571 for (i = 0; i < c->trex_count; i++)
4572 if (c->trex_data[i].track_id == track_id) {
4573 trex = &c->trex_data[i];
4577 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4580 c->fragment.found_tfhd = 1;
4581 frag->track_id = track_id;
4582 set_frag_stream(&c->frag_index, track_id);
4584 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4585 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4586 frag->moof_offset : frag->implicit_offset;
4587 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4589 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4590 avio_rb32(pb) : trex->duration;
4591 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4592 avio_rb32(pb) : trex->size;
4593 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4594 avio_rb32(pb) : trex->flags;
4595 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4600 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4605 num = atom.size / 4;
4606 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4607 return AVERROR(ENOMEM);
4609 av_free(c->chapter_tracks);
4610 c->chapter_tracks = new_tracks;
4611 c->nb_chapter_tracks = num;
4613 for (i = 0; i < num && !pb->eof_reached; i++)
4614 c->chapter_tracks[i] = avio_rb32(pb);
4619 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4624 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4625 return AVERROR_INVALIDDATA;
4626 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4627 sizeof(*c->trex_data))) < 0) {
4632 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4634 trex = &c->trex_data[c->trex_count++];
4635 avio_r8(pb); /* version */
4636 avio_rb24(pb); /* flags */
4637 trex->track_id = avio_rb32(pb);
4638 trex->stsd_id = avio_rb32(pb);
4639 trex->duration = avio_rb32(pb);
4640 trex->size = avio_rb32(pb);
4641 trex->flags = avio_rb32(pb);
4645 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4647 MOVFragment *frag = &c->fragment;
4648 AVStream *st = NULL;
4649 MOVStreamContext *sc;
4651 MOVFragmentStreamInfo * frag_stream_info;
4652 int64_t base_media_decode_time;
4654 for (i = 0; i < c->fc->nb_streams; i++) {
4655 if (c->fc->streams[i]->id == frag->track_id) {
4656 st = c->fc->streams[i];
4661 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4665 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4667 version = avio_r8(pb);
4668 avio_rb24(pb); /* flags */
4670 base_media_decode_time = avio_rb64(pb);
4672 base_media_decode_time = avio_rb32(pb);
4675 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4676 if (frag_stream_info)
4677 frag_stream_info->tfdt_dts = base_media_decode_time;
4678 sc->track_end = base_media_decode_time;
4683 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4685 MOVFragment *frag = &c->fragment;
4686 AVStream *st = NULL;
4687 MOVStreamContext *sc;
4690 int64_t dts, pts = AV_NOPTS_VALUE;
4691 int data_offset = 0;
4692 unsigned entries, first_sample_flags = frag->flags;
4693 int flags, distance, i;
4694 int64_t prev_dts = AV_NOPTS_VALUE;
4695 int next_frag_index = -1, index_entry_pos;
4696 size_t requested_size;
4697 size_t old_ctts_allocated_size;
4698 AVIndexEntry *new_entries;
4699 MOVFragmentStreamInfo * frag_stream_info;
4701 if (!frag->found_tfhd) {
4702 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4703 return AVERROR_INVALIDDATA;
4706 for (i = 0; i < c->fc->nb_streams; i++) {
4707 if (c->fc->streams[i]->id == frag->track_id) {
4708 st = c->fc->streams[i];
4713 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4717 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4720 // Find the next frag_index index that has a valid index_entry for
4721 // the current track_id.
4723 // A valid index_entry means the trun for the fragment was read
4724 // and it's samples are in index_entries at the given position.
4725 // New index entries will be inserted before the index_entry found.
4726 index_entry_pos = st->nb_index_entries;
4727 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4728 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4729 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4730 next_frag_index = i;
4731 index_entry_pos = frag_stream_info->index_entry;
4735 av_assert0(index_entry_pos <= st->nb_index_entries);
4737 avio_r8(pb); /* version */
4738 flags = avio_rb24(pb);
4739 entries = avio_rb32(pb);
4740 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4742 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4743 return AVERROR_INVALIDDATA;
4744 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4745 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4747 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4748 if (frag_stream_info)
4750 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4751 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4752 pts = frag_stream_info->first_tfra_pts;
4753 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4754 ", using it for pts\n", pts);
4755 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4756 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4757 // pts = frag_stream_info->sidx_pts;
4758 dts = frag_stream_info->sidx_pts - sc->time_offset;
4759 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4760 ", using it for pts\n", pts);
4761 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4762 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4763 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4764 ", using it for dts\n", dts);
4766 dts = sc->track_end - sc->time_offset;
4767 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4768 ", using it for dts\n", dts);
4771 dts = sc->track_end - sc->time_offset;
4772 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4773 ", using it for dts\n", dts);
4775 offset = frag->base_data_offset + data_offset;
4777 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4779 // realloc space for new index entries
4780 if((uint64_t)st->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4781 entries = UINT_MAX / sizeof(AVIndexEntry) - st->nb_index_entries;
4782 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4787 requested_size = (st->nb_index_entries + entries) * sizeof(AVIndexEntry);
4788 new_entries = av_fast_realloc(st->index_entries,
4789 &st->index_entries_allocated_size,
4792 return AVERROR(ENOMEM);
4793 st->index_entries= new_entries;
4795 requested_size = (st->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4796 old_ctts_allocated_size = sc->ctts_allocated_size;
4797 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4800 return AVERROR(ENOMEM);
4801 sc->ctts_data = ctts_data;
4803 // In case there were samples without ctts entries, ensure they get
4804 // zero valued entries. This ensures clips which mix boxes with and
4805 // without ctts entries don't pickup uninitialized data.
4806 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4807 sc->ctts_allocated_size - old_ctts_allocated_size);
4809 if (index_entry_pos < st->nb_index_entries) {
4810 // Make hole in index_entries and ctts_data for new samples
4811 memmove(st->index_entries + index_entry_pos + entries,
4812 st->index_entries + index_entry_pos,
4813 sizeof(*st->index_entries) *
4814 (st->nb_index_entries - index_entry_pos));
4815 memmove(sc->ctts_data + index_entry_pos + entries,
4816 sc->ctts_data + index_entry_pos,
4817 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4818 if (index_entry_pos < sc->current_sample) {
4819 sc->current_sample += entries;
4823 st->nb_index_entries += entries;
4824 sc->ctts_count = st->nb_index_entries;
4826 // Record the index_entry position in frag_index of this fragment
4827 if (frag_stream_info)
4828 frag_stream_info->index_entry = index_entry_pos;
4830 if (index_entry_pos > 0)
4831 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4833 for (i = 0; i < entries && !pb->eof_reached; i++) {
4834 unsigned sample_size = frag->size;
4835 int sample_flags = i ? frag->flags : first_sample_flags;
4836 unsigned sample_duration = frag->duration;
4837 unsigned ctts_duration = 0;
4839 int index_entry_flags = 0;
4841 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4842 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4843 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4844 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4846 mov_update_dts_shift(sc, ctts_duration);
4847 if (pts != AV_NOPTS_VALUE) {
4848 dts = pts - sc->dts_shift;
4849 if (flags & MOV_TRUN_SAMPLE_CTS) {
4850 dts -= ctts_duration;
4852 dts -= sc->time_offset;
4854 av_log(c->fc, AV_LOG_DEBUG,
4855 "pts %"PRId64" calculated dts %"PRId64
4856 " sc->dts_shift %d ctts.duration %d"
4857 " sc->time_offset %"PRId64
4858 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4860 sc->dts_shift, ctts_duration,
4861 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4862 pts = AV_NOPTS_VALUE;
4865 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4869 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4870 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4873 index_entry_flags |= AVINDEX_KEYFRAME;
4875 // Fragments can overlap in time. Discard overlapping frames after
4877 if (prev_dts >= dts)
4878 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4880 st->index_entries[index_entry_pos].pos = offset;
4881 st->index_entries[index_entry_pos].timestamp = dts;
4882 st->index_entries[index_entry_pos].size= sample_size;
4883 st->index_entries[index_entry_pos].min_distance= distance;
4884 st->index_entries[index_entry_pos].flags = index_entry_flags;
4886 sc->ctts_data[index_entry_pos].count = 1;
4887 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4890 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4891 "size %u, distance %d, keyframe %d\n", st->index,
4892 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4894 dts += sample_duration;
4895 offset += sample_size;
4896 sc->data_size += sample_size;
4898 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4899 1 <= INT_MAX - sc->nb_frames_for_fps
4901 sc->duration_for_fps += sample_duration;
4902 sc->nb_frames_for_fps ++;
4906 // EOF found before reading all entries. Fix the hole this would
4907 // leave in index_entries and ctts_data
4908 int gap = entries - i;
4909 memmove(st->index_entries + index_entry_pos,
4910 st->index_entries + index_entry_pos + gap,
4911 sizeof(*st->index_entries) *
4912 (st->nb_index_entries - (index_entry_pos + gap)));
4913 memmove(sc->ctts_data + index_entry_pos,
4914 sc->ctts_data + index_entry_pos + gap,
4915 sizeof(*sc->ctts_data) *
4916 (sc->ctts_count - (index_entry_pos + gap)));
4918 st->nb_index_entries -= gap;
4919 sc->ctts_count -= gap;
4920 if (index_entry_pos < sc->current_sample) {
4921 sc->current_sample -= gap;
4926 // The end of this new fragment may overlap in time with the start
4927 // of the next fragment in index_entries. Mark the samples in the next
4928 // fragment that overlap with AVINDEX_DISCARD_FRAME
4929 prev_dts = AV_NOPTS_VALUE;
4930 if (index_entry_pos > 0)
4931 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4932 for (i = index_entry_pos; i < st->nb_index_entries; i++) {
4933 if (prev_dts < st->index_entries[i].timestamp)
4935 st->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
4938 // If a hole was created to insert the new index_entries into,
4939 // the index_entry recorded for all subsequent moof must
4940 // be incremented by the number of entries inserted.
4941 fix_frag_index_entries(&c->frag_index, next_frag_index,
4942 frag->track_id, entries);
4944 if (pb->eof_reached) {
4945 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
4949 frag->implicit_offset = offset;
4951 sc->track_end = dts + sc->time_offset;
4952 if (st->duration < sc->track_end)
4953 st->duration = sc->track_end;
4958 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4960 int64_t offset = avio_tell(pb) + atom.size, pts, timestamp;
4962 unsigned i, j, track_id, item_count;
4963 AVStream *st = NULL;
4964 AVStream *ref_st = NULL;
4965 MOVStreamContext *sc, *ref_sc = NULL;
4966 AVRational timescale;
4968 version = avio_r8(pb);
4970 avpriv_request_sample(c->fc, "sidx version %u", version);
4974 avio_rb24(pb); // flags
4976 track_id = avio_rb32(pb); // Reference ID
4977 for (i = 0; i < c->fc->nb_streams; i++) {
4978 if (c->fc->streams[i]->id == track_id) {
4979 st = c->fc->streams[i];
4984 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
4990 timescale = av_make_q(1, avio_rb32(pb));
4992 if (timescale.den <= 0) {
4993 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
4994 return AVERROR_INVALIDDATA;
4998 pts = avio_rb32(pb);
4999 offset += avio_rb32(pb);
5001 pts = avio_rb64(pb);
5002 offset += avio_rb64(pb);
5005 avio_rb16(pb); // reserved
5007 item_count = avio_rb16(pb);
5009 for (i = 0; i < item_count; i++) {
5011 MOVFragmentStreamInfo * frag_stream_info;
5012 uint32_t size = avio_rb32(pb);
5013 uint32_t duration = avio_rb32(pb);
5014 if (size & 0x80000000) {
5015 avpriv_request_sample(c->fc, "sidx reference_type 1");
5016 return AVERROR_PATCHWELCOME;
5018 avio_rb32(pb); // sap_flags
5019 timestamp = av_rescale_q(pts, st->time_base, timescale);
5021 index = update_frag_index(c, offset);
5022 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5023 if (frag_stream_info)
5024 frag_stream_info->sidx_pts = timestamp;
5030 st->duration = sc->track_end = pts;
5034 if (offset == avio_size(pb)) {
5035 // Find first entry in fragment index that came from an sidx.
5036 // This will pretty much always be the first entry.
5037 for (i = 0; i < c->frag_index.nb_items; i++) {
5038 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5039 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5040 MOVFragmentStreamInfo * si;
5041 si = &item->stream_info[j];
5042 if (si->sidx_pts != AV_NOPTS_VALUE) {
5043 ref_st = c->fc->streams[j];
5044 ref_sc = ref_st->priv_data;
5049 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5050 st = c->fc->streams[i];
5052 if (!sc->has_sidx) {
5053 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5057 c->frag_index.complete = 1;
5063 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5064 /* like the files created with Adobe Premiere 5.0, for samples see */
5065 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5066 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5071 return 0; /* continue */
5072 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5073 avio_skip(pb, atom.size - 4);
5076 atom.type = avio_rl32(pb);
5078 if (atom.type != MKTAG('m','d','a','t')) {
5079 avio_skip(pb, atom.size);
5082 err = mov_read_mdat(c, pb, atom);
5086 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5091 uint8_t *moov_data; /* uncompressed data */
5092 long cmov_len, moov_len;
5095 avio_rb32(pb); /* dcom atom */
5096 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5097 return AVERROR_INVALIDDATA;
5098 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5099 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5100 return AVERROR_INVALIDDATA;
5102 avio_rb32(pb); /* cmvd atom */
5103 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5104 return AVERROR_INVALIDDATA;
5105 moov_len = avio_rb32(pb); /* uncompressed size */
5106 cmov_len = atom.size - 6 * 4;
5108 cmov_data = av_malloc(cmov_len);
5110 return AVERROR(ENOMEM);
5111 moov_data = av_malloc(moov_len);
5114 return AVERROR(ENOMEM);
5116 ret = ffio_read_size(pb, cmov_data, cmov_len);
5118 goto free_and_return;
5120 ret = AVERROR_INVALIDDATA;
5121 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5122 goto free_and_return;
5123 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5124 goto free_and_return;
5125 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5126 atom.type = MKTAG('m','o','o','v');
5127 atom.size = moov_len;
5128 ret = mov_read_default(c, &ctx, atom);
5134 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5135 return AVERROR(ENOSYS);
5139 /* edit list atom */
5140 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5142 MOVStreamContext *sc;
5143 int i, edit_count, version;
5144 int64_t elst_entry_size;
5146 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5148 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5150 version = avio_r8(pb); /* version */
5151 avio_rb24(pb); /* flags */
5152 edit_count = avio_rb32(pb); /* entries */
5155 elst_entry_size = version == 1 ? 20 : 12;
5156 if (atom.size != edit_count * elst_entry_size) {
5157 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5158 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5159 edit_count, atom.size + 8);
5160 return AVERROR_INVALIDDATA;
5162 edit_count = atom.size / elst_entry_size;
5163 if (edit_count * elst_entry_size != atom.size) {
5164 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.", atom.size, edit_count);
5172 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5173 av_free(sc->elst_data);
5175 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5177 return AVERROR(ENOMEM);
5179 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5180 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5181 MOVElst *e = &sc->elst_data[i];
5184 e->duration = avio_rb64(pb);
5185 e->time = avio_rb64(pb);
5188 e->duration = avio_rb32(pb); /* segment duration */
5189 e->time = (int32_t)avio_rb32(pb); /* media time */
5192 e->rate = avio_rb32(pb) / 65536.0;
5194 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5195 e->duration, e->time, e->rate);
5197 if (e->time < 0 && e->time != -1 &&
5198 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5199 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5200 c->fc->nb_streams-1, i, e->time);
5201 return AVERROR_INVALIDDATA;
5209 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5211 MOVStreamContext *sc;
5213 if (c->fc->nb_streams < 1)
5214 return AVERROR_INVALIDDATA;
5215 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5216 sc->timecode_track = avio_rb32(pb);
5220 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5225 if (c->fc->nb_streams < 1)
5227 st = c->fc->streams[c->fc->nb_streams - 1];
5229 if (atom.size < 4) {
5230 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5231 return AVERROR_INVALIDDATA;
5234 /* For now, propagate only the OBUs, if any. Once libavcodec is
5235 updated to handle isobmff style extradata this can be removed. */
5241 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5248 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5251 int version, color_range, color_primaries, color_trc, color_space;
5253 if (c->fc->nb_streams < 1)
5255 st = c->fc->streams[c->fc->nb_streams - 1];
5257 if (atom.size < 5) {
5258 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5259 return AVERROR_INVALIDDATA;
5262 version = avio_r8(pb);
5264 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5267 avio_skip(pb, 3); /* flags */
5269 avio_skip(pb, 2); /* profile + level */
5270 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5271 color_primaries = avio_r8(pb);
5272 color_trc = avio_r8(pb);
5273 color_space = avio_r8(pb);
5274 if (avio_rb16(pb)) /* codecIntializationDataSize */
5275 return AVERROR_INVALIDDATA;
5277 if (!av_color_primaries_name(color_primaries))
5278 color_primaries = AVCOL_PRI_UNSPECIFIED;
5279 if (!av_color_transfer_name(color_trc))
5280 color_trc = AVCOL_TRC_UNSPECIFIED;
5281 if (!av_color_space_name(color_space))
5282 color_space = AVCOL_SPC_UNSPECIFIED;
5284 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5285 st->codecpar->color_primaries = color_primaries;
5286 st->codecpar->color_trc = color_trc;
5287 st->codecpar->color_space = color_space;
5292 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5294 MOVStreamContext *sc;
5297 if (c->fc->nb_streams < 1)
5298 return AVERROR_INVALIDDATA;
5300 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5302 if (atom.size < 5) {
5303 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5304 return AVERROR_INVALIDDATA;
5307 version = avio_r8(pb);
5309 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5312 avio_skip(pb, 3); /* flags */
5314 sc->mastering = av_mastering_display_metadata_alloc();
5316 return AVERROR(ENOMEM);
5318 for (i = 0; i < 3; i++) {
5319 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5320 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5322 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5323 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5325 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5326 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5328 sc->mastering->has_primaries = 1;
5329 sc->mastering->has_luminance = 1;
5334 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5336 MOVStreamContext *sc;
5337 const int mapping[3] = {1, 2, 0};
5338 const int chroma_den = 50000;
5339 const int luma_den = 10000;
5342 if (c->fc->nb_streams < 1)
5343 return AVERROR_INVALIDDATA;
5345 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5347 if (atom.size < 24) {
5348 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5349 return AVERROR_INVALIDDATA;
5352 sc->mastering = av_mastering_display_metadata_alloc();
5354 return AVERROR(ENOMEM);
5356 for (i = 0; i < 3; i++) {
5357 const int j = mapping[i];
5358 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5359 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5361 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5362 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5364 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5365 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5367 sc->mastering->has_luminance = 1;
5368 sc->mastering->has_primaries = 1;
5373 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5375 MOVStreamContext *sc;
5378 if (c->fc->nb_streams < 1)
5379 return AVERROR_INVALIDDATA;
5381 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5383 if (atom.size < 5) {
5384 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5385 return AVERROR_INVALIDDATA;
5388 version = avio_r8(pb);
5390 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5393 avio_skip(pb, 3); /* flags */
5395 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5397 return AVERROR(ENOMEM);
5399 sc->coll->MaxCLL = avio_rb16(pb);
5400 sc->coll->MaxFALL = avio_rb16(pb);
5405 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5407 MOVStreamContext *sc;
5409 if (c->fc->nb_streams < 1)
5410 return AVERROR_INVALIDDATA;
5412 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5414 if (atom.size < 4) {
5415 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5416 return AVERROR_INVALIDDATA;
5419 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5421 return AVERROR(ENOMEM);
5423 sc->coll->MaxCLL = avio_rb16(pb);
5424 sc->coll->MaxFALL = avio_rb16(pb);
5429 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5432 MOVStreamContext *sc;
5433 enum AVStereo3DType type;
5436 if (c->fc->nb_streams < 1)
5439 st = c->fc->streams[c->fc->nb_streams - 1];
5442 if (atom.size < 5) {
5443 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5444 return AVERROR_INVALIDDATA;
5446 avio_skip(pb, 4); /* version + flags */
5451 type = AV_STEREO3D_2D;
5454 type = AV_STEREO3D_TOPBOTTOM;
5457 type = AV_STEREO3D_SIDEBYSIDE;
5460 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5464 sc->stereo3d = av_stereo3d_alloc();
5466 return AVERROR(ENOMEM);
5468 sc->stereo3d->type = type;
5472 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5475 MOVStreamContext *sc;
5476 int size, version, layout;
5477 int32_t yaw, pitch, roll;
5478 uint32_t l = 0, t = 0, r = 0, b = 0;
5479 uint32_t tag, padding = 0;
5480 enum AVSphericalProjection projection;
5482 if (c->fc->nb_streams < 1)
5485 st = c->fc->streams[c->fc->nb_streams - 1];
5488 if (atom.size < 8) {
5489 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5490 return AVERROR_INVALIDDATA;
5493 size = avio_rb32(pb);
5494 if (size <= 12 || size > atom.size)
5495 return AVERROR_INVALIDDATA;
5497 tag = avio_rl32(pb);
5498 if (tag != MKTAG('s','v','h','d')) {
5499 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5502 version = avio_r8(pb);
5504 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5508 avio_skip(pb, 3); /* flags */
5509 avio_skip(pb, size - 12); /* metadata_source */
5511 size = avio_rb32(pb);
5512 if (size > atom.size)
5513 return AVERROR_INVALIDDATA;
5515 tag = avio_rl32(pb);
5516 if (tag != MKTAG('p','r','o','j')) {
5517 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5521 size = avio_rb32(pb);
5522 if (size > atom.size)
5523 return AVERROR_INVALIDDATA;
5525 tag = avio_rl32(pb);
5526 if (tag != MKTAG('p','r','h','d')) {
5527 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5530 version = avio_r8(pb);
5532 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5536 avio_skip(pb, 3); /* flags */
5538 /* 16.16 fixed point */
5539 yaw = avio_rb32(pb);
5540 pitch = avio_rb32(pb);
5541 roll = avio_rb32(pb);
5543 size = avio_rb32(pb);
5544 if (size > atom.size)
5545 return AVERROR_INVALIDDATA;
5547 tag = avio_rl32(pb);
5548 version = avio_r8(pb);
5550 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5554 avio_skip(pb, 3); /* flags */
5556 case MKTAG('c','b','m','p'):
5557 layout = avio_rb32(pb);
5559 av_log(c->fc, AV_LOG_WARNING,
5560 "Unsupported cubemap layout %d\n", layout);
5563 projection = AV_SPHERICAL_CUBEMAP;
5564 padding = avio_rb32(pb);
5566 case MKTAG('e','q','u','i'):
5572 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5573 av_log(c->fc, AV_LOG_ERROR,
5574 "Invalid bounding rectangle coordinates "
5575 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5576 return AVERROR_INVALIDDATA;
5579 if (l || t || r || b)
5580 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5582 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5585 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5589 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5591 return AVERROR(ENOMEM);
5593 sc->spherical->projection = projection;
5595 sc->spherical->yaw = yaw;
5596 sc->spherical->pitch = pitch;
5597 sc->spherical->roll = roll;
5599 sc->spherical->padding = padding;
5601 sc->spherical->bound_left = l;
5602 sc->spherical->bound_top = t;
5603 sc->spherical->bound_right = r;
5604 sc->spherical->bound_bottom = b;
5609 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5612 uint8_t *buffer = av_malloc(len + 1);
5616 return AVERROR(ENOMEM);
5619 ret = ffio_read_size(pb, buffer, len);
5623 /* Check for mandatory keys and values, try to support XML as best-effort */
5624 if (!sc->spherical &&
5625 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5626 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5627 av_stristr(val, "true") &&
5628 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5629 av_stristr(val, "true") &&
5630 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5631 av_stristr(val, "equirectangular")) {
5632 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5636 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5638 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5639 enum AVStereo3DType mode;
5641 if (av_stristr(buffer, "left-right"))
5642 mode = AV_STEREO3D_SIDEBYSIDE;
5643 else if (av_stristr(buffer, "top-bottom"))
5644 mode = AV_STEREO3D_TOPBOTTOM;
5646 mode = AV_STEREO3D_2D;
5648 sc->stereo3d = av_stereo3d_alloc();
5652 sc->stereo3d->type = mode;
5656 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5658 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5659 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5661 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5662 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5664 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5672 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5675 MOVStreamContext *sc;
5678 static const uint8_t uuid_isml_manifest[] = {
5679 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5680 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5682 static const uint8_t uuid_xmp[] = {
5683 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5684 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5686 static const uint8_t uuid_spherical[] = {
5687 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5688 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5691 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5692 return AVERROR_INVALIDDATA;
5694 if (c->fc->nb_streams < 1)
5696 st = c->fc->streams[c->fc->nb_streams - 1];
5699 ret = avio_read(pb, uuid, sizeof(uuid));
5702 } else if (ret != sizeof(uuid)) {
5703 return AVERROR_INVALIDDATA;
5705 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5706 uint8_t *buffer, *ptr;
5708 size_t len = atom.size - sizeof(uuid);
5711 return AVERROR_INVALIDDATA;
5713 ret = avio_skip(pb, 4); // zeroes
5716 buffer = av_mallocz(len + 1);
5718 return AVERROR(ENOMEM);
5720 ret = avio_read(pb, buffer, len);
5724 } else if (ret != len) {
5726 return AVERROR_INVALIDDATA;
5730 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5731 ptr += sizeof("systemBitrate=\"") - 1;
5732 c->bitrates_count++;
5733 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5735 c->bitrates_count = 0;
5737 return AVERROR(ENOMEM);
5740 ret = strtol(ptr, &endptr, 10);
5741 if (ret < 0 || errno || *endptr != '"') {
5742 c->bitrates[c->bitrates_count - 1] = 0;
5744 c->bitrates[c->bitrates_count - 1] = ret;
5749 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5751 size_t len = atom.size - sizeof(uuid);
5752 if (c->export_xmp) {
5753 buffer = av_mallocz(len + 1);
5755 return AVERROR(ENOMEM);
5757 ret = avio_read(pb, buffer, len);
5761 } else if (ret != len) {
5763 return AVERROR_INVALIDDATA;
5766 av_dict_set(&c->fc->metadata, "xmp", buffer, 0);
5769 // skip all uuid atom, which makes it fast for long uuid-xmp file
5770 ret = avio_skip(pb, len);
5774 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5775 size_t len = atom.size - sizeof(uuid);
5776 ret = mov_parse_uuid_spherical(sc, pb, len);
5780 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5786 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5789 uint8_t content[16];
5794 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5800 && !memcmp(content, "Anevia\x1A\x1A", 8)
5801 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5802 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5808 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5810 uint32_t format = avio_rl32(pb);
5811 MOVStreamContext *sc;
5815 if (c->fc->nb_streams < 1)
5817 st = c->fc->streams[c->fc->nb_streams - 1];
5822 case MKTAG('e','n','c','v'): // encrypted video
5823 case MKTAG('e','n','c','a'): // encrypted audio
5824 id = mov_codec_id(st, format);
5825 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5826 st->codecpar->codec_id != id) {
5827 av_log(c->fc, AV_LOG_WARNING,
5828 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5829 (char*)&format, st->codecpar->codec_id);
5833 st->codecpar->codec_id = id;
5834 sc->format = format;
5838 if (format != sc->format) {
5839 av_log(c->fc, AV_LOG_WARNING,
5840 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5841 (char*)&format, (char*)&sc->format);
5850 * Gets the current encryption info and associated current stream context. If
5851 * we are parsing a track fragment, this will return the specific encryption
5852 * info for this fragment; otherwise this will return the global encryption
5853 * info for the current stream.
5855 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5857 MOVFragmentStreamInfo *frag_stream_info;
5861 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5862 if (frag_stream_info) {
5863 for (i = 0; i < c->fc->nb_streams; i++) {
5864 if (c->fc->streams[i]->id == frag_stream_info->id) {
5865 st = c->fc->streams[i];
5869 if (i == c->fc->nb_streams)
5871 *sc = st->priv_data;
5873 if (!frag_stream_info->encryption_index) {
5874 // If this stream isn't encrypted, don't create the index.
5875 if (!(*sc)->cenc.default_encrypted_sample)
5877 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5878 if (!frag_stream_info->encryption_index)
5879 return AVERROR(ENOMEM);
5881 *encryption_index = frag_stream_info->encryption_index;
5884 // No current track fragment, using stream level encryption info.
5886 if (c->fc->nb_streams < 1)
5888 st = c->fc->streams[c->fc->nb_streams - 1];
5889 *sc = st->priv_data;
5891 if (!(*sc)->cenc.encryption_index) {
5892 // If this stream isn't encrypted, don't create the index.
5893 if (!(*sc)->cenc.default_encrypted_sample)
5895 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5896 if (!(*sc)->cenc.encryption_index)
5897 return AVERROR(ENOMEM);
5900 *encryption_index = (*sc)->cenc.encryption_index;
5905 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
5908 unsigned int subsample_count;
5909 AVSubsampleEncryptionInfo *subsamples;
5911 if (!sc->cenc.default_encrypted_sample) {
5912 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
5913 return AVERROR_INVALIDDATA;
5916 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
5918 return AVERROR(ENOMEM);
5920 if (sc->cenc.per_sample_iv_size != 0) {
5921 if (avio_read(pb, (*sample)->iv, sc->cenc.per_sample_iv_size) != sc->cenc.per_sample_iv_size) {
5922 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
5923 av_encryption_info_free(*sample);
5925 return AVERROR_INVALIDDATA;
5929 if (use_subsamples) {
5930 subsample_count = avio_rb16(pb);
5931 av_free((*sample)->subsamples);
5932 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
5933 if (!(*sample)->subsamples) {
5934 av_encryption_info_free(*sample);
5936 return AVERROR(ENOMEM);
5939 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
5940 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
5941 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
5944 if (pb->eof_reached) {
5945 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
5946 av_encryption_info_free(*sample);
5948 return AVERROR_INVALIDDATA;
5950 (*sample)->subsample_count = subsample_count;
5956 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5958 AVEncryptionInfo **encrypted_samples;
5959 MOVEncryptionIndex *encryption_index;
5960 MOVStreamContext *sc;
5961 int use_subsamples, ret;
5962 unsigned int sample_count, i, alloc_size = 0;
5964 ret = get_current_encryption_info(c, &encryption_index, &sc);
5968 if (encryption_index->nb_encrypted_samples) {
5969 // This can happen if we have both saio/saiz and senc atoms.
5970 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
5974 avio_r8(pb); /* version */
5975 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
5977 sample_count = avio_rb32(pb);
5978 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
5979 return AVERROR(ENOMEM);
5981 for (i = 0; i < sample_count; i++) {
5982 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
5983 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
5984 min_samples * sizeof(*encrypted_samples));
5985 if (encrypted_samples) {
5986 encryption_index->encrypted_samples = encrypted_samples;
5988 ret = mov_read_sample_encryption_info(
5989 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
5991 ret = AVERROR(ENOMEM);
5993 if (pb->eof_reached) {
5994 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
5995 ret = AVERROR_INVALIDDATA;
6000 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6001 av_freep(&encryption_index->encrypted_samples);
6005 encryption_index->nb_encrypted_samples = sample_count;
6010 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6012 AVEncryptionInfo **sample, **encrypted_samples;
6014 size_t sample_count, sample_info_size, i;
6016 unsigned int alloc_size = 0;
6018 if (encryption_index->nb_encrypted_samples)
6020 sample_count = encryption_index->auxiliary_info_sample_count;
6021 if (encryption_index->auxiliary_offsets_count != 1) {
6022 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6023 return AVERROR_PATCHWELCOME;
6025 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6026 return AVERROR(ENOMEM);
6028 prev_pos = avio_tell(pb);
6029 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6030 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6031 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6035 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6036 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6037 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6038 min_samples * sizeof(*encrypted_samples));
6039 if (!encrypted_samples) {
6040 ret = AVERROR(ENOMEM);
6043 encryption_index->encrypted_samples = encrypted_samples;
6045 sample = &encryption_index->encrypted_samples[i];
6046 sample_info_size = encryption_index->auxiliary_info_default_size
6047 ? encryption_index->auxiliary_info_default_size
6048 : encryption_index->auxiliary_info_sizes[i];
6050 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6054 if (pb->eof_reached) {
6055 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6056 ret = AVERROR_INVALIDDATA;
6058 encryption_index->nb_encrypted_samples = sample_count;
6062 avio_seek(pb, prev_pos, SEEK_SET);
6064 for (; i > 0; i--) {
6065 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6067 av_freep(&encryption_index->encrypted_samples);
6073 * Tries to read the given number of bytes from the stream and puts it in a
6074 * newly allocated buffer. This reads in small chunks to avoid allocating large
6075 * memory if the file contains an invalid/malicious size value.
6077 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6079 const unsigned int block_size = 1024 * 1024;
6080 uint8_t *buffer = NULL;
6081 unsigned int alloc_size = 0, offset = 0;
6082 while (offset < size) {
6083 unsigned int new_size =
6084 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6085 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6086 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6089 return AVERROR(ENOMEM);
6091 buffer = new_buffer;
6093 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6095 return AVERROR_INVALIDDATA;
6104 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6106 MOVEncryptionIndex *encryption_index;
6107 MOVStreamContext *sc;
6109 unsigned int sample_count, aux_info_type, aux_info_param;
6111 ret = get_current_encryption_info(c, &encryption_index, &sc);
6115 if (encryption_index->nb_encrypted_samples) {
6116 // This can happen if we have both saio/saiz and senc atoms.
6117 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6121 if (encryption_index->auxiliary_info_sample_count) {
6122 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6123 return AVERROR_INVALIDDATA;
6126 avio_r8(pb); /* version */
6127 if (avio_rb24(pb) & 0x01) { /* flags */
6128 aux_info_type = avio_rb32(pb);
6129 aux_info_param = avio_rb32(pb);
6130 if (sc->cenc.default_encrypted_sample) {
6131 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6132 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6135 if (aux_info_param != 0) {
6136 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6140 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6141 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6142 aux_info_type == MKBETAG('c','e','n','s') ||
6143 aux_info_type == MKBETAG('c','b','c','1') ||
6144 aux_info_type == MKBETAG('c','b','c','s')) &&
6145 aux_info_param == 0) {
6146 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6147 return AVERROR_INVALIDDATA;
6152 } else if (!sc->cenc.default_encrypted_sample) {
6153 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6157 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6158 sample_count = avio_rb32(pb);
6159 encryption_index->auxiliary_info_sample_count = sample_count;
6161 if (encryption_index->auxiliary_info_default_size == 0) {
6162 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6164 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6169 if (encryption_index->auxiliary_offsets_count) {
6170 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6176 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6178 uint64_t *auxiliary_offsets;
6179 MOVEncryptionIndex *encryption_index;
6180 MOVStreamContext *sc;
6182 unsigned int version, entry_count, aux_info_type, aux_info_param;
6183 unsigned int alloc_size = 0;
6185 ret = get_current_encryption_info(c, &encryption_index, &sc);
6189 if (encryption_index->nb_encrypted_samples) {
6190 // This can happen if we have both saio/saiz and senc atoms.
6191 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6195 if (encryption_index->auxiliary_offsets_count) {
6196 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6197 return AVERROR_INVALIDDATA;
6200 version = avio_r8(pb); /* version */
6201 if (avio_rb24(pb) & 0x01) { /* flags */
6202 aux_info_type = avio_rb32(pb);
6203 aux_info_param = avio_rb32(pb);
6204 if (sc->cenc.default_encrypted_sample) {
6205 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6206 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6209 if (aux_info_param != 0) {
6210 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6214 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6215 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6216 aux_info_type == MKBETAG('c','e','n','s') ||
6217 aux_info_type == MKBETAG('c','b','c','1') ||
6218 aux_info_type == MKBETAG('c','b','c','s')) &&
6219 aux_info_param == 0) {
6220 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6221 return AVERROR_INVALIDDATA;
6226 } else if (!sc->cenc.default_encrypted_sample) {
6227 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6231 entry_count = avio_rb32(pb);
6232 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6233 return AVERROR(ENOMEM);
6235 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6236 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6237 auxiliary_offsets = av_fast_realloc(
6238 encryption_index->auxiliary_offsets, &alloc_size,
6239 min_offsets * sizeof(*auxiliary_offsets));
6240 if (!auxiliary_offsets) {
6241 av_freep(&encryption_index->auxiliary_offsets);
6242 return AVERROR(ENOMEM);
6244 encryption_index->auxiliary_offsets = auxiliary_offsets;
6247 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6249 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6251 if (c->frag_index.current >= 0) {
6252 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6256 if (pb->eof_reached) {
6257 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6258 av_freep(&encryption_index->auxiliary_offsets);
6259 return AVERROR_INVALIDDATA;
6262 encryption_index->auxiliary_offsets_count = entry_count;
6264 if (encryption_index->auxiliary_info_sample_count) {
6265 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6271 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6273 AVEncryptionInitInfo *info, *old_init_info;
6276 uint8_t *side_data, *extra_data, *old_side_data;
6277 size_t side_data_size;
6278 int ret = 0, old_side_data_size;
6279 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6281 if (c->fc->nb_streams < 1)
6283 st = c->fc->streams[c->fc->nb_streams-1];
6285 version = avio_r8(pb); /* version */
6286 avio_rb24(pb); /* flags */
6288 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6289 /* key_id_size */ 16, /* data_size */ 0);
6291 return AVERROR(ENOMEM);
6293 if (avio_read(pb, info->system_id, 16) != 16) {
6294 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6295 ret = AVERROR_INVALIDDATA;
6300 kid_count = avio_rb32(pb);
6301 if (kid_count >= INT_MAX / sizeof(*key_ids))
6302 return AVERROR(ENOMEM);
6304 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6305 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6306 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6307 min_kid_count * sizeof(*key_ids));
6309 ret = AVERROR(ENOMEM);
6312 info->key_ids = key_ids;
6314 info->key_ids[i] = av_mallocz(16);
6315 if (!info->key_ids[i]) {
6316 ret = AVERROR(ENOMEM);
6319 info->num_key_ids = i + 1;
6321 if (avio_read(pb, info->key_ids[i], 16) != 16) {
6322 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6323 ret = AVERROR_INVALIDDATA;
6328 if (pb->eof_reached) {
6329 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6330 ret = AVERROR_INVALIDDATA;
6335 extra_data_size = avio_rb32(pb);
6336 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6340 av_freep(&info->data); // malloc(0) may still allocate something.
6341 info->data = extra_data;
6342 info->data_size = extra_data_size;
6344 // If there is existing initialization data, append to the list.
6345 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6346 if (old_side_data) {
6347 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6348 if (old_init_info) {
6349 // Append to the end of the list.
6350 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6356 info = old_init_info;
6358 // Assume existing side-data will be valid, so the only error we could get is OOM.
6359 ret = AVERROR(ENOMEM);
6364 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6366 ret = AVERROR(ENOMEM);
6369 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6370 side_data, side_data_size);
6375 av_encryption_init_info_free(info);
6379 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6382 MOVStreamContext *sc;
6384 if (c->fc->nb_streams < 1)
6386 st = c->fc->streams[c->fc->nb_streams-1];
6389 if (sc->pseudo_stream_id != 0) {
6390 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6391 return AVERROR_PATCHWELCOME;
6395 return AVERROR_INVALIDDATA;
6397 avio_rb32(pb); /* version and flags */
6399 if (!sc->cenc.default_encrypted_sample) {
6400 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6401 if (!sc->cenc.default_encrypted_sample) {
6402 return AVERROR(ENOMEM);
6406 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6410 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6413 MOVStreamContext *sc;
6414 unsigned int version, pattern, is_protected, iv_size;
6416 if (c->fc->nb_streams < 1)
6418 st = c->fc->streams[c->fc->nb_streams-1];
6421 if (sc->pseudo_stream_id != 0) {
6422 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6423 return AVERROR_PATCHWELCOME;
6426 if (!sc->cenc.default_encrypted_sample) {
6427 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6428 if (!sc->cenc.default_encrypted_sample) {
6429 return AVERROR(ENOMEM);
6434 return AVERROR_INVALIDDATA;
6436 version = avio_r8(pb); /* version */
6437 avio_rb24(pb); /* flags */
6439 avio_r8(pb); /* reserved */
6440 pattern = avio_r8(pb);
6443 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6444 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6447 is_protected = avio_r8(pb);
6448 if (is_protected && !sc->cenc.encryption_index) {
6449 // The whole stream should be by-default encrypted.
6450 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6451 if (!sc->cenc.encryption_index)
6452 return AVERROR(ENOMEM);
6454 sc->cenc.per_sample_iv_size = avio_r8(pb);
6455 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6456 sc->cenc.per_sample_iv_size != 16) {
6457 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6458 return AVERROR_INVALIDDATA;
6460 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6461 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6462 return AVERROR_INVALIDDATA;
6465 if (is_protected && !sc->cenc.per_sample_iv_size) {
6466 iv_size = avio_r8(pb);
6467 if (iv_size != 8 && iv_size != 16) {
6468 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6469 return AVERROR_INVALIDDATA;
6472 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6473 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6474 return AVERROR_INVALIDDATA;
6481 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6484 int last, type, size, ret;
6487 if (c->fc->nb_streams < 1)
6489 st = c->fc->streams[c->fc->nb_streams-1];
6491 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6492 return AVERROR_INVALIDDATA;
6494 /* Check FlacSpecificBox version. */
6495 if (avio_r8(pb) != 0)
6496 return AVERROR_INVALIDDATA;
6498 avio_rb24(pb); /* Flags */
6500 avio_read(pb, buf, sizeof(buf));
6501 flac_parse_block_header(buf, &last, &type, &size);
6503 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6504 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6505 return AVERROR_INVALIDDATA;
6508 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6513 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6518 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6522 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6523 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6524 return AVERROR_PATCHWELCOME;
6527 if (!sc->cenc.aes_ctr) {
6528 /* initialize the cipher */
6529 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6530 if (!sc->cenc.aes_ctr) {
6531 return AVERROR(ENOMEM);
6534 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6540 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6542 if (!sample->subsample_count)
6544 /* decrypt the whole packet */
6545 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6549 for (i = 0; i < sample->subsample_count; i++)
6551 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6552 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6553 return AVERROR_INVALIDDATA;
6556 /* skip the clear bytes */
6557 input += sample->subsamples[i].bytes_of_clear_data;
6558 size -= sample->subsamples[i].bytes_of_clear_data;
6560 /* decrypt the encrypted bytes */
6561 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6562 input += sample->subsamples[i].bytes_of_protected_data;
6563 size -= sample->subsamples[i].bytes_of_protected_data;
6567 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6568 return AVERROR_INVALIDDATA;
6574 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6576 MOVFragmentStreamInfo *frag_stream_info;
6577 MOVEncryptionIndex *encryption_index;
6578 AVEncryptionInfo *encrypted_sample;
6579 int encrypted_index, ret;
6581 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6582 encrypted_index = current_index;
6583 encryption_index = NULL;
6584 if (frag_stream_info) {
6585 // Note this only supports encryption info in the first sample descriptor.
6586 if (mov->fragment.stsd_id == 1) {
6587 if (frag_stream_info->encryption_index) {
6588 encrypted_index = current_index - frag_stream_info->index_entry;
6589 encryption_index = frag_stream_info->encryption_index;
6591 encryption_index = sc->cenc.encryption_index;
6595 encryption_index = sc->cenc.encryption_index;
6598 if (encryption_index) {
6599 if (encryption_index->auxiliary_info_sample_count &&
6600 !encryption_index->nb_encrypted_samples) {
6601 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6602 return AVERROR_INVALIDDATA;
6604 if (encryption_index->auxiliary_offsets_count &&
6605 !encryption_index->nb_encrypted_samples) {
6606 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6607 return AVERROR_INVALIDDATA;
6610 if (!encryption_index->nb_encrypted_samples) {
6611 // Full-sample encryption with default settings.
6612 encrypted_sample = sc->cenc.default_encrypted_sample;
6613 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6614 // Per-sample setting override.
6615 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6617 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6618 return AVERROR_INVALIDDATA;
6621 if (mov->decryption_key) {
6622 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6625 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6627 return AVERROR(ENOMEM);
6628 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6638 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6640 const int OPUS_SEEK_PREROLL_MS = 80;
6645 if (c->fc->nb_streams < 1)
6647 st = c->fc->streams[c->fc->nb_streams-1];
6649 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6650 return AVERROR_INVALIDDATA;
6652 /* Check OpusSpecificBox version. */
6653 if (avio_r8(pb) != 0) {
6654 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6655 return AVERROR_INVALIDDATA;
6658 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6659 size = atom.size + 8;
6661 if (ff_alloc_extradata(st->codecpar, size))
6662 return AVERROR(ENOMEM);
6664 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6665 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6666 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6667 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6669 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6670 little-endian; aside from the preceeding magic and version they're
6671 otherwise currently identical. Data after output gain at offset 16
6672 doesn't need to be bytewapped. */
6673 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6674 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6675 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6676 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6678 st->codecpar->initial_padding = pre_skip;
6679 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6680 (AVRational){1, 1000},
6681 (AVRational){1, 48000});
6686 static const MOVParseTableEntry mov_default_parse_table[] = {
6687 { MKTAG('A','C','L','R'), mov_read_aclr },
6688 { MKTAG('A','P','R','G'), mov_read_avid },
6689 { MKTAG('A','A','L','P'), mov_read_avid },
6690 { MKTAG('A','R','E','S'), mov_read_ares },
6691 { MKTAG('a','v','s','s'), mov_read_avss },
6692 { MKTAG('a','v','1','C'), mov_read_av1c },
6693 { MKTAG('c','h','p','l'), mov_read_chpl },
6694 { MKTAG('c','o','6','4'), mov_read_stco },
6695 { MKTAG('c','o','l','r'), mov_read_colr },
6696 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6697 { MKTAG('d','i','n','f'), mov_read_default },
6698 { MKTAG('D','p','x','E'), mov_read_dpxe },
6699 { MKTAG('d','r','e','f'), mov_read_dref },
6700 { MKTAG('e','d','t','s'), mov_read_default },
6701 { MKTAG('e','l','s','t'), mov_read_elst },
6702 { MKTAG('e','n','d','a'), mov_read_enda },
6703 { MKTAG('f','i','e','l'), mov_read_fiel },
6704 { MKTAG('a','d','r','m'), mov_read_adrm },
6705 { MKTAG('f','t','y','p'), mov_read_ftyp },
6706 { MKTAG('g','l','b','l'), mov_read_glbl },
6707 { MKTAG('h','d','l','r'), mov_read_hdlr },
6708 { MKTAG('i','l','s','t'), mov_read_ilst },
6709 { MKTAG('j','p','2','h'), mov_read_jp2h },
6710 { MKTAG('m','d','a','t'), mov_read_mdat },
6711 { MKTAG('m','d','h','d'), mov_read_mdhd },
6712 { MKTAG('m','d','i','a'), mov_read_default },
6713 { MKTAG('m','e','t','a'), mov_read_meta },
6714 { MKTAG('m','i','n','f'), mov_read_default },
6715 { MKTAG('m','o','o','f'), mov_read_moof },
6716 { MKTAG('m','o','o','v'), mov_read_moov },
6717 { MKTAG('m','v','e','x'), mov_read_default },
6718 { MKTAG('m','v','h','d'), mov_read_mvhd },
6719 { MKTAG('S','M','I',' '), mov_read_svq3 },
6720 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6721 { MKTAG('a','v','c','C'), mov_read_glbl },
6722 { MKTAG('p','a','s','p'), mov_read_pasp },
6723 { MKTAG('s','i','d','x'), mov_read_sidx },
6724 { MKTAG('s','t','b','l'), mov_read_default },
6725 { MKTAG('s','t','c','o'), mov_read_stco },
6726 { MKTAG('s','t','p','s'), mov_read_stps },
6727 { MKTAG('s','t','r','f'), mov_read_strf },
6728 { MKTAG('s','t','s','c'), mov_read_stsc },
6729 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6730 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6731 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6732 { MKTAG('s','t','t','s'), mov_read_stts },
6733 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6734 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6735 { MKTAG('t','f','d','t'), mov_read_tfdt },
6736 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6737 { MKTAG('t','r','a','k'), mov_read_trak },
6738 { MKTAG('t','r','a','f'), mov_read_default },
6739 { MKTAG('t','r','e','f'), mov_read_default },
6740 { MKTAG('t','m','c','d'), mov_read_tmcd },
6741 { MKTAG('c','h','a','p'), mov_read_chap },
6742 { MKTAG('t','r','e','x'), mov_read_trex },
6743 { MKTAG('t','r','u','n'), mov_read_trun },
6744 { MKTAG('u','d','t','a'), mov_read_default },
6745 { MKTAG('w','a','v','e'), mov_read_wave },
6746 { MKTAG('e','s','d','s'), mov_read_esds },
6747 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6748 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6749 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6750 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6751 { MKTAG('w','f','e','x'), mov_read_wfex },
6752 { MKTAG('c','m','o','v'), mov_read_cmov },
6753 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6754 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6755 { MKTAG('s','b','g','p'), mov_read_sbgp },
6756 { MKTAG('h','v','c','C'), mov_read_glbl },
6757 { MKTAG('u','u','i','d'), mov_read_uuid },
6758 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6759 { MKTAG('f','r','e','e'), mov_read_free },
6760 { MKTAG('-','-','-','-'), mov_read_custom },
6761 { MKTAG('s','i','n','f'), mov_read_default },
6762 { MKTAG('f','r','m','a'), mov_read_frma },
6763 { MKTAG('s','e','n','c'), mov_read_senc },
6764 { MKTAG('s','a','i','z'), mov_read_saiz },
6765 { MKTAG('s','a','i','o'), mov_read_saio },
6766 { MKTAG('p','s','s','h'), mov_read_pssh },
6767 { MKTAG('s','c','h','m'), mov_read_schm },
6768 { MKTAG('s','c','h','i'), mov_read_default },
6769 { MKTAG('t','e','n','c'), mov_read_tenc },
6770 { MKTAG('d','f','L','a'), mov_read_dfla },
6771 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6772 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6773 { MKTAG('d','O','p','s'), mov_read_dops },
6774 { MKTAG('S','m','D','m'), mov_read_smdm },
6775 { MKTAG('C','o','L','L'), mov_read_coll },
6776 { MKTAG('v','p','c','C'), mov_read_vpcc },
6777 { MKTAG('m','d','c','v'), mov_read_mdcv },
6778 { MKTAG('c','l','l','i'), mov_read_clli },
6782 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6784 int64_t total_size = 0;
6788 if (c->atom_depth > 10) {
6789 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6790 return AVERROR_INVALIDDATA;
6795 atom.size = INT64_MAX;
6796 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6797 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
6800 if (atom.size >= 8) {
6801 a.size = avio_rb32(pb);
6802 a.type = avio_rl32(pb);
6803 if (a.type == MKTAG('f','r','e','e') &&
6805 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT &&
6808 uint32_t *type = (uint32_t *)buf + 1;
6809 if (avio_read(pb, buf, 8) != 8)
6810 return AVERROR_INVALIDDATA;
6811 avio_seek(pb, -8, SEEK_CUR);
6812 if (*type == MKTAG('m','v','h','d') ||
6813 *type == MKTAG('c','m','o','v')) {
6814 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free atom.\n");
6815 a.type = MKTAG('m','o','o','v');
6818 if (atom.type != MKTAG('r','o','o','t') &&
6819 atom.type != MKTAG('m','o','o','v'))
6821 if (a.type == MKTAG('t','r','a','k') || a.type == MKTAG('m','d','a','t'))
6823 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
6830 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
6831 a.size = avio_rb64(pb) - 8;
6835 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
6836 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
6838 a.size = atom.size - total_size + 8;
6843 a.size = FFMIN(a.size, atom.size - total_size);
6845 for (i = 0; mov_default_parse_table[i].type; i++)
6846 if (mov_default_parse_table[i].type == a.type) {
6847 parse = mov_default_parse_table[i].parse;
6851 // container is user data
6852 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
6853 atom.type == MKTAG('i','l','s','t')))
6854 parse = mov_read_udta_string;
6856 // Supports parsing the QuickTime Metadata Keys.
6857 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
6858 if (!parse && c->found_hdlr_mdta &&
6859 atom.type == MKTAG('m','e','t','a') &&
6860 a.type == MKTAG('k','e','y','s')) {
6861 parse = mov_read_keys;
6864 if (!parse) { /* skip leaf atoms data */
6865 avio_skip(pb, a.size);
6867 int64_t start_pos = avio_tell(pb);
6869 int err = parse(c, pb, a);
6874 if (c->found_moov && c->found_mdat &&
6875 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
6876 start_pos + a.size == avio_size(pb))) {
6877 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
6878 c->next_root_atom = start_pos + a.size;
6882 left = a.size - avio_tell(pb) + start_pos;
6883 if (left > 0) /* skip garbage at atom end */
6884 avio_skip(pb, left);
6885 else if (left < 0) {
6886 av_log(c->fc, AV_LOG_WARNING,
6887 "overread end of atom '%.4s' by %"PRId64" bytes\n",
6888 (char*)&a.type, -left);
6889 avio_seek(pb, left, SEEK_CUR);
6893 total_size += a.size;
6896 if (total_size < atom.size && atom.size < 0x7ffff)
6897 avio_skip(pb, atom.size - total_size);
6903 static int mov_probe(const AVProbeData *p)
6908 int moov_offset = -1;
6910 /* check file header */
6913 /* ignore invalid offset */
6914 if ((offset + 8) > (unsigned int)p->buf_size)
6916 tag = AV_RL32(p->buf + offset + 4);
6918 /* check for obvious tags */
6919 case MKTAG('m','o','o','v'):
6920 moov_offset = offset + 4;
6921 case MKTAG('m','d','a','t'):
6922 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
6923 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
6924 case MKTAG('f','t','y','p'):
6925 if (AV_RB32(p->buf+offset) < 8 &&
6926 (AV_RB32(p->buf+offset) != 1 ||
6927 offset + 12 > (unsigned int)p->buf_size ||
6928 AV_RB64(p->buf+offset + 8) == 0)) {
6929 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
6930 } else if (tag == MKTAG('f','t','y','p') &&
6931 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
6932 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
6934 score = FFMAX(score, 5);
6936 score = AVPROBE_SCORE_MAX;
6938 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
6940 /* those are more common words, so rate then a bit less */
6941 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
6942 case MKTAG('w','i','d','e'):
6943 case MKTAG('f','r','e','e'):
6944 case MKTAG('j','u','n','k'):
6945 case MKTAG('p','i','c','t'):
6946 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
6947 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
6949 case MKTAG(0x82,0x82,0x7f,0x7d):
6950 case MKTAG('s','k','i','p'):
6951 case MKTAG('u','u','i','d'):
6952 case MKTAG('p','r','f','l'):
6953 /* if we only find those cause probedata is too small at least rate them */
6954 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
6955 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
6958 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
6961 if(score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
6962 /* moov atom in the header - we should make sure that this is not a
6963 * MOV-packed MPEG-PS */
6964 offset = moov_offset;
6966 while(offset < (p->buf_size - 16)){ /* Sufficient space */
6967 /* We found an actual hdlr atom */
6968 if(AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
6969 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
6970 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')){
6971 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
6972 /* We found a media handler reference atom describing an
6973 * MPEG-PS-in-MOV, return a
6974 * low score to force expanding the probe window until
6975 * mpegps_probe finds what it needs */
6986 // must be done after parsing all trak because there's no order requirement
6987 static void mov_read_chapters(AVFormatContext *s)
6989 MOVContext *mov = s->priv_data;
6991 MOVStreamContext *sc;
6996 for (j = 0; j < mov->nb_chapter_tracks; j++) {
6997 chapter_track = mov->chapter_tracks[j];
6999 for (i = 0; i < s->nb_streams; i++)
7000 if (s->streams[i]->id == chapter_track) {
7005 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7010 cur_pos = avio_tell(sc->pb);
7012 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7013 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7014 if (st->nb_index_entries) {
7015 // Retrieve the first frame, if possible
7017 AVIndexEntry *sample = &st->index_entries[0];
7018 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7019 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7023 if (av_get_packet(sc->pb, &pkt, sample->size) < 0)
7026 st->attached_pic = pkt;
7027 st->attached_pic.stream_index = st->index;
7028 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
7031 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7032 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7033 st->discard = AVDISCARD_ALL;
7034 for (i = 0; i < st->nb_index_entries; i++) {
7035 AVIndexEntry *sample = &st->index_entries[i];
7036 int64_t end = i+1 < st->nb_index_entries ? st->index_entries[i+1].timestamp : st->duration;
7041 if (end < sample->timestamp) {
7042 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7043 end = AV_NOPTS_VALUE;
7046 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7047 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7051 // the first two bytes are the length of the title
7052 len = avio_rb16(sc->pb);
7053 if (len > sample->size-2)
7055 title_len = 2*len + 1;
7056 if (!(title = av_mallocz(title_len)))
7059 // The samples could theoretically be in any encoding if there's an encd
7060 // atom following, but in practice are only utf-8 or utf-16, distinguished
7061 // instead by the presence of a BOM
7065 ch = avio_rb16(sc->pb);
7067 avio_get_str16be(sc->pb, len, title, title_len);
7068 else if (ch == 0xfffe)
7069 avio_get_str16le(sc->pb, len, title, title_len);
7072 if (len == 1 || len == 2)
7075 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7079 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7084 avio_seek(sc->pb, cur_pos, SEEK_SET);
7088 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7089 uint32_t value, int flags)
7092 char buf[AV_TIMECODE_STR_SIZE];
7093 AVRational rate = st->avg_frame_rate;
7094 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7097 av_dict_set(&st->metadata, "timecode",
7098 av_timecode_make_string(&tc, buf, value), 0);
7102 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7104 MOVStreamContext *sc = st->priv_data;
7105 char buf[AV_TIMECODE_STR_SIZE];
7106 int64_t cur_pos = avio_tell(sc->pb);
7107 int hh, mm, ss, ff, drop;
7109 if (!st->nb_index_entries)
7112 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7113 avio_skip(s->pb, 13);
7114 hh = avio_r8(s->pb);
7115 mm = avio_r8(s->pb);
7116 ss = avio_r8(s->pb);
7117 drop = avio_r8(s->pb);
7118 ff = avio_r8(s->pb);
7119 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7120 hh, mm, ss, drop ? ';' : ':', ff);
7121 av_dict_set(&st->metadata, "timecode", buf, 0);
7123 avio_seek(sc->pb, cur_pos, SEEK_SET);
7127 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7129 MOVStreamContext *sc = st->priv_data;
7131 int64_t cur_pos = avio_tell(sc->pb);
7134 if (!st->nb_index_entries)
7137 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7138 value = avio_rb32(s->pb);
7140 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7141 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7142 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7144 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7145 * not the case) and thus assume "frame number format" instead of QT one.
7146 * No sample with tmcd track can be found with a QT timecode at the moment,
7147 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7149 parse_timecode_in_framenum_format(s, st, value, flags);
7151 avio_seek(sc->pb, cur_pos, SEEK_SET);
7155 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7157 if (!index || !*index) return;
7158 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7159 av_encryption_info_free((*index)->encrypted_samples[i]);
7161 av_freep(&(*index)->encrypted_samples);
7162 av_freep(&(*index)->auxiliary_info_sizes);
7163 av_freep(&(*index)->auxiliary_offsets);
7167 static int mov_read_close(AVFormatContext *s)
7169 MOVContext *mov = s->priv_data;
7172 for (i = 0; i < s->nb_streams; i++) {
7173 AVStream *st = s->streams[i];
7174 MOVStreamContext *sc = st->priv_data;
7179 av_freep(&sc->ctts_data);
7180 for (j = 0; j < sc->drefs_count; j++) {
7181 av_freep(&sc->drefs[j].path);
7182 av_freep(&sc->drefs[j].dir);
7184 av_freep(&sc->drefs);
7186 sc->drefs_count = 0;
7188 if (!sc->pb_is_copied)
7189 ff_format_io_close(s, &sc->pb);
7192 av_freep(&sc->chunk_offsets);
7193 av_freep(&sc->stsc_data);
7194 av_freep(&sc->sample_sizes);
7195 av_freep(&sc->keyframes);
7196 av_freep(&sc->stts_data);
7197 av_freep(&sc->stps_data);
7198 av_freep(&sc->elst_data);
7199 av_freep(&sc->rap_group);
7200 av_freep(&sc->display_matrix);
7201 av_freep(&sc->index_ranges);
7204 for (j = 0; j < sc->stsd_count; j++)
7205 av_free(sc->extradata[j]);
7206 av_freep(&sc->extradata);
7207 av_freep(&sc->extradata_size);
7209 mov_free_encryption_index(&sc->cenc.encryption_index);
7210 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7211 av_aes_ctr_free(sc->cenc.aes_ctr);
7213 av_freep(&sc->stereo3d);
7214 av_freep(&sc->spherical);
7215 av_freep(&sc->mastering);
7216 av_freep(&sc->coll);
7219 if (mov->dv_demux) {
7220 avformat_free_context(mov->dv_fctx);
7221 mov->dv_fctx = NULL;
7224 if (mov->meta_keys) {
7225 for (i = 1; i < mov->meta_keys_count; i++) {
7226 av_freep(&mov->meta_keys[i]);
7228 av_freep(&mov->meta_keys);
7231 av_freep(&mov->trex_data);
7232 av_freep(&mov->bitrates);
7234 for (i = 0; i < mov->frag_index.nb_items; i++) {
7235 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7236 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7237 mov_free_encryption_index(&frag[j].encryption_index);
7239 av_freep(&mov->frag_index.item[i].stream_info);
7241 av_freep(&mov->frag_index.item);
7243 av_freep(&mov->aes_decrypt);
7244 av_freep(&mov->chapter_tracks);
7249 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7253 for (i = 0; i < s->nb_streams; i++) {
7254 AVStream *st = s->streams[i];
7255 MOVStreamContext *sc = st->priv_data;
7257 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7258 sc->timecode_track == tmcd_id)
7264 /* look for a tmcd track not referenced by any video track, and export it globally */
7265 static void export_orphan_timecode(AVFormatContext *s)
7269 for (i = 0; i < s->nb_streams; i++) {
7270 AVStream *st = s->streams[i];
7272 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7273 !tmcd_is_referenced(s, i + 1)) {
7274 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7276 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7283 static int read_tfra(MOVContext *mov, AVIOContext *f)
7285 int version, fieldlength, i, j;
7286 int64_t pos = avio_tell(f);
7287 uint32_t size = avio_rb32(f);
7288 unsigned track_id, item_count;
7290 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7293 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7295 version = avio_r8(f);
7297 track_id = avio_rb32(f);
7298 fieldlength = avio_rb32(f);
7299 item_count = avio_rb32(f);
7300 for (i = 0; i < item_count; i++) {
7301 int64_t time, offset;
7303 MOVFragmentStreamInfo * frag_stream_info;
7306 return AVERROR_INVALIDDATA;
7310 time = avio_rb64(f);
7311 offset = avio_rb64(f);
7313 time = avio_rb32(f);
7314 offset = avio_rb32(f);
7317 // The first sample of each stream in a fragment is always a random
7318 // access sample. So it's entry in the tfra can be used as the
7319 // initial PTS of the fragment.
7320 index = update_frag_index(mov, offset);
7321 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7322 if (frag_stream_info &&
7323 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7324 frag_stream_info->first_tfra_pts = time;
7326 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7328 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7330 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7334 avio_seek(f, pos + size, SEEK_SET);
7338 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7340 int64_t stream_size = avio_size(f);
7341 int64_t original_pos = avio_tell(f);
7345 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7349 mfra_size = avio_rb32(f);
7350 if (mfra_size < 0 || mfra_size > stream_size) {
7351 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7354 if ((seek_ret = avio_seek(f, -mfra_size, SEEK_CUR)) < 0) {
7358 if (avio_rb32(f) != mfra_size) {
7359 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7362 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7363 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7366 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7368 ret = read_tfra(c, f);
7374 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7376 av_log(c->fc, AV_LOG_ERROR,
7377 "failed to seek back after looking for mfra\n");
7383 static int mov_read_header(AVFormatContext *s)
7385 MOVContext *mov = s->priv_data;
7386 AVIOContext *pb = s->pb;
7388 MOVAtom atom = { AV_RL32("root") };
7391 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7392 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7393 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7394 return AVERROR(EINVAL);
7398 mov->trak_index = -1;
7399 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7400 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7401 atom.size = avio_size(pb);
7403 atom.size = INT64_MAX;
7405 /* check MOV header */
7407 if (mov->moov_retry)
7408 avio_seek(pb, 0, SEEK_SET);
7409 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7410 av_log(s, AV_LOG_ERROR, "error reading header\n");
7414 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7415 if (!mov->found_moov) {
7416 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7418 return AVERROR_INVALIDDATA;
7420 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7422 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7423 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7424 mov_read_chapters(s);
7425 for (i = 0; i < s->nb_streams; i++)
7426 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7427 mov_read_timecode_track(s, s->streams[i]);
7428 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7429 mov_read_rtmd_track(s, s->streams[i]);
7433 /* copy timecode metadata from tmcd tracks to the related video streams */
7434 for (i = 0; i < s->nb_streams; i++) {
7435 AVStream *st = s->streams[i];
7436 MOVStreamContext *sc = st->priv_data;
7437 if (sc->timecode_track > 0) {
7438 AVDictionaryEntry *tcr;
7439 int tmcd_st_id = -1;
7441 for (j = 0; j < s->nb_streams; j++)
7442 if (s->streams[j]->id == sc->timecode_track)
7445 if (tmcd_st_id < 0 || tmcd_st_id == i)
7447 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7449 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7452 export_orphan_timecode(s);
7454 for (i = 0; i < s->nb_streams; i++) {
7455 AVStream *st = s->streams[i];
7456 MOVStreamContext *sc = st->priv_data;
7457 fix_timescale(mov, sc);
7458 if(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7459 st->skip_samples = sc->start_pad;
7461 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7462 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7463 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7464 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7465 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7466 st->codecpar->width = sc->width;
7467 st->codecpar->height = sc->height;
7469 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7470 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7474 if (mov->handbrake_version &&
7475 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7476 st->codecpar->codec_id == AV_CODEC_ID_MP3
7478 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7479 st->need_parsing = AVSTREAM_PARSE_FULL;
7483 if (mov->trex_data) {
7484 for (i = 0; i < s->nb_streams; i++) {
7485 AVStream *st = s->streams[i];
7486 MOVStreamContext *sc = st->priv_data;
7487 if (st->duration > 0) {
7488 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7489 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7490 sc->data_size, sc->time_scale);
7492 return AVERROR_INVALIDDATA;
7494 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7499 if (mov->use_mfra_for > 0) {
7500 for (i = 0; i < s->nb_streams; i++) {
7501 AVStream *st = s->streams[i];
7502 MOVStreamContext *sc = st->priv_data;
7503 if (sc->duration_for_fps > 0) {
7504 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7505 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7506 sc->data_size, sc->time_scale);
7508 return AVERROR_INVALIDDATA;
7510 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7511 sc->duration_for_fps;
7516 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7517 if (mov->bitrates[i]) {
7518 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7522 ff_rfps_calculate(s);
7524 for (i = 0; i < s->nb_streams; i++) {
7525 AVStream *st = s->streams[i];
7526 MOVStreamContext *sc = st->priv_data;
7528 switch (st->codecpar->codec_type) {
7529 case AVMEDIA_TYPE_AUDIO:
7530 err = ff_replaygain_export(st, s->metadata);
7536 case AVMEDIA_TYPE_VIDEO:
7537 if (sc->display_matrix) {
7538 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7539 sizeof(int32_t) * 9);
7543 sc->display_matrix = NULL;
7546 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7547 (uint8_t *)sc->stereo3d,
7548 sizeof(*sc->stereo3d));
7552 sc->stereo3d = NULL;
7554 if (sc->spherical) {
7555 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7556 (uint8_t *)sc->spherical,
7557 sc->spherical_size);
7561 sc->spherical = NULL;
7563 if (sc->mastering) {
7564 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7565 (uint8_t *)sc->mastering,
7566 sizeof(*sc->mastering));
7570 sc->mastering = NULL;
7573 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7574 (uint8_t *)sc->coll,
7584 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7586 for (i = 0; i < mov->frag_index.nb_items; i++)
7587 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7588 mov->frag_index.item[i].headers_read = 1;
7593 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7595 AVIndexEntry *sample = NULL;
7596 int64_t best_dts = INT64_MAX;
7598 for (i = 0; i < s->nb_streams; i++) {
7599 AVStream *avst = s->streams[i];
7600 MOVStreamContext *msc = avst->priv_data;
7601 if (msc->pb && msc->current_sample < avst->nb_index_entries) {
7602 AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample];
7603 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7604 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7605 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7606 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7607 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb &&
7608 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7609 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7610 sample = current_sample;
7619 static int should_retry(AVIOContext *pb, int error_code) {
7620 if (error_code == AVERROR_EOF || avio_feof(pb))
7626 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7629 MOVContext *mov = s->priv_data;
7631 if (index >= 0 && index < mov->frag_index.nb_items)
7632 target = mov->frag_index.item[index].moof_offset;
7633 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7634 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7635 return AVERROR_INVALIDDATA;
7638 mov->next_root_atom = 0;
7639 if (index < 0 || index >= mov->frag_index.nb_items)
7640 index = search_frag_moof_offset(&mov->frag_index, target);
7641 if (index < mov->frag_index.nb_items) {
7642 if (index + 1 < mov->frag_index.nb_items)
7643 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7644 if (mov->frag_index.item[index].headers_read)
7646 mov->frag_index.item[index].headers_read = 1;
7649 mov->found_mdat = 0;
7651 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7654 if (avio_feof(s->pb))
7656 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7661 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7663 uint8_t *side, *extradata;
7666 /* Save the current index. */
7667 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7669 /* Notify the decoder that extradata changed. */
7670 extradata_size = sc->extradata_size[sc->last_stsd_index];
7671 extradata = sc->extradata[sc->last_stsd_index];
7672 if (extradata_size > 0 && extradata) {
7673 side = av_packet_new_side_data(pkt,
7674 AV_PKT_DATA_NEW_EXTRADATA,
7677 return AVERROR(ENOMEM);
7678 memcpy(side, extradata, extradata_size);
7684 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7686 MOVContext *mov = s->priv_data;
7687 MOVStreamContext *sc;
7688 AVIndexEntry *sample;
7689 AVStream *st = NULL;
7690 int64_t current_index;
7694 sample = mov_find_next_sample(s, &st);
7695 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7696 if (!mov->next_root_atom)
7698 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7703 /* must be done just before reading, to avoid infinite loop on sample */
7704 current_index = sc->current_index;
7705 mov_current_sample_inc(sc);
7707 if (mov->next_root_atom) {
7708 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7709 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7712 if (st->discard != AVDISCARD_ALL) {
7713 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7714 if (ret64 != sample->pos) {
7715 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7716 sc->ffindex, sample->pos);
7717 if (should_retry(sc->pb, ret64)) {
7718 mov_current_sample_dec(sc);
7720 return AVERROR_INVALIDDATA;
7723 if( st->discard == AVDISCARD_NONKEY && 0==(sample->flags & AVINDEX_KEYFRAME) ) {
7724 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7728 ret = av_get_packet(sc->pb, pkt, sample->size);
7730 if (should_retry(sc->pb, ret)) {
7731 mov_current_sample_dec(sc);
7735 if (sc->has_palette) {
7738 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7740 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7742 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7743 sc->has_palette = 0;
7746 #if CONFIG_DV_DEMUXER
7747 if (mov->dv_demux && sc->dv_audio_container) {
7748 avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7749 av_freep(&pkt->data);
7751 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7756 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7757 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7758 st->need_parsing = AVSTREAM_PARSE_FULL;
7762 pkt->stream_index = sc->ffindex;
7763 pkt->dts = sample->timestamp;
7764 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7765 pkt->flags |= AV_PKT_FLAG_DISCARD;
7767 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7768 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
7769 /* update ctts context */
7771 if (sc->ctts_index < sc->ctts_count &&
7772 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
7774 sc->ctts_sample = 0;
7777 int64_t next_dts = (sc->current_sample < st->nb_index_entries) ?
7778 st->index_entries[sc->current_sample].timestamp : st->duration;
7780 if (next_dts >= pkt->dts)
7781 pkt->duration = next_dts - pkt->dts;
7782 pkt->pts = pkt->dts;
7784 if (st->discard == AVDISCARD_ALL)
7786 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
7787 pkt->pos = sample->pos;
7789 /* Multiple stsd handling. */
7790 if (sc->stsc_data) {
7791 /* Keep track of the stsc index for the given sample, then check
7792 * if the stsd index is different from the last used one. */
7794 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
7795 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
7797 sc->stsc_sample = 0;
7798 /* Do not check indexes after a switch. */
7799 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
7800 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
7801 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
7802 ret = mov_change_extradata(sc, pkt);
7809 aax_filter(pkt->data, pkt->size, mov);
7811 ret = cenc_filter(mov, st, sc, pkt, current_index);
7818 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
7820 MOVContext *mov = s->priv_data;
7823 if (!mov->frag_index.complete)
7826 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
7829 if (!mov->frag_index.item[index].headers_read)
7830 return mov_switch_root(s, -1, index);
7831 if (index + 1 < mov->frag_index.nb_items)
7832 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7837 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
7839 MOVStreamContext *sc = st->priv_data;
7840 int sample, time_sample, ret;
7843 // Here we consider timestamp to be PTS, hence try to offset it so that we
7844 // can search over the DTS timeline.
7845 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
7847 ret = mov_seek_fragment(s, st, timestamp);
7851 sample = av_index_search_timestamp(st, timestamp, flags);
7852 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
7853 if (sample < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp)
7855 if (sample < 0) /* not sure what to do */
7856 return AVERROR_INVALIDDATA;
7857 mov_current_sample_set(sc, sample);
7858 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
7859 /* adjust ctts index */
7860 if (sc->ctts_data) {
7862 for (i = 0; i < sc->ctts_count; i++) {
7863 int next = time_sample + sc->ctts_data[i].count;
7864 if (next > sc->current_sample) {
7866 sc->ctts_sample = sc->current_sample - time_sample;
7873 /* adjust stsd index */
7874 if (sc->chunk_count) {
7876 for (i = 0; i < sc->stsc_count; i++) {
7877 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
7878 if (next > sc->current_sample) {
7880 sc->stsc_sample = sc->current_sample - time_sample;
7883 av_assert0(next == (int)next);
7891 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
7893 MOVContext *mc = s->priv_data;
7898 if (stream_index >= s->nb_streams)
7899 return AVERROR_INVALIDDATA;
7901 st = s->streams[stream_index];
7902 sample = mov_seek_stream(s, st, sample_time, flags);
7906 if (mc->seek_individually) {
7907 /* adjust seek timestamp to found sample timestamp */
7908 int64_t seek_timestamp = st->index_entries[sample].timestamp;
7910 for (i = 0; i < s->nb_streams; i++) {
7912 MOVStreamContext *sc = s->streams[i]->priv_data;
7914 st->skip_samples = (sample_time <= 0) ? sc->start_pad : 0;
7916 if (stream_index == i)
7919 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
7920 mov_seek_stream(s, st, timestamp, flags);
7923 for (i = 0; i < s->nb_streams; i++) {
7924 MOVStreamContext *sc;
7927 mov_current_sample_set(sc, 0);
7930 MOVStreamContext *sc;
7931 AVIndexEntry *entry = mov_find_next_sample(s, &st);
7933 return AVERROR_INVALIDDATA;
7935 if (sc->ffindex == stream_index && sc->current_sample == sample)
7937 mov_current_sample_inc(sc);
7943 #define OFFSET(x) offsetof(MOVContext, x)
7944 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
7945 static const AVOption mov_options[] = {
7946 {"use_absolute_path",
7947 "allow using absolute path when opening alias, this is a possible security issue",
7948 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
7950 {"seek_streams_individually",
7951 "Seek each stream individually to the to the closest point",
7952 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
7954 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
7956 {"advanced_editlist",
7957 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
7958 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
7960 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
7963 "use mfra for fragment timestamps",
7964 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
7965 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
7967 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
7968 FLAGS, "use_mfra_for" },
7969 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
7970 FLAGS, "use_mfra_for" },
7971 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
7972 FLAGS, "use_mfra_for" },
7973 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
7974 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
7975 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
7976 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
7977 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
7978 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
7979 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
7980 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
7981 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
7982 .flags = AV_OPT_FLAG_DECODING_PARAM },
7983 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
7984 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
7985 {.i64 = 0}, 0, 1, FLAGS },
7990 static const AVClass mov_class = {
7991 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
7992 .item_name = av_default_item_name,
7993 .option = mov_options,
7994 .version = LIBAVUTIL_VERSION_INT,
7997 AVInputFormat ff_mov_demuxer = {
7998 .name = "mov,mp4,m4a,3gp,3g2,mj2",
7999 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8000 .priv_class = &mov_class,
8001 .priv_data_size = sizeof(MOVContext),
8002 .extensions = "mov,mp4,m4a,3gp,3g2,mj2",
8003 .read_probe = mov_probe,
8004 .read_header = mov_read_header,
8005 .read_packet = mov_read_packet,
8006 .read_close = mov_read_close,
8007 .read_seek = mov_read_seek,
8008 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,