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 <= INT64_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 c->fragment.found_tfhd = 1;
4567 avio_r8(pb); /* version */
4568 flags = avio_rb24(pb);
4570 track_id = avio_rb32(pb);
4572 return AVERROR_INVALIDDATA;
4573 for (i = 0; i < c->trex_count; i++)
4574 if (c->trex_data[i].track_id == track_id) {
4575 trex = &c->trex_data[i];
4579 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4582 frag->track_id = track_id;
4583 set_frag_stream(&c->frag_index, track_id);
4585 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4586 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4587 frag->moof_offset : frag->implicit_offset;
4588 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4590 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4591 avio_rb32(pb) : trex->duration;
4592 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4593 avio_rb32(pb) : trex->size;
4594 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4595 avio_rb32(pb) : trex->flags;
4596 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4601 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4606 num = atom.size / 4;
4607 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4608 return AVERROR(ENOMEM);
4610 av_free(c->chapter_tracks);
4611 c->chapter_tracks = new_tracks;
4612 c->nb_chapter_tracks = num;
4614 for (i = 0; i < num && !pb->eof_reached; i++)
4615 c->chapter_tracks[i] = avio_rb32(pb);
4620 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4625 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4626 return AVERROR_INVALIDDATA;
4627 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4628 sizeof(*c->trex_data))) < 0) {
4633 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4635 trex = &c->trex_data[c->trex_count++];
4636 avio_r8(pb); /* version */
4637 avio_rb24(pb); /* flags */
4638 trex->track_id = avio_rb32(pb);
4639 trex->stsd_id = avio_rb32(pb);
4640 trex->duration = avio_rb32(pb);
4641 trex->size = avio_rb32(pb);
4642 trex->flags = avio_rb32(pb);
4646 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4648 MOVFragment *frag = &c->fragment;
4649 AVStream *st = NULL;
4650 MOVStreamContext *sc;
4652 MOVFragmentStreamInfo * frag_stream_info;
4653 int64_t base_media_decode_time;
4655 for (i = 0; i < c->fc->nb_streams; i++) {
4656 if (c->fc->streams[i]->id == frag->track_id) {
4657 st = c->fc->streams[i];
4662 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4666 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4668 version = avio_r8(pb);
4669 avio_rb24(pb); /* flags */
4671 base_media_decode_time = avio_rb64(pb);
4673 base_media_decode_time = avio_rb32(pb);
4676 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4677 if (frag_stream_info)
4678 frag_stream_info->tfdt_dts = base_media_decode_time;
4679 sc->track_end = base_media_decode_time;
4684 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4686 MOVFragment *frag = &c->fragment;
4687 AVStream *st = NULL;
4688 MOVStreamContext *sc;
4691 int64_t dts, pts = AV_NOPTS_VALUE;
4692 int data_offset = 0;
4693 unsigned entries, first_sample_flags = frag->flags;
4694 int flags, distance, i;
4695 int64_t prev_dts = AV_NOPTS_VALUE;
4696 int next_frag_index = -1, index_entry_pos;
4697 size_t requested_size;
4698 size_t old_ctts_allocated_size;
4699 AVIndexEntry *new_entries;
4700 MOVFragmentStreamInfo * frag_stream_info;
4702 if (!frag->found_tfhd) {
4703 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4704 return AVERROR_INVALIDDATA;
4707 for (i = 0; i < c->fc->nb_streams; i++) {
4708 if (c->fc->streams[i]->id == frag->track_id) {
4709 st = c->fc->streams[i];
4714 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4718 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4721 // Find the next frag_index index that has a valid index_entry for
4722 // the current track_id.
4724 // A valid index_entry means the trun for the fragment was read
4725 // and it's samples are in index_entries at the given position.
4726 // New index entries will be inserted before the index_entry found.
4727 index_entry_pos = st->nb_index_entries;
4728 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4729 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4730 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4731 next_frag_index = i;
4732 index_entry_pos = frag_stream_info->index_entry;
4736 av_assert0(index_entry_pos <= st->nb_index_entries);
4738 avio_r8(pb); /* version */
4739 flags = avio_rb24(pb);
4740 entries = avio_rb32(pb);
4741 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4743 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4744 return AVERROR_INVALIDDATA;
4745 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4746 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4748 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4749 if (frag_stream_info)
4751 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4752 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4753 pts = frag_stream_info->first_tfra_pts;
4754 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4755 ", using it for pts\n", pts);
4756 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4757 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4758 // pts = frag_stream_info->sidx_pts;
4759 dts = frag_stream_info->sidx_pts - sc->time_offset;
4760 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4761 ", using it for pts\n", pts);
4762 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4763 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4764 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4765 ", using it for dts\n", dts);
4767 dts = sc->track_end - sc->time_offset;
4768 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4769 ", using it for dts\n", dts);
4772 dts = sc->track_end - sc->time_offset;
4773 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4774 ", using it for dts\n", dts);
4776 offset = frag->base_data_offset + data_offset;
4778 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4780 // realloc space for new index entries
4781 if((unsigned)st->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4782 entries = UINT_MAX / sizeof(AVIndexEntry) - st->nb_index_entries;
4783 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4788 requested_size = (st->nb_index_entries + entries) * sizeof(AVIndexEntry);
4789 new_entries = av_fast_realloc(st->index_entries,
4790 &st->index_entries_allocated_size,
4793 return AVERROR(ENOMEM);
4794 st->index_entries= new_entries;
4796 requested_size = (st->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4797 old_ctts_allocated_size = sc->ctts_allocated_size;
4798 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4801 return AVERROR(ENOMEM);
4802 sc->ctts_data = ctts_data;
4804 // In case there were samples without ctts entries, ensure they get
4805 // zero valued entries. This ensures clips which mix boxes with and
4806 // without ctts entries don't pickup uninitialized data.
4807 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4808 sc->ctts_allocated_size - old_ctts_allocated_size);
4810 if (index_entry_pos < st->nb_index_entries) {
4811 // Make hole in index_entries and ctts_data for new samples
4812 memmove(st->index_entries + index_entry_pos + entries,
4813 st->index_entries + index_entry_pos,
4814 sizeof(*st->index_entries) *
4815 (st->nb_index_entries - index_entry_pos));
4816 memmove(sc->ctts_data + index_entry_pos + entries,
4817 sc->ctts_data + index_entry_pos,
4818 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4819 if (index_entry_pos < sc->current_sample) {
4820 sc->current_sample += entries;
4824 st->nb_index_entries += entries;
4825 sc->ctts_count = st->nb_index_entries;
4827 // Record the index_entry position in frag_index of this fragment
4828 if (frag_stream_info)
4829 frag_stream_info->index_entry = index_entry_pos;
4831 if (index_entry_pos > 0)
4832 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4834 for (i = 0; i < entries && !pb->eof_reached; i++) {
4835 unsigned sample_size = frag->size;
4836 int sample_flags = i ? frag->flags : first_sample_flags;
4837 unsigned sample_duration = frag->duration;
4838 unsigned ctts_duration = 0;
4840 int index_entry_flags = 0;
4842 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4843 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4844 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4845 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4847 mov_update_dts_shift(sc, ctts_duration);
4848 if (pts != AV_NOPTS_VALUE) {
4849 dts = pts - sc->dts_shift;
4850 if (flags & MOV_TRUN_SAMPLE_CTS) {
4851 dts -= ctts_duration;
4853 dts -= sc->time_offset;
4855 av_log(c->fc, AV_LOG_DEBUG,
4856 "pts %"PRId64" calculated dts %"PRId64
4857 " sc->dts_shift %d ctts.duration %d"
4858 " sc->time_offset %"PRId64
4859 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4861 sc->dts_shift, ctts_duration,
4862 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4863 pts = AV_NOPTS_VALUE;
4866 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4870 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4871 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4874 index_entry_flags |= AVINDEX_KEYFRAME;
4876 // Fragments can overlap in time. Discard overlapping frames after
4878 if (prev_dts >= dts)
4879 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4881 st->index_entries[index_entry_pos].pos = offset;
4882 st->index_entries[index_entry_pos].timestamp = dts;
4883 st->index_entries[index_entry_pos].size= sample_size;
4884 st->index_entries[index_entry_pos].min_distance= distance;
4885 st->index_entries[index_entry_pos].flags = index_entry_flags;
4887 sc->ctts_data[index_entry_pos].count = 1;
4888 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4891 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4892 "size %u, distance %d, keyframe %d\n", st->index,
4893 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4895 dts += sample_duration;
4896 offset += sample_size;
4897 sc->data_size += sample_size;
4899 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4900 1 <= INT64_MAX - sc->nb_frames_for_fps
4902 sc->duration_for_fps += sample_duration;
4903 sc->nb_frames_for_fps ++;
4907 // EOF found before reading all entries. Fix the hole this would
4908 // leave in index_entries and ctts_data
4909 int gap = entries - i;
4910 memmove(st->index_entries + index_entry_pos,
4911 st->index_entries + index_entry_pos + gap,
4912 sizeof(*st->index_entries) *
4913 (st->nb_index_entries - (index_entry_pos + gap)));
4914 memmove(sc->ctts_data + index_entry_pos,
4915 sc->ctts_data + index_entry_pos + gap,
4916 sizeof(*sc->ctts_data) *
4917 (sc->ctts_count - (index_entry_pos + gap)));
4919 st->nb_index_entries -= gap;
4920 sc->ctts_count -= gap;
4921 if (index_entry_pos < sc->current_sample) {
4922 sc->current_sample -= gap;
4927 // The end of this new fragment may overlap in time with the start
4928 // of the next fragment in index_entries. Mark the samples in the next
4929 // fragment that overlap with AVINDEX_DISCARD_FRAME
4930 prev_dts = AV_NOPTS_VALUE;
4931 if (index_entry_pos > 0)
4932 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4933 for (i = index_entry_pos; i < st->nb_index_entries; i++) {
4934 if (prev_dts < st->index_entries[i].timestamp)
4936 st->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
4939 // If a hole was created to insert the new index_entries into,
4940 // the index_entry recorded for all subsequent moof must
4941 // be incremented by the number of entries inserted.
4942 fix_frag_index_entries(&c->frag_index, next_frag_index,
4943 frag->track_id, entries);
4945 if (pb->eof_reached) {
4946 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
4950 frag->implicit_offset = offset;
4952 sc->track_end = dts + sc->time_offset;
4953 if (st->duration < sc->track_end)
4954 st->duration = sc->track_end;
4959 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4961 int64_t offset = avio_tell(pb) + atom.size, pts, timestamp;
4963 unsigned i, j, track_id, item_count;
4964 AVStream *st = NULL;
4965 AVStream *ref_st = NULL;
4966 MOVStreamContext *sc, *ref_sc = NULL;
4967 AVRational timescale;
4969 version = avio_r8(pb);
4971 avpriv_request_sample(c->fc, "sidx version %u", version);
4975 avio_rb24(pb); // flags
4977 track_id = avio_rb32(pb); // Reference ID
4978 for (i = 0; i < c->fc->nb_streams; i++) {
4979 if (c->fc->streams[i]->id == track_id) {
4980 st = c->fc->streams[i];
4985 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
4991 timescale = av_make_q(1, avio_rb32(pb));
4993 if (timescale.den <= 0) {
4994 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
4995 return AVERROR_INVALIDDATA;
4999 pts = avio_rb32(pb);
5000 offset += avio_rb32(pb);
5002 pts = avio_rb64(pb);
5003 offset += avio_rb64(pb);
5006 avio_rb16(pb); // reserved
5008 item_count = avio_rb16(pb);
5010 for (i = 0; i < item_count; i++) {
5012 MOVFragmentStreamInfo * frag_stream_info;
5013 uint32_t size = avio_rb32(pb);
5014 uint32_t duration = avio_rb32(pb);
5015 if (size & 0x80000000) {
5016 avpriv_request_sample(c->fc, "sidx reference_type 1");
5017 return AVERROR_PATCHWELCOME;
5019 avio_rb32(pb); // sap_flags
5020 timestamp = av_rescale_q(pts, st->time_base, timescale);
5022 index = update_frag_index(c, offset);
5023 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5024 if (frag_stream_info)
5025 frag_stream_info->sidx_pts = timestamp;
5031 st->duration = sc->track_end = pts;
5035 if (offset == avio_size(pb)) {
5036 // Find first entry in fragment index that came from an sidx.
5037 // This will pretty much always be the first entry.
5038 for (i = 0; i < c->frag_index.nb_items; i++) {
5039 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5040 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5041 MOVFragmentStreamInfo * si;
5042 si = &item->stream_info[j];
5043 if (si->sidx_pts != AV_NOPTS_VALUE) {
5044 ref_st = c->fc->streams[j];
5045 ref_sc = ref_st->priv_data;
5050 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5051 st = c->fc->streams[i];
5053 if (!sc->has_sidx) {
5054 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5058 c->frag_index.complete = 1;
5064 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5065 /* like the files created with Adobe Premiere 5.0, for samples see */
5066 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5067 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5072 return 0; /* continue */
5073 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5074 avio_skip(pb, atom.size - 4);
5077 atom.type = avio_rl32(pb);
5079 if (atom.type != MKTAG('m','d','a','t')) {
5080 avio_skip(pb, atom.size);
5083 err = mov_read_mdat(c, pb, atom);
5087 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5092 uint8_t *moov_data; /* uncompressed data */
5093 long cmov_len, moov_len;
5096 avio_rb32(pb); /* dcom atom */
5097 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5098 return AVERROR_INVALIDDATA;
5099 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5100 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5101 return AVERROR_INVALIDDATA;
5103 avio_rb32(pb); /* cmvd atom */
5104 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5105 return AVERROR_INVALIDDATA;
5106 moov_len = avio_rb32(pb); /* uncompressed size */
5107 cmov_len = atom.size - 6 * 4;
5109 cmov_data = av_malloc(cmov_len);
5111 return AVERROR(ENOMEM);
5112 moov_data = av_malloc(moov_len);
5115 return AVERROR(ENOMEM);
5117 ret = ffio_read_size(pb, cmov_data, cmov_len);
5119 goto free_and_return;
5121 ret = AVERROR_INVALIDDATA;
5122 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5123 goto free_and_return;
5124 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5125 goto free_and_return;
5126 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5127 atom.type = MKTAG('m','o','o','v');
5128 atom.size = moov_len;
5129 ret = mov_read_default(c, &ctx, atom);
5135 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5136 return AVERROR(ENOSYS);
5140 /* edit list atom */
5141 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5143 MOVStreamContext *sc;
5144 int i, edit_count, version;
5145 int64_t elst_entry_size;
5147 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5149 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5151 version = avio_r8(pb); /* version */
5152 avio_rb24(pb); /* flags */
5153 edit_count = avio_rb32(pb); /* entries */
5156 elst_entry_size = version == 1 ? 20 : 12;
5157 if (atom.size != edit_count * elst_entry_size) {
5158 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5159 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5160 edit_count, atom.size + 8);
5161 return AVERROR_INVALIDDATA;
5163 edit_count = atom.size / elst_entry_size;
5164 if (edit_count * elst_entry_size != atom.size) {
5165 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.", atom.size, edit_count);
5173 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5174 av_free(sc->elst_data);
5176 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5178 return AVERROR(ENOMEM);
5180 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5181 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5182 MOVElst *e = &sc->elst_data[i];
5185 e->duration = avio_rb64(pb);
5186 e->time = avio_rb64(pb);
5189 e->duration = avio_rb32(pb); /* segment duration */
5190 e->time = (int32_t)avio_rb32(pb); /* media time */
5193 e->rate = avio_rb32(pb) / 65536.0;
5195 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5196 e->duration, e->time, e->rate);
5198 if (e->time < 0 && e->time != -1 &&
5199 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5200 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5201 c->fc->nb_streams-1, i, e->time);
5202 return AVERROR_INVALIDDATA;
5210 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5212 MOVStreamContext *sc;
5214 if (c->fc->nb_streams < 1)
5215 return AVERROR_INVALIDDATA;
5216 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5217 sc->timecode_track = avio_rb32(pb);
5221 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5226 if (c->fc->nb_streams < 1)
5228 st = c->fc->streams[c->fc->nb_streams - 1];
5230 if (atom.size < 4) {
5231 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5232 return AVERROR_INVALIDDATA;
5235 /* For now, propagate only the OBUs, if any. Once libavcodec is
5236 updated to handle isobmff style extradata this can be removed. */
5242 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5249 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5252 int version, color_range, color_primaries, color_trc, color_space;
5254 if (c->fc->nb_streams < 1)
5256 st = c->fc->streams[c->fc->nb_streams - 1];
5258 if (atom.size < 5) {
5259 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5260 return AVERROR_INVALIDDATA;
5263 version = avio_r8(pb);
5265 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5268 avio_skip(pb, 3); /* flags */
5270 avio_skip(pb, 2); /* profile + level */
5271 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5272 color_primaries = avio_r8(pb);
5273 color_trc = avio_r8(pb);
5274 color_space = avio_r8(pb);
5275 if (avio_rb16(pb)) /* codecIntializationDataSize */
5276 return AVERROR_INVALIDDATA;
5278 if (!av_color_primaries_name(color_primaries))
5279 color_primaries = AVCOL_PRI_UNSPECIFIED;
5280 if (!av_color_transfer_name(color_trc))
5281 color_trc = AVCOL_TRC_UNSPECIFIED;
5282 if (!av_color_space_name(color_space))
5283 color_space = AVCOL_SPC_UNSPECIFIED;
5285 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5286 st->codecpar->color_primaries = color_primaries;
5287 st->codecpar->color_trc = color_trc;
5288 st->codecpar->color_space = color_space;
5293 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5295 MOVStreamContext *sc;
5298 if (c->fc->nb_streams < 1)
5299 return AVERROR_INVALIDDATA;
5301 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5303 if (atom.size < 5) {
5304 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5305 return AVERROR_INVALIDDATA;
5308 version = avio_r8(pb);
5310 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5313 avio_skip(pb, 3); /* flags */
5315 sc->mastering = av_mastering_display_metadata_alloc();
5317 return AVERROR(ENOMEM);
5319 for (i = 0; i < 3; i++) {
5320 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5321 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5323 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5324 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5326 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5327 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5329 sc->mastering->has_primaries = 1;
5330 sc->mastering->has_luminance = 1;
5335 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5337 MOVStreamContext *sc;
5338 const int mapping[3] = {1, 2, 0};
5339 const int chroma_den = 50000;
5340 const int luma_den = 10000;
5343 if (c->fc->nb_streams < 1)
5344 return AVERROR_INVALIDDATA;
5346 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5348 if (atom.size < 24) {
5349 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5350 return AVERROR_INVALIDDATA;
5353 sc->mastering = av_mastering_display_metadata_alloc();
5355 return AVERROR(ENOMEM);
5357 for (i = 0; i < 3; i++) {
5358 const int j = mapping[i];
5359 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5360 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5362 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5363 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5365 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5366 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5368 sc->mastering->has_luminance = 1;
5369 sc->mastering->has_primaries = 1;
5374 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5376 MOVStreamContext *sc;
5379 if (c->fc->nb_streams < 1)
5380 return AVERROR_INVALIDDATA;
5382 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5384 if (atom.size < 5) {
5385 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5386 return AVERROR_INVALIDDATA;
5389 version = avio_r8(pb);
5391 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5394 avio_skip(pb, 3); /* flags */
5396 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5398 return AVERROR(ENOMEM);
5400 sc->coll->MaxCLL = avio_rb16(pb);
5401 sc->coll->MaxFALL = avio_rb16(pb);
5406 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5408 MOVStreamContext *sc;
5410 if (c->fc->nb_streams < 1)
5411 return AVERROR_INVALIDDATA;
5413 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5415 if (atom.size < 4) {
5416 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5417 return AVERROR_INVALIDDATA;
5420 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5422 return AVERROR(ENOMEM);
5424 sc->coll->MaxCLL = avio_rb16(pb);
5425 sc->coll->MaxFALL = avio_rb16(pb);
5430 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5433 MOVStreamContext *sc;
5434 enum AVStereo3DType type;
5437 if (c->fc->nb_streams < 1)
5440 st = c->fc->streams[c->fc->nb_streams - 1];
5443 if (atom.size < 5) {
5444 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5445 return AVERROR_INVALIDDATA;
5447 avio_skip(pb, 4); /* version + flags */
5452 type = AV_STEREO3D_2D;
5455 type = AV_STEREO3D_TOPBOTTOM;
5458 type = AV_STEREO3D_SIDEBYSIDE;
5461 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5465 sc->stereo3d = av_stereo3d_alloc();
5467 return AVERROR(ENOMEM);
5469 sc->stereo3d->type = type;
5473 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5476 MOVStreamContext *sc;
5477 int size, version, layout;
5478 int32_t yaw, pitch, roll;
5479 uint32_t l = 0, t = 0, r = 0, b = 0;
5480 uint32_t tag, padding = 0;
5481 enum AVSphericalProjection projection;
5483 if (c->fc->nb_streams < 1)
5486 st = c->fc->streams[c->fc->nb_streams - 1];
5489 if (atom.size < 8) {
5490 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5491 return AVERROR_INVALIDDATA;
5494 size = avio_rb32(pb);
5495 if (size <= 12 || size > atom.size)
5496 return AVERROR_INVALIDDATA;
5498 tag = avio_rl32(pb);
5499 if (tag != MKTAG('s','v','h','d')) {
5500 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5503 version = avio_r8(pb);
5505 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5509 avio_skip(pb, 3); /* flags */
5510 avio_skip(pb, size - 12); /* metadata_source */
5512 size = avio_rb32(pb);
5513 if (size > atom.size)
5514 return AVERROR_INVALIDDATA;
5516 tag = avio_rl32(pb);
5517 if (tag != MKTAG('p','r','o','j')) {
5518 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5522 size = avio_rb32(pb);
5523 if (size > atom.size)
5524 return AVERROR_INVALIDDATA;
5526 tag = avio_rl32(pb);
5527 if (tag != MKTAG('p','r','h','d')) {
5528 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5531 version = avio_r8(pb);
5533 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5537 avio_skip(pb, 3); /* flags */
5539 /* 16.16 fixed point */
5540 yaw = avio_rb32(pb);
5541 pitch = avio_rb32(pb);
5542 roll = avio_rb32(pb);
5544 size = avio_rb32(pb);
5545 if (size > atom.size)
5546 return AVERROR_INVALIDDATA;
5548 tag = avio_rl32(pb);
5549 version = avio_r8(pb);
5551 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5555 avio_skip(pb, 3); /* flags */
5557 case MKTAG('c','b','m','p'):
5558 layout = avio_rb32(pb);
5560 av_log(c->fc, AV_LOG_WARNING,
5561 "Unsupported cubemap layout %d\n", layout);
5564 projection = AV_SPHERICAL_CUBEMAP;
5565 padding = avio_rb32(pb);
5567 case MKTAG('e','q','u','i'):
5573 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5574 av_log(c->fc, AV_LOG_ERROR,
5575 "Invalid bounding rectangle coordinates "
5576 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5577 return AVERROR_INVALIDDATA;
5580 if (l || t || r || b)
5581 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5583 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5586 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5590 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5592 return AVERROR(ENOMEM);
5594 sc->spherical->projection = projection;
5596 sc->spherical->yaw = yaw;
5597 sc->spherical->pitch = pitch;
5598 sc->spherical->roll = roll;
5600 sc->spherical->padding = padding;
5602 sc->spherical->bound_left = l;
5603 sc->spherical->bound_top = t;
5604 sc->spherical->bound_right = r;
5605 sc->spherical->bound_bottom = b;
5610 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5613 uint8_t *buffer = av_malloc(len + 1);
5617 return AVERROR(ENOMEM);
5620 ret = ffio_read_size(pb, buffer, len);
5624 /* Check for mandatory keys and values, try to support XML as best-effort */
5625 if (!sc->spherical &&
5626 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5627 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5628 av_stristr(val, "true") &&
5629 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5630 av_stristr(val, "true") &&
5631 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5632 av_stristr(val, "equirectangular")) {
5633 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5637 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5639 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5640 enum AVStereo3DType mode;
5642 if (av_stristr(buffer, "left-right"))
5643 mode = AV_STEREO3D_SIDEBYSIDE;
5644 else if (av_stristr(buffer, "top-bottom"))
5645 mode = AV_STEREO3D_TOPBOTTOM;
5647 mode = AV_STEREO3D_2D;
5649 sc->stereo3d = av_stereo3d_alloc();
5653 sc->stereo3d->type = mode;
5657 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5659 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5660 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5662 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5663 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5665 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5673 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5676 MOVStreamContext *sc;
5679 static const uint8_t uuid_isml_manifest[] = {
5680 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5681 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5683 static const uint8_t uuid_xmp[] = {
5684 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5685 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5687 static const uint8_t uuid_spherical[] = {
5688 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5689 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5692 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5693 return AVERROR_INVALIDDATA;
5695 if (c->fc->nb_streams < 1)
5697 st = c->fc->streams[c->fc->nb_streams - 1];
5700 ret = avio_read(pb, uuid, sizeof(uuid));
5703 } else if (ret != sizeof(uuid)) {
5704 return AVERROR_INVALIDDATA;
5706 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5707 uint8_t *buffer, *ptr;
5709 size_t len = atom.size - sizeof(uuid);
5712 return AVERROR_INVALIDDATA;
5714 ret = avio_skip(pb, 4); // zeroes
5717 buffer = av_mallocz(len + 1);
5719 return AVERROR(ENOMEM);
5721 ret = avio_read(pb, buffer, len);
5725 } else if (ret != len) {
5727 return AVERROR_INVALIDDATA;
5731 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5732 ptr += sizeof("systemBitrate=\"") - 1;
5733 c->bitrates_count++;
5734 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5736 c->bitrates_count = 0;
5738 return AVERROR(ENOMEM);
5741 ret = strtol(ptr, &endptr, 10);
5742 if (ret < 0 || errno || *endptr != '"') {
5743 c->bitrates[c->bitrates_count - 1] = 0;
5745 c->bitrates[c->bitrates_count - 1] = ret;
5750 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5752 size_t len = atom.size - sizeof(uuid);
5753 if (c->export_xmp) {
5754 buffer = av_mallocz(len + 1);
5756 return AVERROR(ENOMEM);
5758 ret = avio_read(pb, buffer, len);
5762 } else if (ret != len) {
5764 return AVERROR_INVALIDDATA;
5767 av_dict_set(&c->fc->metadata, "xmp", buffer, 0);
5770 // skip all uuid atom, which makes it fast for long uuid-xmp file
5771 ret = avio_skip(pb, len);
5775 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5776 size_t len = atom.size - sizeof(uuid);
5777 ret = mov_parse_uuid_spherical(sc, pb, len);
5781 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5787 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5790 uint8_t content[16];
5795 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5801 && !memcmp(content, "Anevia\x1A\x1A", 8)
5802 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5803 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5809 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5811 uint32_t format = avio_rl32(pb);
5812 MOVStreamContext *sc;
5816 if (c->fc->nb_streams < 1)
5818 st = c->fc->streams[c->fc->nb_streams - 1];
5823 case MKTAG('e','n','c','v'): // encrypted video
5824 case MKTAG('e','n','c','a'): // encrypted audio
5825 id = mov_codec_id(st, format);
5826 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5827 st->codecpar->codec_id != id) {
5828 av_log(c->fc, AV_LOG_WARNING,
5829 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5830 (char*)&format, st->codecpar->codec_id);
5834 st->codecpar->codec_id = id;
5835 sc->format = format;
5839 if (format != sc->format) {
5840 av_log(c->fc, AV_LOG_WARNING,
5841 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5842 (char*)&format, (char*)&sc->format);
5851 * Gets the current encryption info and associated current stream context. If
5852 * we are parsing a track fragment, this will return the specific encryption
5853 * info for this fragment; otherwise this will return the global encryption
5854 * info for the current stream.
5856 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5858 MOVFragmentStreamInfo *frag_stream_info;
5862 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5863 if (frag_stream_info) {
5864 for (i = 0; i < c->fc->nb_streams; i++) {
5865 if (c->fc->streams[i]->id == frag_stream_info->id) {
5866 st = c->fc->streams[i];
5870 if (i == c->fc->nb_streams)
5872 *sc = st->priv_data;
5874 if (!frag_stream_info->encryption_index) {
5875 // If this stream isn't encrypted, don't create the index.
5876 if (!(*sc)->cenc.default_encrypted_sample)
5878 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5879 if (!frag_stream_info->encryption_index)
5880 return AVERROR(ENOMEM);
5882 *encryption_index = frag_stream_info->encryption_index;
5885 // No current track fragment, using stream level encryption info.
5887 if (c->fc->nb_streams < 1)
5889 st = c->fc->streams[c->fc->nb_streams - 1];
5890 *sc = st->priv_data;
5892 if (!(*sc)->cenc.encryption_index) {
5893 // If this stream isn't encrypted, don't create the index.
5894 if (!(*sc)->cenc.default_encrypted_sample)
5896 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5897 if (!(*sc)->cenc.encryption_index)
5898 return AVERROR(ENOMEM);
5901 *encryption_index = (*sc)->cenc.encryption_index;
5906 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
5909 unsigned int subsample_count;
5910 AVSubsampleEncryptionInfo *subsamples;
5912 if (!sc->cenc.default_encrypted_sample) {
5913 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
5914 return AVERROR_INVALIDDATA;
5917 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
5919 return AVERROR(ENOMEM);
5921 if (sc->cenc.per_sample_iv_size != 0) {
5922 if (avio_read(pb, (*sample)->iv, sc->cenc.per_sample_iv_size) != sc->cenc.per_sample_iv_size) {
5923 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
5924 av_encryption_info_free(*sample);
5926 return AVERROR_INVALIDDATA;
5930 if (use_subsamples) {
5931 subsample_count = avio_rb16(pb);
5932 av_free((*sample)->subsamples);
5933 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
5934 if (!(*sample)->subsamples) {
5935 av_encryption_info_free(*sample);
5937 return AVERROR(ENOMEM);
5940 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
5941 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
5942 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
5945 if (pb->eof_reached) {
5946 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
5947 av_encryption_info_free(*sample);
5949 return AVERROR_INVALIDDATA;
5951 (*sample)->subsample_count = subsample_count;
5957 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5959 AVEncryptionInfo **encrypted_samples;
5960 MOVEncryptionIndex *encryption_index;
5961 MOVStreamContext *sc;
5962 int use_subsamples, ret;
5963 unsigned int sample_count, i, alloc_size = 0;
5965 ret = get_current_encryption_info(c, &encryption_index, &sc);
5969 if (encryption_index->nb_encrypted_samples) {
5970 // This can happen if we have both saio/saiz and senc atoms.
5971 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
5975 avio_r8(pb); /* version */
5976 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
5978 sample_count = avio_rb32(pb);
5979 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
5980 return AVERROR(ENOMEM);
5982 for (i = 0; i < sample_count; i++) {
5983 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
5984 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
5985 min_samples * sizeof(*encrypted_samples));
5986 if (encrypted_samples) {
5987 encryption_index->encrypted_samples = encrypted_samples;
5989 ret = mov_read_sample_encryption_info(
5990 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
5992 ret = AVERROR(ENOMEM);
5994 if (pb->eof_reached) {
5995 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
5996 ret = AVERROR_INVALIDDATA;
6001 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6002 av_freep(&encryption_index->encrypted_samples);
6006 encryption_index->nb_encrypted_samples = sample_count;
6011 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6013 AVEncryptionInfo **sample, **encrypted_samples;
6015 size_t sample_count, sample_info_size, i;
6017 unsigned int alloc_size = 0;
6019 if (encryption_index->nb_encrypted_samples)
6021 sample_count = encryption_index->auxiliary_info_sample_count;
6022 if (encryption_index->auxiliary_offsets_count != 1) {
6023 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6024 return AVERROR_PATCHWELCOME;
6026 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6027 return AVERROR(ENOMEM);
6029 prev_pos = avio_tell(pb);
6030 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6031 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6032 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6036 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6037 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6038 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6039 min_samples * sizeof(*encrypted_samples));
6040 if (!encrypted_samples) {
6041 ret = AVERROR(ENOMEM);
6044 encryption_index->encrypted_samples = encrypted_samples;
6046 sample = &encryption_index->encrypted_samples[i];
6047 sample_info_size = encryption_index->auxiliary_info_default_size
6048 ? encryption_index->auxiliary_info_default_size
6049 : encryption_index->auxiliary_info_sizes[i];
6051 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6055 if (pb->eof_reached) {
6056 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6057 ret = AVERROR_INVALIDDATA;
6059 encryption_index->nb_encrypted_samples = sample_count;
6063 avio_seek(pb, prev_pos, SEEK_SET);
6065 for (; i > 0; i--) {
6066 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6068 av_freep(&encryption_index->encrypted_samples);
6074 * Tries to read the given number of bytes from the stream and puts it in a
6075 * newly allocated buffer. This reads in small chunks to avoid allocating large
6076 * memory if the file contains an invalid/malicious size value.
6078 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6080 const unsigned int block_size = 1024 * 1024;
6081 uint8_t *buffer = NULL;
6082 unsigned int alloc_size = 0, offset = 0;
6083 while (offset < size) {
6084 unsigned int new_size =
6085 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6086 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6087 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6090 return AVERROR(ENOMEM);
6092 buffer = new_buffer;
6094 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6096 return AVERROR_INVALIDDATA;
6105 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6107 MOVEncryptionIndex *encryption_index;
6108 MOVStreamContext *sc;
6110 unsigned int sample_count, aux_info_type, aux_info_param;
6112 ret = get_current_encryption_info(c, &encryption_index, &sc);
6116 if (encryption_index->nb_encrypted_samples) {
6117 // This can happen if we have both saio/saiz and senc atoms.
6118 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6122 if (encryption_index->auxiliary_info_sample_count) {
6123 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6124 return AVERROR_INVALIDDATA;
6127 avio_r8(pb); /* version */
6128 if (avio_rb24(pb) & 0x01) { /* flags */
6129 aux_info_type = avio_rb32(pb);
6130 aux_info_param = avio_rb32(pb);
6131 if (sc->cenc.default_encrypted_sample) {
6132 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6133 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6136 if (aux_info_param != 0) {
6137 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6141 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6142 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6143 aux_info_type == MKBETAG('c','e','n','s') ||
6144 aux_info_type == MKBETAG('c','b','c','1') ||
6145 aux_info_type == MKBETAG('c','b','c','s')) &&
6146 aux_info_param == 0) {
6147 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6148 return AVERROR_INVALIDDATA;
6153 } else if (!sc->cenc.default_encrypted_sample) {
6154 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6158 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6159 sample_count = avio_rb32(pb);
6160 encryption_index->auxiliary_info_sample_count = sample_count;
6162 if (encryption_index->auxiliary_info_default_size == 0) {
6163 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6165 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6170 if (encryption_index->auxiliary_offsets_count) {
6171 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6177 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6179 uint64_t *auxiliary_offsets;
6180 MOVEncryptionIndex *encryption_index;
6181 MOVStreamContext *sc;
6183 unsigned int version, entry_count, aux_info_type, aux_info_param;
6184 unsigned int alloc_size = 0;
6186 ret = get_current_encryption_info(c, &encryption_index, &sc);
6190 if (encryption_index->nb_encrypted_samples) {
6191 // This can happen if we have both saio/saiz and senc atoms.
6192 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6196 if (encryption_index->auxiliary_offsets_count) {
6197 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6198 return AVERROR_INVALIDDATA;
6201 version = avio_r8(pb); /* version */
6202 if (avio_rb24(pb) & 0x01) { /* flags */
6203 aux_info_type = avio_rb32(pb);
6204 aux_info_param = avio_rb32(pb);
6205 if (sc->cenc.default_encrypted_sample) {
6206 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6207 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6210 if (aux_info_param != 0) {
6211 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6215 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6216 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6217 aux_info_type == MKBETAG('c','e','n','s') ||
6218 aux_info_type == MKBETAG('c','b','c','1') ||
6219 aux_info_type == MKBETAG('c','b','c','s')) &&
6220 aux_info_param == 0) {
6221 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6222 return AVERROR_INVALIDDATA;
6227 } else if (!sc->cenc.default_encrypted_sample) {
6228 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6232 entry_count = avio_rb32(pb);
6233 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6234 return AVERROR(ENOMEM);
6236 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6237 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6238 auxiliary_offsets = av_fast_realloc(
6239 encryption_index->auxiliary_offsets, &alloc_size,
6240 min_offsets * sizeof(*auxiliary_offsets));
6241 if (!auxiliary_offsets) {
6242 av_freep(&encryption_index->auxiliary_offsets);
6243 return AVERROR(ENOMEM);
6245 encryption_index->auxiliary_offsets = auxiliary_offsets;
6248 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6250 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6252 if (c->frag_index.current >= 0) {
6253 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6257 if (pb->eof_reached) {
6258 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6259 av_freep(&encryption_index->auxiliary_offsets);
6260 return AVERROR_INVALIDDATA;
6263 encryption_index->auxiliary_offsets_count = entry_count;
6265 if (encryption_index->auxiliary_info_sample_count) {
6266 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6272 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6274 AVEncryptionInitInfo *info, *old_init_info;
6277 uint8_t *side_data, *extra_data, *old_side_data;
6278 size_t side_data_size;
6279 int ret = 0, old_side_data_size;
6280 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6282 if (c->fc->nb_streams < 1)
6284 st = c->fc->streams[c->fc->nb_streams-1];
6286 version = avio_r8(pb); /* version */
6287 avio_rb24(pb); /* flags */
6289 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6290 /* key_id_size */ 16, /* data_size */ 0);
6292 return AVERROR(ENOMEM);
6294 if (avio_read(pb, info->system_id, 16) != 16) {
6295 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6296 ret = AVERROR_INVALIDDATA;
6301 kid_count = avio_rb32(pb);
6302 if (kid_count >= INT_MAX / sizeof(*key_ids))
6303 return AVERROR(ENOMEM);
6305 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6306 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6307 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6308 min_kid_count * sizeof(*key_ids));
6310 ret = AVERROR(ENOMEM);
6313 info->key_ids = key_ids;
6315 info->key_ids[i] = av_mallocz(16);
6316 if (!info->key_ids[i]) {
6317 ret = AVERROR(ENOMEM);
6320 info->num_key_ids = i + 1;
6322 if (avio_read(pb, info->key_ids[i], 16) != 16) {
6323 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6324 ret = AVERROR_INVALIDDATA;
6329 if (pb->eof_reached) {
6330 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6331 ret = AVERROR_INVALIDDATA;
6336 extra_data_size = avio_rb32(pb);
6337 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6341 av_freep(&info->data); // malloc(0) may still allocate something.
6342 info->data = extra_data;
6343 info->data_size = extra_data_size;
6345 // If there is existing initialization data, append to the list.
6346 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6347 if (old_side_data) {
6348 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6349 if (old_init_info) {
6350 // Append to the end of the list.
6351 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6357 info = old_init_info;
6359 // Assume existing side-data will be valid, so the only error we could get is OOM.
6360 ret = AVERROR(ENOMEM);
6365 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6367 ret = AVERROR(ENOMEM);
6370 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6371 side_data, side_data_size);
6376 av_encryption_init_info_free(info);
6380 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6383 MOVStreamContext *sc;
6385 if (c->fc->nb_streams < 1)
6387 st = c->fc->streams[c->fc->nb_streams-1];
6390 if (sc->pseudo_stream_id != 0) {
6391 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6392 return AVERROR_PATCHWELCOME;
6396 return AVERROR_INVALIDDATA;
6398 avio_rb32(pb); /* version and flags */
6400 if (!sc->cenc.default_encrypted_sample) {
6401 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6402 if (!sc->cenc.default_encrypted_sample) {
6403 return AVERROR(ENOMEM);
6407 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6411 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6414 MOVStreamContext *sc;
6415 unsigned int version, pattern, is_protected, iv_size;
6417 if (c->fc->nb_streams < 1)
6419 st = c->fc->streams[c->fc->nb_streams-1];
6422 if (sc->pseudo_stream_id != 0) {
6423 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6424 return AVERROR_PATCHWELCOME;
6427 if (!sc->cenc.default_encrypted_sample) {
6428 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6429 if (!sc->cenc.default_encrypted_sample) {
6430 return AVERROR(ENOMEM);
6435 return AVERROR_INVALIDDATA;
6437 version = avio_r8(pb); /* version */
6438 avio_rb24(pb); /* flags */
6440 avio_r8(pb); /* reserved */
6441 pattern = avio_r8(pb);
6444 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6445 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6448 is_protected = avio_r8(pb);
6449 if (is_protected && !sc->cenc.encryption_index) {
6450 // The whole stream should be by-default encrypted.
6451 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6452 if (!sc->cenc.encryption_index)
6453 return AVERROR(ENOMEM);
6455 sc->cenc.per_sample_iv_size = avio_r8(pb);
6456 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6457 sc->cenc.per_sample_iv_size != 16) {
6458 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6459 return AVERROR_INVALIDDATA;
6461 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6462 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6463 return AVERROR_INVALIDDATA;
6466 if (is_protected && !sc->cenc.per_sample_iv_size) {
6467 iv_size = avio_r8(pb);
6468 if (iv_size != 8 && iv_size != 16) {
6469 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6470 return AVERROR_INVALIDDATA;
6473 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6474 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6475 return AVERROR_INVALIDDATA;
6482 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6485 int last, type, size, ret;
6488 if (c->fc->nb_streams < 1)
6490 st = c->fc->streams[c->fc->nb_streams-1];
6492 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6493 return AVERROR_INVALIDDATA;
6495 /* Check FlacSpecificBox version. */
6496 if (avio_r8(pb) != 0)
6497 return AVERROR_INVALIDDATA;
6499 avio_rb24(pb); /* Flags */
6501 avio_read(pb, buf, sizeof(buf));
6502 flac_parse_block_header(buf, &last, &type, &size);
6504 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6505 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6506 return AVERROR_INVALIDDATA;
6509 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6514 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6519 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6523 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6524 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6525 return AVERROR_PATCHWELCOME;
6528 if (!sc->cenc.aes_ctr) {
6529 /* initialize the cipher */
6530 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6531 if (!sc->cenc.aes_ctr) {
6532 return AVERROR(ENOMEM);
6535 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6541 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6543 if (!sample->subsample_count)
6545 /* decrypt the whole packet */
6546 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6550 for (i = 0; i < sample->subsample_count; i++)
6552 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6553 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6554 return AVERROR_INVALIDDATA;
6557 /* skip the clear bytes */
6558 input += sample->subsamples[i].bytes_of_clear_data;
6559 size -= sample->subsamples[i].bytes_of_clear_data;
6561 /* decrypt the encrypted bytes */
6562 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6563 input += sample->subsamples[i].bytes_of_protected_data;
6564 size -= sample->subsamples[i].bytes_of_protected_data;
6568 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6569 return AVERROR_INVALIDDATA;
6575 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6577 MOVFragmentStreamInfo *frag_stream_info;
6578 MOVEncryptionIndex *encryption_index;
6579 AVEncryptionInfo *encrypted_sample;
6580 int encrypted_index, ret;
6582 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6583 encrypted_index = current_index;
6584 encryption_index = NULL;
6585 if (frag_stream_info) {
6586 // Note this only supports encryption info in the first sample descriptor.
6587 if (mov->fragment.stsd_id == 1) {
6588 if (frag_stream_info->encryption_index) {
6589 encrypted_index = current_index - frag_stream_info->index_entry;
6590 encryption_index = frag_stream_info->encryption_index;
6592 encryption_index = sc->cenc.encryption_index;
6596 encryption_index = sc->cenc.encryption_index;
6599 if (encryption_index) {
6600 if (encryption_index->auxiliary_info_sample_count &&
6601 !encryption_index->nb_encrypted_samples) {
6602 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6603 return AVERROR_INVALIDDATA;
6605 if (encryption_index->auxiliary_offsets_count &&
6606 !encryption_index->nb_encrypted_samples) {
6607 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6608 return AVERROR_INVALIDDATA;
6611 if (!encryption_index->nb_encrypted_samples) {
6612 // Full-sample encryption with default settings.
6613 encrypted_sample = sc->cenc.default_encrypted_sample;
6614 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6615 // Per-sample setting override.
6616 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6618 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6619 return AVERROR_INVALIDDATA;
6622 if (mov->decryption_key) {
6623 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6626 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6628 return AVERROR(ENOMEM);
6629 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6639 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6641 const int OPUS_SEEK_PREROLL_MS = 80;
6646 if (c->fc->nb_streams < 1)
6648 st = c->fc->streams[c->fc->nb_streams-1];
6650 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6651 return AVERROR_INVALIDDATA;
6653 /* Check OpusSpecificBox version. */
6654 if (avio_r8(pb) != 0) {
6655 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6656 return AVERROR_INVALIDDATA;
6659 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6660 size = atom.size + 8;
6662 if (ff_alloc_extradata(st->codecpar, size))
6663 return AVERROR(ENOMEM);
6665 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6666 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6667 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6668 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6670 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6671 little-endian; aside from the preceeding magic and version they're
6672 otherwise currently identical. Data after output gain at offset 16
6673 doesn't need to be bytewapped. */
6674 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6675 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6676 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6677 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6679 st->codecpar->initial_padding = pre_skip;
6680 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6681 (AVRational){1, 1000},
6682 (AVRational){1, 48000});
6687 static const MOVParseTableEntry mov_default_parse_table[] = {
6688 { MKTAG('A','C','L','R'), mov_read_aclr },
6689 { MKTAG('A','P','R','G'), mov_read_avid },
6690 { MKTAG('A','A','L','P'), mov_read_avid },
6691 { MKTAG('A','R','E','S'), mov_read_ares },
6692 { MKTAG('a','v','s','s'), mov_read_avss },
6693 { MKTAG('a','v','1','C'), mov_read_av1c },
6694 { MKTAG('c','h','p','l'), mov_read_chpl },
6695 { MKTAG('c','o','6','4'), mov_read_stco },
6696 { MKTAG('c','o','l','r'), mov_read_colr },
6697 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6698 { MKTAG('d','i','n','f'), mov_read_default },
6699 { MKTAG('D','p','x','E'), mov_read_dpxe },
6700 { MKTAG('d','r','e','f'), mov_read_dref },
6701 { MKTAG('e','d','t','s'), mov_read_default },
6702 { MKTAG('e','l','s','t'), mov_read_elst },
6703 { MKTAG('e','n','d','a'), mov_read_enda },
6704 { MKTAG('f','i','e','l'), mov_read_fiel },
6705 { MKTAG('a','d','r','m'), mov_read_adrm },
6706 { MKTAG('f','t','y','p'), mov_read_ftyp },
6707 { MKTAG('g','l','b','l'), mov_read_glbl },
6708 { MKTAG('h','d','l','r'), mov_read_hdlr },
6709 { MKTAG('i','l','s','t'), mov_read_ilst },
6710 { MKTAG('j','p','2','h'), mov_read_jp2h },
6711 { MKTAG('m','d','a','t'), mov_read_mdat },
6712 { MKTAG('m','d','h','d'), mov_read_mdhd },
6713 { MKTAG('m','d','i','a'), mov_read_default },
6714 { MKTAG('m','e','t','a'), mov_read_meta },
6715 { MKTAG('m','i','n','f'), mov_read_default },
6716 { MKTAG('m','o','o','f'), mov_read_moof },
6717 { MKTAG('m','o','o','v'), mov_read_moov },
6718 { MKTAG('m','v','e','x'), mov_read_default },
6719 { MKTAG('m','v','h','d'), mov_read_mvhd },
6720 { MKTAG('S','M','I',' '), mov_read_svq3 },
6721 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6722 { MKTAG('a','v','c','C'), mov_read_glbl },
6723 { MKTAG('p','a','s','p'), mov_read_pasp },
6724 { MKTAG('s','i','d','x'), mov_read_sidx },
6725 { MKTAG('s','t','b','l'), mov_read_default },
6726 { MKTAG('s','t','c','o'), mov_read_stco },
6727 { MKTAG('s','t','p','s'), mov_read_stps },
6728 { MKTAG('s','t','r','f'), mov_read_strf },
6729 { MKTAG('s','t','s','c'), mov_read_stsc },
6730 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6731 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6732 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6733 { MKTAG('s','t','t','s'), mov_read_stts },
6734 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6735 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6736 { MKTAG('t','f','d','t'), mov_read_tfdt },
6737 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6738 { MKTAG('t','r','a','k'), mov_read_trak },
6739 { MKTAG('t','r','a','f'), mov_read_default },
6740 { MKTAG('t','r','e','f'), mov_read_default },
6741 { MKTAG('t','m','c','d'), mov_read_tmcd },
6742 { MKTAG('c','h','a','p'), mov_read_chap },
6743 { MKTAG('t','r','e','x'), mov_read_trex },
6744 { MKTAG('t','r','u','n'), mov_read_trun },
6745 { MKTAG('u','d','t','a'), mov_read_default },
6746 { MKTAG('w','a','v','e'), mov_read_wave },
6747 { MKTAG('e','s','d','s'), mov_read_esds },
6748 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6749 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6750 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6751 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6752 { MKTAG('w','f','e','x'), mov_read_wfex },
6753 { MKTAG('c','m','o','v'), mov_read_cmov },
6754 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6755 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6756 { MKTAG('s','b','g','p'), mov_read_sbgp },
6757 { MKTAG('h','v','c','C'), mov_read_glbl },
6758 { MKTAG('u','u','i','d'), mov_read_uuid },
6759 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6760 { MKTAG('f','r','e','e'), mov_read_free },
6761 { MKTAG('-','-','-','-'), mov_read_custom },
6762 { MKTAG('s','i','n','f'), mov_read_default },
6763 { MKTAG('f','r','m','a'), mov_read_frma },
6764 { MKTAG('s','e','n','c'), mov_read_senc },
6765 { MKTAG('s','a','i','z'), mov_read_saiz },
6766 { MKTAG('s','a','i','o'), mov_read_saio },
6767 { MKTAG('p','s','s','h'), mov_read_pssh },
6768 { MKTAG('s','c','h','m'), mov_read_schm },
6769 { MKTAG('s','c','h','i'), mov_read_default },
6770 { MKTAG('t','e','n','c'), mov_read_tenc },
6771 { MKTAG('d','f','L','a'), mov_read_dfla },
6772 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6773 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6774 { MKTAG('d','O','p','s'), mov_read_dops },
6775 { MKTAG('S','m','D','m'), mov_read_smdm },
6776 { MKTAG('C','o','L','L'), mov_read_coll },
6777 { MKTAG('v','p','c','C'), mov_read_vpcc },
6778 { MKTAG('m','d','c','v'), mov_read_mdcv },
6779 { MKTAG('c','l','l','i'), mov_read_clli },
6783 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6785 int64_t total_size = 0;
6789 if (c->atom_depth > 10) {
6790 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6791 return AVERROR_INVALIDDATA;
6796 atom.size = INT64_MAX;
6797 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6798 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
6801 if (atom.size >= 8) {
6802 a.size = avio_rb32(pb);
6803 a.type = avio_rl32(pb);
6804 if (a.type == MKTAG('f','r','e','e') &&
6806 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT &&
6809 uint32_t *type = (uint32_t *)buf + 1;
6810 if (avio_read(pb, buf, 8) != 8)
6811 return AVERROR_INVALIDDATA;
6812 avio_seek(pb, -8, SEEK_CUR);
6813 if (*type == MKTAG('m','v','h','d') ||
6814 *type == MKTAG('c','m','o','v')) {
6815 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free atom.\n");
6816 a.type = MKTAG('m','o','o','v');
6819 if (atom.type != MKTAG('r','o','o','t') &&
6820 atom.type != MKTAG('m','o','o','v'))
6822 if (a.type == MKTAG('t','r','a','k') || a.type == MKTAG('m','d','a','t'))
6824 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
6831 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
6832 a.size = avio_rb64(pb) - 8;
6836 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
6837 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
6839 a.size = atom.size - total_size + 8;
6844 a.size = FFMIN(a.size, atom.size - total_size);
6846 for (i = 0; mov_default_parse_table[i].type; i++)
6847 if (mov_default_parse_table[i].type == a.type) {
6848 parse = mov_default_parse_table[i].parse;
6852 // container is user data
6853 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
6854 atom.type == MKTAG('i','l','s','t')))
6855 parse = mov_read_udta_string;
6857 // Supports parsing the QuickTime Metadata Keys.
6858 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
6859 if (!parse && c->found_hdlr_mdta &&
6860 atom.type == MKTAG('m','e','t','a') &&
6861 a.type == MKTAG('k','e','y','s')) {
6862 parse = mov_read_keys;
6865 if (!parse) { /* skip leaf atoms data */
6866 avio_skip(pb, a.size);
6868 int64_t start_pos = avio_tell(pb);
6870 int err = parse(c, pb, a);
6875 if (c->found_moov && c->found_mdat &&
6876 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
6877 start_pos + a.size == avio_size(pb))) {
6878 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
6879 c->next_root_atom = start_pos + a.size;
6883 left = a.size - avio_tell(pb) + start_pos;
6884 if (left > 0) /* skip garbage at atom end */
6885 avio_skip(pb, left);
6886 else if (left < 0) {
6887 av_log(c->fc, AV_LOG_WARNING,
6888 "overread end of atom '%.4s' by %"PRId64" bytes\n",
6889 (char*)&a.type, -left);
6890 avio_seek(pb, left, SEEK_CUR);
6894 total_size += a.size;
6897 if (total_size < atom.size && atom.size < 0x7ffff)
6898 avio_skip(pb, atom.size - total_size);
6904 static int mov_probe(AVProbeData *p)
6909 int moov_offset = -1;
6911 /* check file header */
6914 /* ignore invalid offset */
6915 if ((offset + 8) > (unsigned int)p->buf_size)
6917 tag = AV_RL32(p->buf + offset + 4);
6919 /* check for obvious tags */
6920 case MKTAG('m','o','o','v'):
6921 moov_offset = offset + 4;
6922 case MKTAG('m','d','a','t'):
6923 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
6924 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
6925 case MKTAG('f','t','y','p'):
6926 if (AV_RB32(p->buf+offset) < 8 &&
6927 (AV_RB32(p->buf+offset) != 1 ||
6928 offset + 12 > (unsigned int)p->buf_size ||
6929 AV_RB64(p->buf+offset + 8) == 0)) {
6930 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
6931 } else if (tag == MKTAG('f','t','y','p') &&
6932 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
6933 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
6935 score = FFMAX(score, 5);
6937 score = AVPROBE_SCORE_MAX;
6939 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
6941 /* those are more common words, so rate then a bit less */
6942 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
6943 case MKTAG('w','i','d','e'):
6944 case MKTAG('f','r','e','e'):
6945 case MKTAG('j','u','n','k'):
6946 case MKTAG('p','i','c','t'):
6947 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
6948 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
6950 case MKTAG(0x82,0x82,0x7f,0x7d):
6951 case MKTAG('s','k','i','p'):
6952 case MKTAG('u','u','i','d'):
6953 case MKTAG('p','r','f','l'):
6954 /* if we only find those cause probedata is too small at least rate them */
6955 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
6956 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
6959 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
6962 if(score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
6963 /* moov atom in the header - we should make sure that this is not a
6964 * MOV-packed MPEG-PS */
6965 offset = moov_offset;
6967 while(offset < (p->buf_size - 16)){ /* Sufficient space */
6968 /* We found an actual hdlr atom */
6969 if(AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
6970 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
6971 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')){
6972 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
6973 /* We found a media handler reference atom describing an
6974 * MPEG-PS-in-MOV, return a
6975 * low score to force expanding the probe window until
6976 * mpegps_probe finds what it needs */
6987 // must be done after parsing all trak because there's no order requirement
6988 static void mov_read_chapters(AVFormatContext *s)
6990 MOVContext *mov = s->priv_data;
6992 MOVStreamContext *sc;
6997 for (j = 0; j < mov->nb_chapter_tracks; j++) {
6998 chapter_track = mov->chapter_tracks[j];
7000 for (i = 0; i < s->nb_streams; i++)
7001 if (s->streams[i]->id == chapter_track) {
7006 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7011 cur_pos = avio_tell(sc->pb);
7013 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7014 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7015 if (st->nb_index_entries) {
7016 // Retrieve the first frame, if possible
7018 AVIndexEntry *sample = &st->index_entries[0];
7019 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7020 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7024 if (av_get_packet(sc->pb, &pkt, sample->size) < 0)
7027 st->attached_pic = pkt;
7028 st->attached_pic.stream_index = st->index;
7029 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
7032 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7033 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7034 st->discard = AVDISCARD_ALL;
7035 for (i = 0; i < st->nb_index_entries; i++) {
7036 AVIndexEntry *sample = &st->index_entries[i];
7037 int64_t end = i+1 < st->nb_index_entries ? st->index_entries[i+1].timestamp : st->duration;
7042 if (end < sample->timestamp) {
7043 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7044 end = AV_NOPTS_VALUE;
7047 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7048 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7052 // the first two bytes are the length of the title
7053 len = avio_rb16(sc->pb);
7054 if (len > sample->size-2)
7056 title_len = 2*len + 1;
7057 if (!(title = av_mallocz(title_len)))
7060 // The samples could theoretically be in any encoding if there's an encd
7061 // atom following, but in practice are only utf-8 or utf-16, distinguished
7062 // instead by the presence of a BOM
7066 ch = avio_rb16(sc->pb);
7068 avio_get_str16be(sc->pb, len, title, title_len);
7069 else if (ch == 0xfffe)
7070 avio_get_str16le(sc->pb, len, title, title_len);
7073 if (len == 1 || len == 2)
7076 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7080 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7085 avio_seek(sc->pb, cur_pos, SEEK_SET);
7089 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7090 uint32_t value, int flags)
7093 char buf[AV_TIMECODE_STR_SIZE];
7094 AVRational rate = st->avg_frame_rate;
7095 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7098 av_dict_set(&st->metadata, "timecode",
7099 av_timecode_make_string(&tc, buf, value), 0);
7103 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7105 MOVStreamContext *sc = st->priv_data;
7106 char buf[AV_TIMECODE_STR_SIZE];
7107 int64_t cur_pos = avio_tell(sc->pb);
7108 int hh, mm, ss, ff, drop;
7110 if (!st->nb_index_entries)
7113 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7114 avio_skip(s->pb, 13);
7115 hh = avio_r8(s->pb);
7116 mm = avio_r8(s->pb);
7117 ss = avio_r8(s->pb);
7118 drop = avio_r8(s->pb);
7119 ff = avio_r8(s->pb);
7120 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7121 hh, mm, ss, drop ? ';' : ':', ff);
7122 av_dict_set(&st->metadata, "timecode", buf, 0);
7124 avio_seek(sc->pb, cur_pos, SEEK_SET);
7128 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7130 MOVStreamContext *sc = st->priv_data;
7132 int64_t cur_pos = avio_tell(sc->pb);
7135 if (!st->nb_index_entries)
7138 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7139 value = avio_rb32(s->pb);
7141 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7142 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7143 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7145 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7146 * not the case) and thus assume "frame number format" instead of QT one.
7147 * No sample with tmcd track can be found with a QT timecode at the moment,
7148 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7150 parse_timecode_in_framenum_format(s, st, value, flags);
7152 avio_seek(sc->pb, cur_pos, SEEK_SET);
7156 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7158 if (!index || !*index) return;
7159 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7160 av_encryption_info_free((*index)->encrypted_samples[i]);
7162 av_freep(&(*index)->encrypted_samples);
7163 av_freep(&(*index)->auxiliary_info_sizes);
7164 av_freep(&(*index)->auxiliary_offsets);
7168 static int mov_read_close(AVFormatContext *s)
7170 MOVContext *mov = s->priv_data;
7173 for (i = 0; i < s->nb_streams; i++) {
7174 AVStream *st = s->streams[i];
7175 MOVStreamContext *sc = st->priv_data;
7180 av_freep(&sc->ctts_data);
7181 for (j = 0; j < sc->drefs_count; j++) {
7182 av_freep(&sc->drefs[j].path);
7183 av_freep(&sc->drefs[j].dir);
7185 av_freep(&sc->drefs);
7187 sc->drefs_count = 0;
7189 if (!sc->pb_is_copied)
7190 ff_format_io_close(s, &sc->pb);
7193 av_freep(&sc->chunk_offsets);
7194 av_freep(&sc->stsc_data);
7195 av_freep(&sc->sample_sizes);
7196 av_freep(&sc->keyframes);
7197 av_freep(&sc->stts_data);
7198 av_freep(&sc->stps_data);
7199 av_freep(&sc->elst_data);
7200 av_freep(&sc->rap_group);
7201 av_freep(&sc->display_matrix);
7202 av_freep(&sc->index_ranges);
7205 for (j = 0; j < sc->stsd_count; j++)
7206 av_free(sc->extradata[j]);
7207 av_freep(&sc->extradata);
7208 av_freep(&sc->extradata_size);
7210 mov_free_encryption_index(&sc->cenc.encryption_index);
7211 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7212 av_aes_ctr_free(sc->cenc.aes_ctr);
7214 av_freep(&sc->stereo3d);
7215 av_freep(&sc->spherical);
7216 av_freep(&sc->mastering);
7217 av_freep(&sc->coll);
7220 if (mov->dv_demux) {
7221 avformat_free_context(mov->dv_fctx);
7222 mov->dv_fctx = NULL;
7225 if (mov->meta_keys) {
7226 for (i = 1; i < mov->meta_keys_count; i++) {
7227 av_freep(&mov->meta_keys[i]);
7229 av_freep(&mov->meta_keys);
7232 av_freep(&mov->trex_data);
7233 av_freep(&mov->bitrates);
7235 for (i = 0; i < mov->frag_index.nb_items; i++) {
7236 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7237 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7238 mov_free_encryption_index(&frag[j].encryption_index);
7240 av_freep(&mov->frag_index.item[i].stream_info);
7242 av_freep(&mov->frag_index.item);
7244 av_freep(&mov->aes_decrypt);
7245 av_freep(&mov->chapter_tracks);
7250 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7254 for (i = 0; i < s->nb_streams; i++) {
7255 AVStream *st = s->streams[i];
7256 MOVStreamContext *sc = st->priv_data;
7258 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7259 sc->timecode_track == tmcd_id)
7265 /* look for a tmcd track not referenced by any video track, and export it globally */
7266 static void export_orphan_timecode(AVFormatContext *s)
7270 for (i = 0; i < s->nb_streams; i++) {
7271 AVStream *st = s->streams[i];
7273 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7274 !tmcd_is_referenced(s, i + 1)) {
7275 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7277 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7284 static int read_tfra(MOVContext *mov, AVIOContext *f)
7286 int version, fieldlength, i, j;
7287 int64_t pos = avio_tell(f);
7288 uint32_t size = avio_rb32(f);
7289 unsigned track_id, item_count;
7291 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7294 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7296 version = avio_r8(f);
7298 track_id = avio_rb32(f);
7299 fieldlength = avio_rb32(f);
7300 item_count = avio_rb32(f);
7301 for (i = 0; i < item_count; i++) {
7302 int64_t time, offset;
7304 MOVFragmentStreamInfo * frag_stream_info;
7307 return AVERROR_INVALIDDATA;
7311 time = avio_rb64(f);
7312 offset = avio_rb64(f);
7314 time = avio_rb32(f);
7315 offset = avio_rb32(f);
7318 // The first sample of each stream in a fragment is always a random
7319 // access sample. So it's entry in the tfra can be used as the
7320 // initial PTS of the fragment.
7321 index = update_frag_index(mov, offset);
7322 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7323 if (frag_stream_info &&
7324 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7325 frag_stream_info->first_tfra_pts = time;
7327 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7329 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7331 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7335 avio_seek(f, pos + size, SEEK_SET);
7339 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7341 int64_t stream_size = avio_size(f);
7342 int64_t original_pos = avio_tell(f);
7346 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7350 mfra_size = avio_rb32(f);
7351 if (mfra_size < 0 || mfra_size > stream_size) {
7352 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7355 if ((seek_ret = avio_seek(f, -mfra_size, SEEK_CUR)) < 0) {
7359 if (avio_rb32(f) != mfra_size) {
7360 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7363 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7364 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7367 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7369 ret = read_tfra(c, f);
7375 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7377 av_log(c->fc, AV_LOG_ERROR,
7378 "failed to seek back after looking for mfra\n");
7384 static int mov_read_header(AVFormatContext *s)
7386 MOVContext *mov = s->priv_data;
7387 AVIOContext *pb = s->pb;
7389 MOVAtom atom = { AV_RL32("root") };
7392 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7393 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7394 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7395 return AVERROR(EINVAL);
7399 mov->trak_index = -1;
7400 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7401 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7402 atom.size = avio_size(pb);
7404 atom.size = INT64_MAX;
7406 /* check MOV header */
7408 if (mov->moov_retry)
7409 avio_seek(pb, 0, SEEK_SET);
7410 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7411 av_log(s, AV_LOG_ERROR, "error reading header\n");
7415 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7416 if (!mov->found_moov) {
7417 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7419 return AVERROR_INVALIDDATA;
7421 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7423 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7424 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7425 mov_read_chapters(s);
7426 for (i = 0; i < s->nb_streams; i++)
7427 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7428 mov_read_timecode_track(s, s->streams[i]);
7429 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7430 mov_read_rtmd_track(s, s->streams[i]);
7434 /* copy timecode metadata from tmcd tracks to the related video streams */
7435 for (i = 0; i < s->nb_streams; i++) {
7436 AVStream *st = s->streams[i];
7437 MOVStreamContext *sc = st->priv_data;
7438 if (sc->timecode_track > 0) {
7439 AVDictionaryEntry *tcr;
7440 int tmcd_st_id = -1;
7442 for (j = 0; j < s->nb_streams; j++)
7443 if (s->streams[j]->id == sc->timecode_track)
7446 if (tmcd_st_id < 0 || tmcd_st_id == i)
7448 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7450 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7453 export_orphan_timecode(s);
7455 for (i = 0; i < s->nb_streams; i++) {
7456 AVStream *st = s->streams[i];
7457 MOVStreamContext *sc = st->priv_data;
7458 fix_timescale(mov, sc);
7459 if(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7460 st->skip_samples = sc->start_pad;
7462 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7463 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7464 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7465 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7466 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7467 st->codecpar->width = sc->width;
7468 st->codecpar->height = sc->height;
7470 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7471 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7475 if (mov->handbrake_version &&
7476 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7477 st->codecpar->codec_id == AV_CODEC_ID_MP3
7479 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7480 st->need_parsing = AVSTREAM_PARSE_FULL;
7484 if (mov->trex_data) {
7485 for (i = 0; i < s->nb_streams; i++) {
7486 AVStream *st = s->streams[i];
7487 MOVStreamContext *sc = st->priv_data;
7488 if (st->duration > 0) {
7489 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7490 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7491 sc->data_size, sc->time_scale);
7493 return AVERROR_INVALIDDATA;
7495 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7500 if (mov->use_mfra_for > 0) {
7501 for (i = 0; i < s->nb_streams; i++) {
7502 AVStream *st = s->streams[i];
7503 MOVStreamContext *sc = st->priv_data;
7504 if (sc->duration_for_fps > 0) {
7505 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7506 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7507 sc->data_size, sc->time_scale);
7509 return AVERROR_INVALIDDATA;
7511 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7512 sc->duration_for_fps;
7517 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7518 if (mov->bitrates[i]) {
7519 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7523 ff_rfps_calculate(s);
7525 for (i = 0; i < s->nb_streams; i++) {
7526 AVStream *st = s->streams[i];
7527 MOVStreamContext *sc = st->priv_data;
7529 switch (st->codecpar->codec_type) {
7530 case AVMEDIA_TYPE_AUDIO:
7531 err = ff_replaygain_export(st, s->metadata);
7537 case AVMEDIA_TYPE_VIDEO:
7538 if (sc->display_matrix) {
7539 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7540 sizeof(int32_t) * 9);
7544 sc->display_matrix = NULL;
7547 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7548 (uint8_t *)sc->stereo3d,
7549 sizeof(*sc->stereo3d));
7553 sc->stereo3d = NULL;
7555 if (sc->spherical) {
7556 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7557 (uint8_t *)sc->spherical,
7558 sc->spherical_size);
7562 sc->spherical = NULL;
7564 if (sc->mastering) {
7565 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7566 (uint8_t *)sc->mastering,
7567 sizeof(*sc->mastering));
7571 sc->mastering = NULL;
7574 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7575 (uint8_t *)sc->coll,
7585 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7587 for (i = 0; i < mov->frag_index.nb_items; i++)
7588 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7589 mov->frag_index.item[i].headers_read = 1;
7594 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7596 AVIndexEntry *sample = NULL;
7597 int64_t best_dts = INT64_MAX;
7599 for (i = 0; i < s->nb_streams; i++) {
7600 AVStream *avst = s->streams[i];
7601 MOVStreamContext *msc = avst->priv_data;
7602 if (msc->pb && msc->current_sample < avst->nb_index_entries) {
7603 AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample];
7604 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7605 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7606 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7607 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7608 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb &&
7609 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7610 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7611 sample = current_sample;
7620 static int should_retry(AVIOContext *pb, int error_code) {
7621 if (error_code == AVERROR_EOF || avio_feof(pb))
7627 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7630 MOVContext *mov = s->priv_data;
7632 if (index >= 0 && index < mov->frag_index.nb_items)
7633 target = mov->frag_index.item[index].moof_offset;
7634 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7635 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7636 return AVERROR_INVALIDDATA;
7639 mov->next_root_atom = 0;
7640 if (index < 0 || index >= mov->frag_index.nb_items)
7641 index = search_frag_moof_offset(&mov->frag_index, target);
7642 if (index < mov->frag_index.nb_items) {
7643 if (index + 1 < mov->frag_index.nb_items)
7644 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7645 if (mov->frag_index.item[index].headers_read)
7647 mov->frag_index.item[index].headers_read = 1;
7650 mov->found_mdat = 0;
7652 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7655 if (avio_feof(s->pb))
7657 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7662 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7664 uint8_t *side, *extradata;
7667 /* Save the current index. */
7668 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7670 /* Notify the decoder that extradata changed. */
7671 extradata_size = sc->extradata_size[sc->last_stsd_index];
7672 extradata = sc->extradata[sc->last_stsd_index];
7673 if (extradata_size > 0 && extradata) {
7674 side = av_packet_new_side_data(pkt,
7675 AV_PKT_DATA_NEW_EXTRADATA,
7678 return AVERROR(ENOMEM);
7679 memcpy(side, extradata, extradata_size);
7685 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7687 MOVContext *mov = s->priv_data;
7688 MOVStreamContext *sc;
7689 AVIndexEntry *sample;
7690 AVStream *st = NULL;
7691 int64_t current_index;
7695 sample = mov_find_next_sample(s, &st);
7696 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7697 if (!mov->next_root_atom)
7699 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7704 /* must be done just before reading, to avoid infinite loop on sample */
7705 current_index = sc->current_index;
7706 mov_current_sample_inc(sc);
7708 if (mov->next_root_atom) {
7709 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7710 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7713 if (st->discard != AVDISCARD_ALL) {
7714 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7715 if (ret64 != sample->pos) {
7716 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7717 sc->ffindex, sample->pos);
7718 if (should_retry(sc->pb, ret64)) {
7719 mov_current_sample_dec(sc);
7721 return AVERROR_INVALIDDATA;
7724 if( st->discard == AVDISCARD_NONKEY && 0==(sample->flags & AVINDEX_KEYFRAME) ) {
7725 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7729 ret = av_get_packet(sc->pb, pkt, sample->size);
7731 if (should_retry(sc->pb, ret)) {
7732 mov_current_sample_dec(sc);
7736 if (sc->has_palette) {
7739 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7741 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7743 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7744 sc->has_palette = 0;
7747 #if CONFIG_DV_DEMUXER
7748 if (mov->dv_demux && sc->dv_audio_container) {
7749 avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7750 av_freep(&pkt->data);
7752 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7757 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7758 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7759 st->need_parsing = AVSTREAM_PARSE_FULL;
7763 pkt->stream_index = sc->ffindex;
7764 pkt->dts = sample->timestamp;
7765 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7766 pkt->flags |= AV_PKT_FLAG_DISCARD;
7768 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7769 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
7770 /* update ctts context */
7772 if (sc->ctts_index < sc->ctts_count &&
7773 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
7775 sc->ctts_sample = 0;
7778 int64_t next_dts = (sc->current_sample < st->nb_index_entries) ?
7779 st->index_entries[sc->current_sample].timestamp : st->duration;
7781 if (next_dts >= pkt->dts)
7782 pkt->duration = next_dts - pkt->dts;
7783 pkt->pts = pkt->dts;
7785 if (st->discard == AVDISCARD_ALL)
7787 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
7788 pkt->pos = sample->pos;
7790 /* Multiple stsd handling. */
7791 if (sc->stsc_data) {
7792 /* Keep track of the stsc index for the given sample, then check
7793 * if the stsd index is different from the last used one. */
7795 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
7796 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
7798 sc->stsc_sample = 0;
7799 /* Do not check indexes after a switch. */
7800 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
7801 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
7802 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
7803 ret = mov_change_extradata(sc, pkt);
7810 aax_filter(pkt->data, pkt->size, mov);
7812 ret = cenc_filter(mov, st, sc, pkt, current_index);
7819 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
7821 MOVContext *mov = s->priv_data;
7824 if (!mov->frag_index.complete)
7827 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
7830 if (!mov->frag_index.item[index].headers_read)
7831 return mov_switch_root(s, -1, index);
7832 if (index + 1 < mov->frag_index.nb_items)
7833 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7838 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
7840 MOVStreamContext *sc = st->priv_data;
7841 int sample, time_sample, ret;
7844 // Here we consider timestamp to be PTS, hence try to offset it so that we
7845 // can search over the DTS timeline.
7846 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
7848 ret = mov_seek_fragment(s, st, timestamp);
7852 sample = av_index_search_timestamp(st, timestamp, flags);
7853 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
7854 if (sample < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp)
7856 if (sample < 0) /* not sure what to do */
7857 return AVERROR_INVALIDDATA;
7858 mov_current_sample_set(sc, sample);
7859 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
7860 /* adjust ctts index */
7861 if (sc->ctts_data) {
7863 for (i = 0; i < sc->ctts_count; i++) {
7864 int next = time_sample + sc->ctts_data[i].count;
7865 if (next > sc->current_sample) {
7867 sc->ctts_sample = sc->current_sample - time_sample;
7874 /* adjust stsd index */
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);
7890 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
7892 MOVContext *mc = s->priv_data;
7897 if (stream_index >= s->nb_streams)
7898 return AVERROR_INVALIDDATA;
7900 st = s->streams[stream_index];
7901 sample = mov_seek_stream(s, st, sample_time, flags);
7905 if (mc->seek_individually) {
7906 /* adjust seek timestamp to found sample timestamp */
7907 int64_t seek_timestamp = st->index_entries[sample].timestamp;
7909 for (i = 0; i < s->nb_streams; i++) {
7911 MOVStreamContext *sc = s->streams[i]->priv_data;
7913 st->skip_samples = (sample_time <= 0) ? sc->start_pad : 0;
7915 if (stream_index == i)
7918 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
7919 mov_seek_stream(s, st, timestamp, flags);
7922 for (i = 0; i < s->nb_streams; i++) {
7923 MOVStreamContext *sc;
7926 mov_current_sample_set(sc, 0);
7929 MOVStreamContext *sc;
7930 AVIndexEntry *entry = mov_find_next_sample(s, &st);
7932 return AVERROR_INVALIDDATA;
7934 if (sc->ffindex == stream_index && sc->current_sample == sample)
7936 mov_current_sample_inc(sc);
7942 #define OFFSET(x) offsetof(MOVContext, x)
7943 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
7944 static const AVOption mov_options[] = {
7945 {"use_absolute_path",
7946 "allow using absolute path when opening alias, this is a possible security issue",
7947 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
7949 {"seek_streams_individually",
7950 "Seek each stream individually to the to the closest point",
7951 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
7953 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
7955 {"advanced_editlist",
7956 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
7957 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
7959 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
7962 "use mfra for fragment timestamps",
7963 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
7964 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
7966 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
7967 FLAGS, "use_mfra_for" },
7968 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
7969 FLAGS, "use_mfra_for" },
7970 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
7971 FLAGS, "use_mfra_for" },
7972 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
7973 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
7974 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
7975 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
7976 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
7977 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
7978 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
7979 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
7980 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
7981 .flags = AV_OPT_FLAG_DECODING_PARAM },
7982 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
7983 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
7984 {.i64 = 0}, 0, 1, FLAGS },
7989 static const AVClass mov_class = {
7990 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
7991 .item_name = av_default_item_name,
7992 .option = mov_options,
7993 .version = LIBAVUTIL_VERSION_INT,
7996 AVInputFormat ff_mov_demuxer = {
7997 .name = "mov,mp4,m4a,3gp,3g2,mj2",
7998 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
7999 .priv_class = &mov_class,
8000 .priv_data_size = sizeof(MOVContext),
8001 .extensions = "mov,mp4,m4a,3gp,3g2,mj2",
8002 .read_probe = mov_probe,
8003 .read_header = mov_read_header,
8004 .read_packet = mov_read_packet,
8005 .read_close = mov_read_close,
8006 .read_seek = mov_read_seek,
8007 .flags = AVFMT_NO_BYTE_SEEK,