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;
3450 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
3454 // allocate the index ranges array
3455 msc->index_ranges = av_malloc((msc->elst_count + 1) * sizeof(msc->index_ranges[0]));
3456 if (!msc->index_ranges) {
3457 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
3460 msc->current_index_range = msc->index_ranges;
3461 current_index_range = msc->index_ranges - 1;
3463 // Clean AVStream from traces of old index
3464 st->index_entries = NULL;
3465 st->index_entries_allocated_size = 0;
3466 st->nb_index_entries = 0;
3468 // Clean ctts fields of MOVStreamContext
3469 msc->ctts_data = NULL;
3470 msc->ctts_count = 0;
3471 msc->ctts_index = 0;
3472 msc->ctts_sample = 0;
3473 msc->ctts_allocated_size = 0;
3475 // Reinitialize min_corrected_pts so that it can be computed again.
3476 msc->min_corrected_pts = -1;
3478 // If the dts_shift is positive (in case of negative ctts values in mov),
3479 // then negate the DTS by dts_shift
3480 if (msc->dts_shift > 0) {
3481 edit_list_dts_entry_end -= msc->dts_shift;
3482 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
3485 start_dts = edit_list_dts_entry_end;
3487 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
3488 &edit_list_duration, mov->time_scale)) {
3489 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
3490 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
3492 edit_list_dts_counter = edit_list_dts_entry_end;
3493 edit_list_dts_entry_end += edit_list_duration;
3494 num_discarded_begin = 0;
3495 if (edit_list_media_time == -1) {
3496 empty_edits_sum_duration += edit_list_duration;
3500 // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
3501 // according to the edit list below.
3502 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3503 if (first_non_zero_audio_edit < 0) {
3504 first_non_zero_audio_edit = 1;
3506 first_non_zero_audio_edit = 0;
3509 if (first_non_zero_audio_edit > 0)
3510 st->skip_samples = msc->start_pad = 0;
3513 // While reordering frame index according to edit list we must handle properly
3514 // the scenario when edit list entry starts from none key frame.
3515 // We find closest previous key frame and preserve it and consequent frames in index.
3516 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
3517 search_timestamp = edit_list_media_time;
3518 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3519 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
3520 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
3521 // edit_list_media_time to cover the decoder delay.
3522 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
3525 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
3526 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3527 av_log(mov->fc, AV_LOG_WARNING,
3528 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
3529 st->index, edit_list_index, search_timestamp);
3530 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
3531 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3532 av_log(mov->fc, AV_LOG_WARNING,
3533 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
3534 st->index, edit_list_index, search_timestamp);
3537 ctts_sample_old = 0;
3540 current = e_old + index;
3541 edit_list_start_ctts_sample = ctts_sample_old;
3543 // Iterate over index and arrange it according to edit list
3544 edit_list_start_encountered = 0;
3545 found_keyframe_after_edit = 0;
3546 for (; current < e_old_end; current++, index++) {
3547 // check if frame outside edit list mark it for discard
3548 frame_duration = (current + 1 < e_old_end) ?
3549 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
3551 flags = current->flags;
3553 // frames (pts) before or after edit list
3554 curr_cts = current->timestamp + msc->dts_shift;
3557 if (ctts_data_old && ctts_index_old < ctts_count_old) {
3558 curr_ctts = ctts_data_old[ctts_index_old].duration;
3559 av_log(mov->fc, AV_LOG_DEBUG, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
3560 curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
3561 curr_cts += curr_ctts;
3563 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
3564 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3565 &msc->ctts_allocated_size,
3566 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3567 ctts_data_old[ctts_index_old].duration) == -1) {
3568 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3570 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3571 ctts_data_old[ctts_index_old].duration);
3575 ctts_sample_old = 0;
3576 edit_list_start_ctts_sample = 0;
3580 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
3581 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
3582 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
3583 first_non_zero_audio_edit > 0) {
3584 packet_skip_samples = edit_list_media_time - curr_cts;
3585 st->skip_samples += packet_skip_samples;
3587 // Shift the index entry timestamp by packet_skip_samples to be correct.
3588 edit_list_dts_counter -= packet_skip_samples;
3589 if (edit_list_start_encountered == 0) {
3590 edit_list_start_encountered = 1;
3591 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
3592 // discarded packets.
3593 if (frame_duration_buffer) {
3594 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3595 frame_duration_buffer, num_discarded_begin);
3596 av_freep(&frame_duration_buffer);
3600 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
3602 flags |= AVINDEX_DISCARD_FRAME;
3603 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
3605 if (edit_list_start_encountered == 0) {
3606 num_discarded_begin++;
3607 frame_duration_buffer = av_realloc(frame_duration_buffer,
3608 num_discarded_begin * sizeof(int64_t));
3609 if (!frame_duration_buffer) {
3610 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
3613 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
3615 // Increment skip_samples for the first non-zero audio edit list
3616 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3617 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
3618 st->skip_samples += frame_duration;
3623 if (msc->min_corrected_pts < 0) {
3624 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
3626 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
3628 if (edit_list_start_encountered == 0) {
3629 edit_list_start_encountered = 1;
3630 // Make timestamps strictly monotonically increasing by rewriting timestamps for
3631 // discarded packets.
3632 if (frame_duration_buffer) {
3633 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3634 frame_duration_buffer, num_discarded_begin);
3635 av_freep(&frame_duration_buffer);
3640 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
3641 current->min_distance, flags) == -1) {
3642 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
3646 // Update the index ranges array
3647 if (current_index_range < msc->index_ranges || index != current_index_range->end) {
3648 current_index_range++;
3649 current_index_range->start = index;
3651 current_index_range->end = index + 1;
3653 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
3654 if (edit_list_start_encountered > 0) {
3655 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
3658 // Break when found first key frame after edit entry completion
3659 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
3660 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
3661 if (ctts_data_old) {
3662 // If we have CTTS and this is the first keyframe after edit elist,
3663 // wait for one more, because there might be trailing B-frames after this I-frame
3664 // that do belong to the edit.
3665 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
3666 found_keyframe_after_edit = 1;
3669 if (ctts_sample_old != 0) {
3670 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3671 &msc->ctts_allocated_size,
3672 ctts_sample_old - edit_list_start_ctts_sample,
3673 ctts_data_old[ctts_index_old].duration) == -1) {
3674 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3675 ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
3676 ctts_data_old[ctts_index_old].duration);
3685 // If there are empty edits, then msc->min_corrected_pts might be positive
3686 // intentionally. So we subtract the sum duration of emtpy edits here.
3687 msc->min_corrected_pts -= empty_edits_sum_duration;
3689 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
3690 // dts by that amount to make the first pts zero.
3691 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
3692 if (msc->min_corrected_pts > 0) {
3693 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
3694 for (i = 0; i < st->nb_index_entries; ++i) {
3695 st->index_entries[i].timestamp -= msc->min_corrected_pts;
3699 // Start time should be equal to zero or the duration of any empty edits.
3700 st->start_time = empty_edits_sum_duration;
3702 // Update av stream length, if it ends up shorter than the track's media duration
3703 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
3704 msc->start_pad = st->skip_samples;
3706 // Free the old index and the old CTTS structures
3708 av_free(ctts_data_old);
3709 av_freep(&frame_duration_buffer);
3711 // Null terminate the index ranges array
3712 current_index_range++;
3713 current_index_range->start = 0;
3714 current_index_range->end = 0;
3715 msc->current_index = msc->index_ranges[0].start;
3718 static void mov_build_index(MOVContext *mov, AVStream *st)
3720 MOVStreamContext *sc = st->priv_data;
3721 int64_t current_offset;
3722 int64_t current_dts = 0;
3723 unsigned int stts_index = 0;
3724 unsigned int stsc_index = 0;
3725 unsigned int stss_index = 0;
3726 unsigned int stps_index = 0;
3728 uint64_t stream_size = 0;
3729 MOVStts *ctts_data_old = sc->ctts_data;
3730 unsigned int ctts_count_old = sc->ctts_count;
3732 if (sc->elst_count) {
3733 int i, edit_start_index = 0, multiple_edits = 0;
3734 int64_t empty_duration = 0; // empty duration of the first edit list entry
3735 int64_t start_time = 0; // start time of the media
3737 for (i = 0; i < sc->elst_count; i++) {
3738 const MOVElst *e = &sc->elst_data[i];
3739 if (i == 0 && e->time == -1) {
3740 /* if empty, the first entry is the start time of the stream
3741 * relative to the presentation itself */
3742 empty_duration = e->duration;
3743 edit_start_index = 1;
3744 } else if (i == edit_start_index && e->time >= 0) {
3745 start_time = e->time;
3751 if (multiple_edits && !mov->advanced_editlist)
3752 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
3753 "Use -advanced_editlist to correctly decode otherwise "
3754 "a/v desync might occur\n");
3756 /* adjust first dts according to edit list */
3757 if ((empty_duration || start_time) && mov->time_scale > 0) {
3759 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
3760 sc->time_offset = start_time - empty_duration;
3761 sc->min_corrected_pts = start_time;
3762 if (!mov->advanced_editlist)
3763 current_dts = -sc->time_offset;
3766 if (!multiple_edits && !mov->advanced_editlist &&
3767 st->codecpar->codec_id == AV_CODEC_ID_AAC && start_time > 0)
3768 sc->start_pad = start_time;
3771 /* only use old uncompressed audio chunk demuxing when stts specifies it */
3772 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3773 sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
3774 unsigned int current_sample = 0;
3775 unsigned int stts_sample = 0;
3776 unsigned int sample_size;
3777 unsigned int distance = 0;
3778 unsigned int rap_group_index = 0;
3779 unsigned int rap_group_sample = 0;
3780 int64_t last_dts = 0;
3781 int64_t dts_correction = 0;
3782 int rap_group_present = sc->rap_group_count && sc->rap_group;
3783 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
3785 current_dts -= sc->dts_shift;
3786 last_dts = current_dts;
3788 if (!sc->sample_count || st->nb_index_entries)
3790 if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
3792 if (av_reallocp_array(&st->index_entries,
3793 st->nb_index_entries + sc->sample_count,
3794 sizeof(*st->index_entries)) < 0) {
3795 st->nb_index_entries = 0;
3798 st->index_entries_allocated_size = (st->nb_index_entries + sc->sample_count) * sizeof(*st->index_entries);
3800 if (ctts_data_old) {
3801 // Expand ctts entries such that we have a 1-1 mapping with samples
3802 if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
3805 sc->ctts_allocated_size = 0;
3806 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size,
3807 sc->sample_count * sizeof(*sc->ctts_data));
3808 if (!sc->ctts_data) {
3809 av_free(ctts_data_old);
3813 memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
3815 for (i = 0; i < ctts_count_old &&
3816 sc->ctts_count < sc->sample_count; i++)
3817 for (j = 0; j < ctts_data_old[i].count &&
3818 sc->ctts_count < sc->sample_count; j++)
3819 add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
3820 &sc->ctts_allocated_size, 1,
3821 ctts_data_old[i].duration);
3822 av_free(ctts_data_old);
3825 for (i = 0; i < sc->chunk_count; i++) {
3826 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
3827 current_offset = sc->chunk_offsets[i];
3828 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3829 i + 1 == sc->stsc_data[stsc_index + 1].first)
3832 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
3833 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
3834 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
3835 sc->stsz_sample_size = sc->sample_size;
3837 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
3838 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
3839 sc->stsz_sample_size = sc->sample_size;
3842 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
3844 if (current_sample >= sc->sample_count) {
3845 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
3849 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
3851 if (stss_index + 1 < sc->keyframe_count)
3853 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
3855 if (stps_index + 1 < sc->stps_count)
3858 if (rap_group_present && rap_group_index < sc->rap_group_count) {
3859 if (sc->rap_group[rap_group_index].index > 0)
3861 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
3862 rap_group_sample = 0;
3866 if (sc->keyframe_absent
3868 && !rap_group_present
3869 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
3873 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
3874 if (sc->pseudo_stream_id == -1 ||
3875 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
3877 if (sample_size > 0x3FFFFFFF) {
3878 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
3881 e = &st->index_entries[st->nb_index_entries++];
3882 e->pos = current_offset;
3883 e->timestamp = current_dts;
3884 e->size = sample_size;
3885 e->min_distance = distance;
3886 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
3887 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
3888 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
3889 current_offset, current_dts, sample_size, distance, keyframe);
3890 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries < 100)
3891 ff_rfps_add_frame(mov->fc, st, current_dts);
3894 current_offset += sample_size;
3895 stream_size += sample_size;
3897 /* A negative sample duration is invalid based on the spec,
3898 * but some samples need it to correct the DTS. */
3899 if (sc->stts_data[stts_index].duration < 0) {
3900 av_log(mov->fc, AV_LOG_WARNING,
3901 "Invalid SampleDelta %d in STTS, at %d st:%d\n",
3902 sc->stts_data[stts_index].duration, stts_index,
3904 dts_correction += sc->stts_data[stts_index].duration - 1;
3905 sc->stts_data[stts_index].duration = 1;
3907 current_dts += sc->stts_data[stts_index].duration;
3908 if (!dts_correction || current_dts + dts_correction > last_dts) {
3909 current_dts += dts_correction;
3912 /* Avoid creating non-monotonous DTS */
3913 dts_correction += current_dts - last_dts - 1;
3914 current_dts = last_dts + 1;
3916 last_dts = current_dts;
3920 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
3926 if (st->duration > 0)
3927 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
3929 unsigned chunk_samples, total = 0;
3931 if (!sc->chunk_count)
3934 // compute total chunk count
3935 for (i = 0; i < sc->stsc_count; i++) {
3936 unsigned count, chunk_count;
3938 chunk_samples = sc->stsc_data[i].count;
3939 if (i != sc->stsc_count - 1 &&
3940 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
3941 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
3945 if (sc->samples_per_frame >= 160) { // gsm
3946 count = chunk_samples / sc->samples_per_frame;
3947 } else if (sc->samples_per_frame > 1) {
3948 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
3949 count = (chunk_samples+samples-1) / samples;
3951 count = (chunk_samples+1023) / 1024;
3954 if (mov_stsc_index_valid(i, sc->stsc_count))
3955 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
3957 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
3958 total += chunk_count * count;
3961 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
3962 if (total >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
3964 if (av_reallocp_array(&st->index_entries,
3965 st->nb_index_entries + total,
3966 sizeof(*st->index_entries)) < 0) {
3967 st->nb_index_entries = 0;
3970 st->index_entries_allocated_size = (st->nb_index_entries + total) * sizeof(*st->index_entries);
3973 for (i = 0; i < sc->chunk_count; i++) {
3974 current_offset = sc->chunk_offsets[i];
3975 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3976 i + 1 == sc->stsc_data[stsc_index + 1].first)
3978 chunk_samples = sc->stsc_data[stsc_index].count;
3980 while (chunk_samples > 0) {
3982 unsigned size, samples;
3984 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
3985 avpriv_request_sample(mov->fc,
3986 "Zero bytes per frame, but %d samples per frame",
3987 sc->samples_per_frame);
3991 if (sc->samples_per_frame >= 160) { // gsm
3992 samples = sc->samples_per_frame;
3993 size = sc->bytes_per_frame;
3995 if (sc->samples_per_frame > 1) {
3996 samples = FFMIN((1024 / sc->samples_per_frame)*
3997 sc->samples_per_frame, chunk_samples);
3998 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
4000 samples = FFMIN(1024, chunk_samples);
4001 size = samples * sc->sample_size;
4005 if (st->nb_index_entries >= total) {
4006 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4009 if (size > 0x3FFFFFFF) {
4010 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4013 e = &st->index_entries[st->nb_index_entries++];
4014 e->pos = current_offset;
4015 e->timestamp = current_dts;
4017 e->min_distance = 0;
4018 e->flags = AVINDEX_KEYFRAME;
4019 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4020 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4023 current_offset += size;
4024 current_dts += samples;
4025 chunk_samples -= samples;
4030 if (!mov->ignore_editlist && mov->advanced_editlist) {
4031 // Fix index according to edit lists.
4032 mov_fix_index(mov, st);
4035 // Update start time of the stream.
4036 if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries > 0) {
4037 st->start_time = st->index_entries[0].timestamp + sc->dts_shift;
4038 if (sc->ctts_data) {
4039 st->start_time += sc->ctts_data[0].duration;
4043 mov_estimate_video_delay(mov, st);
4046 static int test_same_origin(const char *src, const char *ref) {
4056 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4057 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4059 if (strlen(src) == 0) {
4061 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4062 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4063 strlen(src_host) + 1 >= sizeof(src_host) ||
4064 strlen(ref_host) + 1 >= sizeof(ref_host)) {
4066 } else if (strcmp(src_proto, ref_proto) ||
4067 strcmp(src_auth, ref_auth) ||
4068 strcmp(src_host, ref_host) ||
4069 src_port != ref_port) {
4075 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4077 /* try relative path, we do not try the absolute because it can leak information about our
4078 system to an attacker */
4079 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4080 char filename[1025];
4081 const char *src_path;
4084 /* find a source dir */
4085 src_path = strrchr(src, '/');
4091 /* find a next level down to target */
4092 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4093 if (ref->path[l] == '/') {
4094 if (i == ref->nlvl_to - 1)
4100 /* compose filename if next level down to target was found */
4101 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4102 memcpy(filename, src, src_path - src);
4103 filename[src_path - src] = 0;
4105 for (i = 1; i < ref->nlvl_from; i++)
4106 av_strlcat(filename, "../", sizeof(filename));
4108 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4109 if (!c->use_absolute_path) {
4110 int same_origin = test_same_origin(src, filename);
4113 av_log(c->fc, AV_LOG_ERROR,
4114 "Reference with mismatching origin, %s not tried for security reasons, "
4115 "set demuxer option use_absolute_path to allow it anyway\n",
4117 return AVERROR(ENOENT);
4120 if(strstr(ref->path + l + 1, "..") ||
4121 strstr(ref->path + l + 1, ":") ||
4122 (ref->nlvl_from > 1 && same_origin < 0) ||
4123 (filename[0] == '/' && src_path == src))
4124 return AVERROR(ENOENT);
4127 if (strlen(filename) + 1 == sizeof(filename))
4128 return AVERROR(ENOENT);
4129 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4132 } else if (c->use_absolute_path) {
4133 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4134 "this is a possible security issue\n");
4135 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4138 av_log(c->fc, AV_LOG_ERROR,
4139 "Absolute path %s not tried for security reasons, "
4140 "set demuxer option use_absolute_path to allow absolute paths\n",
4144 return AVERROR(ENOENT);
4147 static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
4149 if (sc->time_scale <= 0) {
4150 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4151 sc->time_scale = c->time_scale;
4152 if (sc->time_scale <= 0)
4157 static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4160 MOVStreamContext *sc;
4163 st = avformat_new_stream(c->fc, NULL);
4164 if (!st) return AVERROR(ENOMEM);
4166 sc = av_mallocz(sizeof(MOVStreamContext));
4167 if (!sc) return AVERROR(ENOMEM);
4170 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
4171 sc->ffindex = st->index;
4172 c->trak_index = st->index;
4174 if ((ret = mov_read_default(c, pb, atom)) < 0)
4179 // Here stsc refers to a chunk not described in stco. This is technically invalid,
4180 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4181 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4183 av_freep(&sc->stsc_data);
4187 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4188 (!sc->sample_size && !sc->sample_count))) ||
4189 (!sc->chunk_count && sc->sample_count)) {
4190 av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4194 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4195 av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4197 return AVERROR_INVALIDDATA;
4200 fix_timescale(c, sc);
4202 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4204 mov_build_index(c, st);
4206 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4207 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4208 if (c->enable_drefs) {
4209 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4210 av_log(c->fc, AV_LOG_ERROR,
4211 "stream %d, error opening alias: path='%s', dir='%s', "
4212 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4213 st->index, dref->path, dref->dir, dref->filename,
4214 dref->volume, dref->nlvl_from, dref->nlvl_to);
4216 av_log(c->fc, AV_LOG_WARNING,
4217 "Skipped opening external track: "
4218 "stream %d, alias: path='%s', dir='%s', "
4219 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4220 "Set enable_drefs to allow this.\n",
4221 st->index, dref->path, dref->dir, dref->filename,
4222 dref->volume, dref->nlvl_from, dref->nlvl_to);
4226 sc->pb_is_copied = 1;
4229 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4230 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4231 sc->height && sc->width &&
4232 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4233 st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4234 ((double)st->codecpar->width * sc->height), INT_MAX);
4237 #if FF_API_R_FRAME_RATE
4238 if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4239 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
4240 sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4244 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4245 if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4246 TAG_IS_AVCI(st->codecpar->codec_tag)) {
4247 ret = ff_generate_avci_extradata(st);
4252 switch (st->codecpar->codec_id) {
4253 #if CONFIG_H261_DECODER
4254 case AV_CODEC_ID_H261:
4256 #if CONFIG_H263_DECODER
4257 case AV_CODEC_ID_H263:
4259 #if CONFIG_MPEG4_DECODER
4260 case AV_CODEC_ID_MPEG4:
4262 st->codecpar->width = 0; /* let decoder init width/height */
4263 st->codecpar->height= 0;
4267 // If the duration of the mp3 packets is not constant, then they could need a parser
4268 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4269 && sc->stts_count > 3
4270 && sc->stts_count*10 > st->nb_frames
4271 && sc->time_scale == st->codecpar->sample_rate) {
4272 st->need_parsing = AVSTREAM_PARSE_FULL;
4274 /* Do not need those anymore. */
4275 av_freep(&sc->chunk_offsets);
4276 av_freep(&sc->sample_sizes);
4277 av_freep(&sc->keyframes);
4278 av_freep(&sc->stts_data);
4279 av_freep(&sc->stps_data);
4280 av_freep(&sc->elst_data);
4281 av_freep(&sc->rap_group);
4286 static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4289 c->itunes_metadata = 1;
4290 ret = mov_read_default(c, pb, atom);
4291 c->itunes_metadata = 0;
4295 static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4304 count = avio_rb32(pb);
4305 if (count > UINT_MAX / sizeof(*c->meta_keys) - 1) {
4306 av_log(c->fc, AV_LOG_ERROR,
4307 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
4308 return AVERROR_INVALIDDATA;
4311 c->meta_keys_count = count + 1;
4312 c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
4314 return AVERROR(ENOMEM);
4316 for (i = 1; i <= count; ++i) {
4317 uint32_t key_size = avio_rb32(pb);
4318 uint32_t type = avio_rl32(pb);
4320 av_log(c->fc, AV_LOG_ERROR,
4321 "The key# %"PRIu32" in meta has invalid size:"
4322 "%"PRIu32"\n", i, key_size);
4323 return AVERROR_INVALIDDATA;
4326 if (type != MKTAG('m','d','t','a')) {
4327 avio_skip(pb, key_size);
4329 c->meta_keys[i] = av_mallocz(key_size + 1);
4330 if (!c->meta_keys[i])
4331 return AVERROR(ENOMEM);
4332 avio_read(pb, c->meta_keys[i], key_size);
4338 static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4340 int64_t end = avio_tell(pb) + atom.size;
4341 uint8_t *key = NULL, *val = NULL, *mean = NULL;
4345 MOVStreamContext *sc;
4347 if (c->fc->nb_streams < 1)
4349 st = c->fc->streams[c->fc->nb_streams-1];
4352 for (i = 0; i < 3; i++) {
4356 if (end - avio_tell(pb) <= 12)
4359 len = avio_rb32(pb);
4360 tag = avio_rl32(pb);
4361 avio_skip(pb, 4); // flags
4363 if (len < 12 || len - 12 > end - avio_tell(pb))
4367 if (tag == MKTAG('m', 'e', 'a', 'n'))
4369 else if (tag == MKTAG('n', 'a', 'm', 'e'))
4371 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
4378 *p = av_malloc(len + 1);
4380 ret = AVERROR(ENOMEM);
4383 ret = ffio_read_size(pb, *p, len);
4391 if (mean && key && val) {
4392 if (strcmp(key, "iTunSMPB") == 0) {
4393 int priming, remainder, samples;
4394 if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
4395 if(priming>0 && priming<16384)
4396 sc->start_pad = priming;
4399 if (strcmp(key, "cdec") != 0) {
4400 av_dict_set(&c->fc->metadata, key, val,
4401 AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
4405 av_log(c->fc, AV_LOG_VERBOSE,
4406 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
4409 avio_seek(pb, end, SEEK_SET);
4416 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4418 while (atom.size > 8) {
4419 uint32_t tag = avio_rl32(pb);
4421 if (tag == MKTAG('h','d','l','r')) {
4422 avio_seek(pb, -8, SEEK_CUR);
4424 return mov_read_default(c, pb, atom);
4430 // return 1 when matrix is identity, 0 otherwise
4431 #define IS_MATRIX_IDENT(matrix) \
4432 ( (matrix)[0][0] == (1 << 16) && \
4433 (matrix)[1][1] == (1 << 16) && \
4434 (matrix)[2][2] == (1 << 30) && \
4435 !(matrix)[0][1] && !(matrix)[0][2] && \
4436 !(matrix)[1][0] && !(matrix)[1][2] && \
4437 !(matrix)[2][0] && !(matrix)[2][1])
4439 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4444 int display_matrix[3][3];
4445 int res_display_matrix[3][3] = { { 0 } };
4447 MOVStreamContext *sc;
4451 if (c->fc->nb_streams < 1)
4453 st = c->fc->streams[c->fc->nb_streams-1];
4456 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4457 // avoids corrupting AVStreams mapped to an earlier tkhd.
4459 return AVERROR_INVALIDDATA;
4461 version = avio_r8(pb);
4462 flags = avio_rb24(pb);
4463 st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
4469 avio_rb32(pb); /* creation time */
4470 avio_rb32(pb); /* modification time */
4472 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4473 avio_rb32(pb); /* reserved */
4475 /* highlevel (considering edits) duration in movie timebase */
4476 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4477 avio_rb32(pb); /* reserved */
4478 avio_rb32(pb); /* reserved */
4480 avio_rb16(pb); /* layer */
4481 avio_rb16(pb); /* alternate group */
4482 avio_rb16(pb); /* volume */
4483 avio_rb16(pb); /* reserved */
4485 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4486 // they're kept in fixed point format through all calculations
4487 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4488 // side data, but the scale factor is not needed to calculate aspect ratio
4489 for (i = 0; i < 3; i++) {
4490 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
4491 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
4492 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
4495 width = avio_rb32(pb); // 16.16 fixed point track width
4496 height = avio_rb32(pb); // 16.16 fixed point track height
4497 sc->width = width >> 16;
4498 sc->height = height >> 16;
4500 // apply the moov display matrix (after the tkhd one)
4501 for (i = 0; i < 3; i++) {
4502 const int sh[3] = { 16, 16, 30 };
4503 for (j = 0; j < 3; j++) {
4504 for (e = 0; e < 3; e++) {
4505 res_display_matrix[i][j] +=
4506 ((int64_t) display_matrix[i][e] *
4507 c->movie_display_matrix[e][j]) >> sh[e];
4512 // save the matrix when it is not the default identity
4513 if (!IS_MATRIX_IDENT(res_display_matrix)) {
4516 av_freep(&sc->display_matrix);
4517 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4518 if (!sc->display_matrix)
4519 return AVERROR(ENOMEM);
4521 for (i = 0; i < 3; i++)
4522 for (j = 0; j < 3; j++)
4523 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4525 #if FF_API_OLD_ROTATE_API
4526 rotate = av_display_rotation_get(sc->display_matrix);
4527 if (!isnan(rotate)) {
4528 char rotate_buf[64];
4530 if (rotate < 0) // for backward compatibility
4532 snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate);
4533 av_dict_set(&st->metadata, "rotate", rotate_buf, 0);
4538 // transform the display width/height according to the matrix
4539 // to keep the same scale, use [width height 1<<16]
4540 if (width && height && sc->display_matrix) {
4541 double disp_transform[2];
4543 for (i = 0; i < 2; i++)
4544 disp_transform[i] = hypot(sc->display_matrix[0 + i],
4545 sc->display_matrix[3 + i]);
4547 if (disp_transform[0] > 0 && disp_transform[1] > 0 &&
4548 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4549 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4550 st->sample_aspect_ratio = av_d2q(
4551 disp_transform[0] / disp_transform[1],
4557 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4559 MOVFragment *frag = &c->fragment;
4560 MOVTrackExt *trex = NULL;
4561 int flags, track_id, i;
4563 c->fragment.found_tfhd = 1;
4565 avio_r8(pb); /* version */
4566 flags = avio_rb24(pb);
4568 track_id = avio_rb32(pb);
4570 return AVERROR_INVALIDDATA;
4571 for (i = 0; i < c->trex_count; i++)
4572 if (c->trex_data[i].track_id == track_id) {
4573 trex = &c->trex_data[i];
4577 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4580 frag->track_id = track_id;
4581 set_frag_stream(&c->frag_index, track_id);
4583 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4584 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4585 frag->moof_offset : frag->implicit_offset;
4586 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4588 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4589 avio_rb32(pb) : trex->duration;
4590 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4591 avio_rb32(pb) : trex->size;
4592 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4593 avio_rb32(pb) : trex->flags;
4594 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4599 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4604 num = atom.size / 4;
4605 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4606 return AVERROR(ENOMEM);
4608 av_free(c->chapter_tracks);
4609 c->chapter_tracks = new_tracks;
4610 c->nb_chapter_tracks = num;
4612 for (i = 0; i < num && !pb->eof_reached; i++)
4613 c->chapter_tracks[i] = avio_rb32(pb);
4618 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4623 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4624 return AVERROR_INVALIDDATA;
4625 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4626 sizeof(*c->trex_data))) < 0) {
4631 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4633 trex = &c->trex_data[c->trex_count++];
4634 avio_r8(pb); /* version */
4635 avio_rb24(pb); /* flags */
4636 trex->track_id = avio_rb32(pb);
4637 trex->stsd_id = avio_rb32(pb);
4638 trex->duration = avio_rb32(pb);
4639 trex->size = avio_rb32(pb);
4640 trex->flags = avio_rb32(pb);
4644 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4646 MOVFragment *frag = &c->fragment;
4647 AVStream *st = NULL;
4648 MOVStreamContext *sc;
4650 MOVFragmentStreamInfo * frag_stream_info;
4651 int64_t base_media_decode_time;
4653 for (i = 0; i < c->fc->nb_streams; i++) {
4654 if (c->fc->streams[i]->id == frag->track_id) {
4655 st = c->fc->streams[i];
4660 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4664 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4666 version = avio_r8(pb);
4667 avio_rb24(pb); /* flags */
4669 base_media_decode_time = avio_rb64(pb);
4671 base_media_decode_time = avio_rb32(pb);
4674 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4675 if (frag_stream_info)
4676 frag_stream_info->tfdt_dts = base_media_decode_time;
4677 sc->track_end = base_media_decode_time;
4682 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4684 MOVFragment *frag = &c->fragment;
4685 AVStream *st = NULL;
4686 MOVStreamContext *sc;
4689 int64_t dts, pts = AV_NOPTS_VALUE;
4690 int data_offset = 0;
4691 unsigned entries, first_sample_flags = frag->flags;
4692 int flags, distance, i;
4693 int64_t prev_dts = AV_NOPTS_VALUE;
4694 int next_frag_index = -1, index_entry_pos;
4695 size_t requested_size;
4696 size_t old_ctts_allocated_size;
4697 AVIndexEntry *new_entries;
4698 MOVFragmentStreamInfo * frag_stream_info;
4700 if (!frag->found_tfhd) {
4701 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4702 return AVERROR_INVALIDDATA;
4705 for (i = 0; i < c->fc->nb_streams; i++) {
4706 if (c->fc->streams[i]->id == frag->track_id) {
4707 st = c->fc->streams[i];
4712 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4716 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4719 // Find the next frag_index index that has a valid index_entry for
4720 // the current track_id.
4722 // A valid index_entry means the trun for the fragment was read
4723 // and it's samples are in index_entries at the given position.
4724 // New index entries will be inserted before the index_entry found.
4725 index_entry_pos = st->nb_index_entries;
4726 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4727 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4728 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4729 next_frag_index = i;
4730 index_entry_pos = frag_stream_info->index_entry;
4734 av_assert0(index_entry_pos <= st->nb_index_entries);
4736 avio_r8(pb); /* version */
4737 flags = avio_rb24(pb);
4738 entries = avio_rb32(pb);
4739 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4741 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4742 return AVERROR_INVALIDDATA;
4743 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4744 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4746 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4747 if (frag_stream_info)
4749 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4750 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4751 pts = frag_stream_info->first_tfra_pts;
4752 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4753 ", using it for pts\n", pts);
4754 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4755 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4756 // pts = frag_stream_info->sidx_pts;
4757 dts = frag_stream_info->sidx_pts - sc->time_offset;
4758 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4759 ", using it for pts\n", pts);
4760 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4761 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4762 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4763 ", using it for dts\n", dts);
4765 dts = sc->track_end - sc->time_offset;
4766 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4767 ", using it for dts\n", dts);
4770 dts = sc->track_end - sc->time_offset;
4771 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4772 ", using it for dts\n", dts);
4774 offset = frag->base_data_offset + data_offset;
4776 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4778 // realloc space for new index entries
4779 if((unsigned)st->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4780 entries = UINT_MAX / sizeof(AVIndexEntry) - st->nb_index_entries;
4781 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4786 requested_size = (st->nb_index_entries + entries) * sizeof(AVIndexEntry);
4787 new_entries = av_fast_realloc(st->index_entries,
4788 &st->index_entries_allocated_size,
4791 return AVERROR(ENOMEM);
4792 st->index_entries= new_entries;
4794 requested_size = (st->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4795 old_ctts_allocated_size = sc->ctts_allocated_size;
4796 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4799 return AVERROR(ENOMEM);
4800 sc->ctts_data = ctts_data;
4802 // In case there were samples without ctts entries, ensure they get
4803 // zero valued entries. This ensures clips which mix boxes with and
4804 // without ctts entries don't pickup uninitialized data.
4805 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4806 sc->ctts_allocated_size - old_ctts_allocated_size);
4808 if (index_entry_pos < st->nb_index_entries) {
4809 // Make hole in index_entries and ctts_data for new samples
4810 memmove(st->index_entries + index_entry_pos + entries,
4811 st->index_entries + index_entry_pos,
4812 sizeof(*st->index_entries) *
4813 (st->nb_index_entries - index_entry_pos));
4814 memmove(sc->ctts_data + index_entry_pos + entries,
4815 sc->ctts_data + index_entry_pos,
4816 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4817 if (index_entry_pos < sc->current_sample) {
4818 sc->current_sample += entries;
4822 st->nb_index_entries += entries;
4823 sc->ctts_count = st->nb_index_entries;
4825 // Record the index_entry position in frag_index of this fragment
4826 if (frag_stream_info)
4827 frag_stream_info->index_entry = index_entry_pos;
4829 if (index_entry_pos > 0)
4830 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4832 for (i = 0; i < entries && !pb->eof_reached; i++) {
4833 unsigned sample_size = frag->size;
4834 int sample_flags = i ? frag->flags : first_sample_flags;
4835 unsigned sample_duration = frag->duration;
4836 unsigned ctts_duration = 0;
4838 int index_entry_flags = 0;
4840 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4841 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4842 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4843 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4845 mov_update_dts_shift(sc, ctts_duration);
4846 if (pts != AV_NOPTS_VALUE) {
4847 dts = pts - sc->dts_shift;
4848 if (flags & MOV_TRUN_SAMPLE_CTS) {
4849 dts -= ctts_duration;
4851 dts -= sc->time_offset;
4853 av_log(c->fc, AV_LOG_DEBUG,
4854 "pts %"PRId64" calculated dts %"PRId64
4855 " sc->dts_shift %d ctts.duration %d"
4856 " sc->time_offset %"PRId64
4857 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4859 sc->dts_shift, ctts_duration,
4860 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4861 pts = AV_NOPTS_VALUE;
4864 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4868 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4869 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4872 index_entry_flags |= AVINDEX_KEYFRAME;
4874 // Fragments can overlap in time. Discard overlapping frames after
4876 if (prev_dts >= dts)
4877 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4879 st->index_entries[index_entry_pos].pos = offset;
4880 st->index_entries[index_entry_pos].timestamp = dts;
4881 st->index_entries[index_entry_pos].size= sample_size;
4882 st->index_entries[index_entry_pos].min_distance= distance;
4883 st->index_entries[index_entry_pos].flags = index_entry_flags;
4885 sc->ctts_data[index_entry_pos].count = 1;
4886 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4889 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4890 "size %u, distance %d, keyframe %d\n", st->index,
4891 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4893 dts += sample_duration;
4894 offset += sample_size;
4895 sc->data_size += sample_size;
4897 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4898 1 <= INT64_MAX - sc->nb_frames_for_fps
4900 sc->duration_for_fps += sample_duration;
4901 sc->nb_frames_for_fps ++;
4905 // EOF found before reading all entries. Fix the hole this would
4906 // leave in index_entries and ctts_data
4907 int gap = entries - i;
4908 memmove(st->index_entries + index_entry_pos,
4909 st->index_entries + index_entry_pos + gap,
4910 sizeof(*st->index_entries) *
4911 (st->nb_index_entries - (index_entry_pos + gap)));
4912 memmove(sc->ctts_data + index_entry_pos,
4913 sc->ctts_data + index_entry_pos + gap,
4914 sizeof(*sc->ctts_data) *
4915 (sc->ctts_count - (index_entry_pos + gap)));
4917 st->nb_index_entries -= gap;
4918 sc->ctts_count -= gap;
4919 if (index_entry_pos < sc->current_sample) {
4920 sc->current_sample -= gap;
4925 // The end of this new fragment may overlap in time with the start
4926 // of the next fragment in index_entries. Mark the samples in the next
4927 // fragment that overlap with AVINDEX_DISCARD_FRAME
4928 prev_dts = AV_NOPTS_VALUE;
4929 if (index_entry_pos > 0)
4930 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4931 for (i = index_entry_pos; i < st->nb_index_entries; i++) {
4932 if (prev_dts < st->index_entries[i].timestamp)
4934 st->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
4937 // If a hole was created to insert the new index_entries into,
4938 // the index_entry recorded for all subsequent moof must
4939 // be incremented by the number of entries inserted.
4940 fix_frag_index_entries(&c->frag_index, next_frag_index,
4941 frag->track_id, entries);
4943 if (pb->eof_reached) {
4944 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
4948 frag->implicit_offset = offset;
4950 sc->track_end = dts + sc->time_offset;
4951 if (st->duration < sc->track_end)
4952 st->duration = sc->track_end;
4957 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4959 int64_t offset = avio_tell(pb) + atom.size, pts, timestamp;
4961 unsigned i, j, track_id, item_count;
4962 AVStream *st = NULL;
4963 AVStream *ref_st = NULL;
4964 MOVStreamContext *sc, *ref_sc = NULL;
4965 AVRational timescale;
4967 version = avio_r8(pb);
4969 avpriv_request_sample(c->fc, "sidx version %u", version);
4973 avio_rb24(pb); // flags
4975 track_id = avio_rb32(pb); // Reference ID
4976 for (i = 0; i < c->fc->nb_streams; i++) {
4977 if (c->fc->streams[i]->id == track_id) {
4978 st = c->fc->streams[i];
4983 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
4989 timescale = av_make_q(1, avio_rb32(pb));
4991 if (timescale.den <= 0) {
4992 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
4993 return AVERROR_INVALIDDATA;
4997 pts = avio_rb32(pb);
4998 offset += avio_rb32(pb);
5000 pts = avio_rb64(pb);
5001 offset += avio_rb64(pb);
5004 avio_rb16(pb); // reserved
5006 item_count = avio_rb16(pb);
5008 for (i = 0; i < item_count; i++) {
5010 MOVFragmentStreamInfo * frag_stream_info;
5011 uint32_t size = avio_rb32(pb);
5012 uint32_t duration = avio_rb32(pb);
5013 if (size & 0x80000000) {
5014 avpriv_request_sample(c->fc, "sidx reference_type 1");
5015 return AVERROR_PATCHWELCOME;
5017 avio_rb32(pb); // sap_flags
5018 timestamp = av_rescale_q(pts, st->time_base, timescale);
5020 index = update_frag_index(c, offset);
5021 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5022 if (frag_stream_info)
5023 frag_stream_info->sidx_pts = timestamp;
5029 st->duration = sc->track_end = pts;
5033 if (offset == avio_size(pb)) {
5034 // Find first entry in fragment index that came from an sidx.
5035 // This will pretty much always be the first entry.
5036 for (i = 0; i < c->frag_index.nb_items; i++) {
5037 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5038 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5039 MOVFragmentStreamInfo * si;
5040 si = &item->stream_info[j];
5041 if (si->sidx_pts != AV_NOPTS_VALUE) {
5042 ref_st = c->fc->streams[j];
5043 ref_sc = ref_st->priv_data;
5048 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5049 st = c->fc->streams[i];
5051 if (!sc->has_sidx) {
5052 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5056 c->frag_index.complete = 1;
5062 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5063 /* like the files created with Adobe Premiere 5.0, for samples see */
5064 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5065 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5070 return 0; /* continue */
5071 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5072 avio_skip(pb, atom.size - 4);
5075 atom.type = avio_rl32(pb);
5077 if (atom.type != MKTAG('m','d','a','t')) {
5078 avio_skip(pb, atom.size);
5081 err = mov_read_mdat(c, pb, atom);
5085 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5090 uint8_t *moov_data; /* uncompressed data */
5091 long cmov_len, moov_len;
5094 avio_rb32(pb); /* dcom atom */
5095 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5096 return AVERROR_INVALIDDATA;
5097 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5098 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5099 return AVERROR_INVALIDDATA;
5101 avio_rb32(pb); /* cmvd atom */
5102 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5103 return AVERROR_INVALIDDATA;
5104 moov_len = avio_rb32(pb); /* uncompressed size */
5105 cmov_len = atom.size - 6 * 4;
5107 cmov_data = av_malloc(cmov_len);
5109 return AVERROR(ENOMEM);
5110 moov_data = av_malloc(moov_len);
5113 return AVERROR(ENOMEM);
5115 ret = ffio_read_size(pb, cmov_data, cmov_len);
5117 goto free_and_return;
5119 ret = AVERROR_INVALIDDATA;
5120 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5121 goto free_and_return;
5122 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5123 goto free_and_return;
5124 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5125 atom.type = MKTAG('m','o','o','v');
5126 atom.size = moov_len;
5127 ret = mov_read_default(c, &ctx, atom);
5133 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5134 return AVERROR(ENOSYS);
5138 /* edit list atom */
5139 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5141 MOVStreamContext *sc;
5142 int i, edit_count, version;
5143 int64_t elst_entry_size;
5145 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5147 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5149 version = avio_r8(pb); /* version */
5150 avio_rb24(pb); /* flags */
5151 edit_count = avio_rb32(pb); /* entries */
5154 elst_entry_size = version == 1 ? 20 : 12;
5155 if (atom.size != edit_count * elst_entry_size) {
5156 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5157 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5158 edit_count, atom.size + 8);
5159 return AVERROR_INVALIDDATA;
5161 edit_count = atom.size / elst_entry_size;
5162 if (edit_count * elst_entry_size != atom.size) {
5163 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.", atom.size, edit_count);
5171 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5172 av_free(sc->elst_data);
5174 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5176 return AVERROR(ENOMEM);
5178 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5179 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5180 MOVElst *e = &sc->elst_data[i];
5183 e->duration = avio_rb64(pb);
5184 e->time = avio_rb64(pb);
5187 e->duration = avio_rb32(pb); /* segment duration */
5188 e->time = (int32_t)avio_rb32(pb); /* media time */
5191 e->rate = avio_rb32(pb) / 65536.0;
5193 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5194 e->duration, e->time, e->rate);
5196 if (e->time < 0 && e->time != -1 &&
5197 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5198 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5199 c->fc->nb_streams-1, i, e->time);
5200 return AVERROR_INVALIDDATA;
5208 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5210 MOVStreamContext *sc;
5212 if (c->fc->nb_streams < 1)
5213 return AVERROR_INVALIDDATA;
5214 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5215 sc->timecode_track = avio_rb32(pb);
5219 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5224 if (c->fc->nb_streams < 1)
5226 st = c->fc->streams[c->fc->nb_streams - 1];
5228 if (atom.size < 4) {
5229 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5230 return AVERROR_INVALIDDATA;
5233 /* For now, propagate only the OBUs, if any. Once libavcodec is
5234 updated to handle isobmff style extradata this can be removed. */
5240 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5247 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5250 int version, color_range, color_primaries, color_trc, color_space;
5252 if (c->fc->nb_streams < 1)
5254 st = c->fc->streams[c->fc->nb_streams - 1];
5256 if (atom.size < 5) {
5257 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5258 return AVERROR_INVALIDDATA;
5261 version = avio_r8(pb);
5263 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5266 avio_skip(pb, 3); /* flags */
5268 avio_skip(pb, 2); /* profile + level */
5269 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5270 color_primaries = avio_r8(pb);
5271 color_trc = avio_r8(pb);
5272 color_space = avio_r8(pb);
5273 if (avio_rb16(pb)) /* codecIntializationDataSize */
5274 return AVERROR_INVALIDDATA;
5276 if (!av_color_primaries_name(color_primaries))
5277 color_primaries = AVCOL_PRI_UNSPECIFIED;
5278 if (!av_color_transfer_name(color_trc))
5279 color_trc = AVCOL_TRC_UNSPECIFIED;
5280 if (!av_color_space_name(color_space))
5281 color_space = AVCOL_SPC_UNSPECIFIED;
5283 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5284 st->codecpar->color_primaries = color_primaries;
5285 st->codecpar->color_trc = color_trc;
5286 st->codecpar->color_space = color_space;
5291 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5293 MOVStreamContext *sc;
5296 if (c->fc->nb_streams < 1)
5297 return AVERROR_INVALIDDATA;
5299 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5301 if (atom.size < 5) {
5302 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5303 return AVERROR_INVALIDDATA;
5306 version = avio_r8(pb);
5308 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5311 avio_skip(pb, 3); /* flags */
5313 sc->mastering = av_mastering_display_metadata_alloc();
5315 return AVERROR(ENOMEM);
5317 for (i = 0; i < 3; i++) {
5318 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5319 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5321 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5322 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5324 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5325 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5327 sc->mastering->has_primaries = 1;
5328 sc->mastering->has_luminance = 1;
5333 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5335 MOVStreamContext *sc;
5336 const int mapping[3] = {1, 2, 0};
5337 const int chroma_den = 50000;
5338 const int luma_den = 10000;
5341 if (c->fc->nb_streams < 1)
5342 return AVERROR_INVALIDDATA;
5344 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5346 if (atom.size < 24) {
5347 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5348 return AVERROR_INVALIDDATA;
5351 sc->mastering = av_mastering_display_metadata_alloc();
5353 return AVERROR(ENOMEM);
5355 for (i = 0; i < 3; i++) {
5356 const int j = mapping[i];
5357 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5358 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5360 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5361 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5363 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5364 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5366 sc->mastering->has_luminance = 1;
5367 sc->mastering->has_primaries = 1;
5372 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5374 MOVStreamContext *sc;
5377 if (c->fc->nb_streams < 1)
5378 return AVERROR_INVALIDDATA;
5380 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5382 if (atom.size < 5) {
5383 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5384 return AVERROR_INVALIDDATA;
5387 version = avio_r8(pb);
5389 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5392 avio_skip(pb, 3); /* flags */
5394 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5396 return AVERROR(ENOMEM);
5398 sc->coll->MaxCLL = avio_rb16(pb);
5399 sc->coll->MaxFALL = avio_rb16(pb);
5404 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5406 MOVStreamContext *sc;
5408 if (c->fc->nb_streams < 1)
5409 return AVERROR_INVALIDDATA;
5411 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5413 if (atom.size < 4) {
5414 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5415 return AVERROR_INVALIDDATA;
5418 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5420 return AVERROR(ENOMEM);
5422 sc->coll->MaxCLL = avio_rb16(pb);
5423 sc->coll->MaxFALL = avio_rb16(pb);
5428 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5431 MOVStreamContext *sc;
5432 enum AVStereo3DType type;
5435 if (c->fc->nb_streams < 1)
5438 st = c->fc->streams[c->fc->nb_streams - 1];
5441 if (atom.size < 5) {
5442 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5443 return AVERROR_INVALIDDATA;
5445 avio_skip(pb, 4); /* version + flags */
5450 type = AV_STEREO3D_2D;
5453 type = AV_STEREO3D_TOPBOTTOM;
5456 type = AV_STEREO3D_SIDEBYSIDE;
5459 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5463 sc->stereo3d = av_stereo3d_alloc();
5465 return AVERROR(ENOMEM);
5467 sc->stereo3d->type = type;
5471 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5474 MOVStreamContext *sc;
5475 int size, version, layout;
5476 int32_t yaw, pitch, roll;
5477 uint32_t l = 0, t = 0, r = 0, b = 0;
5478 uint32_t tag, padding = 0;
5479 enum AVSphericalProjection projection;
5481 if (c->fc->nb_streams < 1)
5484 st = c->fc->streams[c->fc->nb_streams - 1];
5487 if (atom.size < 8) {
5488 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5489 return AVERROR_INVALIDDATA;
5492 size = avio_rb32(pb);
5493 if (size <= 12 || size > atom.size)
5494 return AVERROR_INVALIDDATA;
5496 tag = avio_rl32(pb);
5497 if (tag != MKTAG('s','v','h','d')) {
5498 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5501 version = avio_r8(pb);
5503 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5507 avio_skip(pb, 3); /* flags */
5508 avio_skip(pb, size - 12); /* metadata_source */
5510 size = avio_rb32(pb);
5511 if (size > atom.size)
5512 return AVERROR_INVALIDDATA;
5514 tag = avio_rl32(pb);
5515 if (tag != MKTAG('p','r','o','j')) {
5516 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5520 size = avio_rb32(pb);
5521 if (size > atom.size)
5522 return AVERROR_INVALIDDATA;
5524 tag = avio_rl32(pb);
5525 if (tag != MKTAG('p','r','h','d')) {
5526 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5529 version = avio_r8(pb);
5531 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5535 avio_skip(pb, 3); /* flags */
5537 /* 16.16 fixed point */
5538 yaw = avio_rb32(pb);
5539 pitch = avio_rb32(pb);
5540 roll = avio_rb32(pb);
5542 size = avio_rb32(pb);
5543 if (size > atom.size)
5544 return AVERROR_INVALIDDATA;
5546 tag = avio_rl32(pb);
5547 version = avio_r8(pb);
5549 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5553 avio_skip(pb, 3); /* flags */
5555 case MKTAG('c','b','m','p'):
5556 layout = avio_rb32(pb);
5558 av_log(c->fc, AV_LOG_WARNING,
5559 "Unsupported cubemap layout %d\n", layout);
5562 projection = AV_SPHERICAL_CUBEMAP;
5563 padding = avio_rb32(pb);
5565 case MKTAG('e','q','u','i'):
5571 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5572 av_log(c->fc, AV_LOG_ERROR,
5573 "Invalid bounding rectangle coordinates "
5574 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5575 return AVERROR_INVALIDDATA;
5578 if (l || t || r || b)
5579 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5581 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5584 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5588 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5590 return AVERROR(ENOMEM);
5592 sc->spherical->projection = projection;
5594 sc->spherical->yaw = yaw;
5595 sc->spherical->pitch = pitch;
5596 sc->spherical->roll = roll;
5598 sc->spherical->padding = padding;
5600 sc->spherical->bound_left = l;
5601 sc->spherical->bound_top = t;
5602 sc->spherical->bound_right = r;
5603 sc->spherical->bound_bottom = b;
5608 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5611 uint8_t *buffer = av_malloc(len + 1);
5615 return AVERROR(ENOMEM);
5618 ret = ffio_read_size(pb, buffer, len);
5622 /* Check for mandatory keys and values, try to support XML as best-effort */
5623 if (!sc->spherical &&
5624 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5625 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5626 av_stristr(val, "true") &&
5627 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5628 av_stristr(val, "true") &&
5629 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5630 av_stristr(val, "equirectangular")) {
5631 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5635 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5637 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5638 enum AVStereo3DType mode;
5640 if (av_stristr(buffer, "left-right"))
5641 mode = AV_STEREO3D_SIDEBYSIDE;
5642 else if (av_stristr(buffer, "top-bottom"))
5643 mode = AV_STEREO3D_TOPBOTTOM;
5645 mode = AV_STEREO3D_2D;
5647 sc->stereo3d = av_stereo3d_alloc();
5651 sc->stereo3d->type = mode;
5655 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5657 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5658 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5660 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5661 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5663 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5671 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5674 MOVStreamContext *sc;
5677 static const uint8_t uuid_isml_manifest[] = {
5678 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5679 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5681 static const uint8_t uuid_xmp[] = {
5682 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5683 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5685 static const uint8_t uuid_spherical[] = {
5686 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5687 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5690 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5691 return AVERROR_INVALIDDATA;
5693 if (c->fc->nb_streams < 1)
5695 st = c->fc->streams[c->fc->nb_streams - 1];
5698 ret = avio_read(pb, uuid, sizeof(uuid));
5701 } else if (ret != sizeof(uuid)) {
5702 return AVERROR_INVALIDDATA;
5704 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5705 uint8_t *buffer, *ptr;
5707 size_t len = atom.size - sizeof(uuid);
5710 return AVERROR_INVALIDDATA;
5712 ret = avio_skip(pb, 4); // zeroes
5715 buffer = av_mallocz(len + 1);
5717 return AVERROR(ENOMEM);
5719 ret = avio_read(pb, buffer, len);
5723 } else if (ret != len) {
5725 return AVERROR_INVALIDDATA;
5729 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5730 ptr += sizeof("systemBitrate=\"") - 1;
5731 c->bitrates_count++;
5732 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5734 c->bitrates_count = 0;
5736 return AVERROR(ENOMEM);
5739 ret = strtol(ptr, &endptr, 10);
5740 if (ret < 0 || errno || *endptr != '"') {
5741 c->bitrates[c->bitrates_count - 1] = 0;
5743 c->bitrates[c->bitrates_count - 1] = ret;
5748 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5750 size_t len = atom.size - sizeof(uuid);
5751 if (c->export_xmp) {
5752 buffer = av_mallocz(len + 1);
5754 return AVERROR(ENOMEM);
5756 ret = avio_read(pb, buffer, len);
5760 } else if (ret != len) {
5762 return AVERROR_INVALIDDATA;
5765 av_dict_set(&c->fc->metadata, "xmp", buffer, 0);
5768 // skip all uuid atom, which makes it fast for long uuid-xmp file
5769 ret = avio_skip(pb, len);
5773 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5774 size_t len = atom.size - sizeof(uuid);
5775 ret = mov_parse_uuid_spherical(sc, pb, len);
5779 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5785 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5788 uint8_t content[16];
5793 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5799 && !memcmp(content, "Anevia\x1A\x1A", 8)
5800 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5801 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5807 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5809 uint32_t format = avio_rl32(pb);
5810 MOVStreamContext *sc;
5814 if (c->fc->nb_streams < 1)
5816 st = c->fc->streams[c->fc->nb_streams - 1];
5821 case MKTAG('e','n','c','v'): // encrypted video
5822 case MKTAG('e','n','c','a'): // encrypted audio
5823 id = mov_codec_id(st, format);
5824 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5825 st->codecpar->codec_id != id) {
5826 av_log(c->fc, AV_LOG_WARNING,
5827 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5828 (char*)&format, st->codecpar->codec_id);
5832 st->codecpar->codec_id = id;
5833 sc->format = format;
5837 if (format != sc->format) {
5838 av_log(c->fc, AV_LOG_WARNING,
5839 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5840 (char*)&format, (char*)&sc->format);
5849 * Gets the current encryption info and associated current stream context. If
5850 * we are parsing a track fragment, this will return the specific encryption
5851 * info for this fragment; otherwise this will return the global encryption
5852 * info for the current stream.
5854 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5856 MOVFragmentStreamInfo *frag_stream_info;
5860 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5861 if (frag_stream_info) {
5862 for (i = 0; i < c->fc->nb_streams; i++) {
5863 if (c->fc->streams[i]->id == frag_stream_info->id) {
5864 st = c->fc->streams[i];
5868 if (i == c->fc->nb_streams)
5870 *sc = st->priv_data;
5872 if (!frag_stream_info->encryption_index) {
5873 // If this stream isn't encrypted, don't create the index.
5874 if (!(*sc)->cenc.default_encrypted_sample)
5876 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5877 if (!frag_stream_info->encryption_index)
5878 return AVERROR(ENOMEM);
5880 *encryption_index = frag_stream_info->encryption_index;
5883 // No current track fragment, using stream level encryption info.
5885 if (c->fc->nb_streams < 1)
5887 st = c->fc->streams[c->fc->nb_streams - 1];
5888 *sc = st->priv_data;
5890 if (!(*sc)->cenc.encryption_index) {
5891 // If this stream isn't encrypted, don't create the index.
5892 if (!(*sc)->cenc.default_encrypted_sample)
5894 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5895 if (!(*sc)->cenc.encryption_index)
5896 return AVERROR(ENOMEM);
5899 *encryption_index = (*sc)->cenc.encryption_index;
5904 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
5907 unsigned int subsample_count;
5908 AVSubsampleEncryptionInfo *subsamples;
5910 if (!sc->cenc.default_encrypted_sample) {
5911 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
5912 return AVERROR_INVALIDDATA;
5915 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
5917 return AVERROR(ENOMEM);
5919 if (sc->cenc.per_sample_iv_size != 0) {
5920 if (avio_read(pb, (*sample)->iv, sc->cenc.per_sample_iv_size) != sc->cenc.per_sample_iv_size) {
5921 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
5922 av_encryption_info_free(*sample);
5924 return AVERROR_INVALIDDATA;
5928 if (use_subsamples) {
5929 subsample_count = avio_rb16(pb);
5930 av_free((*sample)->subsamples);
5931 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
5932 if (!(*sample)->subsamples) {
5933 av_encryption_info_free(*sample);
5935 return AVERROR(ENOMEM);
5938 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
5939 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
5940 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
5943 if (pb->eof_reached) {
5944 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
5945 av_encryption_info_free(*sample);
5947 return AVERROR_INVALIDDATA;
5949 (*sample)->subsample_count = subsample_count;
5955 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5957 AVEncryptionInfo **encrypted_samples;
5958 MOVEncryptionIndex *encryption_index;
5959 MOVStreamContext *sc;
5960 int use_subsamples, ret;
5961 unsigned int sample_count, i, alloc_size = 0;
5963 ret = get_current_encryption_info(c, &encryption_index, &sc);
5967 if (encryption_index->nb_encrypted_samples) {
5968 // This can happen if we have both saio/saiz and senc atoms.
5969 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
5973 avio_r8(pb); /* version */
5974 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
5976 sample_count = avio_rb32(pb);
5977 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
5978 return AVERROR(ENOMEM);
5980 for (i = 0; i < sample_count; i++) {
5981 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
5982 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
5983 min_samples * sizeof(*encrypted_samples));
5984 if (encrypted_samples) {
5985 encryption_index->encrypted_samples = encrypted_samples;
5987 ret = mov_read_sample_encryption_info(
5988 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
5990 ret = AVERROR(ENOMEM);
5992 if (pb->eof_reached) {
5993 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
5994 ret = AVERROR_INVALIDDATA;
5999 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6000 av_freep(&encryption_index->encrypted_samples);
6004 encryption_index->nb_encrypted_samples = sample_count;
6009 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6011 AVEncryptionInfo **sample, **encrypted_samples;
6013 size_t sample_count, sample_info_size, i;
6015 unsigned int alloc_size = 0;
6017 if (encryption_index->nb_encrypted_samples)
6019 sample_count = encryption_index->auxiliary_info_sample_count;
6020 if (encryption_index->auxiliary_offsets_count != 1) {
6021 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6022 return AVERROR_PATCHWELCOME;
6024 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6025 return AVERROR(ENOMEM);
6027 prev_pos = avio_tell(pb);
6028 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6029 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6030 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6034 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6035 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6036 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6037 min_samples * sizeof(*encrypted_samples));
6038 if (!encrypted_samples) {
6039 ret = AVERROR(ENOMEM);
6042 encryption_index->encrypted_samples = encrypted_samples;
6044 sample = &encryption_index->encrypted_samples[i];
6045 sample_info_size = encryption_index->auxiliary_info_default_size
6046 ? encryption_index->auxiliary_info_default_size
6047 : encryption_index->auxiliary_info_sizes[i];
6049 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6053 if (pb->eof_reached) {
6054 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6055 ret = AVERROR_INVALIDDATA;
6057 encryption_index->nb_encrypted_samples = sample_count;
6061 avio_seek(pb, prev_pos, SEEK_SET);
6063 for (; i > 0; i--) {
6064 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6066 av_freep(&encryption_index->encrypted_samples);
6072 * Tries to read the given number of bytes from the stream and puts it in a
6073 * newly allocated buffer. This reads in small chunks to avoid allocating large
6074 * memory if the file contains an invalid/malicious size value.
6076 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6078 const unsigned int block_size = 1024 * 1024;
6079 uint8_t *buffer = NULL;
6080 unsigned int alloc_size = 0, offset = 0;
6081 while (offset < size) {
6082 unsigned int new_size =
6083 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6084 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6085 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6088 return AVERROR(ENOMEM);
6090 buffer = new_buffer;
6092 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6094 return AVERROR_INVALIDDATA;
6103 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6105 MOVEncryptionIndex *encryption_index;
6106 MOVStreamContext *sc;
6108 unsigned int sample_count, aux_info_type, aux_info_param;
6110 ret = get_current_encryption_info(c, &encryption_index, &sc);
6114 if (encryption_index->nb_encrypted_samples) {
6115 // This can happen if we have both saio/saiz and senc atoms.
6116 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6120 if (encryption_index->auxiliary_info_sample_count) {
6121 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6122 return AVERROR_INVALIDDATA;
6125 avio_r8(pb); /* version */
6126 if (avio_rb24(pb) & 0x01) { /* flags */
6127 aux_info_type = avio_rb32(pb);
6128 aux_info_param = avio_rb32(pb);
6129 if (sc->cenc.default_encrypted_sample) {
6130 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6131 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6134 if (aux_info_param != 0) {
6135 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6139 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6140 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6141 aux_info_type == MKBETAG('c','e','n','s') ||
6142 aux_info_type == MKBETAG('c','b','c','1') ||
6143 aux_info_type == MKBETAG('c','b','c','s')) &&
6144 aux_info_param == 0) {
6145 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6146 return AVERROR_INVALIDDATA;
6151 } else if (!sc->cenc.default_encrypted_sample) {
6152 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6156 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6157 sample_count = avio_rb32(pb);
6158 encryption_index->auxiliary_info_sample_count = sample_count;
6160 if (encryption_index->auxiliary_info_default_size == 0) {
6161 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6163 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6168 if (encryption_index->auxiliary_offsets_count) {
6169 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6175 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6177 uint64_t *auxiliary_offsets;
6178 MOVEncryptionIndex *encryption_index;
6179 MOVStreamContext *sc;
6181 unsigned int version, entry_count, aux_info_type, aux_info_param;
6182 unsigned int alloc_size = 0;
6184 ret = get_current_encryption_info(c, &encryption_index, &sc);
6188 if (encryption_index->nb_encrypted_samples) {
6189 // This can happen if we have both saio/saiz and senc atoms.
6190 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6194 if (encryption_index->auxiliary_offsets_count) {
6195 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6196 return AVERROR_INVALIDDATA;
6199 version = avio_r8(pb); /* version */
6200 if (avio_rb24(pb) & 0x01) { /* flags */
6201 aux_info_type = avio_rb32(pb);
6202 aux_info_param = avio_rb32(pb);
6203 if (sc->cenc.default_encrypted_sample) {
6204 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6205 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6208 if (aux_info_param != 0) {
6209 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6213 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6214 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6215 aux_info_type == MKBETAG('c','e','n','s') ||
6216 aux_info_type == MKBETAG('c','b','c','1') ||
6217 aux_info_type == MKBETAG('c','b','c','s')) &&
6218 aux_info_param == 0) {
6219 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6220 return AVERROR_INVALIDDATA;
6225 } else if (!sc->cenc.default_encrypted_sample) {
6226 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6230 entry_count = avio_rb32(pb);
6231 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6232 return AVERROR(ENOMEM);
6234 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6235 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6236 auxiliary_offsets = av_fast_realloc(
6237 encryption_index->auxiliary_offsets, &alloc_size,
6238 min_offsets * sizeof(*auxiliary_offsets));
6239 if (!auxiliary_offsets) {
6240 av_freep(&encryption_index->auxiliary_offsets);
6241 return AVERROR(ENOMEM);
6243 encryption_index->auxiliary_offsets = auxiliary_offsets;
6246 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6248 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6250 if (c->frag_index.current >= 0) {
6251 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6255 if (pb->eof_reached) {
6256 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6257 av_freep(&encryption_index->auxiliary_offsets);
6258 return AVERROR_INVALIDDATA;
6261 encryption_index->auxiliary_offsets_count = entry_count;
6263 if (encryption_index->auxiliary_info_sample_count) {
6264 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6270 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6272 AVEncryptionInitInfo *info, *old_init_info;
6275 uint8_t *side_data, *extra_data, *old_side_data;
6276 size_t side_data_size;
6277 int ret = 0, old_side_data_size;
6278 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6280 if (c->fc->nb_streams < 1)
6282 st = c->fc->streams[c->fc->nb_streams-1];
6284 version = avio_r8(pb); /* version */
6285 avio_rb24(pb); /* flags */
6287 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6288 /* key_id_size */ 16, /* data_size */ 0);
6290 return AVERROR(ENOMEM);
6292 if (avio_read(pb, info->system_id, 16) != 16) {
6293 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6294 ret = AVERROR_INVALIDDATA;
6299 kid_count = avio_rb32(pb);
6300 if (kid_count >= INT_MAX / sizeof(*key_ids))
6301 return AVERROR(ENOMEM);
6303 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6304 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6305 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6306 min_kid_count * sizeof(*key_ids));
6308 ret = AVERROR(ENOMEM);
6311 info->key_ids = key_ids;
6313 info->key_ids[i] = av_mallocz(16);
6314 if (!info->key_ids[i]) {
6315 ret = AVERROR(ENOMEM);
6318 info->num_key_ids = i + 1;
6320 if (avio_read(pb, info->key_ids[i], 16) != 16) {
6321 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6322 ret = AVERROR_INVALIDDATA;
6327 if (pb->eof_reached) {
6328 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6329 ret = AVERROR_INVALIDDATA;
6334 extra_data_size = avio_rb32(pb);
6335 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6339 av_freep(&info->data); // malloc(0) may still allocate something.
6340 info->data = extra_data;
6341 info->data_size = extra_data_size;
6343 // If there is existing initialization data, append to the list.
6344 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6345 if (old_side_data) {
6346 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6347 if (old_init_info) {
6348 // Append to the end of the list.
6349 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6355 info = old_init_info;
6357 // Assume existing side-data will be valid, so the only error we could get is OOM.
6358 ret = AVERROR(ENOMEM);
6363 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6365 ret = AVERROR(ENOMEM);
6368 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6369 side_data, side_data_size);
6374 av_encryption_init_info_free(info);
6378 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6381 MOVStreamContext *sc;
6383 if (c->fc->nb_streams < 1)
6385 st = c->fc->streams[c->fc->nb_streams-1];
6388 if (sc->pseudo_stream_id != 0) {
6389 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6390 return AVERROR_PATCHWELCOME;
6394 return AVERROR_INVALIDDATA;
6396 avio_rb32(pb); /* version and flags */
6398 if (!sc->cenc.default_encrypted_sample) {
6399 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6400 if (!sc->cenc.default_encrypted_sample) {
6401 return AVERROR(ENOMEM);
6405 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6409 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6412 MOVStreamContext *sc;
6413 unsigned int version, pattern, is_protected, iv_size;
6415 if (c->fc->nb_streams < 1)
6417 st = c->fc->streams[c->fc->nb_streams-1];
6420 if (sc->pseudo_stream_id != 0) {
6421 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6422 return AVERROR_PATCHWELCOME;
6425 if (!sc->cenc.default_encrypted_sample) {
6426 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6427 if (!sc->cenc.default_encrypted_sample) {
6428 return AVERROR(ENOMEM);
6433 return AVERROR_INVALIDDATA;
6435 version = avio_r8(pb); /* version */
6436 avio_rb24(pb); /* flags */
6438 avio_r8(pb); /* reserved */
6439 pattern = avio_r8(pb);
6442 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6443 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6446 is_protected = avio_r8(pb);
6447 if (is_protected && !sc->cenc.encryption_index) {
6448 // The whole stream should be by-default encrypted.
6449 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6450 if (!sc->cenc.encryption_index)
6451 return AVERROR(ENOMEM);
6453 sc->cenc.per_sample_iv_size = avio_r8(pb);
6454 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6455 sc->cenc.per_sample_iv_size != 16) {
6456 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6457 return AVERROR_INVALIDDATA;
6459 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6460 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6461 return AVERROR_INVALIDDATA;
6464 if (is_protected && !sc->cenc.per_sample_iv_size) {
6465 iv_size = avio_r8(pb);
6466 if (iv_size != 8 && iv_size != 16) {
6467 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6468 return AVERROR_INVALIDDATA;
6471 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6472 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6473 return AVERROR_INVALIDDATA;
6480 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6483 int last, type, size, ret;
6486 if (c->fc->nb_streams < 1)
6488 st = c->fc->streams[c->fc->nb_streams-1];
6490 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6491 return AVERROR_INVALIDDATA;
6493 /* Check FlacSpecificBox version. */
6494 if (avio_r8(pb) != 0)
6495 return AVERROR_INVALIDDATA;
6497 avio_rb24(pb); /* Flags */
6499 avio_read(pb, buf, sizeof(buf));
6500 flac_parse_block_header(buf, &last, &type, &size);
6502 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6503 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6504 return AVERROR_INVALIDDATA;
6507 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6512 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6517 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6521 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6522 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6523 return AVERROR_PATCHWELCOME;
6526 if (!sc->cenc.aes_ctr) {
6527 /* initialize the cipher */
6528 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6529 if (!sc->cenc.aes_ctr) {
6530 return AVERROR(ENOMEM);
6533 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6539 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6541 if (!sample->subsample_count)
6543 /* decrypt the whole packet */
6544 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6548 for (i = 0; i < sample->subsample_count; i++)
6550 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6551 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6552 return AVERROR_INVALIDDATA;
6555 /* skip the clear bytes */
6556 input += sample->subsamples[i].bytes_of_clear_data;
6557 size -= sample->subsamples[i].bytes_of_clear_data;
6559 /* decrypt the encrypted bytes */
6560 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6561 input += sample->subsamples[i].bytes_of_protected_data;
6562 size -= sample->subsamples[i].bytes_of_protected_data;
6566 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6567 return AVERROR_INVALIDDATA;
6573 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6575 MOVFragmentStreamInfo *frag_stream_info;
6576 MOVEncryptionIndex *encryption_index;
6577 AVEncryptionInfo *encrypted_sample;
6578 int encrypted_index, ret;
6580 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6581 encrypted_index = current_index;
6582 encryption_index = NULL;
6583 if (frag_stream_info) {
6584 // Note this only supports encryption info in the first sample descriptor.
6585 if (mov->fragment.stsd_id == 1) {
6586 if (frag_stream_info->encryption_index) {
6587 encrypted_index = current_index - frag_stream_info->index_entry;
6588 encryption_index = frag_stream_info->encryption_index;
6590 encryption_index = sc->cenc.encryption_index;
6594 encryption_index = sc->cenc.encryption_index;
6597 if (encryption_index) {
6598 if (encryption_index->auxiliary_info_sample_count &&
6599 !encryption_index->nb_encrypted_samples) {
6600 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6601 return AVERROR_INVALIDDATA;
6603 if (encryption_index->auxiliary_offsets_count &&
6604 !encryption_index->nb_encrypted_samples) {
6605 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6606 return AVERROR_INVALIDDATA;
6609 if (!encryption_index->nb_encrypted_samples) {
6610 // Full-sample encryption with default settings.
6611 encrypted_sample = sc->cenc.default_encrypted_sample;
6612 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6613 // Per-sample setting override.
6614 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6616 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6617 return AVERROR_INVALIDDATA;
6620 if (mov->decryption_key) {
6621 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6624 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6626 return AVERROR(ENOMEM);
6627 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6637 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6639 const int OPUS_SEEK_PREROLL_MS = 80;
6644 if (c->fc->nb_streams < 1)
6646 st = c->fc->streams[c->fc->nb_streams-1];
6648 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6649 return AVERROR_INVALIDDATA;
6651 /* Check OpusSpecificBox version. */
6652 if (avio_r8(pb) != 0) {
6653 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6654 return AVERROR_INVALIDDATA;
6657 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6658 size = atom.size + 8;
6660 if (ff_alloc_extradata(st->codecpar, size))
6661 return AVERROR(ENOMEM);
6663 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6664 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6665 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6666 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6668 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6669 little-endian; aside from the preceeding magic and version they're
6670 otherwise currently identical. Data after output gain at offset 16
6671 doesn't need to be bytewapped. */
6672 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6673 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6674 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6675 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6677 st->codecpar->initial_padding = pre_skip;
6678 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6679 (AVRational){1, 1000},
6680 (AVRational){1, 48000});
6685 static const MOVParseTableEntry mov_default_parse_table[] = {
6686 { MKTAG('A','C','L','R'), mov_read_aclr },
6687 { MKTAG('A','P','R','G'), mov_read_avid },
6688 { MKTAG('A','A','L','P'), mov_read_avid },
6689 { MKTAG('A','R','E','S'), mov_read_ares },
6690 { MKTAG('a','v','s','s'), mov_read_avss },
6691 { MKTAG('a','v','1','C'), mov_read_av1c },
6692 { MKTAG('c','h','p','l'), mov_read_chpl },
6693 { MKTAG('c','o','6','4'), mov_read_stco },
6694 { MKTAG('c','o','l','r'), mov_read_colr },
6695 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6696 { MKTAG('d','i','n','f'), mov_read_default },
6697 { MKTAG('D','p','x','E'), mov_read_dpxe },
6698 { MKTAG('d','r','e','f'), mov_read_dref },
6699 { MKTAG('e','d','t','s'), mov_read_default },
6700 { MKTAG('e','l','s','t'), mov_read_elst },
6701 { MKTAG('e','n','d','a'), mov_read_enda },
6702 { MKTAG('f','i','e','l'), mov_read_fiel },
6703 { MKTAG('a','d','r','m'), mov_read_adrm },
6704 { MKTAG('f','t','y','p'), mov_read_ftyp },
6705 { MKTAG('g','l','b','l'), mov_read_glbl },
6706 { MKTAG('h','d','l','r'), mov_read_hdlr },
6707 { MKTAG('i','l','s','t'), mov_read_ilst },
6708 { MKTAG('j','p','2','h'), mov_read_jp2h },
6709 { MKTAG('m','d','a','t'), mov_read_mdat },
6710 { MKTAG('m','d','h','d'), mov_read_mdhd },
6711 { MKTAG('m','d','i','a'), mov_read_default },
6712 { MKTAG('m','e','t','a'), mov_read_meta },
6713 { MKTAG('m','i','n','f'), mov_read_default },
6714 { MKTAG('m','o','o','f'), mov_read_moof },
6715 { MKTAG('m','o','o','v'), mov_read_moov },
6716 { MKTAG('m','v','e','x'), mov_read_default },
6717 { MKTAG('m','v','h','d'), mov_read_mvhd },
6718 { MKTAG('S','M','I',' '), mov_read_svq3 },
6719 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6720 { MKTAG('a','v','c','C'), mov_read_glbl },
6721 { MKTAG('p','a','s','p'), mov_read_pasp },
6722 { MKTAG('s','i','d','x'), mov_read_sidx },
6723 { MKTAG('s','t','b','l'), mov_read_default },
6724 { MKTAG('s','t','c','o'), mov_read_stco },
6725 { MKTAG('s','t','p','s'), mov_read_stps },
6726 { MKTAG('s','t','r','f'), mov_read_strf },
6727 { MKTAG('s','t','s','c'), mov_read_stsc },
6728 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6729 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6730 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6731 { MKTAG('s','t','t','s'), mov_read_stts },
6732 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6733 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6734 { MKTAG('t','f','d','t'), mov_read_tfdt },
6735 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6736 { MKTAG('t','r','a','k'), mov_read_trak },
6737 { MKTAG('t','r','a','f'), mov_read_default },
6738 { MKTAG('t','r','e','f'), mov_read_default },
6739 { MKTAG('t','m','c','d'), mov_read_tmcd },
6740 { MKTAG('c','h','a','p'), mov_read_chap },
6741 { MKTAG('t','r','e','x'), mov_read_trex },
6742 { MKTAG('t','r','u','n'), mov_read_trun },
6743 { MKTAG('u','d','t','a'), mov_read_default },
6744 { MKTAG('w','a','v','e'), mov_read_wave },
6745 { MKTAG('e','s','d','s'), mov_read_esds },
6746 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6747 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6748 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6749 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6750 { MKTAG('w','f','e','x'), mov_read_wfex },
6751 { MKTAG('c','m','o','v'), mov_read_cmov },
6752 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6753 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6754 { MKTAG('s','b','g','p'), mov_read_sbgp },
6755 { MKTAG('h','v','c','C'), mov_read_glbl },
6756 { MKTAG('u','u','i','d'), mov_read_uuid },
6757 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6758 { MKTAG('f','r','e','e'), mov_read_free },
6759 { MKTAG('-','-','-','-'), mov_read_custom },
6760 { MKTAG('s','i','n','f'), mov_read_default },
6761 { MKTAG('f','r','m','a'), mov_read_frma },
6762 { MKTAG('s','e','n','c'), mov_read_senc },
6763 { MKTAG('s','a','i','z'), mov_read_saiz },
6764 { MKTAG('s','a','i','o'), mov_read_saio },
6765 { MKTAG('p','s','s','h'), mov_read_pssh },
6766 { MKTAG('s','c','h','m'), mov_read_schm },
6767 { MKTAG('s','c','h','i'), mov_read_default },
6768 { MKTAG('t','e','n','c'), mov_read_tenc },
6769 { MKTAG('d','f','L','a'), mov_read_dfla },
6770 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6771 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6772 { MKTAG('d','O','p','s'), mov_read_dops },
6773 { MKTAG('S','m','D','m'), mov_read_smdm },
6774 { MKTAG('C','o','L','L'), mov_read_coll },
6775 { MKTAG('v','p','c','C'), mov_read_vpcc },
6776 { MKTAG('m','d','c','v'), mov_read_mdcv },
6777 { MKTAG('c','l','l','i'), mov_read_clli },
6781 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6783 int64_t total_size = 0;
6787 if (c->atom_depth > 10) {
6788 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6789 return AVERROR_INVALIDDATA;
6794 atom.size = INT64_MAX;
6795 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6796 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
6799 if (atom.size >= 8) {
6800 a.size = avio_rb32(pb);
6801 a.type = avio_rl32(pb);
6802 if (a.type == MKTAG('f','r','e','e') &&
6804 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT &&
6807 uint32_t *type = (uint32_t *)buf + 1;
6808 if (avio_read(pb, buf, 8) != 8)
6809 return AVERROR_INVALIDDATA;
6810 avio_seek(pb, -8, SEEK_CUR);
6811 if (*type == MKTAG('m','v','h','d') ||
6812 *type == MKTAG('c','m','o','v')) {
6813 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free atom.\n");
6814 a.type = MKTAG('m','o','o','v');
6817 if (atom.type != MKTAG('r','o','o','t') &&
6818 atom.type != MKTAG('m','o','o','v'))
6820 if (a.type == MKTAG('t','r','a','k') || a.type == MKTAG('m','d','a','t'))
6822 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
6829 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
6830 a.size = avio_rb64(pb) - 8;
6834 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
6835 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
6837 a.size = atom.size - total_size + 8;
6842 a.size = FFMIN(a.size, atom.size - total_size);
6844 for (i = 0; mov_default_parse_table[i].type; i++)
6845 if (mov_default_parse_table[i].type == a.type) {
6846 parse = mov_default_parse_table[i].parse;
6850 // container is user data
6851 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
6852 atom.type == MKTAG('i','l','s','t')))
6853 parse = mov_read_udta_string;
6855 // Supports parsing the QuickTime Metadata Keys.
6856 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
6857 if (!parse && c->found_hdlr_mdta &&
6858 atom.type == MKTAG('m','e','t','a') &&
6859 a.type == MKTAG('k','e','y','s')) {
6860 parse = mov_read_keys;
6863 if (!parse) { /* skip leaf atoms data */
6864 avio_skip(pb, a.size);
6866 int64_t start_pos = avio_tell(pb);
6868 int err = parse(c, pb, a);
6873 if (c->found_moov && c->found_mdat &&
6874 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
6875 start_pos + a.size == avio_size(pb))) {
6876 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
6877 c->next_root_atom = start_pos + a.size;
6881 left = a.size - avio_tell(pb) + start_pos;
6882 if (left > 0) /* skip garbage at atom end */
6883 avio_skip(pb, left);
6884 else if (left < 0) {
6885 av_log(c->fc, AV_LOG_WARNING,
6886 "overread end of atom '%.4s' by %"PRId64" bytes\n",
6887 (char*)&a.type, -left);
6888 avio_seek(pb, left, SEEK_CUR);
6892 total_size += a.size;
6895 if (total_size < atom.size && atom.size < 0x7ffff)
6896 avio_skip(pb, atom.size - total_size);
6902 static int mov_probe(AVProbeData *p)
6907 int moov_offset = -1;
6909 /* check file header */
6912 /* ignore invalid offset */
6913 if ((offset + 8) > (unsigned int)p->buf_size)
6915 tag = AV_RL32(p->buf + offset + 4);
6917 /* check for obvious tags */
6918 case MKTAG('m','o','o','v'):
6919 moov_offset = offset + 4;
6920 case MKTAG('m','d','a','t'):
6921 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
6922 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
6923 case MKTAG('f','t','y','p'):
6924 if (AV_RB32(p->buf+offset) < 8 &&
6925 (AV_RB32(p->buf+offset) != 1 ||
6926 offset + 12 > (unsigned int)p->buf_size ||
6927 AV_RB64(p->buf+offset + 8) == 0)) {
6928 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
6929 } else if (tag == MKTAG('f','t','y','p') &&
6930 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
6931 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
6933 score = FFMAX(score, 5);
6935 score = AVPROBE_SCORE_MAX;
6937 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
6939 /* those are more common words, so rate then a bit less */
6940 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
6941 case MKTAG('w','i','d','e'):
6942 case MKTAG('f','r','e','e'):
6943 case MKTAG('j','u','n','k'):
6944 case MKTAG('p','i','c','t'):
6945 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
6946 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
6948 case MKTAG(0x82,0x82,0x7f,0x7d):
6949 case MKTAG('s','k','i','p'):
6950 case MKTAG('u','u','i','d'):
6951 case MKTAG('p','r','f','l'):
6952 /* if we only find those cause probedata is too small at least rate them */
6953 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
6954 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
6957 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
6960 if(score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
6961 /* moov atom in the header - we should make sure that this is not a
6962 * MOV-packed MPEG-PS */
6963 offset = moov_offset;
6965 while(offset < (p->buf_size - 16)){ /* Sufficient space */
6966 /* We found an actual hdlr atom */
6967 if(AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
6968 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
6969 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')){
6970 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
6971 /* We found a media handler reference atom describing an
6972 * MPEG-PS-in-MOV, return a
6973 * low score to force expanding the probe window until
6974 * mpegps_probe finds what it needs */
6985 // must be done after parsing all trak because there's no order requirement
6986 static void mov_read_chapters(AVFormatContext *s)
6988 MOVContext *mov = s->priv_data;
6990 MOVStreamContext *sc;
6995 for (j = 0; j < mov->nb_chapter_tracks; j++) {
6996 chapter_track = mov->chapter_tracks[j];
6998 for (i = 0; i < s->nb_streams; i++)
6999 if (s->streams[i]->id == chapter_track) {
7004 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7009 cur_pos = avio_tell(sc->pb);
7011 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7012 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7013 if (st->nb_index_entries) {
7014 // Retrieve the first frame, if possible
7016 AVIndexEntry *sample = &st->index_entries[0];
7017 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7018 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7022 if (av_get_packet(sc->pb, &pkt, sample->size) < 0)
7025 st->attached_pic = pkt;
7026 st->attached_pic.stream_index = st->index;
7027 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
7030 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7031 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7032 st->discard = AVDISCARD_ALL;
7033 for (i = 0; i < st->nb_index_entries; i++) {
7034 AVIndexEntry *sample = &st->index_entries[i];
7035 int64_t end = i+1 < st->nb_index_entries ? st->index_entries[i+1].timestamp : st->duration;
7040 if (end < sample->timestamp) {
7041 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7042 end = AV_NOPTS_VALUE;
7045 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7046 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7050 // the first two bytes are the length of the title
7051 len = avio_rb16(sc->pb);
7052 if (len > sample->size-2)
7054 title_len = 2*len + 1;
7055 if (!(title = av_mallocz(title_len)))
7058 // The samples could theoretically be in any encoding if there's an encd
7059 // atom following, but in practice are only utf-8 or utf-16, distinguished
7060 // instead by the presence of a BOM
7064 ch = avio_rb16(sc->pb);
7066 avio_get_str16be(sc->pb, len, title, title_len);
7067 else if (ch == 0xfffe)
7068 avio_get_str16le(sc->pb, len, title, title_len);
7071 if (len == 1 || len == 2)
7074 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7078 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7083 avio_seek(sc->pb, cur_pos, SEEK_SET);
7087 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7088 uint32_t value, int flags)
7091 char buf[AV_TIMECODE_STR_SIZE];
7092 AVRational rate = st->avg_frame_rate;
7093 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7096 av_dict_set(&st->metadata, "timecode",
7097 av_timecode_make_string(&tc, buf, value), 0);
7101 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7103 MOVStreamContext *sc = st->priv_data;
7104 char buf[AV_TIMECODE_STR_SIZE];
7105 int64_t cur_pos = avio_tell(sc->pb);
7106 int hh, mm, ss, ff, drop;
7108 if (!st->nb_index_entries)
7111 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7112 avio_skip(s->pb, 13);
7113 hh = avio_r8(s->pb);
7114 mm = avio_r8(s->pb);
7115 ss = avio_r8(s->pb);
7116 drop = avio_r8(s->pb);
7117 ff = avio_r8(s->pb);
7118 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7119 hh, mm, ss, drop ? ';' : ':', ff);
7120 av_dict_set(&st->metadata, "timecode", buf, 0);
7122 avio_seek(sc->pb, cur_pos, SEEK_SET);
7126 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7128 MOVStreamContext *sc = st->priv_data;
7130 int64_t cur_pos = avio_tell(sc->pb);
7133 if (!st->nb_index_entries)
7136 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7137 value = avio_rb32(s->pb);
7139 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7140 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7141 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7143 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7144 * not the case) and thus assume "frame number format" instead of QT one.
7145 * No sample with tmcd track can be found with a QT timecode at the moment,
7146 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7148 parse_timecode_in_framenum_format(s, st, value, flags);
7150 avio_seek(sc->pb, cur_pos, SEEK_SET);
7154 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7156 if (!index || !*index) return;
7157 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7158 av_encryption_info_free((*index)->encrypted_samples[i]);
7160 av_freep(&(*index)->encrypted_samples);
7161 av_freep(&(*index)->auxiliary_info_sizes);
7162 av_freep(&(*index)->auxiliary_offsets);
7166 static int mov_read_close(AVFormatContext *s)
7168 MOVContext *mov = s->priv_data;
7171 for (i = 0; i < s->nb_streams; i++) {
7172 AVStream *st = s->streams[i];
7173 MOVStreamContext *sc = st->priv_data;
7178 av_freep(&sc->ctts_data);
7179 for (j = 0; j < sc->drefs_count; j++) {
7180 av_freep(&sc->drefs[j].path);
7181 av_freep(&sc->drefs[j].dir);
7183 av_freep(&sc->drefs);
7185 sc->drefs_count = 0;
7187 if (!sc->pb_is_copied)
7188 ff_format_io_close(s, &sc->pb);
7191 av_freep(&sc->chunk_offsets);
7192 av_freep(&sc->stsc_data);
7193 av_freep(&sc->sample_sizes);
7194 av_freep(&sc->keyframes);
7195 av_freep(&sc->stts_data);
7196 av_freep(&sc->stps_data);
7197 av_freep(&sc->elst_data);
7198 av_freep(&sc->rap_group);
7199 av_freep(&sc->display_matrix);
7200 av_freep(&sc->index_ranges);
7203 for (j = 0; j < sc->stsd_count; j++)
7204 av_free(sc->extradata[j]);
7205 av_freep(&sc->extradata);
7206 av_freep(&sc->extradata_size);
7208 mov_free_encryption_index(&sc->cenc.encryption_index);
7209 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7210 av_aes_ctr_free(sc->cenc.aes_ctr);
7212 av_freep(&sc->stereo3d);
7213 av_freep(&sc->spherical);
7214 av_freep(&sc->mastering);
7215 av_freep(&sc->coll);
7218 if (mov->dv_demux) {
7219 avformat_free_context(mov->dv_fctx);
7220 mov->dv_fctx = NULL;
7223 if (mov->meta_keys) {
7224 for (i = 1; i < mov->meta_keys_count; i++) {
7225 av_freep(&mov->meta_keys[i]);
7227 av_freep(&mov->meta_keys);
7230 av_freep(&mov->trex_data);
7231 av_freep(&mov->bitrates);
7233 for (i = 0; i < mov->frag_index.nb_items; i++) {
7234 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7235 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7236 mov_free_encryption_index(&frag[j].encryption_index);
7238 av_freep(&mov->frag_index.item[i].stream_info);
7240 av_freep(&mov->frag_index.item);
7242 av_freep(&mov->aes_decrypt);
7243 av_freep(&mov->chapter_tracks);
7248 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7252 for (i = 0; i < s->nb_streams; i++) {
7253 AVStream *st = s->streams[i];
7254 MOVStreamContext *sc = st->priv_data;
7256 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7257 sc->timecode_track == tmcd_id)
7263 /* look for a tmcd track not referenced by any video track, and export it globally */
7264 static void export_orphan_timecode(AVFormatContext *s)
7268 for (i = 0; i < s->nb_streams; i++) {
7269 AVStream *st = s->streams[i];
7271 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7272 !tmcd_is_referenced(s, i + 1)) {
7273 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7275 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7282 static int read_tfra(MOVContext *mov, AVIOContext *f)
7284 int version, fieldlength, i, j;
7285 int64_t pos = avio_tell(f);
7286 uint32_t size = avio_rb32(f);
7287 unsigned track_id, item_count;
7289 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7292 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7294 version = avio_r8(f);
7296 track_id = avio_rb32(f);
7297 fieldlength = avio_rb32(f);
7298 item_count = avio_rb32(f);
7299 for (i = 0; i < item_count; i++) {
7300 int64_t time, offset;
7302 MOVFragmentStreamInfo * frag_stream_info;
7305 return AVERROR_INVALIDDATA;
7309 time = avio_rb64(f);
7310 offset = avio_rb64(f);
7312 time = avio_rb32(f);
7313 offset = avio_rb32(f);
7316 // The first sample of each stream in a fragment is always a random
7317 // access sample. So it's entry in the tfra can be used as the
7318 // initial PTS of the fragment.
7319 index = update_frag_index(mov, offset);
7320 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7321 if (frag_stream_info &&
7322 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7323 frag_stream_info->first_tfra_pts = time;
7325 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7327 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7329 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7333 avio_seek(f, pos + size, SEEK_SET);
7337 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7339 int64_t stream_size = avio_size(f);
7340 int64_t original_pos = avio_tell(f);
7344 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7348 mfra_size = avio_rb32(f);
7349 if (mfra_size < 0 || mfra_size > stream_size) {
7350 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7353 if ((seek_ret = avio_seek(f, -mfra_size, SEEK_CUR)) < 0) {
7357 if (avio_rb32(f) != mfra_size) {
7358 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7361 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7362 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7365 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7367 ret = read_tfra(c, f);
7373 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7375 av_log(c->fc, AV_LOG_ERROR,
7376 "failed to seek back after looking for mfra\n");
7382 static int mov_read_header(AVFormatContext *s)
7384 MOVContext *mov = s->priv_data;
7385 AVIOContext *pb = s->pb;
7387 MOVAtom atom = { AV_RL32("root") };
7390 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7391 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7392 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7393 return AVERROR(EINVAL);
7397 mov->trak_index = -1;
7398 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7399 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7400 atom.size = avio_size(pb);
7402 atom.size = INT64_MAX;
7404 /* check MOV header */
7406 if (mov->moov_retry)
7407 avio_seek(pb, 0, SEEK_SET);
7408 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7409 av_log(s, AV_LOG_ERROR, "error reading header\n");
7413 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7414 if (!mov->found_moov) {
7415 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7417 return AVERROR_INVALIDDATA;
7419 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7421 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7422 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7423 mov_read_chapters(s);
7424 for (i = 0; i < s->nb_streams; i++)
7425 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7426 mov_read_timecode_track(s, s->streams[i]);
7427 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7428 mov_read_rtmd_track(s, s->streams[i]);
7432 /* copy timecode metadata from tmcd tracks to the related video streams */
7433 for (i = 0; i < s->nb_streams; i++) {
7434 AVStream *st = s->streams[i];
7435 MOVStreamContext *sc = st->priv_data;
7436 if (sc->timecode_track > 0) {
7437 AVDictionaryEntry *tcr;
7438 int tmcd_st_id = -1;
7440 for (j = 0; j < s->nb_streams; j++)
7441 if (s->streams[j]->id == sc->timecode_track)
7444 if (tmcd_st_id < 0 || tmcd_st_id == i)
7446 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7448 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7451 export_orphan_timecode(s);
7453 for (i = 0; i < s->nb_streams; i++) {
7454 AVStream *st = s->streams[i];
7455 MOVStreamContext *sc = st->priv_data;
7456 fix_timescale(mov, sc);
7457 if(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7458 st->skip_samples = sc->start_pad;
7460 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7461 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7462 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7463 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7464 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7465 st->codecpar->width = sc->width;
7466 st->codecpar->height = sc->height;
7468 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7469 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7473 if (mov->handbrake_version &&
7474 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7475 st->codecpar->codec_id == AV_CODEC_ID_MP3
7477 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7478 st->need_parsing = AVSTREAM_PARSE_FULL;
7482 if (mov->trex_data) {
7483 for (i = 0; i < s->nb_streams; i++) {
7484 AVStream *st = s->streams[i];
7485 MOVStreamContext *sc = st->priv_data;
7486 if (st->duration > 0) {
7487 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7488 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7489 sc->data_size, sc->time_scale);
7491 return AVERROR_INVALIDDATA;
7493 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7498 if (mov->use_mfra_for > 0) {
7499 for (i = 0; i < s->nb_streams; i++) {
7500 AVStream *st = s->streams[i];
7501 MOVStreamContext *sc = st->priv_data;
7502 if (sc->duration_for_fps > 0) {
7503 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7504 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7505 sc->data_size, sc->time_scale);
7507 return AVERROR_INVALIDDATA;
7509 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7510 sc->duration_for_fps;
7515 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7516 if (mov->bitrates[i]) {
7517 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7521 ff_rfps_calculate(s);
7523 for (i = 0; i < s->nb_streams; i++) {
7524 AVStream *st = s->streams[i];
7525 MOVStreamContext *sc = st->priv_data;
7527 switch (st->codecpar->codec_type) {
7528 case AVMEDIA_TYPE_AUDIO:
7529 err = ff_replaygain_export(st, s->metadata);
7535 case AVMEDIA_TYPE_VIDEO:
7536 if (sc->display_matrix) {
7537 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7538 sizeof(int32_t) * 9);
7542 sc->display_matrix = NULL;
7545 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7546 (uint8_t *)sc->stereo3d,
7547 sizeof(*sc->stereo3d));
7551 sc->stereo3d = NULL;
7553 if (sc->spherical) {
7554 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7555 (uint8_t *)sc->spherical,
7556 sc->spherical_size);
7560 sc->spherical = NULL;
7562 if (sc->mastering) {
7563 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7564 (uint8_t *)sc->mastering,
7565 sizeof(*sc->mastering));
7569 sc->mastering = NULL;
7572 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7573 (uint8_t *)sc->coll,
7583 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7585 for (i = 0; i < mov->frag_index.nb_items; i++)
7586 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7587 mov->frag_index.item[i].headers_read = 1;
7592 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7594 AVIndexEntry *sample = NULL;
7595 int64_t best_dts = INT64_MAX;
7597 for (i = 0; i < s->nb_streams; i++) {
7598 AVStream *avst = s->streams[i];
7599 MOVStreamContext *msc = avst->priv_data;
7600 if (msc->pb && msc->current_sample < avst->nb_index_entries) {
7601 AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample];
7602 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7603 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7604 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7605 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7606 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb &&
7607 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7608 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7609 sample = current_sample;
7618 static int should_retry(AVIOContext *pb, int error_code) {
7619 if (error_code == AVERROR_EOF || avio_feof(pb))
7625 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7628 MOVContext *mov = s->priv_data;
7630 if (index >= 0 && index < mov->frag_index.nb_items)
7631 target = mov->frag_index.item[index].moof_offset;
7632 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7633 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7634 return AVERROR_INVALIDDATA;
7637 mov->next_root_atom = 0;
7638 if (index < 0 || index >= mov->frag_index.nb_items)
7639 index = search_frag_moof_offset(&mov->frag_index, target);
7640 if (index < mov->frag_index.nb_items) {
7641 if (index + 1 < mov->frag_index.nb_items)
7642 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7643 if (mov->frag_index.item[index].headers_read)
7645 mov->frag_index.item[index].headers_read = 1;
7648 mov->found_mdat = 0;
7650 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7653 if (avio_feof(s->pb))
7655 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7660 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7662 uint8_t *side, *extradata;
7665 /* Save the current index. */
7666 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7668 /* Notify the decoder that extradata changed. */
7669 extradata_size = sc->extradata_size[sc->last_stsd_index];
7670 extradata = sc->extradata[sc->last_stsd_index];
7671 if (extradata_size > 0 && extradata) {
7672 side = av_packet_new_side_data(pkt,
7673 AV_PKT_DATA_NEW_EXTRADATA,
7676 return AVERROR(ENOMEM);
7677 memcpy(side, extradata, extradata_size);
7683 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7685 MOVContext *mov = s->priv_data;
7686 MOVStreamContext *sc;
7687 AVIndexEntry *sample;
7688 AVStream *st = NULL;
7689 int64_t current_index;
7693 sample = mov_find_next_sample(s, &st);
7694 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7695 if (!mov->next_root_atom)
7697 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7702 /* must be done just before reading, to avoid infinite loop on sample */
7703 current_index = sc->current_index;
7704 mov_current_sample_inc(sc);
7706 if (mov->next_root_atom) {
7707 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7708 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7711 if (st->discard != AVDISCARD_ALL) {
7712 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7713 if (ret64 != sample->pos) {
7714 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7715 sc->ffindex, sample->pos);
7716 if (should_retry(sc->pb, ret64)) {
7717 mov_current_sample_dec(sc);
7719 return AVERROR_INVALIDDATA;
7722 if( st->discard == AVDISCARD_NONKEY && 0==(sample->flags & AVINDEX_KEYFRAME) ) {
7723 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7727 ret = av_get_packet(sc->pb, pkt, sample->size);
7729 if (should_retry(sc->pb, ret)) {
7730 mov_current_sample_dec(sc);
7734 if (sc->has_palette) {
7737 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7739 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7741 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7742 sc->has_palette = 0;
7745 #if CONFIG_DV_DEMUXER
7746 if (mov->dv_demux && sc->dv_audio_container) {
7747 avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7748 av_freep(&pkt->data);
7750 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7755 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7756 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7757 st->need_parsing = AVSTREAM_PARSE_FULL;
7761 pkt->stream_index = sc->ffindex;
7762 pkt->dts = sample->timestamp;
7763 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7764 pkt->flags |= AV_PKT_FLAG_DISCARD;
7766 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7767 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
7768 /* update ctts context */
7770 if (sc->ctts_index < sc->ctts_count &&
7771 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
7773 sc->ctts_sample = 0;
7776 int64_t next_dts = (sc->current_sample < st->nb_index_entries) ?
7777 st->index_entries[sc->current_sample].timestamp : st->duration;
7779 if (next_dts >= pkt->dts)
7780 pkt->duration = next_dts - pkt->dts;
7781 pkt->pts = pkt->dts;
7783 if (st->discard == AVDISCARD_ALL)
7785 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
7786 pkt->pos = sample->pos;
7788 /* Multiple stsd handling. */
7789 if (sc->stsc_data) {
7790 /* Keep track of the stsc index for the given sample, then check
7791 * if the stsd index is different from the last used one. */
7793 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
7794 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
7796 sc->stsc_sample = 0;
7797 /* Do not check indexes after a switch. */
7798 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
7799 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
7800 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
7801 ret = mov_change_extradata(sc, pkt);
7808 aax_filter(pkt->data, pkt->size, mov);
7810 ret = cenc_filter(mov, st, sc, pkt, current_index);
7817 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
7819 MOVContext *mov = s->priv_data;
7822 if (!mov->frag_index.complete)
7825 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
7828 if (!mov->frag_index.item[index].headers_read)
7829 return mov_switch_root(s, -1, index);
7830 if (index + 1 < mov->frag_index.nb_items)
7831 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7836 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
7838 MOVStreamContext *sc = st->priv_data;
7839 int sample, time_sample, ret;
7842 // Here we consider timestamp to be PTS, hence try to offset it so that we
7843 // can search over the DTS timeline.
7844 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
7846 ret = mov_seek_fragment(s, st, timestamp);
7850 sample = av_index_search_timestamp(st, timestamp, flags);
7851 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
7852 if (sample < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp)
7854 if (sample < 0) /* not sure what to do */
7855 return AVERROR_INVALIDDATA;
7856 mov_current_sample_set(sc, sample);
7857 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
7858 /* adjust ctts index */
7859 if (sc->ctts_data) {
7861 for (i = 0; i < sc->ctts_count; i++) {
7862 int next = time_sample + sc->ctts_data[i].count;
7863 if (next > sc->current_sample) {
7865 sc->ctts_sample = sc->current_sample - time_sample;
7872 /* adjust stsd index */
7874 for (i = 0; i < sc->stsc_count; i++) {
7875 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
7876 if (next > sc->current_sample) {
7878 sc->stsc_sample = sc->current_sample - time_sample;
7881 av_assert0(next == (int)next);
7888 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
7890 MOVContext *mc = s->priv_data;
7895 if (stream_index >= s->nb_streams)
7896 return AVERROR_INVALIDDATA;
7898 st = s->streams[stream_index];
7899 sample = mov_seek_stream(s, st, sample_time, flags);
7903 if (mc->seek_individually) {
7904 /* adjust seek timestamp to found sample timestamp */
7905 int64_t seek_timestamp = st->index_entries[sample].timestamp;
7907 for (i = 0; i < s->nb_streams; i++) {
7909 MOVStreamContext *sc = s->streams[i]->priv_data;
7911 st->skip_samples = (sample_time <= 0) ? sc->start_pad : 0;
7913 if (stream_index == i)
7916 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
7917 mov_seek_stream(s, st, timestamp, flags);
7920 for (i = 0; i < s->nb_streams; i++) {
7921 MOVStreamContext *sc;
7924 mov_current_sample_set(sc, 0);
7927 MOVStreamContext *sc;
7928 AVIndexEntry *entry = mov_find_next_sample(s, &st);
7930 return AVERROR_INVALIDDATA;
7932 if (sc->ffindex == stream_index && sc->current_sample == sample)
7934 mov_current_sample_inc(sc);
7940 #define OFFSET(x) offsetof(MOVContext, x)
7941 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
7942 static const AVOption mov_options[] = {
7943 {"use_absolute_path",
7944 "allow using absolute path when opening alias, this is a possible security issue",
7945 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
7947 {"seek_streams_individually",
7948 "Seek each stream individually to the to the closest point",
7949 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
7951 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
7953 {"advanced_editlist",
7954 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
7955 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
7957 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
7960 "use mfra for fragment timestamps",
7961 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
7962 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
7964 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
7965 FLAGS, "use_mfra_for" },
7966 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
7967 FLAGS, "use_mfra_for" },
7968 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
7969 FLAGS, "use_mfra_for" },
7970 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
7971 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
7972 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
7973 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
7974 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
7975 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
7976 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
7977 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
7978 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
7979 .flags = AV_OPT_FLAG_DECODING_PARAM },
7980 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
7981 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
7982 {.i64 = 0}, 0, 1, FLAGS },
7987 static const AVClass mov_class = {
7988 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
7989 .item_name = av_default_item_name,
7990 .option = mov_options,
7991 .version = LIBAVUTIL_VERSION_INT,
7994 AVInputFormat ff_mov_demuxer = {
7995 .name = "mov,mp4,m4a,3gp,3g2,mj2",
7996 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
7997 .priv_class = &mov_class,
7998 .priv_data_size = sizeof(MOVContext),
7999 .extensions = "mov,mp4,m4a,3gp,3g2,mj2",
8000 .read_probe = mov_probe,
8001 .read_header = mov_read_header,
8002 .read_packet = mov_read_packet,
8003 .read_close = mov_read_close,
8004 .read_seek = mov_read_seek,
8005 .flags = AVFMT_NO_BYTE_SEEK,