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;
1286 frag_time = get_frag_time(frag_index, m, id);
1287 if (frag_time != AV_NOPTS_VALUE) {
1288 if (frag_time >= timestamp)
1290 if (frag_time <= timestamp)
1297 static int update_frag_index(MOVContext *c, int64_t offset)
1300 MOVFragmentIndexItem * item;
1301 MOVFragmentStreamInfo * frag_stream_info;
1303 // If moof_offset already exists in frag_index, return index to it
1304 index = search_frag_moof_offset(&c->frag_index, offset);
1305 if (index < c->frag_index.nb_items &&
1306 c->frag_index.item[index].moof_offset == offset)
1309 // offset is not yet in frag index.
1310 // Insert new item at index (sorted by moof offset)
1311 item = av_fast_realloc(c->frag_index.item,
1312 &c->frag_index.allocated_size,
1313 (c->frag_index.nb_items + 1) *
1314 sizeof(*c->frag_index.item));
1317 c->frag_index.item = item;
1319 frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1320 sizeof(*item->stream_info));
1321 if (!frag_stream_info)
1324 for (i = 0; i < c->fc->nb_streams; i++) {
1325 // Avoid building frag index if streams lack track id.
1326 if (c->fc->streams[i]->id < 0)
1327 return AVERROR_INVALIDDATA;
1329 frag_stream_info[i].id = c->fc->streams[i]->id;
1330 frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1331 frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1332 frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1333 frag_stream_info[i].index_entry = -1;
1334 frag_stream_info[i].encryption_index = NULL;
1337 if (index < c->frag_index.nb_items)
1338 memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1339 (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1341 item = &c->frag_index.item[index];
1342 item->headers_read = 0;
1344 item->nb_stream_info = c->fc->nb_streams;
1345 item->moof_offset = offset;
1346 item->stream_info = frag_stream_info;
1347 c->frag_index.nb_items++;
1352 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1353 int id, int entries)
1356 MOVFragmentStreamInfo * frag_stream_info;
1360 for (i = index; i < frag_index->nb_items; i++) {
1361 frag_stream_info = get_frag_stream_info(frag_index, i, id);
1362 if (frag_stream_info && frag_stream_info->index_entry >= 0)
1363 frag_stream_info->index_entry += entries;
1367 static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1369 if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1370 c->has_looked_for_mfra = 1;
1371 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1373 av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1375 if ((ret = mov_read_mfra(c, pb)) < 0) {
1376 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1377 "read the mfra (may be a live ismv)\n");
1380 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1381 "seekable, can not look for mfra\n");
1384 c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1385 av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1386 c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1387 return mov_read_default(c, pb, atom);
1390 static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time)
1393 if(time >= 2082844800)
1394 time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1396 if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1397 av_log(NULL, AV_LOG_DEBUG, "creation_time is not representable\n");
1401 avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1405 static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1408 MOVStreamContext *sc;
1410 char language[4] = {0};
1412 int64_t creation_time;
1414 if (c->fc->nb_streams < 1)
1416 st = c->fc->streams[c->fc->nb_streams-1];
1419 if (sc->time_scale) {
1420 av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1421 return AVERROR_INVALIDDATA;
1424 version = avio_r8(pb);
1426 avpriv_request_sample(c->fc, "Version %d", version);
1427 return AVERROR_PATCHWELCOME;
1429 avio_rb24(pb); /* flags */
1431 creation_time = avio_rb64(pb);
1434 creation_time = avio_rb32(pb);
1435 avio_rb32(pb); /* modification time */
1437 mov_metadata_creation_time(&st->metadata, creation_time);
1439 sc->time_scale = avio_rb32(pb);
1440 if (sc->time_scale <= 0) {
1441 av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1444 st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1446 lang = avio_rb16(pb); /* language */
1447 if (ff_mov_lang_to_iso639(lang, language))
1448 av_dict_set(&st->metadata, "language", language, 0);
1449 avio_rb16(pb); /* quality */
1454 static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1457 int64_t creation_time;
1458 int version = avio_r8(pb); /* version */
1459 avio_rb24(pb); /* flags */
1462 creation_time = avio_rb64(pb);
1465 creation_time = avio_rb32(pb);
1466 avio_rb32(pb); /* modification time */
1468 mov_metadata_creation_time(&c->fc->metadata, creation_time);
1469 c->time_scale = avio_rb32(pb); /* time scale */
1470 if (c->time_scale <= 0) {
1471 av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1474 av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1476 c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1477 // set the AVCodecContext duration because the duration of individual tracks
1478 // may be inaccurate
1479 if (c->time_scale > 0 && !c->trex_data)
1480 c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale);
1481 avio_rb32(pb); /* preferred scale */
1483 avio_rb16(pb); /* preferred volume */
1485 avio_skip(pb, 10); /* reserved */
1487 /* movie display matrix, store it in main context and use it later on */
1488 for (i = 0; i < 3; i++) {
1489 c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1490 c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1491 c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1494 avio_rb32(pb); /* preview time */
1495 avio_rb32(pb); /* preview duration */
1496 avio_rb32(pb); /* poster time */
1497 avio_rb32(pb); /* selection time */
1498 avio_rb32(pb); /* selection duration */
1499 avio_rb32(pb); /* current time */
1500 avio_rb32(pb); /* next track ID */
1505 static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1510 if (c->fc->nb_streams < 1)
1512 st = c->fc->streams[c->fc->nb_streams-1];
1514 little_endian = avio_rb16(pb) & 0xFF;
1515 av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1516 if (little_endian == 1) {
1517 switch (st->codecpar->codec_id) {
1518 case AV_CODEC_ID_PCM_S24BE:
1519 st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE;
1521 case AV_CODEC_ID_PCM_S32BE:
1522 st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE;
1524 case AV_CODEC_ID_PCM_F32BE:
1525 st->codecpar->codec_id = AV_CODEC_ID_PCM_F32LE;
1527 case AV_CODEC_ID_PCM_F64BE:
1528 st->codecpar->codec_id = AV_CODEC_ID_PCM_F64LE;
1537 static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1540 char color_parameter_type[5] = { 0 };
1541 uint16_t color_primaries, color_trc, color_matrix;
1544 if (c->fc->nb_streams < 1)
1546 st = c->fc->streams[c->fc->nb_streams - 1];
1548 ret = ffio_read_size(pb, color_parameter_type, 4);
1551 if (strncmp(color_parameter_type, "nclx", 4) &&
1552 strncmp(color_parameter_type, "nclc", 4)) {
1553 av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
1554 color_parameter_type);
1558 color_primaries = avio_rb16(pb);
1559 color_trc = avio_rb16(pb);
1560 color_matrix = avio_rb16(pb);
1562 av_log(c->fc, AV_LOG_TRACE,
1563 "%s: pri %d trc %d matrix %d",
1564 color_parameter_type, color_primaries, color_trc, color_matrix);
1566 if (!strncmp(color_parameter_type, "nclx", 4)) {
1567 uint8_t color_range = avio_r8(pb) >> 7;
1568 av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
1570 st->codecpar->color_range = AVCOL_RANGE_JPEG;
1572 st->codecpar->color_range = AVCOL_RANGE_MPEG;
1575 if (!av_color_primaries_name(color_primaries))
1576 color_primaries = AVCOL_PRI_UNSPECIFIED;
1577 if (!av_color_transfer_name(color_trc))
1578 color_trc = AVCOL_TRC_UNSPECIFIED;
1579 if (!av_color_space_name(color_matrix))
1580 color_matrix = AVCOL_SPC_UNSPECIFIED;
1582 st->codecpar->color_primaries = color_primaries;
1583 st->codecpar->color_trc = color_trc;
1584 st->codecpar->color_space = color_matrix;
1585 av_log(c->fc, AV_LOG_TRACE, "\n");
1590 static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1593 unsigned mov_field_order;
1594 enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
1596 if (c->fc->nb_streams < 1) // will happen with jp2 files
1598 st = c->fc->streams[c->fc->nb_streams-1];
1600 return AVERROR_INVALIDDATA;
1601 mov_field_order = avio_rb16(pb);
1602 if ((mov_field_order & 0xFF00) == 0x0100)
1603 decoded_field_order = AV_FIELD_PROGRESSIVE;
1604 else if ((mov_field_order & 0xFF00) == 0x0200) {
1605 switch (mov_field_order & 0xFF) {
1606 case 0x01: decoded_field_order = AV_FIELD_TT;
1608 case 0x06: decoded_field_order = AV_FIELD_BB;
1610 case 0x09: decoded_field_order = AV_FIELD_TB;
1612 case 0x0E: decoded_field_order = AV_FIELD_BT;
1616 if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
1617 av_log(NULL, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
1619 st->codecpar->field_order = decoded_field_order;
1624 static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
1627 uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
1628 if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
1629 return AVERROR_INVALIDDATA;
1630 if ((err = av_reallocp(&par->extradata, size)) < 0) {
1631 par->extradata_size = 0;
1634 par->extradata_size = size - AV_INPUT_BUFFER_PADDING_SIZE;
1638 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
1639 static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1640 AVCodecParameters *par, uint8_t *buf)
1642 int64_t result = atom.size;
1645 AV_WB32(buf , atom.size + 8);
1646 AV_WL32(buf + 4, atom.type);
1647 err = ffio_read_size(pb, buf + 8, atom.size);
1649 par->extradata_size -= atom.size;
1651 } else if (err < atom.size) {
1652 av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
1653 par->extradata_size -= atom.size - err;
1656 memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1660 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
1661 static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1662 enum AVCodecID codec_id)
1665 uint64_t original_size;
1668 if (c->fc->nb_streams < 1) // will happen with jp2 files
1670 st = c->fc->streams[c->fc->nb_streams-1];
1672 if (st->codecpar->codec_id != codec_id)
1673 return 0; /* unexpected codec_id - don't mess with extradata */
1675 original_size = st->codecpar->extradata_size;
1676 err = mov_realloc_extradata(st->codecpar, atom);
1680 err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
1683 return 0; // Note: this is the original behavior to ignore truncation.
1686 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
1687 static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1689 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
1692 static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1694 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS);
1697 static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1699 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
1702 static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1704 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
1707 static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1709 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
1711 ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
1715 static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1717 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
1719 if (!ret && c->fc->nb_streams >= 1) {
1720 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1721 if (par->extradata_size >= 40) {
1722 par->height = AV_RB16(&par->extradata[36]);
1723 par->width = AV_RB16(&par->extradata[38]);
1729 static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1731 if (c->fc->nb_streams >= 1) {
1732 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1733 if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
1734 par->codec_id == AV_CODEC_ID_H264 &&
1738 cid = avio_rb16(pb);
1739 /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
1740 if (cid == 0xd4d || cid == 0xd4e)
1743 } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
1744 par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
1745 par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
1749 num = avio_rb32(pb);
1750 den = avio_rb32(pb);
1751 if (num <= 0 || den <= 0)
1753 switch (avio_rb32(pb)) {
1755 if (den >= INT_MAX / 2)
1759 c->fc->streams[c->fc->nb_streams-1]->display_aspect_ratio.num = num;
1760 c->fc->streams[c->fc->nb_streams-1]->display_aspect_ratio.den = den;
1767 return mov_read_avid(c, pb, atom);
1770 static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1774 uint64_t original_size;
1775 if (c->fc->nb_streams >= 1) {
1776 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1777 if (par->codec_id == AV_CODEC_ID_H264)
1779 if (atom.size == 16) {
1780 original_size = par->extradata_size;
1781 ret = mov_realloc_extradata(par, atom);
1783 length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
1784 if (length == atom.size) {
1785 const uint8_t range_value = par->extradata[original_size + 19];
1786 switch (range_value) {
1788 par->color_range = AVCOL_RANGE_MPEG;
1791 par->color_range = AVCOL_RANGE_JPEG;
1794 av_log(c, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
1797 ff_dlog(c, "color_range: %d\n", par->color_range);
1799 /* For some reason the whole atom was not added to the extradata */
1800 av_log(c, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
1803 av_log(c, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
1806 av_log(c, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
1813 static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1815 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
1818 static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1823 if (c->fc->nb_streams < 1)
1825 st = c->fc->streams[c->fc->nb_streams-1];
1827 if ((uint64_t)atom.size > (1<<30))
1828 return AVERROR_INVALIDDATA;
1830 if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
1831 st->codecpar->codec_id == AV_CODEC_ID_QDMC ||
1832 st->codecpar->codec_id == AV_CODEC_ID_SPEEX) {
1833 // pass all frma atom to codec, needed at least for QDMC and QDM2
1834 av_freep(&st->codecpar->extradata);
1835 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1838 } else if (atom.size > 8) { /* to read frma, esds atoms */
1839 if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
1841 ret = ffio_ensure_seekback(pb, 8);
1844 buffer = avio_rb64(pb);
1846 if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
1847 && buffer >> 32 <= atom.size
1848 && buffer >> 32 >= 8) {
1851 } else if (!st->codecpar->extradata_size) {
1852 #define ALAC_EXTRADATA_SIZE 36
1853 st->codecpar->extradata = av_mallocz(ALAC_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
1854 if (!st->codecpar->extradata)
1855 return AVERROR(ENOMEM);
1856 st->codecpar->extradata_size = ALAC_EXTRADATA_SIZE;
1857 AV_WB32(st->codecpar->extradata , ALAC_EXTRADATA_SIZE);
1858 AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
1859 AV_WB64(st->codecpar->extradata + 12, buffer);
1860 avio_read(pb, st->codecpar->extradata + 20, 16);
1861 avio_skip(pb, atom.size - 24);
1865 if ((ret = mov_read_default(c, pb, atom)) < 0)
1868 avio_skip(pb, atom.size);
1873 * This function reads atom content and puts data in extradata without tag
1874 * nor size unlike mov_read_extradata.
1876 static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1881 if (c->fc->nb_streams < 1)
1883 st = c->fc->streams[c->fc->nb_streams-1];
1885 if ((uint64_t)atom.size > (1<<30))
1886 return AVERROR_INVALIDDATA;
1888 if (atom.size >= 10) {
1889 // Broken files created by legacy versions of libavformat will
1890 // wrap a whole fiel atom inside of a glbl atom.
1891 unsigned size = avio_rb32(pb);
1892 unsigned type = avio_rl32(pb);
1893 avio_seek(pb, -8, SEEK_CUR);
1894 if (type == MKTAG('f','i','e','l') && size == atom.size)
1895 return mov_read_default(c, pb, atom);
1897 if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
1898 av_log(c, AV_LOG_WARNING, "ignoring multiple glbl\n");
1901 av_freep(&st->codecpar->extradata);
1902 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1905 if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
1906 /* HEVC-based Dolby Vision derived from hvc1.
1907 Happens to match with an identifier
1908 previously utilized for DV. Thus, if we have
1909 the hvcC extradata box available as specified,
1910 set codec to HEVC */
1911 st->codecpar->codec_id = AV_CODEC_ID_HEVC;
1916 static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1919 uint8_t profile_level;
1922 if (c->fc->nb_streams < 1)
1924 st = c->fc->streams[c->fc->nb_streams-1];
1926 if (atom.size >= (1<<28) || atom.size < 7)
1927 return AVERROR_INVALIDDATA;
1929 profile_level = avio_r8(pb);
1930 if ((profile_level & 0xf0) != 0xc0)
1933 avio_seek(pb, 6, SEEK_CUR);
1934 av_freep(&st->codecpar->extradata);
1935 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
1943 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
1944 * but can have extradata appended at the end after the 40 bytes belonging
1947 static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1952 if (c->fc->nb_streams < 1)
1954 if (atom.size <= 40)
1956 st = c->fc->streams[c->fc->nb_streams-1];
1958 if ((uint64_t)atom.size > (1<<30))
1959 return AVERROR_INVALIDDATA;
1962 av_freep(&st->codecpar->extradata);
1963 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
1970 static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1973 MOVStreamContext *sc;
1974 unsigned int i, entries;
1976 if (c->fc->nb_streams < 1)
1978 st = c->fc->streams[c->fc->nb_streams-1];
1981 avio_r8(pb); /* version */
1982 avio_rb24(pb); /* flags */
1984 entries = avio_rb32(pb);
1989 if (sc->chunk_offsets)
1990 av_log(c->fc, AV_LOG_WARNING, "Duplicated STCO atom\n");
1991 av_free(sc->chunk_offsets);
1992 sc->chunk_count = 0;
1993 sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
1994 if (!sc->chunk_offsets)
1995 return AVERROR(ENOMEM);
1996 sc->chunk_count = entries;
1998 if (atom.type == MKTAG('s','t','c','o'))
1999 for (i = 0; i < entries && !pb->eof_reached; i++)
2000 sc->chunk_offsets[i] = avio_rb32(pb);
2001 else if (atom.type == MKTAG('c','o','6','4'))
2002 for (i = 0; i < entries && !pb->eof_reached; i++)
2003 sc->chunk_offsets[i] = avio_rb64(pb);
2005 return AVERROR_INVALIDDATA;
2007 sc->chunk_count = i;
2009 if (pb->eof_reached) {
2010 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2017 static int mov_codec_id(AVStream *st, uint32_t format)
2019 int id = ff_codec_get_id(ff_codec_movaudio_tags, format);
2022 ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2023 (format & 0xFFFF) == 'T' + ('S' << 8)))
2024 id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format) & 0xFFFF);
2026 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2027 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2028 } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2029 /* skip old ASF MPEG-4 tag */
2030 format && format != MKTAG('m','p','4','s')) {
2031 id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2033 id = ff_codec_get_id(ff_codec_bmp_tags, format);
2035 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
2036 else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2037 (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE &&
2038 st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2039 id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
2041 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
2043 id = ff_codec_get_id(ff_codec_movdata_tags, format);
2047 st->codecpar->codec_tag = format;
2052 static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
2053 AVStream *st, MOVStreamContext *sc)
2055 uint8_t codec_name[32] = { 0 };
2059 /* The first 16 bytes of the video sample description are already
2060 * read in ff_mov_read_stsd_entries() */
2061 stsd_start = avio_tell(pb) - 16;
2063 avio_rb16(pb); /* version */
2064 avio_rb16(pb); /* revision level */
2065 avio_rb32(pb); /* vendor */
2066 avio_rb32(pb); /* temporal quality */
2067 avio_rb32(pb); /* spatial quality */
2069 st->codecpar->width = avio_rb16(pb); /* width */
2070 st->codecpar->height = avio_rb16(pb); /* height */
2072 avio_rb32(pb); /* horiz resolution */
2073 avio_rb32(pb); /* vert resolution */
2074 avio_rb32(pb); /* data size, always 0 */
2075 avio_rb16(pb); /* frames per samples */
2077 len = avio_r8(pb); /* codec name, pascal string */
2080 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2082 avio_skip(pb, 31 - len);
2085 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2087 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2088 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2089 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2090 st->codecpar->width &= ~1;
2091 st->codecpar->height &= ~1;
2093 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2094 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2095 !strncmp(codec_name, "Sorenson H263", 13))
2096 st->codecpar->codec_id = AV_CODEC_ID_FLV1;
2098 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2100 avio_seek(pb, stsd_start, SEEK_SET);
2102 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2103 st->codecpar->bits_per_coded_sample &= 0x1F;
2104 sc->has_palette = 1;
2108 static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
2109 AVStream *st, MOVStreamContext *sc)
2111 int bits_per_sample, flags;
2112 uint16_t version = avio_rb16(pb);
2113 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2115 avio_rb16(pb); /* revision level */
2116 avio_rb32(pb); /* vendor */
2118 st->codecpar->channels = avio_rb16(pb); /* channel count */
2119 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2120 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", st->codecpar->channels);
2122 sc->audio_cid = avio_rb16(pb);
2123 avio_rb16(pb); /* packet size = 0 */
2125 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2127 // Read QT version 1 fields. In version 0 these do not exist.
2128 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2130 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2131 (sc->stsd_version == 0 && version > 0)) {
2133 sc->samples_per_frame = avio_rb32(pb);
2134 avio_rb32(pb); /* bytes per packet */
2135 sc->bytes_per_frame = avio_rb32(pb);
2136 avio_rb32(pb); /* bytes per sample */
2137 } else if (version == 2) {
2138 avio_rb32(pb); /* sizeof struct only */
2139 st->codecpar->sample_rate = av_int2double(avio_rb64(pb));
2140 st->codecpar->channels = avio_rb32(pb);
2141 avio_rb32(pb); /* always 0x7F000000 */
2142 st->codecpar->bits_per_coded_sample = avio_rb32(pb);
2144 flags = avio_rb32(pb); /* lpcm format specific flag */
2145 sc->bytes_per_frame = avio_rb32(pb);
2146 sc->samples_per_frame = avio_rb32(pb);
2147 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2148 st->codecpar->codec_id =
2149 ff_mov_get_lpcm_codec_id(st->codecpar->bits_per_coded_sample,
2152 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2153 /* can't correctly handle variable sized packet as audio unit */
2154 switch (st->codecpar->codec_id) {
2155 case AV_CODEC_ID_MP2:
2156 case AV_CODEC_ID_MP3:
2157 st->need_parsing = AVSTREAM_PARSE_FULL;
2163 if (sc->format == 0) {
2164 if (st->codecpar->bits_per_coded_sample == 8)
2165 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2166 else if (st->codecpar->bits_per_coded_sample == 16)
2167 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2170 switch (st->codecpar->codec_id) {
2171 case AV_CODEC_ID_PCM_S8:
2172 case AV_CODEC_ID_PCM_U8:
2173 if (st->codecpar->bits_per_coded_sample == 16)
2174 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16BE;
2176 case AV_CODEC_ID_PCM_S16LE:
2177 case AV_CODEC_ID_PCM_S16BE:
2178 if (st->codecpar->bits_per_coded_sample == 8)
2179 st->codecpar->codec_id = AV_CODEC_ID_PCM_S8;
2180 else if (st->codecpar->bits_per_coded_sample == 24)
2181 st->codecpar->codec_id =
2182 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2183 AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
2184 else if (st->codecpar->bits_per_coded_sample == 32)
2185 st->codecpar->codec_id =
2186 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2187 AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
2189 /* set values for old format before stsd version 1 appeared */
2190 case AV_CODEC_ID_MACE3:
2191 sc->samples_per_frame = 6;
2192 sc->bytes_per_frame = 2 * st->codecpar->channels;
2194 case AV_CODEC_ID_MACE6:
2195 sc->samples_per_frame = 6;
2196 sc->bytes_per_frame = 1 * st->codecpar->channels;
2198 case AV_CODEC_ID_ADPCM_IMA_QT:
2199 sc->samples_per_frame = 64;
2200 sc->bytes_per_frame = 34 * st->codecpar->channels;
2202 case AV_CODEC_ID_GSM:
2203 sc->samples_per_frame = 160;
2204 sc->bytes_per_frame = 33;
2210 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2211 if (bits_per_sample) {
2212 st->codecpar->bits_per_coded_sample = bits_per_sample;
2213 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->channels;
2217 static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
2218 AVStream *st, MOVStreamContext *sc,
2221 // ttxt stsd contains display flags, justification, background
2222 // color, fonts, and default styles, so fake an atom to read it
2223 MOVAtom fake_atom = { .size = size };
2224 // mp4s contains a regular esds atom
2225 if (st->codecpar->codec_tag != AV_RL32("mp4s"))
2226 mov_read_glbl(c, pb, fake_atom);
2227 st->codecpar->width = sc->width;
2228 st->codecpar->height = sc->height;
2231 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2236 y = (ycbcr >> 16) & 0xFF;
2237 cr = (ycbcr >> 8) & 0xFF;
2240 b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
2241 g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
2242 r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
2244 return (r << 16) | (g << 8) | b;
2247 static int mov_rewrite_dvd_sub_extradata(AVStream *st)
2249 char buf[256] = {0};
2250 uint8_t *src = st->codecpar->extradata;
2253 if (st->codecpar->extradata_size != 64)
2256 if (st->codecpar->width > 0 && st->codecpar->height > 0)
2257 snprintf(buf, sizeof(buf), "size: %dx%d\n",
2258 st->codecpar->width, st->codecpar->height);
2259 av_strlcat(buf, "palette: ", sizeof(buf));
2261 for (i = 0; i < 16; i++) {
2262 uint32_t yuv = AV_RB32(src + i * 4);
2263 uint32_t rgba = yuv_to_rgba(yuv);
2265 av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2268 if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2271 av_freep(&st->codecpar->extradata);
2272 st->codecpar->extradata_size = 0;
2273 st->codecpar->extradata = av_mallocz(strlen(buf) + AV_INPUT_BUFFER_PADDING_SIZE);
2274 if (!st->codecpar->extradata)
2275 return AVERROR(ENOMEM);
2276 st->codecpar->extradata_size = strlen(buf);
2277 memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2282 static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
2283 AVStream *st, MOVStreamContext *sc,
2288 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2289 if ((int)size != size)
2290 return AVERROR(ENOMEM);
2292 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2296 MOVStreamContext *tmcd_ctx = st->priv_data;
2298 val = AV_RB32(st->codecpar->extradata + 4);
2299 tmcd_ctx->tmcd_flags = val;
2300 st->avg_frame_rate.num = st->codecpar->extradata[16]; /* number of frame */
2301 st->avg_frame_rate.den = 1;
2302 #if FF_API_LAVF_AVCTX
2303 FF_DISABLE_DEPRECATION_WARNINGS
2304 st->codec->time_base = av_inv_q(st->avg_frame_rate);
2305 FF_ENABLE_DEPRECATION_WARNINGS
2307 /* adjust for per frame dur in counter mode */
2308 if (tmcd_ctx->tmcd_flags & 0x0008) {
2309 int timescale = AV_RB32(st->codecpar->extradata + 8);
2310 int framedur = AV_RB32(st->codecpar->extradata + 12);
2311 st->avg_frame_rate.num *= timescale;
2312 st->avg_frame_rate.den *= framedur;
2313 #if FF_API_LAVF_AVCTX
2314 FF_DISABLE_DEPRECATION_WARNINGS
2315 st->codec->time_base.den *= timescale;
2316 st->codec->time_base.num *= framedur;
2317 FF_ENABLE_DEPRECATION_WARNINGS
2321 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2322 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2323 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2324 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2325 if (str_size > 0 && size >= (int)str_size + 26) {
2326 char *reel_name = av_malloc(str_size + 1);
2328 return AVERROR(ENOMEM);
2329 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2330 reel_name[str_size] = 0; /* Add null terminator */
2331 /* don't add reel_name if emtpy string */
2332 if (*reel_name == 0) {
2335 av_dict_set(&st->metadata, "reel_name", reel_name, AV_DICT_DONT_STRDUP_VAL);
2342 /* other codec type, just skip (rtp, mp4s ...) */
2343 avio_skip(pb, size);
2348 static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
2349 AVStream *st, MOVStreamContext *sc)
2351 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2352 !st->codecpar->sample_rate && sc->time_scale > 1)
2353 st->codecpar->sample_rate = sc->time_scale;
2355 /* special codec parameters handling */
2356 switch (st->codecpar->codec_id) {
2357 #if CONFIG_DV_DEMUXER
2358 case AV_CODEC_ID_DVAUDIO:
2359 c->dv_fctx = avformat_alloc_context();
2361 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2362 return AVERROR(ENOMEM);
2364 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2366 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2367 return AVERROR(ENOMEM);
2369 sc->dv_audio_container = 1;
2370 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
2373 /* no ifdef since parameters are always those */
2374 case AV_CODEC_ID_QCELP:
2375 st->codecpar->channels = 1;
2376 // force sample rate for qcelp when not stored in mov
2377 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2378 st->codecpar->sample_rate = 8000;
2379 // FIXME: Why is the following needed for some files?
2380 sc->samples_per_frame = 160;
2381 if (!sc->bytes_per_frame)
2382 sc->bytes_per_frame = 35;
2384 case AV_CODEC_ID_AMR_NB:
2385 st->codecpar->channels = 1;
2386 /* force sample rate for amr, stsd in 3gp does not store sample rate */
2387 st->codecpar->sample_rate = 8000;
2389 case AV_CODEC_ID_AMR_WB:
2390 st->codecpar->channels = 1;
2391 st->codecpar->sample_rate = 16000;
2393 case AV_CODEC_ID_MP2:
2394 case AV_CODEC_ID_MP3:
2395 /* force type after stsd for m1a hdlr */
2396 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2398 case AV_CODEC_ID_GSM:
2399 case AV_CODEC_ID_ADPCM_MS:
2400 case AV_CODEC_ID_ADPCM_IMA_WAV:
2401 case AV_CODEC_ID_ILBC:
2402 case AV_CODEC_ID_MACE3:
2403 case AV_CODEC_ID_MACE6:
2404 case AV_CODEC_ID_QDM2:
2405 st->codecpar->block_align = sc->bytes_per_frame;
2407 case AV_CODEC_ID_ALAC:
2408 if (st->codecpar->extradata_size == 36) {
2409 st->codecpar->channels = AV_RB8 (st->codecpar->extradata + 21);
2410 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2413 case AV_CODEC_ID_AC3:
2414 case AV_CODEC_ID_EAC3:
2415 case AV_CODEC_ID_MPEG1VIDEO:
2416 case AV_CODEC_ID_VC1:
2417 case AV_CODEC_ID_VP8:
2418 case AV_CODEC_ID_VP9:
2419 st->need_parsing = AVSTREAM_PARSE_FULL;
2427 static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
2428 int codec_tag, int format,
2431 int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2434 (codec_tag != format &&
2435 // AVID 1:1 samples with differing data format and codec tag exist
2436 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
2437 // prores is allowed to have differing data format and codec tag
2438 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
2440 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
2441 (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id
2442 : codec_tag != MKTAG('j','p','e','g')))) {
2443 /* Multiple fourcc, we skip JPEG. This is not correct, we should
2444 * export it as a separate AVStream but this needs a few changes
2445 * in the MOV demuxer, patch welcome. */
2447 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
2448 avio_skip(pb, size);
2455 int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
2458 MOVStreamContext *sc;
2459 int pseudo_stream_id;
2461 av_assert0 (c->fc->nb_streams >= 1);
2462 st = c->fc->streams[c->fc->nb_streams-1];
2465 for (pseudo_stream_id = 0;
2466 pseudo_stream_id < entries && !pb->eof_reached;
2467 pseudo_stream_id++) {
2468 //Parsing Sample description table
2470 int ret, dref_id = 1;
2471 MOVAtom a = { AV_RL32("stsd") };
2472 int64_t start_pos = avio_tell(pb);
2473 int64_t size = avio_rb32(pb); /* size */
2474 uint32_t format = avio_rl32(pb); /* data format */
2477 avio_rb32(pb); /* reserved */
2478 avio_rb16(pb); /* reserved */
2479 dref_id = avio_rb16(pb);
2480 } else if (size <= 7) {
2481 av_log(c->fc, AV_LOG_ERROR,
2482 "invalid size %"PRId64" in stsd\n", size);
2483 return AVERROR_INVALIDDATA;
2486 if (mov_skip_multiple_stsd(c, pb, st->codecpar->codec_tag, format,
2487 size - (avio_tell(pb) - start_pos))) {
2492 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
2493 sc->dref_id= dref_id;
2494 sc->format = format;
2496 id = mov_codec_id(st, format);
2498 av_log(c->fc, AV_LOG_TRACE,
2499 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
2500 av_fourcc2str(format), st->codecpar->codec_type);
2502 st->codecpar->codec_id = id;
2503 if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) {
2504 mov_parse_stsd_video(c, pb, st, sc);
2505 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
2506 mov_parse_stsd_audio(c, pb, st, sc);
2507 if (st->codecpar->sample_rate < 0) {
2508 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
2509 return AVERROR_INVALIDDATA;
2511 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
2512 mov_parse_stsd_subtitle(c, pb, st, sc,
2513 size - (avio_tell(pb) - start_pos));
2515 ret = mov_parse_stsd_data(c, pb, st, sc,
2516 size - (avio_tell(pb) - start_pos));
2520 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
2521 a.size = size - (avio_tell(pb) - start_pos);
2523 if ((ret = mov_read_default(c, pb, a)) < 0)
2525 } else if (a.size > 0)
2526 avio_skip(pb, a.size);
2528 if (sc->extradata && st->codecpar->extradata) {
2529 int extra_size = st->codecpar->extradata_size;
2531 /* Move the current stream extradata to the stream context one. */
2532 sc->extradata_size[pseudo_stream_id] = extra_size;
2533 sc->extradata[pseudo_stream_id] = av_malloc(extra_size + AV_INPUT_BUFFER_PADDING_SIZE);
2534 if (!sc->extradata[pseudo_stream_id])
2535 return AVERROR(ENOMEM);
2536 memcpy(sc->extradata[pseudo_stream_id], st->codecpar->extradata, extra_size);
2537 av_freep(&st->codecpar->extradata);
2538 st->codecpar->extradata_size = 0;
2543 if (pb->eof_reached) {
2544 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
2551 static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2554 MOVStreamContext *sc;
2557 if (c->fc->nb_streams < 1)
2559 st = c->fc->streams[c->fc->nb_streams - 1];
2562 sc->stsd_version = avio_r8(pb);
2563 avio_rb24(pb); /* flags */
2564 entries = avio_rb32(pb);
2566 /* Each entry contains a size (4 bytes) and format (4 bytes). */
2567 if (entries <= 0 || entries > atom.size / 8) {
2568 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
2569 return AVERROR_INVALIDDATA;
2572 if (sc->extradata) {
2573 av_log(c->fc, AV_LOG_ERROR,
2574 "Duplicate stsd found in this track.\n");
2575 return AVERROR_INVALIDDATA;
2578 /* Prepare space for hosting multiple extradata. */
2579 sc->extradata = av_mallocz_array(entries, sizeof(*sc->extradata));
2581 return AVERROR(ENOMEM);
2583 sc->extradata_size = av_mallocz_array(entries, sizeof(*sc->extradata_size));
2584 if (!sc->extradata_size) {
2585 ret = AVERROR(ENOMEM);
2589 ret = ff_mov_read_stsd_entries(c, pb, entries);
2593 /* Restore back the primary extradata. */
2594 av_freep(&st->codecpar->extradata);
2595 st->codecpar->extradata_size = sc->extradata_size[0];
2596 if (sc->extradata_size[0]) {
2597 st->codecpar->extradata = av_mallocz(sc->extradata_size[0] + AV_INPUT_BUFFER_PADDING_SIZE);
2598 if (!st->codecpar->extradata)
2599 return AVERROR(ENOMEM);
2600 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
2603 return mov_finalize_stsd_codec(c, pb, st, sc);
2605 if (sc->extradata) {
2607 for (j = 0; j < sc->stsd_count; j++)
2608 av_freep(&sc->extradata[j]);
2611 av_freep(&sc->extradata);
2612 av_freep(&sc->extradata_size);
2616 static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2619 MOVStreamContext *sc;
2620 unsigned int i, entries;
2622 if (c->fc->nb_streams < 1)
2624 st = c->fc->streams[c->fc->nb_streams-1];
2627 avio_r8(pb); /* version */
2628 avio_rb24(pb); /* flags */
2630 entries = avio_rb32(pb);
2631 if ((uint64_t)entries * 12 + 4 > atom.size)
2632 return AVERROR_INVALIDDATA;
2634 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
2639 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSC atom\n");
2640 av_free(sc->stsc_data);
2642 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
2644 return AVERROR(ENOMEM);
2646 for (i = 0; i < entries && !pb->eof_reached; i++) {
2647 sc->stsc_data[i].first = avio_rb32(pb);
2648 sc->stsc_data[i].count = avio_rb32(pb);
2649 sc->stsc_data[i].id = avio_rb32(pb);
2653 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
2654 int64_t first_min = i + 1;
2655 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
2656 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
2657 sc->stsc_data[i].first < first_min ||
2658 sc->stsc_data[i].count < 1 ||
2659 sc->stsc_data[i].id < 1) {
2660 av_log(c->fc, AV_LOG_WARNING, "STSC entry %d is invalid (first=%d count=%d id=%d)\n", i, sc->stsc_data[i].first, sc->stsc_data[i].count, sc->stsc_data[i].id);
2661 if (i+1 >= sc->stsc_count) {
2662 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
2663 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
2664 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
2665 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
2666 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
2669 av_assert0(sc->stsc_data[i+1].first >= 2);
2670 // We replace this entry by the next valid
2671 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
2672 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
2673 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
2677 if (pb->eof_reached) {
2678 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
2685 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
2687 return index < count - 1;
2690 /* Compute the samples value for the stsc entry at the given index. */
2691 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
2695 if (mov_stsc_index_valid(index, sc->stsc_count))
2696 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
2698 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
2700 return sc->stsc_data[index].count * (int64_t)chunk_count;
2703 static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2706 MOVStreamContext *sc;
2707 unsigned i, entries;
2709 if (c->fc->nb_streams < 1)
2711 st = c->fc->streams[c->fc->nb_streams-1];
2714 avio_rb32(pb); // version + flags
2716 entries = avio_rb32(pb);
2718 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
2719 av_free(sc->stps_data);
2721 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
2723 return AVERROR(ENOMEM);
2725 for (i = 0; i < entries && !pb->eof_reached; i++) {
2726 sc->stps_data[i] = avio_rb32(pb);
2731 if (pb->eof_reached) {
2732 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
2739 static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2742 MOVStreamContext *sc;
2743 unsigned int i, entries;
2745 if (c->fc->nb_streams < 1)
2747 st = c->fc->streams[c->fc->nb_streams-1];
2750 avio_r8(pb); /* version */
2751 avio_rb24(pb); /* flags */
2753 entries = avio_rb32(pb);
2755 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
2759 sc->keyframe_absent = 1;
2760 if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
2761 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2765 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
2766 if (entries >= UINT_MAX / sizeof(int))
2767 return AVERROR_INVALIDDATA;
2768 av_freep(&sc->keyframes);
2769 sc->keyframe_count = 0;
2770 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
2772 return AVERROR(ENOMEM);
2774 for (i = 0; i < entries && !pb->eof_reached; i++) {
2775 sc->keyframes[i] = avio_rb32(pb);
2778 sc->keyframe_count = i;
2780 if (pb->eof_reached) {
2781 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
2788 static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2791 MOVStreamContext *sc;
2792 unsigned int i, entries, sample_size, field_size, num_bytes;
2797 if (c->fc->nb_streams < 1)
2799 st = c->fc->streams[c->fc->nb_streams-1];
2802 avio_r8(pb); /* version */
2803 avio_rb24(pb); /* flags */
2805 if (atom.type == MKTAG('s','t','s','z')) {
2806 sample_size = avio_rb32(pb);
2807 if (!sc->sample_size) /* do not overwrite value computed in stsd */
2808 sc->sample_size = sample_size;
2809 sc->stsz_sample_size = sample_size;
2813 avio_rb24(pb); /* reserved */
2814 field_size = avio_r8(pb);
2816 entries = avio_rb32(pb);
2818 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
2820 sc->sample_count = entries;
2824 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
2825 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
2826 return AVERROR_INVALIDDATA;
2831 if (entries >= (UINT_MAX - 4) / field_size)
2832 return AVERROR_INVALIDDATA;
2833 if (sc->sample_sizes)
2834 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
2835 av_free(sc->sample_sizes);
2836 sc->sample_count = 0;
2837 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
2838 if (!sc->sample_sizes)
2839 return AVERROR(ENOMEM);
2841 num_bytes = (entries*field_size+4)>>3;
2843 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
2845 av_freep(&sc->sample_sizes);
2846 return AVERROR(ENOMEM);
2849 ret = ffio_read_size(pb, buf, num_bytes);
2851 av_freep(&sc->sample_sizes);
2853 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
2857 init_get_bits(&gb, buf, 8*num_bytes);
2859 for (i = 0; i < entries && !pb->eof_reached; i++) {
2860 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
2861 sc->data_size += sc->sample_sizes[i];
2864 sc->sample_count = i;
2868 if (pb->eof_reached) {
2869 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSZ atom\n");
2876 static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2879 MOVStreamContext *sc;
2880 unsigned int i, entries, alloc_size = 0;
2882 int64_t total_sample_count=0;
2884 if (c->fc->nb_streams < 1)
2886 st = c->fc->streams[c->fc->nb_streams-1];
2889 avio_r8(pb); /* version */
2890 avio_rb24(pb); /* flags */
2891 entries = avio_rb32(pb);
2893 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
2894 c->fc->nb_streams-1, entries);
2897 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
2898 av_freep(&sc->stts_data);
2900 if (entries >= INT_MAX / sizeof(*sc->stts_data))
2901 return AVERROR(ENOMEM);
2903 for (i = 0; i < entries && !pb->eof_reached; i++) {
2904 int sample_duration;
2905 unsigned int sample_count;
2906 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
2907 MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
2908 min_entries * sizeof(*sc->stts_data));
2910 av_freep(&sc->stts_data);
2912 return AVERROR(ENOMEM);
2914 sc->stts_count = min_entries;
2915 sc->stts_data = stts_data;
2917 sample_count=avio_rb32(pb);
2918 sample_duration = avio_rb32(pb);
2920 sc->stts_data[i].count= sample_count;
2921 sc->stts_data[i].duration= sample_duration;
2923 av_log(c->fc, AV_LOG_TRACE, "sample_count=%d, sample_duration=%d\n",
2924 sample_count, sample_duration);
2926 duration+=(int64_t)sample_duration*(uint64_t)sample_count;
2927 total_sample_count+=sample_count;
2933 duration <= INT64_MAX - sc->duration_for_fps &&
2934 total_sample_count <= INT64_MAX - sc->nb_frames_for_fps
2936 sc->duration_for_fps += duration;
2937 sc->nb_frames_for_fps += total_sample_count;
2940 if (pb->eof_reached) {
2941 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
2945 st->nb_frames= total_sample_count;
2947 st->duration= FFMIN(st->duration, duration);
2948 sc->track_end = duration;
2952 static void mov_update_dts_shift(MOVStreamContext *sc, int duration)
2955 if (duration == INT_MIN) {
2956 av_log(NULL, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
2959 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
2963 static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2966 MOVStreamContext *sc;
2967 unsigned int i, entries, ctts_count = 0;
2969 if (c->fc->nb_streams < 1)
2971 st = c->fc->streams[c->fc->nb_streams-1];
2974 avio_r8(pb); /* version */
2975 avio_rb24(pb); /* flags */
2976 entries = avio_rb32(pb);
2978 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
2982 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
2983 return AVERROR_INVALIDDATA;
2984 av_freep(&sc->ctts_data);
2985 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
2987 return AVERROR(ENOMEM);
2989 for (i = 0; i < entries && !pb->eof_reached; i++) {
2990 int count =avio_rb32(pb);
2991 int duration =avio_rb32(pb);
2994 av_log(c->fc, AV_LOG_TRACE,
2995 "ignoring CTTS entry with count=%d duration=%d\n",
3000 add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3003 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3006 if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3007 av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3008 av_freep(&sc->ctts_data);
3014 mov_update_dts_shift(sc, duration);
3017 sc->ctts_count = ctts_count;
3019 if (pb->eof_reached) {
3020 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3024 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3029 static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3032 MOVStreamContext *sc;
3033 unsigned int i, entries;
3035 uint32_t grouping_type;
3037 if (c->fc->nb_streams < 1)
3039 st = c->fc->streams[c->fc->nb_streams-1];
3042 version = avio_r8(pb); /* version */
3043 avio_rb24(pb); /* flags */
3044 grouping_type = avio_rl32(pb);
3045 if (grouping_type != MKTAG( 'r','a','p',' '))
3046 return 0; /* only support 'rap ' grouping */
3048 avio_rb32(pb); /* grouping_type_parameter */
3050 entries = avio_rb32(pb);
3054 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP atom\n");
3055 av_free(sc->rap_group);
3056 sc->rap_group_count = 0;
3057 sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group));
3059 return AVERROR(ENOMEM);
3061 for (i = 0; i < entries && !pb->eof_reached; i++) {
3062 sc->rap_group[i].count = avio_rb32(pb); /* sample_count */
3063 sc->rap_group[i].index = avio_rb32(pb); /* group_description_index */
3066 sc->rap_group_count = i;
3068 if (pb->eof_reached) {
3069 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3077 * Get ith edit list entry (media time, duration).
3079 static int get_edit_list_entry(MOVContext *mov,
3080 const MOVStreamContext *msc,
3081 unsigned int edit_list_index,
3082 int64_t *edit_list_media_time,
3083 int64_t *edit_list_duration,
3084 int64_t global_timescale)
3086 if (edit_list_index == msc->elst_count) {
3089 *edit_list_media_time = msc->elst_data[edit_list_index].time;
3090 *edit_list_duration = msc->elst_data[edit_list_index].duration;
3092 /* duration is in global timescale units;convert to msc timescale */
3093 if (global_timescale == 0) {
3094 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3097 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3103 * Find the closest previous frame to the timestamp_pts, in e_old index
3104 * entries. Searching for just any frame / just key frames can be controlled by
3105 * last argument 'flag'.
3106 * Note that if ctts_data is not NULL, we will always search for a key frame
3107 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3108 * return the first frame of the video.
3110 * Here the timestamp_pts is considered to be a presentation timestamp and
3111 * the timestamp of index entries are considered to be decoding timestamps.
3113 * Returns 0 if successful in finding a frame, else returns -1.
3114 * Places the found index corresponding output arg.
3116 * If ctts_old is not NULL, then refines the searched entry by searching
3117 * backwards from the found timestamp, to find the frame with correct PTS.
3119 * Places the found ctts_index and ctts_sample in corresponding output args.
3121 static int find_prev_closest_index(AVStream *st,
3122 AVIndexEntry *e_old,
3126 int64_t timestamp_pts,
3129 int64_t* ctts_index,
3130 int64_t* ctts_sample)
3132 MOVStreamContext *msc = st->priv_data;
3133 AVIndexEntry *e_keep = st->index_entries;
3134 int nb_keep = st->nb_index_entries;
3136 int64_t index_ctts_count;
3140 // If dts_shift > 0, then all the index timestamps will have to be offset by
3141 // at least dts_shift amount to obtain PTS.
3142 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3143 if (msc->dts_shift > 0) {
3144 timestamp_pts -= msc->dts_shift;
3147 st->index_entries = e_old;
3148 st->nb_index_entries = nb_old;
3149 *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3151 // Keep going backwards in the index entries until the timestamp is the same.
3153 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3155 if ((flag & AVSEEK_FLAG_ANY) ||
3156 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3162 // If we have CTTS then refine the search, by searching backwards over PTS
3163 // computed by adding corresponding CTTS durations to index timestamps.
3164 if (ctts_data && *index >= 0) {
3165 av_assert0(ctts_index);
3166 av_assert0(ctts_sample);
3167 // Find out the ctts_index for the found frame.
3170 for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3171 if (*ctts_index < ctts_count) {
3173 if (ctts_data[*ctts_index].count == *ctts_sample) {
3180 while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3181 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3182 // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3183 // compensated by dts_shift above.
3184 if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3185 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3190 if (*ctts_sample == 0) {
3192 if (*ctts_index >= 0)
3193 *ctts_sample = ctts_data[*ctts_index].count - 1;
3200 /* restore AVStream state*/
3201 st->index_entries = e_keep;
3202 st->nb_index_entries = nb_keep;
3203 return *index >= 0 ? 0 : -1;
3207 * Add index entry with the given values, to the end of st->index_entries.
3208 * Returns the new size st->index_entries if successful, else returns -1.
3210 * This function is similar to ff_add_index_entry in libavformat/utils.c
3211 * except that here we are always unconditionally adding an index entry to
3212 * the end, instead of searching the entries list and skipping the add if
3213 * there is an existing entry with the same timestamp.
3214 * This is needed because the mov_fix_index calls this func with the same
3215 * unincremented timestamp for successive discarded frames.
3217 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3218 int size, int distance, int flags)
3220 AVIndexEntry *entries, *ie;
3222 const size_t min_size_needed = (st->nb_index_entries + 1) * sizeof(AVIndexEntry);
3224 // Double the allocation each time, to lower memory fragmentation.
3225 // Another difference from ff_add_index_entry function.
3226 const size_t requested_size =
3227 min_size_needed > st->index_entries_allocated_size ?
3228 FFMAX(min_size_needed, 2 * st->index_entries_allocated_size) :
3231 if((unsigned)st->nb_index_entries + 1 >= UINT_MAX / sizeof(AVIndexEntry))
3234 entries = av_fast_realloc(st->index_entries,
3235 &st->index_entries_allocated_size,
3240 st->index_entries= entries;
3242 index= st->nb_index_entries++;
3243 ie= &entries[index];
3246 ie->timestamp = timestamp;
3247 ie->min_distance= distance;
3254 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3255 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3257 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3258 int64_t* frame_duration_buffer,
3259 int frame_duration_buffer_size) {
3261 av_assert0(end_index >= 0 && end_index <= st->nb_index_entries);
3262 for (i = 0; i < frame_duration_buffer_size; i++) {
3263 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3264 st->index_entries[end_index - 1 - i].timestamp = end_ts;
3269 * Append a new ctts entry to ctts_data.
3270 * Returns the new ctts_count if successful, else returns -1.
3272 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3273 int count, int duration)
3275 MOVStts *ctts_buf_new;
3276 const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVStts);
3277 const size_t requested_size =
3278 min_size_needed > *allocated_size ?
3279 FFMAX(min_size_needed, 2 * (*allocated_size)) :
3282 if((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
3285 ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3290 *ctts_data = ctts_buf_new;
3292 ctts_buf_new[*ctts_count].count = count;
3293 ctts_buf_new[*ctts_count].duration = duration;
3295 *ctts_count = (*ctts_count) + 1;
3299 #define MAX_REORDER_DELAY 16
3300 static void mov_estimate_video_delay(MOVContext *c, AVStream* st) {
3301 MOVStreamContext *msc = st->priv_data;
3304 int ctts_sample = 0;
3305 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3307 int j, r, num_swaps;
3309 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3310 pts_buf[j] = INT64_MIN;
3312 if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3313 st->codecpar->codec_id == AV_CODEC_ID_H264) {
3314 st->codecpar->video_delay = 0;
3315 for(ind = 0; ind < st->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3316 // Point j to the last elem of the buffer and insert the current pts there.
3318 buf_start = (buf_start + 1);
3319 if (buf_start == MAX_REORDER_DELAY + 1)
3322 pts_buf[j] = st->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3324 // The timestamps that are already in the sorted buffer, and are greater than the
3325 // current pts, are exactly the timestamps that need to be buffered to output PTS
3326 // in correct sorted order.
3327 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3328 // can be computed as the maximum no. of swaps any particular timestamp needs to
3329 // go through, to keep this buffer in sorted order.
3331 while (j != buf_start) {
3333 if (r < 0) r = MAX_REORDER_DELAY;
3334 if (pts_buf[j] < pts_buf[r]) {
3335 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3342 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3345 if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3350 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3351 st->codecpar->video_delay, st->index);
3355 static void mov_current_sample_inc(MOVStreamContext *sc)
3357 sc->current_sample++;
3358 sc->current_index++;
3359 if (sc->index_ranges &&
3360 sc->current_index >= sc->current_index_range->end &&
3361 sc->current_index_range->end) {
3362 sc->current_index_range++;
3363 sc->current_index = sc->current_index_range->start;
3367 static void mov_current_sample_dec(MOVStreamContext *sc)
3369 sc->current_sample--;
3370 sc->current_index--;
3371 if (sc->index_ranges &&
3372 sc->current_index < sc->current_index_range->start &&
3373 sc->current_index_range > sc->index_ranges) {
3374 sc->current_index_range--;
3375 sc->current_index = sc->current_index_range->end - 1;
3379 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3383 sc->current_sample = current_sample;
3384 sc->current_index = current_sample;
3385 if (!sc->index_ranges) {
3389 for (sc->current_index_range = sc->index_ranges;
3390 sc->current_index_range->end;
3391 sc->current_index_range++) {
3392 range_size = sc->current_index_range->end - sc->current_index_range->start;
3393 if (range_size > current_sample) {
3394 sc->current_index = sc->current_index_range->start + current_sample;
3397 current_sample -= range_size;
3402 * Fix st->index_entries, so that it contains only the entries (and the entries
3403 * which are needed to decode them) that fall in the edit list time ranges.
3404 * Also fixes the timestamps of the index entries to match the timeline
3405 * specified the edit lists.
3407 static void mov_fix_index(MOVContext *mov, AVStream *st)
3409 MOVStreamContext *msc = st->priv_data;
3410 AVIndexEntry *e_old = st->index_entries;
3411 int nb_old = st->nb_index_entries;
3412 const AVIndexEntry *e_old_end = e_old + nb_old;
3413 const AVIndexEntry *current = NULL;
3414 MOVStts *ctts_data_old = msc->ctts_data;
3415 int64_t ctts_index_old = 0;
3416 int64_t ctts_sample_old = 0;
3417 int64_t ctts_count_old = msc->ctts_count;
3418 int64_t edit_list_media_time = 0;
3419 int64_t edit_list_duration = 0;
3420 int64_t frame_duration = 0;
3421 int64_t edit_list_dts_counter = 0;
3422 int64_t edit_list_dts_entry_end = 0;
3423 int64_t edit_list_start_ctts_sample = 0;
3425 int64_t curr_ctts = 0;
3426 int64_t empty_edits_sum_duration = 0;
3427 int64_t edit_list_index = 0;
3430 int64_t start_dts = 0;
3431 int64_t edit_list_start_encountered = 0;
3432 int64_t search_timestamp = 0;
3433 int64_t* frame_duration_buffer = NULL;
3434 int num_discarded_begin = 0;
3435 int first_non_zero_audio_edit = -1;
3436 int packet_skip_samples = 0;
3437 MOVIndexRange *current_index_range;
3439 int found_keyframe_after_edit = 0;
3441 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
3445 // allocate the index ranges array
3446 msc->index_ranges = av_malloc((msc->elst_count + 1) * sizeof(msc->index_ranges[0]));
3447 if (!msc->index_ranges) {
3448 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
3451 msc->current_index_range = msc->index_ranges;
3452 current_index_range = msc->index_ranges - 1;
3454 // Clean AVStream from traces of old index
3455 st->index_entries = NULL;
3456 st->index_entries_allocated_size = 0;
3457 st->nb_index_entries = 0;
3459 // Clean ctts fields of MOVStreamContext
3460 msc->ctts_data = NULL;
3461 msc->ctts_count = 0;
3462 msc->ctts_index = 0;
3463 msc->ctts_sample = 0;
3464 msc->ctts_allocated_size = 0;
3466 // Reinitialize min_corrected_pts so that it can be computed again.
3467 msc->min_corrected_pts = -1;
3469 // If the dts_shift is positive (in case of negative ctts values in mov),
3470 // then negate the DTS by dts_shift
3471 if (msc->dts_shift > 0) {
3472 edit_list_dts_entry_end -= msc->dts_shift;
3473 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
3476 start_dts = edit_list_dts_entry_end;
3478 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
3479 &edit_list_duration, mov->time_scale)) {
3480 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
3481 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
3483 edit_list_dts_counter = edit_list_dts_entry_end;
3484 edit_list_dts_entry_end += edit_list_duration;
3485 num_discarded_begin = 0;
3486 if (edit_list_media_time == -1) {
3487 empty_edits_sum_duration += edit_list_duration;
3491 // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
3492 // according to the edit list below.
3493 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3494 if (first_non_zero_audio_edit < 0) {
3495 first_non_zero_audio_edit = 1;
3497 first_non_zero_audio_edit = 0;
3500 if (first_non_zero_audio_edit > 0)
3501 st->skip_samples = msc->start_pad = 0;
3504 // While reordering frame index according to edit list we must handle properly
3505 // the scenario when edit list entry starts from none key frame.
3506 // We find closest previous key frame and preserve it and consequent frames in index.
3507 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
3508 search_timestamp = edit_list_media_time;
3509 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3510 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
3511 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
3512 // edit_list_media_time to cover the decoder delay.
3513 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
3516 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
3517 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3518 av_log(mov->fc, AV_LOG_WARNING,
3519 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
3520 st->index, edit_list_index, search_timestamp);
3521 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
3522 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3523 av_log(mov->fc, AV_LOG_WARNING,
3524 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
3525 st->index, edit_list_index, search_timestamp);
3528 ctts_sample_old = 0;
3531 current = e_old + index;
3532 edit_list_start_ctts_sample = ctts_sample_old;
3534 // Iterate over index and arrange it according to edit list
3535 edit_list_start_encountered = 0;
3536 found_keyframe_after_edit = 0;
3537 for (; current < e_old_end; current++, index++) {
3538 // check if frame outside edit list mark it for discard
3539 frame_duration = (current + 1 < e_old_end) ?
3540 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
3542 flags = current->flags;
3544 // frames (pts) before or after edit list
3545 curr_cts = current->timestamp + msc->dts_shift;
3548 if (ctts_data_old && ctts_index_old < ctts_count_old) {
3549 curr_ctts = ctts_data_old[ctts_index_old].duration;
3550 av_log(mov->fc, AV_LOG_DEBUG, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
3551 curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
3552 curr_cts += curr_ctts;
3554 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
3555 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3556 &msc->ctts_allocated_size,
3557 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3558 ctts_data_old[ctts_index_old].duration) == -1) {
3559 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3561 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3562 ctts_data_old[ctts_index_old].duration);
3566 ctts_sample_old = 0;
3567 edit_list_start_ctts_sample = 0;
3571 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
3572 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
3573 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
3574 first_non_zero_audio_edit > 0) {
3575 packet_skip_samples = edit_list_media_time - curr_cts;
3576 st->skip_samples += packet_skip_samples;
3578 // Shift the index entry timestamp by packet_skip_samples to be correct.
3579 edit_list_dts_counter -= packet_skip_samples;
3580 if (edit_list_start_encountered == 0) {
3581 edit_list_start_encountered = 1;
3582 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
3583 // discarded packets.
3584 if (frame_duration_buffer) {
3585 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3586 frame_duration_buffer, num_discarded_begin);
3587 av_freep(&frame_duration_buffer);
3591 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
3593 flags |= AVINDEX_DISCARD_FRAME;
3594 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
3596 if (edit_list_start_encountered == 0) {
3597 num_discarded_begin++;
3598 frame_duration_buffer = av_realloc(frame_duration_buffer,
3599 num_discarded_begin * sizeof(int64_t));
3600 if (!frame_duration_buffer) {
3601 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
3604 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
3606 // Increment skip_samples for the first non-zero audio edit list
3607 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3608 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
3609 st->skip_samples += frame_duration;
3614 if (msc->min_corrected_pts < 0) {
3615 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
3617 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
3619 if (edit_list_start_encountered == 0) {
3620 edit_list_start_encountered = 1;
3621 // Make timestamps strictly monotonically increasing by rewriting timestamps for
3622 // discarded packets.
3623 if (frame_duration_buffer) {
3624 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3625 frame_duration_buffer, num_discarded_begin);
3626 av_freep(&frame_duration_buffer);
3631 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
3632 current->min_distance, flags) == -1) {
3633 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
3637 // Update the index ranges array
3638 if (current_index_range < msc->index_ranges || index != current_index_range->end) {
3639 current_index_range++;
3640 current_index_range->start = index;
3642 current_index_range->end = index + 1;
3644 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
3645 if (edit_list_start_encountered > 0) {
3646 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
3649 // Break when found first key frame after edit entry completion
3650 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
3651 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
3652 if (ctts_data_old) {
3653 // If we have CTTS and this is the first keyframe after edit elist,
3654 // wait for one more, because there might be trailing B-frames after this I-frame
3655 // that do belong to the edit.
3656 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
3657 found_keyframe_after_edit = 1;
3660 if (ctts_sample_old != 0) {
3661 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3662 &msc->ctts_allocated_size,
3663 ctts_sample_old - edit_list_start_ctts_sample,
3664 ctts_data_old[ctts_index_old].duration) == -1) {
3665 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3666 ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
3667 ctts_data_old[ctts_index_old].duration);
3676 // If there are empty edits, then msc->min_corrected_pts might be positive
3677 // intentionally. So we subtract the sum duration of emtpy edits here.
3678 msc->min_corrected_pts -= empty_edits_sum_duration;
3680 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
3681 // dts by that amount to make the first pts zero.
3682 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
3683 if (msc->min_corrected_pts > 0) {
3684 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
3685 for (i = 0; i < st->nb_index_entries; ++i) {
3686 st->index_entries[i].timestamp -= msc->min_corrected_pts;
3690 // Start time should be equal to zero or the duration of any empty edits.
3691 st->start_time = empty_edits_sum_duration;
3693 // Update av stream length, if it ends up shorter than the track's media duration
3694 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
3695 msc->start_pad = st->skip_samples;
3697 // Free the old index and the old CTTS structures
3699 av_free(ctts_data_old);
3700 av_freep(&frame_duration_buffer);
3702 // Null terminate the index ranges array
3703 current_index_range++;
3704 current_index_range->start = 0;
3705 current_index_range->end = 0;
3706 msc->current_index = msc->index_ranges[0].start;
3709 static void mov_build_index(MOVContext *mov, AVStream *st)
3711 MOVStreamContext *sc = st->priv_data;
3712 int64_t current_offset;
3713 int64_t current_dts = 0;
3714 unsigned int stts_index = 0;
3715 unsigned int stsc_index = 0;
3716 unsigned int stss_index = 0;
3717 unsigned int stps_index = 0;
3719 uint64_t stream_size = 0;
3720 MOVStts *ctts_data_old = sc->ctts_data;
3721 unsigned int ctts_count_old = sc->ctts_count;
3723 if (sc->elst_count) {
3724 int i, edit_start_index = 0, multiple_edits = 0;
3725 int64_t empty_duration = 0; // empty duration of the first edit list entry
3726 int64_t start_time = 0; // start time of the media
3728 for (i = 0; i < sc->elst_count; i++) {
3729 const MOVElst *e = &sc->elst_data[i];
3730 if (i == 0 && e->time == -1) {
3731 /* if empty, the first entry is the start time of the stream
3732 * relative to the presentation itself */
3733 empty_duration = e->duration;
3734 edit_start_index = 1;
3735 } else if (i == edit_start_index && e->time >= 0) {
3736 start_time = e->time;
3742 if (multiple_edits && !mov->advanced_editlist)
3743 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
3744 "Use -advanced_editlist to correctly decode otherwise "
3745 "a/v desync might occur\n");
3747 /* adjust first dts according to edit list */
3748 if ((empty_duration || start_time) && mov->time_scale > 0) {
3750 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
3751 sc->time_offset = start_time - empty_duration;
3752 sc->min_corrected_pts = start_time;
3753 if (!mov->advanced_editlist)
3754 current_dts = -sc->time_offset;
3757 if (!multiple_edits && !mov->advanced_editlist &&
3758 st->codecpar->codec_id == AV_CODEC_ID_AAC && start_time > 0)
3759 sc->start_pad = start_time;
3762 /* only use old uncompressed audio chunk demuxing when stts specifies it */
3763 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3764 sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
3765 unsigned int current_sample = 0;
3766 unsigned int stts_sample = 0;
3767 unsigned int sample_size;
3768 unsigned int distance = 0;
3769 unsigned int rap_group_index = 0;
3770 unsigned int rap_group_sample = 0;
3771 int64_t last_dts = 0;
3772 int64_t dts_correction = 0;
3773 int rap_group_present = sc->rap_group_count && sc->rap_group;
3774 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
3776 current_dts -= sc->dts_shift;
3777 last_dts = current_dts;
3779 if (!sc->sample_count || st->nb_index_entries)
3781 if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
3783 if (av_reallocp_array(&st->index_entries,
3784 st->nb_index_entries + sc->sample_count,
3785 sizeof(*st->index_entries)) < 0) {
3786 st->nb_index_entries = 0;
3789 st->index_entries_allocated_size = (st->nb_index_entries + sc->sample_count) * sizeof(*st->index_entries);
3791 if (ctts_data_old) {
3792 // Expand ctts entries such that we have a 1-1 mapping with samples
3793 if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
3796 sc->ctts_allocated_size = 0;
3797 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size,
3798 sc->sample_count * sizeof(*sc->ctts_data));
3799 if (!sc->ctts_data) {
3800 av_free(ctts_data_old);
3804 memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
3806 for (i = 0; i < ctts_count_old &&
3807 sc->ctts_count < sc->sample_count; i++)
3808 for (j = 0; j < ctts_data_old[i].count &&
3809 sc->ctts_count < sc->sample_count; j++)
3810 add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
3811 &sc->ctts_allocated_size, 1,
3812 ctts_data_old[i].duration);
3813 av_free(ctts_data_old);
3816 for (i = 0; i < sc->chunk_count; i++) {
3817 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
3818 current_offset = sc->chunk_offsets[i];
3819 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3820 i + 1 == sc->stsc_data[stsc_index + 1].first)
3823 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
3824 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
3825 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
3826 sc->stsz_sample_size = sc->sample_size;
3828 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
3829 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
3830 sc->stsz_sample_size = sc->sample_size;
3833 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
3835 if (current_sample >= sc->sample_count) {
3836 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
3840 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
3842 if (stss_index + 1 < sc->keyframe_count)
3844 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
3846 if (stps_index + 1 < sc->stps_count)
3849 if (rap_group_present && rap_group_index < sc->rap_group_count) {
3850 if (sc->rap_group[rap_group_index].index > 0)
3852 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
3853 rap_group_sample = 0;
3857 if (sc->keyframe_absent
3859 && !rap_group_present
3860 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
3864 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
3865 if (sc->pseudo_stream_id == -1 ||
3866 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
3868 if (sample_size > 0x3FFFFFFF) {
3869 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
3872 e = &st->index_entries[st->nb_index_entries++];
3873 e->pos = current_offset;
3874 e->timestamp = current_dts;
3875 e->size = sample_size;
3876 e->min_distance = distance;
3877 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
3878 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
3879 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
3880 current_offset, current_dts, sample_size, distance, keyframe);
3881 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries < 100)
3882 ff_rfps_add_frame(mov->fc, st, current_dts);
3885 current_offset += sample_size;
3886 stream_size += sample_size;
3888 /* A negative sample duration is invalid based on the spec,
3889 * but some samples need it to correct the DTS. */
3890 if (sc->stts_data[stts_index].duration < 0) {
3891 av_log(mov->fc, AV_LOG_WARNING,
3892 "Invalid SampleDelta %d in STTS, at %d st:%d\n",
3893 sc->stts_data[stts_index].duration, stts_index,
3895 dts_correction += sc->stts_data[stts_index].duration - 1;
3896 sc->stts_data[stts_index].duration = 1;
3898 current_dts += sc->stts_data[stts_index].duration;
3899 if (!dts_correction || current_dts + dts_correction > last_dts) {
3900 current_dts += dts_correction;
3903 /* Avoid creating non-monotonous DTS */
3904 dts_correction += current_dts - last_dts - 1;
3905 current_dts = last_dts + 1;
3907 last_dts = current_dts;
3911 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
3917 if (st->duration > 0)
3918 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
3920 unsigned chunk_samples, total = 0;
3922 if (!sc->chunk_count)
3925 // compute total chunk count
3926 for (i = 0; i < sc->stsc_count; i++) {
3927 unsigned count, chunk_count;
3929 chunk_samples = sc->stsc_data[i].count;
3930 if (i != sc->stsc_count - 1 &&
3931 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
3932 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
3936 if (sc->samples_per_frame >= 160) { // gsm
3937 count = chunk_samples / sc->samples_per_frame;
3938 } else if (sc->samples_per_frame > 1) {
3939 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
3940 count = (chunk_samples+samples-1) / samples;
3942 count = (chunk_samples+1023) / 1024;
3945 if (mov_stsc_index_valid(i, sc->stsc_count))
3946 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
3948 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
3949 total += chunk_count * count;
3952 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
3953 if (total >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
3955 if (av_reallocp_array(&st->index_entries,
3956 st->nb_index_entries + total,
3957 sizeof(*st->index_entries)) < 0) {
3958 st->nb_index_entries = 0;
3961 st->index_entries_allocated_size = (st->nb_index_entries + total) * sizeof(*st->index_entries);
3964 for (i = 0; i < sc->chunk_count; i++) {
3965 current_offset = sc->chunk_offsets[i];
3966 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3967 i + 1 == sc->stsc_data[stsc_index + 1].first)
3969 chunk_samples = sc->stsc_data[stsc_index].count;
3971 while (chunk_samples > 0) {
3973 unsigned size, samples;
3975 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
3976 avpriv_request_sample(mov->fc,
3977 "Zero bytes per frame, but %d samples per frame",
3978 sc->samples_per_frame);
3982 if (sc->samples_per_frame >= 160) { // gsm
3983 samples = sc->samples_per_frame;
3984 size = sc->bytes_per_frame;
3986 if (sc->samples_per_frame > 1) {
3987 samples = FFMIN((1024 / sc->samples_per_frame)*
3988 sc->samples_per_frame, chunk_samples);
3989 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
3991 samples = FFMIN(1024, chunk_samples);
3992 size = samples * sc->sample_size;
3996 if (st->nb_index_entries >= total) {
3997 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4000 if (size > 0x3FFFFFFF) {
4001 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4004 e = &st->index_entries[st->nb_index_entries++];
4005 e->pos = current_offset;
4006 e->timestamp = current_dts;
4008 e->min_distance = 0;
4009 e->flags = AVINDEX_KEYFRAME;
4010 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4011 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4014 current_offset += size;
4015 current_dts += samples;
4016 chunk_samples -= samples;
4021 if (!mov->ignore_editlist && mov->advanced_editlist) {
4022 // Fix index according to edit lists.
4023 mov_fix_index(mov, st);
4026 // Update start time of the stream.
4027 if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries > 0) {
4028 st->start_time = st->index_entries[0].timestamp + sc->dts_shift;
4029 if (sc->ctts_data) {
4030 st->start_time += sc->ctts_data[0].duration;
4034 mov_estimate_video_delay(mov, st);
4037 static int test_same_origin(const char *src, const char *ref) {
4047 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4048 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4050 if (strlen(src) == 0) {
4052 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4053 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4054 strlen(src_host) + 1 >= sizeof(src_host) ||
4055 strlen(ref_host) + 1 >= sizeof(ref_host)) {
4057 } else if (strcmp(src_proto, ref_proto) ||
4058 strcmp(src_auth, ref_auth) ||
4059 strcmp(src_host, ref_host) ||
4060 src_port != ref_port) {
4066 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4068 /* try relative path, we do not try the absolute because it can leak information about our
4069 system to an attacker */
4070 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4071 char filename[1025];
4072 const char *src_path;
4075 /* find a source dir */
4076 src_path = strrchr(src, '/');
4082 /* find a next level down to target */
4083 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4084 if (ref->path[l] == '/') {
4085 if (i == ref->nlvl_to - 1)
4091 /* compose filename if next level down to target was found */
4092 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4093 memcpy(filename, src, src_path - src);
4094 filename[src_path - src] = 0;
4096 for (i = 1; i < ref->nlvl_from; i++)
4097 av_strlcat(filename, "../", sizeof(filename));
4099 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4100 if (!c->use_absolute_path) {
4101 int same_origin = test_same_origin(src, filename);
4104 av_log(c->fc, AV_LOG_ERROR,
4105 "Reference with mismatching origin, %s not tried for security reasons, "
4106 "set demuxer option use_absolute_path to allow it anyway\n",
4108 return AVERROR(ENOENT);
4111 if(strstr(ref->path + l + 1, "..") ||
4112 strstr(ref->path + l + 1, ":") ||
4113 (ref->nlvl_from > 1 && same_origin < 0) ||
4114 (filename[0] == '/' && src_path == src))
4115 return AVERROR(ENOENT);
4118 if (strlen(filename) + 1 == sizeof(filename))
4119 return AVERROR(ENOENT);
4120 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4123 } else if (c->use_absolute_path) {
4124 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4125 "this is a possible security issue\n");
4126 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4129 av_log(c->fc, AV_LOG_ERROR,
4130 "Absolute path %s not tried for security reasons, "
4131 "set demuxer option use_absolute_path to allow absolute paths\n",
4135 return AVERROR(ENOENT);
4138 static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
4140 if (sc->time_scale <= 0) {
4141 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4142 sc->time_scale = c->time_scale;
4143 if (sc->time_scale <= 0)
4148 static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4151 MOVStreamContext *sc;
4154 st = avformat_new_stream(c->fc, NULL);
4155 if (!st) return AVERROR(ENOMEM);
4157 sc = av_mallocz(sizeof(MOVStreamContext));
4158 if (!sc) return AVERROR(ENOMEM);
4161 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
4162 sc->ffindex = st->index;
4163 c->trak_index = st->index;
4165 if ((ret = mov_read_default(c, pb, atom)) < 0)
4171 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4172 (!sc->sample_size && !sc->sample_count))) ||
4173 (!sc->chunk_count && sc->sample_count)) {
4174 av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4178 if (sc->chunk_count && sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4179 av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4181 return AVERROR_INVALIDDATA;
4184 fix_timescale(c, sc);
4186 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4188 mov_build_index(c, st);
4190 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4191 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4192 if (c->enable_drefs) {
4193 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4194 av_log(c->fc, AV_LOG_ERROR,
4195 "stream %d, error opening alias: path='%s', dir='%s', "
4196 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4197 st->index, dref->path, dref->dir, dref->filename,
4198 dref->volume, dref->nlvl_from, dref->nlvl_to);
4200 av_log(c->fc, AV_LOG_WARNING,
4201 "Skipped opening external track: "
4202 "stream %d, alias: path='%s', dir='%s', "
4203 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4204 "Set enable_drefs to allow this.\n",
4205 st->index, dref->path, dref->dir, dref->filename,
4206 dref->volume, dref->nlvl_from, dref->nlvl_to);
4210 sc->pb_is_copied = 1;
4213 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4214 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4215 sc->height && sc->width &&
4216 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4217 st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4218 ((double)st->codecpar->width * sc->height), INT_MAX);
4221 #if FF_API_R_FRAME_RATE
4222 if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4223 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
4224 sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4228 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4229 if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4230 TAG_IS_AVCI(st->codecpar->codec_tag)) {
4231 ret = ff_generate_avci_extradata(st);
4236 switch (st->codecpar->codec_id) {
4237 #if CONFIG_H261_DECODER
4238 case AV_CODEC_ID_H261:
4240 #if CONFIG_H263_DECODER
4241 case AV_CODEC_ID_H263:
4243 #if CONFIG_MPEG4_DECODER
4244 case AV_CODEC_ID_MPEG4:
4246 st->codecpar->width = 0; /* let decoder init width/height */
4247 st->codecpar->height= 0;
4251 // If the duration of the mp3 packets is not constant, then they could need a parser
4252 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4253 && sc->stts_count > 3
4254 && sc->stts_count*10 > st->nb_frames
4255 && sc->time_scale == st->codecpar->sample_rate) {
4256 st->need_parsing = AVSTREAM_PARSE_FULL;
4258 /* Do not need those anymore. */
4259 av_freep(&sc->chunk_offsets);
4260 av_freep(&sc->sample_sizes);
4261 av_freep(&sc->keyframes);
4262 av_freep(&sc->stts_data);
4263 av_freep(&sc->stps_data);
4264 av_freep(&sc->elst_data);
4265 av_freep(&sc->rap_group);
4270 static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4273 c->itunes_metadata = 1;
4274 ret = mov_read_default(c, pb, atom);
4275 c->itunes_metadata = 0;
4279 static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4288 count = avio_rb32(pb);
4289 if (count > UINT_MAX / sizeof(*c->meta_keys) - 1) {
4290 av_log(c->fc, AV_LOG_ERROR,
4291 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
4292 return AVERROR_INVALIDDATA;
4295 c->meta_keys_count = count + 1;
4296 c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
4298 return AVERROR(ENOMEM);
4300 for (i = 1; i <= count; ++i) {
4301 uint32_t key_size = avio_rb32(pb);
4302 uint32_t type = avio_rl32(pb);
4304 av_log(c->fc, AV_LOG_ERROR,
4305 "The key# %"PRIu32" in meta has invalid size:"
4306 "%"PRIu32"\n", i, key_size);
4307 return AVERROR_INVALIDDATA;
4310 if (type != MKTAG('m','d','t','a')) {
4311 avio_skip(pb, key_size);
4313 c->meta_keys[i] = av_mallocz(key_size + 1);
4314 if (!c->meta_keys[i])
4315 return AVERROR(ENOMEM);
4316 avio_read(pb, c->meta_keys[i], key_size);
4322 static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4324 int64_t end = avio_tell(pb) + atom.size;
4325 uint8_t *key = NULL, *val = NULL, *mean = NULL;
4329 MOVStreamContext *sc;
4331 if (c->fc->nb_streams < 1)
4333 st = c->fc->streams[c->fc->nb_streams-1];
4336 for (i = 0; i < 3; i++) {
4340 if (end - avio_tell(pb) <= 12)
4343 len = avio_rb32(pb);
4344 tag = avio_rl32(pb);
4345 avio_skip(pb, 4); // flags
4347 if (len < 12 || len - 12 > end - avio_tell(pb))
4351 if (tag == MKTAG('m', 'e', 'a', 'n'))
4353 else if (tag == MKTAG('n', 'a', 'm', 'e'))
4355 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
4362 *p = av_malloc(len + 1);
4364 ret = AVERROR(ENOMEM);
4367 ret = ffio_read_size(pb, *p, len);
4375 if (mean && key && val) {
4376 if (strcmp(key, "iTunSMPB") == 0) {
4377 int priming, remainder, samples;
4378 if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
4379 if(priming>0 && priming<16384)
4380 sc->start_pad = priming;
4383 if (strcmp(key, "cdec") != 0) {
4384 av_dict_set(&c->fc->metadata, key, val,
4385 AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
4389 av_log(c->fc, AV_LOG_VERBOSE,
4390 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
4393 avio_seek(pb, end, SEEK_SET);
4400 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4402 while (atom.size > 8) {
4403 uint32_t tag = avio_rl32(pb);
4405 if (tag == MKTAG('h','d','l','r')) {
4406 avio_seek(pb, -8, SEEK_CUR);
4408 return mov_read_default(c, pb, atom);
4414 // return 1 when matrix is identity, 0 otherwise
4415 #define IS_MATRIX_IDENT(matrix) \
4416 ( (matrix)[0][0] == (1 << 16) && \
4417 (matrix)[1][1] == (1 << 16) && \
4418 (matrix)[2][2] == (1 << 30) && \
4419 !(matrix)[0][1] && !(matrix)[0][2] && \
4420 !(matrix)[1][0] && !(matrix)[1][2] && \
4421 !(matrix)[2][0] && !(matrix)[2][1])
4423 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4428 int display_matrix[3][3];
4429 int res_display_matrix[3][3] = { { 0 } };
4431 MOVStreamContext *sc;
4435 if (c->fc->nb_streams < 1)
4437 st = c->fc->streams[c->fc->nb_streams-1];
4440 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4441 // avoids corrupting AVStreams mapped to an earlier tkhd.
4443 return AVERROR_INVALIDDATA;
4445 version = avio_r8(pb);
4446 flags = avio_rb24(pb);
4447 st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
4453 avio_rb32(pb); /* creation time */
4454 avio_rb32(pb); /* modification time */
4456 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4457 avio_rb32(pb); /* reserved */
4459 /* highlevel (considering edits) duration in movie timebase */
4460 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4461 avio_rb32(pb); /* reserved */
4462 avio_rb32(pb); /* reserved */
4464 avio_rb16(pb); /* layer */
4465 avio_rb16(pb); /* alternate group */
4466 avio_rb16(pb); /* volume */
4467 avio_rb16(pb); /* reserved */
4469 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4470 // they're kept in fixed point format through all calculations
4471 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4472 // side data, but the scale factor is not needed to calculate aspect ratio
4473 for (i = 0; i < 3; i++) {
4474 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
4475 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
4476 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
4479 width = avio_rb32(pb); // 16.16 fixed point track width
4480 height = avio_rb32(pb); // 16.16 fixed point track height
4481 sc->width = width >> 16;
4482 sc->height = height >> 16;
4484 // apply the moov display matrix (after the tkhd one)
4485 for (i = 0; i < 3; i++) {
4486 const int sh[3] = { 16, 16, 30 };
4487 for (j = 0; j < 3; j++) {
4488 for (e = 0; e < 3; e++) {
4489 res_display_matrix[i][j] +=
4490 ((int64_t) display_matrix[i][e] *
4491 c->movie_display_matrix[e][j]) >> sh[e];
4496 // save the matrix when it is not the default identity
4497 if (!IS_MATRIX_IDENT(res_display_matrix)) {
4500 av_freep(&sc->display_matrix);
4501 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4502 if (!sc->display_matrix)
4503 return AVERROR(ENOMEM);
4505 for (i = 0; i < 3; i++)
4506 for (j = 0; j < 3; j++)
4507 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4509 #if FF_API_OLD_ROTATE_API
4510 rotate = av_display_rotation_get(sc->display_matrix);
4511 if (!isnan(rotate)) {
4512 char rotate_buf[64];
4514 if (rotate < 0) // for backward compatibility
4516 snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate);
4517 av_dict_set(&st->metadata, "rotate", rotate_buf, 0);
4522 // transform the display width/height according to the matrix
4523 // to keep the same scale, use [width height 1<<16]
4524 if (width && height && sc->display_matrix) {
4525 double disp_transform[2];
4527 for (i = 0; i < 2; i++)
4528 disp_transform[i] = hypot(sc->display_matrix[0 + i],
4529 sc->display_matrix[3 + i]);
4531 if (disp_transform[0] > 0 && disp_transform[1] > 0 &&
4532 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4533 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4534 st->sample_aspect_ratio = av_d2q(
4535 disp_transform[0] / disp_transform[1],
4541 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4543 MOVFragment *frag = &c->fragment;
4544 MOVTrackExt *trex = NULL;
4545 int flags, track_id, i;
4547 avio_r8(pb); /* version */
4548 flags = avio_rb24(pb);
4550 track_id = avio_rb32(pb);
4552 return AVERROR_INVALIDDATA;
4553 for (i = 0; i < c->trex_count; i++)
4554 if (c->trex_data[i].track_id == track_id) {
4555 trex = &c->trex_data[i];
4559 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4562 frag->track_id = track_id;
4563 set_frag_stream(&c->frag_index, track_id);
4565 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4566 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4567 frag->moof_offset : frag->implicit_offset;
4568 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4570 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4571 avio_rb32(pb) : trex->duration;
4572 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4573 avio_rb32(pb) : trex->size;
4574 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4575 avio_rb32(pb) : trex->flags;
4576 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4581 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4586 num = atom.size / 4;
4587 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4588 return AVERROR(ENOMEM);
4590 av_free(c->chapter_tracks);
4591 c->chapter_tracks = new_tracks;
4592 c->nb_chapter_tracks = num;
4594 for (i = 0; i < num && !pb->eof_reached; i++)
4595 c->chapter_tracks[i] = avio_rb32(pb);
4600 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4605 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4606 return AVERROR_INVALIDDATA;
4607 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4608 sizeof(*c->trex_data))) < 0) {
4613 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4615 trex = &c->trex_data[c->trex_count++];
4616 avio_r8(pb); /* version */
4617 avio_rb24(pb); /* flags */
4618 trex->track_id = avio_rb32(pb);
4619 trex->stsd_id = avio_rb32(pb);
4620 trex->duration = avio_rb32(pb);
4621 trex->size = avio_rb32(pb);
4622 trex->flags = avio_rb32(pb);
4626 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4628 MOVFragment *frag = &c->fragment;
4629 AVStream *st = NULL;
4630 MOVStreamContext *sc;
4632 MOVFragmentStreamInfo * frag_stream_info;
4633 int64_t base_media_decode_time;
4635 for (i = 0; i < c->fc->nb_streams; i++) {
4636 if (c->fc->streams[i]->id == frag->track_id) {
4637 st = c->fc->streams[i];
4642 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4646 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4648 version = avio_r8(pb);
4649 avio_rb24(pb); /* flags */
4651 base_media_decode_time = avio_rb64(pb);
4653 base_media_decode_time = avio_rb32(pb);
4656 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4657 if (frag_stream_info)
4658 frag_stream_info->tfdt_dts = base_media_decode_time;
4659 sc->track_end = base_media_decode_time;
4664 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4666 MOVFragment *frag = &c->fragment;
4667 AVStream *st = NULL;
4668 MOVStreamContext *sc;
4671 int64_t dts, pts = AV_NOPTS_VALUE;
4672 int data_offset = 0;
4673 unsigned entries, first_sample_flags = frag->flags;
4674 int flags, distance, i;
4675 int64_t prev_dts = AV_NOPTS_VALUE;
4676 int next_frag_index = -1, index_entry_pos;
4677 size_t requested_size;
4678 size_t old_ctts_allocated_size;
4679 AVIndexEntry *new_entries;
4680 MOVFragmentStreamInfo * frag_stream_info;
4682 for (i = 0; i < c->fc->nb_streams; i++) {
4683 if (c->fc->streams[i]->id == frag->track_id) {
4684 st = c->fc->streams[i];
4689 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4693 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4696 // Find the next frag_index index that has a valid index_entry for
4697 // the current track_id.
4699 // A valid index_entry means the trun for the fragment was read
4700 // and it's samples are in index_entries at the given position.
4701 // New index entries will be inserted before the index_entry found.
4702 index_entry_pos = st->nb_index_entries;
4703 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4704 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4705 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4706 next_frag_index = i;
4707 index_entry_pos = frag_stream_info->index_entry;
4711 av_assert0(index_entry_pos <= st->nb_index_entries);
4713 avio_r8(pb); /* version */
4714 flags = avio_rb24(pb);
4715 entries = avio_rb32(pb);
4716 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4718 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4719 return AVERROR_INVALIDDATA;
4720 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4721 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4723 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4724 if (frag_stream_info)
4726 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4727 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4728 pts = frag_stream_info->first_tfra_pts;
4729 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4730 ", using it for pts\n", pts);
4731 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4732 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4733 // pts = frag_stream_info->sidx_pts;
4734 dts = frag_stream_info->sidx_pts - sc->time_offset;
4735 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4736 ", using it for pts\n", pts);
4737 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4738 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4739 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4740 ", using it for dts\n", dts);
4742 dts = sc->track_end - sc->time_offset;
4743 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4744 ", using it for dts\n", dts);
4747 dts = sc->track_end - sc->time_offset;
4748 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4749 ", using it for dts\n", dts);
4751 offset = frag->base_data_offset + data_offset;
4753 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4755 // realloc space for new index entries
4756 if((unsigned)st->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4757 entries = UINT_MAX / sizeof(AVIndexEntry) - st->nb_index_entries;
4758 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4763 requested_size = (st->nb_index_entries + entries) * sizeof(AVIndexEntry);
4764 new_entries = av_fast_realloc(st->index_entries,
4765 &st->index_entries_allocated_size,
4768 return AVERROR(ENOMEM);
4769 st->index_entries= new_entries;
4771 requested_size = (st->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4772 old_ctts_allocated_size = sc->ctts_allocated_size;
4773 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4776 return AVERROR(ENOMEM);
4777 sc->ctts_data = ctts_data;
4779 // In case there were samples without ctts entries, ensure they get
4780 // zero valued entries. This ensures clips which mix boxes with and
4781 // without ctts entries don't pickup uninitialized data.
4782 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4783 sc->ctts_allocated_size - old_ctts_allocated_size);
4785 if (index_entry_pos < st->nb_index_entries) {
4786 // Make hole in index_entries and ctts_data for new samples
4787 memmove(st->index_entries + index_entry_pos + entries,
4788 st->index_entries + index_entry_pos,
4789 sizeof(*st->index_entries) *
4790 (st->nb_index_entries - index_entry_pos));
4791 memmove(sc->ctts_data + index_entry_pos + entries,
4792 sc->ctts_data + index_entry_pos,
4793 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4794 if (index_entry_pos < sc->current_sample) {
4795 sc->current_sample += entries;
4799 st->nb_index_entries += entries;
4800 sc->ctts_count = st->nb_index_entries;
4802 // Record the index_entry position in frag_index of this fragment
4803 if (frag_stream_info)
4804 frag_stream_info->index_entry = index_entry_pos;
4806 if (index_entry_pos > 0)
4807 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4809 for (i = 0; i < entries && !pb->eof_reached; i++) {
4810 unsigned sample_size = frag->size;
4811 int sample_flags = i ? frag->flags : first_sample_flags;
4812 unsigned sample_duration = frag->duration;
4813 unsigned ctts_duration = 0;
4815 int index_entry_flags = 0;
4817 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4818 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4819 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4820 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4822 mov_update_dts_shift(sc, ctts_duration);
4823 if (pts != AV_NOPTS_VALUE) {
4824 dts = pts - sc->dts_shift;
4825 if (flags & MOV_TRUN_SAMPLE_CTS) {
4826 dts -= ctts_duration;
4828 dts -= sc->time_offset;
4830 av_log(c->fc, AV_LOG_DEBUG,
4831 "pts %"PRId64" calculated dts %"PRId64
4832 " sc->dts_shift %d ctts.duration %d"
4833 " sc->time_offset %"PRId64
4834 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4836 sc->dts_shift, ctts_duration,
4837 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4838 pts = AV_NOPTS_VALUE;
4841 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4845 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4846 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4849 index_entry_flags |= AVINDEX_KEYFRAME;
4851 // Fragments can overlap in time. Discard overlapping frames after
4853 if (prev_dts >= dts)
4854 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4856 st->index_entries[index_entry_pos].pos = offset;
4857 st->index_entries[index_entry_pos].timestamp = dts;
4858 st->index_entries[index_entry_pos].size= sample_size;
4859 st->index_entries[index_entry_pos].min_distance= distance;
4860 st->index_entries[index_entry_pos].flags = index_entry_flags;
4862 sc->ctts_data[index_entry_pos].count = 1;
4863 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4866 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4867 "size %u, distance %d, keyframe %d\n", st->index,
4868 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4870 dts += sample_duration;
4871 offset += sample_size;
4872 sc->data_size += sample_size;
4874 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4875 1 <= INT64_MAX - sc->nb_frames_for_fps
4877 sc->duration_for_fps += sample_duration;
4878 sc->nb_frames_for_fps ++;
4882 // EOF found before reading all entries. Fix the hole this would
4883 // leave in index_entries and ctts_data
4884 int gap = entries - i;
4885 memmove(st->index_entries + index_entry_pos,
4886 st->index_entries + index_entry_pos + gap,
4887 sizeof(*st->index_entries) *
4888 (st->nb_index_entries - (index_entry_pos + gap)));
4889 memmove(sc->ctts_data + index_entry_pos,
4890 sc->ctts_data + index_entry_pos + gap,
4891 sizeof(*sc->ctts_data) *
4892 (sc->ctts_count - (index_entry_pos + gap)));
4894 st->nb_index_entries -= gap;
4895 sc->ctts_count -= gap;
4896 if (index_entry_pos < sc->current_sample) {
4897 sc->current_sample -= gap;
4902 // The end of this new fragment may overlap in time with the start
4903 // of the next fragment in index_entries. Mark the samples in the next
4904 // fragment that overlap with AVINDEX_DISCARD_FRAME
4905 prev_dts = AV_NOPTS_VALUE;
4906 if (index_entry_pos > 0)
4907 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4908 for (i = index_entry_pos; i < st->nb_index_entries; i++) {
4909 if (prev_dts < st->index_entries[i].timestamp)
4911 st->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
4914 // If a hole was created to insert the new index_entries into,
4915 // the index_entry recorded for all subsequent moof must
4916 // be incremented by the number of entries inserted.
4917 fix_frag_index_entries(&c->frag_index, next_frag_index,
4918 frag->track_id, entries);
4920 if (pb->eof_reached) {
4921 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
4925 frag->implicit_offset = offset;
4927 sc->track_end = dts + sc->time_offset;
4928 if (st->duration < sc->track_end)
4929 st->duration = sc->track_end;
4934 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4936 int64_t offset = avio_tell(pb) + atom.size, pts, timestamp;
4938 unsigned i, j, track_id, item_count;
4939 AVStream *st = NULL;
4940 AVStream *ref_st = NULL;
4941 MOVStreamContext *sc, *ref_sc = NULL;
4942 AVRational timescale;
4944 version = avio_r8(pb);
4946 avpriv_request_sample(c->fc, "sidx version %u", version);
4950 avio_rb24(pb); // flags
4952 track_id = avio_rb32(pb); // Reference ID
4953 for (i = 0; i < c->fc->nb_streams; i++) {
4954 if (c->fc->streams[i]->id == track_id) {
4955 st = c->fc->streams[i];
4960 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
4966 timescale = av_make_q(1, avio_rb32(pb));
4968 if (timescale.den <= 0) {
4969 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
4970 return AVERROR_INVALIDDATA;
4974 pts = avio_rb32(pb);
4975 offset += avio_rb32(pb);
4977 pts = avio_rb64(pb);
4978 offset += avio_rb64(pb);
4981 avio_rb16(pb); // reserved
4983 item_count = avio_rb16(pb);
4985 for (i = 0; i < item_count; i++) {
4987 MOVFragmentStreamInfo * frag_stream_info;
4988 uint32_t size = avio_rb32(pb);
4989 uint32_t duration = avio_rb32(pb);
4990 if (size & 0x80000000) {
4991 avpriv_request_sample(c->fc, "sidx reference_type 1");
4992 return AVERROR_PATCHWELCOME;
4994 avio_rb32(pb); // sap_flags
4995 timestamp = av_rescale_q(pts, st->time_base, timescale);
4997 index = update_frag_index(c, offset);
4998 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
4999 if (frag_stream_info)
5000 frag_stream_info->sidx_pts = timestamp;
5006 st->duration = sc->track_end = pts;
5010 if (offset == avio_size(pb)) {
5011 // Find first entry in fragment index that came from an sidx.
5012 // This will pretty much always be the first entry.
5013 for (i = 0; i < c->frag_index.nb_items; i++) {
5014 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5015 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5016 MOVFragmentStreamInfo * si;
5017 si = &item->stream_info[j];
5018 if (si->sidx_pts != AV_NOPTS_VALUE) {
5019 ref_st = c->fc->streams[j];
5020 ref_sc = ref_st->priv_data;
5025 for (i = 0; i < c->fc->nb_streams; i++) {
5026 st = c->fc->streams[i];
5028 if (!sc->has_sidx) {
5029 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5033 c->frag_index.complete = 1;
5039 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5040 /* like the files created with Adobe Premiere 5.0, for samples see */
5041 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5042 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5047 return 0; /* continue */
5048 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5049 avio_skip(pb, atom.size - 4);
5052 atom.type = avio_rl32(pb);
5054 if (atom.type != MKTAG('m','d','a','t')) {
5055 avio_skip(pb, atom.size);
5058 err = mov_read_mdat(c, pb, atom);
5062 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5067 uint8_t *moov_data; /* uncompressed data */
5068 long cmov_len, moov_len;
5071 avio_rb32(pb); /* dcom atom */
5072 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5073 return AVERROR_INVALIDDATA;
5074 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5075 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5076 return AVERROR_INVALIDDATA;
5078 avio_rb32(pb); /* cmvd atom */
5079 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5080 return AVERROR_INVALIDDATA;
5081 moov_len = avio_rb32(pb); /* uncompressed size */
5082 cmov_len = atom.size - 6 * 4;
5084 cmov_data = av_malloc(cmov_len);
5086 return AVERROR(ENOMEM);
5087 moov_data = av_malloc(moov_len);
5090 return AVERROR(ENOMEM);
5092 ret = ffio_read_size(pb, cmov_data, cmov_len);
5094 goto free_and_return;
5096 ret = AVERROR_INVALIDDATA;
5097 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5098 goto free_and_return;
5099 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5100 goto free_and_return;
5101 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5102 atom.type = MKTAG('m','o','o','v');
5103 atom.size = moov_len;
5104 ret = mov_read_default(c, &ctx, atom);
5110 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5111 return AVERROR(ENOSYS);
5115 /* edit list atom */
5116 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5118 MOVStreamContext *sc;
5119 int i, edit_count, version;
5120 int64_t elst_entry_size;
5122 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5124 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5126 version = avio_r8(pb); /* version */
5127 avio_rb24(pb); /* flags */
5128 edit_count = avio_rb32(pb); /* entries */
5131 elst_entry_size = version == 1 ? 20 : 12;
5132 if (atom.size != edit_count * elst_entry_size) {
5133 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5134 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5135 edit_count, atom.size + 8);
5136 return AVERROR_INVALIDDATA;
5138 edit_count = atom.size / elst_entry_size;
5139 if (edit_count * elst_entry_size != atom.size) {
5140 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.", atom.size, edit_count);
5148 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5149 av_free(sc->elst_data);
5151 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5153 return AVERROR(ENOMEM);
5155 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5156 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5157 MOVElst *e = &sc->elst_data[i];
5160 e->duration = avio_rb64(pb);
5161 e->time = avio_rb64(pb);
5164 e->duration = avio_rb32(pb); /* segment duration */
5165 e->time = (int32_t)avio_rb32(pb); /* media time */
5168 e->rate = avio_rb32(pb) / 65536.0;
5170 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5171 e->duration, e->time, e->rate);
5173 if (e->time < 0 && e->time != -1 &&
5174 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5175 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5176 c->fc->nb_streams-1, i, e->time);
5177 return AVERROR_INVALIDDATA;
5185 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5187 MOVStreamContext *sc;
5189 if (c->fc->nb_streams < 1)
5190 return AVERROR_INVALIDDATA;
5191 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5192 sc->timecode_track = avio_rb32(pb);
5196 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5201 if (c->fc->nb_streams < 1)
5203 st = c->fc->streams[c->fc->nb_streams - 1];
5205 if (atom.size < 4) {
5206 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5207 return AVERROR_INVALIDDATA;
5210 /* For now, propagate only the OBUs, if any. Once libavcodec is
5211 updated to handle isobmff style extradata this can be removed. */
5217 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5224 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5227 int version, color_range, color_primaries, color_trc, color_space;
5229 if (c->fc->nb_streams < 1)
5231 st = c->fc->streams[c->fc->nb_streams - 1];
5233 if (atom.size < 5) {
5234 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5235 return AVERROR_INVALIDDATA;
5238 version = avio_r8(pb);
5240 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5243 avio_skip(pb, 3); /* flags */
5245 avio_skip(pb, 2); /* profile + level */
5246 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5247 color_primaries = avio_r8(pb);
5248 color_trc = avio_r8(pb);
5249 color_space = avio_r8(pb);
5250 if (avio_rb16(pb)) /* codecIntializationDataSize */
5251 return AVERROR_INVALIDDATA;
5253 if (!av_color_primaries_name(color_primaries))
5254 color_primaries = AVCOL_PRI_UNSPECIFIED;
5255 if (!av_color_transfer_name(color_trc))
5256 color_trc = AVCOL_TRC_UNSPECIFIED;
5257 if (!av_color_space_name(color_space))
5258 color_space = AVCOL_SPC_UNSPECIFIED;
5260 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5261 st->codecpar->color_primaries = color_primaries;
5262 st->codecpar->color_trc = color_trc;
5263 st->codecpar->color_space = color_space;
5268 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5270 MOVStreamContext *sc;
5271 const int chroma_den = 50000;
5272 const int luma_den = 10000;
5275 if (c->fc->nb_streams < 1)
5276 return AVERROR_INVALIDDATA;
5278 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5280 if (atom.size < 5) {
5281 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5282 return AVERROR_INVALIDDATA;
5285 version = avio_r8(pb);
5287 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5290 avio_skip(pb, 3); /* flags */
5292 sc->mastering = av_mastering_display_metadata_alloc();
5294 return AVERROR(ENOMEM);
5296 for (i = 0; i < 3; i++)
5297 for (j = 0; j < 2; j++)
5298 sc->mastering->display_primaries[i][j] =
5299 av_make_q(lrint(((double)avio_rb16(pb) / (1 << 16)) * chroma_den), chroma_den);
5300 for (i = 0; i < 2; i++)
5301 sc->mastering->white_point[i] =
5302 av_make_q(lrint(((double)avio_rb16(pb) / (1 << 16)) * chroma_den), chroma_den);
5303 sc->mastering->max_luminance =
5304 av_make_q(lrint(((double)avio_rb32(pb) / (1 << 8)) * luma_den), luma_den);
5305 sc->mastering->min_luminance =
5306 av_make_q(lrint(((double)avio_rb32(pb) / (1 << 14)) * luma_den), luma_den);
5308 sc->mastering->has_primaries = 1;
5309 sc->mastering->has_luminance = 1;
5314 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5316 MOVStreamContext *sc;
5317 const int mapping[3] = {1, 2, 0};
5318 const int chroma_den = 50000;
5319 const int luma_den = 10000;
5322 if (c->fc->nb_streams < 1)
5323 return AVERROR_INVALIDDATA;
5325 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5327 if (atom.size < 24) {
5328 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5329 return AVERROR_INVALIDDATA;
5332 sc->mastering = av_mastering_display_metadata_alloc();
5334 return AVERROR(ENOMEM);
5336 for (i = 0; i < 3; i++) {
5337 const int j = mapping[i];
5338 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5339 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5341 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5342 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5344 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5345 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5347 sc->mastering->has_luminance = 1;
5348 sc->mastering->has_primaries = 1;
5353 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5355 MOVStreamContext *sc;
5358 if (c->fc->nb_streams < 1)
5359 return AVERROR_INVALIDDATA;
5361 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5363 if (atom.size < 5) {
5364 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5365 return AVERROR_INVALIDDATA;
5368 version = avio_r8(pb);
5370 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5373 avio_skip(pb, 3); /* flags */
5375 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5377 return AVERROR(ENOMEM);
5379 sc->coll->MaxCLL = avio_rb16(pb);
5380 sc->coll->MaxFALL = avio_rb16(pb);
5385 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5387 MOVStreamContext *sc;
5389 if (c->fc->nb_streams < 1)
5390 return AVERROR_INVALIDDATA;
5392 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5394 if (atom.size < 4) {
5395 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5396 return AVERROR_INVALIDDATA;
5399 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5401 return AVERROR(ENOMEM);
5403 sc->coll->MaxCLL = avio_rb16(pb);
5404 sc->coll->MaxFALL = avio_rb16(pb);
5409 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5412 MOVStreamContext *sc;
5413 enum AVStereo3DType type;
5416 if (c->fc->nb_streams < 1)
5419 st = c->fc->streams[c->fc->nb_streams - 1];
5422 if (atom.size < 5) {
5423 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5424 return AVERROR_INVALIDDATA;
5426 avio_skip(pb, 4); /* version + flags */
5431 type = AV_STEREO3D_2D;
5434 type = AV_STEREO3D_TOPBOTTOM;
5437 type = AV_STEREO3D_SIDEBYSIDE;
5440 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5444 sc->stereo3d = av_stereo3d_alloc();
5446 return AVERROR(ENOMEM);
5448 sc->stereo3d->type = type;
5452 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5455 MOVStreamContext *sc;
5456 int size, version, layout;
5457 int32_t yaw, pitch, roll;
5458 uint32_t l = 0, t = 0, r = 0, b = 0;
5459 uint32_t tag, padding = 0;
5460 enum AVSphericalProjection projection;
5462 if (c->fc->nb_streams < 1)
5465 st = c->fc->streams[c->fc->nb_streams - 1];
5468 if (atom.size < 8) {
5469 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5470 return AVERROR_INVALIDDATA;
5473 size = avio_rb32(pb);
5474 if (size <= 12 || size > atom.size)
5475 return AVERROR_INVALIDDATA;
5477 tag = avio_rl32(pb);
5478 if (tag != MKTAG('s','v','h','d')) {
5479 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5482 version = avio_r8(pb);
5484 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5488 avio_skip(pb, 3); /* flags */
5489 avio_skip(pb, size - 12); /* metadata_source */
5491 size = avio_rb32(pb);
5492 if (size > atom.size)
5493 return AVERROR_INVALIDDATA;
5495 tag = avio_rl32(pb);
5496 if (tag != MKTAG('p','r','o','j')) {
5497 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5501 size = avio_rb32(pb);
5502 if (size > atom.size)
5503 return AVERROR_INVALIDDATA;
5505 tag = avio_rl32(pb);
5506 if (tag != MKTAG('p','r','h','d')) {
5507 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5510 version = avio_r8(pb);
5512 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5516 avio_skip(pb, 3); /* flags */
5518 /* 16.16 fixed point */
5519 yaw = avio_rb32(pb);
5520 pitch = avio_rb32(pb);
5521 roll = avio_rb32(pb);
5523 size = avio_rb32(pb);
5524 if (size > atom.size)
5525 return AVERROR_INVALIDDATA;
5527 tag = avio_rl32(pb);
5528 version = avio_r8(pb);
5530 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5534 avio_skip(pb, 3); /* flags */
5536 case MKTAG('c','b','m','p'):
5537 layout = avio_rb32(pb);
5539 av_log(c->fc, AV_LOG_WARNING,
5540 "Unsupported cubemap layout %d\n", layout);
5543 projection = AV_SPHERICAL_CUBEMAP;
5544 padding = avio_rb32(pb);
5546 case MKTAG('e','q','u','i'):
5552 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5553 av_log(c->fc, AV_LOG_ERROR,
5554 "Invalid bounding rectangle coordinates "
5555 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5556 return AVERROR_INVALIDDATA;
5559 if (l || t || r || b)
5560 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5562 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5565 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5569 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5571 return AVERROR(ENOMEM);
5573 sc->spherical->projection = projection;
5575 sc->spherical->yaw = yaw;
5576 sc->spherical->pitch = pitch;
5577 sc->spherical->roll = roll;
5579 sc->spherical->padding = padding;
5581 sc->spherical->bound_left = l;
5582 sc->spherical->bound_top = t;
5583 sc->spherical->bound_right = r;
5584 sc->spherical->bound_bottom = b;
5589 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5592 uint8_t *buffer = av_malloc(len + 1);
5596 return AVERROR(ENOMEM);
5599 ret = ffio_read_size(pb, buffer, len);
5603 /* Check for mandatory keys and values, try to support XML as best-effort */
5604 if (!sc->spherical &&
5605 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5606 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5607 av_stristr(val, "true") &&
5608 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5609 av_stristr(val, "true") &&
5610 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5611 av_stristr(val, "equirectangular")) {
5612 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5616 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5618 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5619 enum AVStereo3DType mode;
5621 if (av_stristr(buffer, "left-right"))
5622 mode = AV_STEREO3D_SIDEBYSIDE;
5623 else if (av_stristr(buffer, "top-bottom"))
5624 mode = AV_STEREO3D_TOPBOTTOM;
5626 mode = AV_STEREO3D_2D;
5628 sc->stereo3d = av_stereo3d_alloc();
5632 sc->stereo3d->type = mode;
5636 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5638 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5639 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5641 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5642 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5644 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5652 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5655 MOVStreamContext *sc;
5658 static const uint8_t uuid_isml_manifest[] = {
5659 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5660 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5662 static const uint8_t uuid_xmp[] = {
5663 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5664 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5666 static const uint8_t uuid_spherical[] = {
5667 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5668 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5671 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5672 return AVERROR_INVALIDDATA;
5674 if (c->fc->nb_streams < 1)
5676 st = c->fc->streams[c->fc->nb_streams - 1];
5679 ret = avio_read(pb, uuid, sizeof(uuid));
5682 } else if (ret != sizeof(uuid)) {
5683 return AVERROR_INVALIDDATA;
5685 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5686 uint8_t *buffer, *ptr;
5688 size_t len = atom.size - sizeof(uuid);
5691 return AVERROR_INVALIDDATA;
5693 ret = avio_skip(pb, 4); // zeroes
5696 buffer = av_mallocz(len + 1);
5698 return AVERROR(ENOMEM);
5700 ret = avio_read(pb, buffer, len);
5704 } else if (ret != len) {
5706 return AVERROR_INVALIDDATA;
5710 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5711 ptr += sizeof("systemBitrate=\"") - 1;
5712 c->bitrates_count++;
5713 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5715 c->bitrates_count = 0;
5717 return AVERROR(ENOMEM);
5720 ret = strtol(ptr, &endptr, 10);
5721 if (ret < 0 || errno || *endptr != '"') {
5722 c->bitrates[c->bitrates_count - 1] = 0;
5724 c->bitrates[c->bitrates_count - 1] = ret;
5729 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5731 size_t len = atom.size - sizeof(uuid);
5732 if (c->export_xmp) {
5733 buffer = av_mallocz(len + 1);
5735 return AVERROR(ENOMEM);
5737 ret = avio_read(pb, buffer, len);
5741 } else if (ret != len) {
5743 return AVERROR_INVALIDDATA;
5746 av_dict_set(&c->fc->metadata, "xmp", buffer, 0);
5749 // skip all uuid atom, which makes it fast for long uuid-xmp file
5750 ret = avio_skip(pb, len);
5754 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5755 size_t len = atom.size - sizeof(uuid);
5756 ret = mov_parse_uuid_spherical(sc, pb, len);
5760 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5766 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5769 uint8_t content[16];
5774 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5780 && !memcmp(content, "Anevia\x1A\x1A", 8)
5781 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5782 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5788 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5790 uint32_t format = avio_rl32(pb);
5791 MOVStreamContext *sc;
5795 if (c->fc->nb_streams < 1)
5797 st = c->fc->streams[c->fc->nb_streams - 1];
5802 case MKTAG('e','n','c','v'): // encrypted video
5803 case MKTAG('e','n','c','a'): // encrypted audio
5804 id = mov_codec_id(st, format);
5805 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5806 st->codecpar->codec_id != id) {
5807 av_log(c->fc, AV_LOG_WARNING,
5808 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5809 (char*)&format, st->codecpar->codec_id);
5813 st->codecpar->codec_id = id;
5814 sc->format = format;
5818 if (format != sc->format) {
5819 av_log(c->fc, AV_LOG_WARNING,
5820 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5821 (char*)&format, (char*)&sc->format);
5830 * Gets the current encryption info and associated current stream context. If
5831 * we are parsing a track fragment, this will return the specific encryption
5832 * info for this fragment; otherwise this will return the global encryption
5833 * info for the current stream.
5835 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5837 MOVFragmentStreamInfo *frag_stream_info;
5841 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5842 if (frag_stream_info) {
5843 for (i = 0; i < c->fc->nb_streams; i++) {
5844 if (c->fc->streams[i]->id == frag_stream_info->id) {
5845 st = c->fc->streams[i];
5849 if (i == c->fc->nb_streams)
5851 *sc = st->priv_data;
5853 if (!frag_stream_info->encryption_index) {
5854 // If this stream isn't encrypted, don't create the index.
5855 if (!(*sc)->cenc.default_encrypted_sample)
5857 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5858 if (!frag_stream_info->encryption_index)
5859 return AVERROR(ENOMEM);
5861 *encryption_index = frag_stream_info->encryption_index;
5864 // No current track fragment, using stream level encryption info.
5866 if (c->fc->nb_streams < 1)
5868 st = c->fc->streams[c->fc->nb_streams - 1];
5869 *sc = st->priv_data;
5871 if (!(*sc)->cenc.encryption_index) {
5872 // If this stream isn't encrypted, don't create the index.
5873 if (!(*sc)->cenc.default_encrypted_sample)
5875 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5876 if (!(*sc)->cenc.encryption_index)
5877 return AVERROR(ENOMEM);
5880 *encryption_index = (*sc)->cenc.encryption_index;
5885 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
5888 unsigned int subsample_count;
5889 AVSubsampleEncryptionInfo *subsamples;
5891 if (!sc->cenc.default_encrypted_sample) {
5892 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
5893 return AVERROR_INVALIDDATA;
5896 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
5898 return AVERROR(ENOMEM);
5900 if (sc->cenc.per_sample_iv_size != 0) {
5901 if (avio_read(pb, (*sample)->iv, sc->cenc.per_sample_iv_size) != sc->cenc.per_sample_iv_size) {
5902 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
5903 av_encryption_info_free(*sample);
5905 return AVERROR_INVALIDDATA;
5909 if (use_subsamples) {
5910 subsample_count = avio_rb16(pb);
5911 av_free((*sample)->subsamples);
5912 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
5913 if (!(*sample)->subsamples) {
5914 av_encryption_info_free(*sample);
5916 return AVERROR(ENOMEM);
5919 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
5920 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
5921 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
5924 if (pb->eof_reached) {
5925 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
5926 av_encryption_info_free(*sample);
5928 return AVERROR_INVALIDDATA;
5930 (*sample)->subsample_count = subsample_count;
5936 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5938 AVEncryptionInfo **encrypted_samples;
5939 MOVEncryptionIndex *encryption_index;
5940 MOVStreamContext *sc;
5941 int use_subsamples, ret;
5942 unsigned int sample_count, i, alloc_size = 0;
5944 ret = get_current_encryption_info(c, &encryption_index, &sc);
5948 if (encryption_index->nb_encrypted_samples) {
5949 // This can happen if we have both saio/saiz and senc atoms.
5950 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
5954 avio_r8(pb); /* version */
5955 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
5957 sample_count = avio_rb32(pb);
5958 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
5959 return AVERROR(ENOMEM);
5961 for (i = 0; i < sample_count; i++) {
5962 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
5963 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
5964 min_samples * sizeof(*encrypted_samples));
5965 if (encrypted_samples) {
5966 encryption_index->encrypted_samples = encrypted_samples;
5968 ret = mov_read_sample_encryption_info(
5969 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
5971 ret = AVERROR(ENOMEM);
5973 if (pb->eof_reached) {
5974 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
5975 ret = AVERROR_INVALIDDATA;
5980 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
5981 av_freep(&encryption_index->encrypted_samples);
5985 encryption_index->nb_encrypted_samples = sample_count;
5990 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
5992 AVEncryptionInfo **sample, **encrypted_samples;
5994 size_t sample_count, sample_info_size, i;
5996 unsigned int alloc_size = 0;
5998 if (encryption_index->nb_encrypted_samples)
6000 sample_count = encryption_index->auxiliary_info_sample_count;
6001 if (encryption_index->auxiliary_offsets_count != 1) {
6002 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6003 return AVERROR_PATCHWELCOME;
6005 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6006 return AVERROR(ENOMEM);
6008 prev_pos = avio_tell(pb);
6009 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6010 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6011 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6015 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6016 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6017 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6018 min_samples * sizeof(*encrypted_samples));
6019 if (!encrypted_samples) {
6020 ret = AVERROR(ENOMEM);
6023 encryption_index->encrypted_samples = encrypted_samples;
6025 sample = &encryption_index->encrypted_samples[i];
6026 sample_info_size = encryption_index->auxiliary_info_default_size
6027 ? encryption_index->auxiliary_info_default_size
6028 : encryption_index->auxiliary_info_sizes[i];
6030 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6034 if (pb->eof_reached) {
6035 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6036 ret = AVERROR_INVALIDDATA;
6038 encryption_index->nb_encrypted_samples = sample_count;
6042 avio_seek(pb, prev_pos, SEEK_SET);
6044 for (; i > 0; i--) {
6045 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6047 av_freep(&encryption_index->encrypted_samples);
6053 * Tries to read the given number of bytes from the stream and puts it in a
6054 * newly allocated buffer. This reads in small chunks to avoid allocating large
6055 * memory if the file contains an invalid/malicious size value.
6057 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6059 const unsigned int block_size = 1024 * 1024;
6060 uint8_t *buffer = NULL;
6061 unsigned int alloc_size = 0, offset = 0;
6062 while (offset < size) {
6063 unsigned int new_size =
6064 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6065 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6066 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6069 return AVERROR(ENOMEM);
6071 buffer = new_buffer;
6073 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6075 return AVERROR_INVALIDDATA;
6084 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6086 MOVEncryptionIndex *encryption_index;
6087 MOVStreamContext *sc;
6089 unsigned int sample_count, aux_info_type, aux_info_param;
6091 ret = get_current_encryption_info(c, &encryption_index, &sc);
6095 if (encryption_index->nb_encrypted_samples) {
6096 // This can happen if we have both saio/saiz and senc atoms.
6097 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6101 if (encryption_index->auxiliary_info_sample_count) {
6102 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6103 return AVERROR_INVALIDDATA;
6106 avio_r8(pb); /* version */
6107 if (avio_rb24(pb) & 0x01) { /* flags */
6108 aux_info_type = avio_rb32(pb);
6109 aux_info_param = avio_rb32(pb);
6110 if (sc->cenc.default_encrypted_sample) {
6111 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6112 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6115 if (aux_info_param != 0) {
6116 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6120 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6121 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6122 aux_info_type == MKBETAG('c','e','n','s') ||
6123 aux_info_type == MKBETAG('c','b','c','1') ||
6124 aux_info_type == MKBETAG('c','b','c','s')) &&
6125 aux_info_param == 0) {
6126 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6127 return AVERROR_INVALIDDATA;
6132 } else if (!sc->cenc.default_encrypted_sample) {
6133 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6137 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6138 sample_count = avio_rb32(pb);
6139 encryption_index->auxiliary_info_sample_count = sample_count;
6141 if (encryption_index->auxiliary_info_default_size == 0) {
6142 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6144 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6149 if (encryption_index->auxiliary_offsets_count) {
6150 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6156 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6158 uint64_t *auxiliary_offsets;
6159 MOVEncryptionIndex *encryption_index;
6160 MOVStreamContext *sc;
6162 unsigned int version, entry_count, aux_info_type, aux_info_param;
6163 unsigned int alloc_size = 0;
6165 ret = get_current_encryption_info(c, &encryption_index, &sc);
6169 if (encryption_index->nb_encrypted_samples) {
6170 // This can happen if we have both saio/saiz and senc atoms.
6171 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6175 if (encryption_index->auxiliary_offsets_count) {
6176 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6177 return AVERROR_INVALIDDATA;
6180 version = avio_r8(pb); /* version */
6181 if (avio_rb24(pb) & 0x01) { /* flags */
6182 aux_info_type = avio_rb32(pb);
6183 aux_info_param = avio_rb32(pb);
6184 if (sc->cenc.default_encrypted_sample) {
6185 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6186 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6189 if (aux_info_param != 0) {
6190 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6194 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6195 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6196 aux_info_type == MKBETAG('c','e','n','s') ||
6197 aux_info_type == MKBETAG('c','b','c','1') ||
6198 aux_info_type == MKBETAG('c','b','c','s')) &&
6199 aux_info_param == 0) {
6200 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6201 return AVERROR_INVALIDDATA;
6206 } else if (!sc->cenc.default_encrypted_sample) {
6207 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6211 entry_count = avio_rb32(pb);
6212 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6213 return AVERROR(ENOMEM);
6215 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6216 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6217 auxiliary_offsets = av_fast_realloc(
6218 encryption_index->auxiliary_offsets, &alloc_size,
6219 min_offsets * sizeof(*auxiliary_offsets));
6220 if (!auxiliary_offsets) {
6221 av_freep(&encryption_index->auxiliary_offsets);
6222 return AVERROR(ENOMEM);
6224 encryption_index->auxiliary_offsets = auxiliary_offsets;
6227 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6229 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6231 if (c->frag_index.current >= 0) {
6232 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6236 if (pb->eof_reached) {
6237 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6238 av_freep(&encryption_index->auxiliary_offsets);
6239 return AVERROR_INVALIDDATA;
6242 encryption_index->auxiliary_offsets_count = entry_count;
6244 if (encryption_index->auxiliary_info_sample_count) {
6245 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6251 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6253 AVEncryptionInitInfo *info, *old_init_info;
6256 uint8_t *side_data, *extra_data, *old_side_data;
6257 size_t side_data_size;
6258 int ret = 0, old_side_data_size;
6259 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6261 if (c->fc->nb_streams < 1)
6263 st = c->fc->streams[c->fc->nb_streams-1];
6265 version = avio_r8(pb); /* version */
6266 avio_rb24(pb); /* flags */
6268 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6269 /* key_id_size */ 16, /* data_size */ 0);
6271 return AVERROR(ENOMEM);
6273 if (avio_read(pb, info->system_id, 16) != 16) {
6274 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6275 ret = AVERROR_INVALIDDATA;
6280 kid_count = avio_rb32(pb);
6281 if (kid_count >= INT_MAX / sizeof(*key_ids))
6282 return AVERROR(ENOMEM);
6284 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6285 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6286 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6287 min_kid_count * sizeof(*key_ids));
6289 ret = AVERROR(ENOMEM);
6292 info->key_ids = key_ids;
6294 info->key_ids[i] = av_mallocz(16);
6295 if (!info->key_ids[i]) {
6296 ret = AVERROR(ENOMEM);
6299 info->num_key_ids = i + 1;
6301 if (avio_read(pb, info->key_ids[i], 16) != 16) {
6302 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6303 ret = AVERROR_INVALIDDATA;
6308 if (pb->eof_reached) {
6309 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6310 ret = AVERROR_INVALIDDATA;
6315 extra_data_size = avio_rb32(pb);
6316 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6320 av_freep(&info->data); // malloc(0) may still allocate something.
6321 info->data = extra_data;
6322 info->data_size = extra_data_size;
6324 // If there is existing initialization data, append to the list.
6325 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6326 if (old_side_data) {
6327 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6328 if (old_init_info) {
6329 // Append to the end of the list.
6330 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6336 info = old_init_info;
6338 // Assume existing side-data will be valid, so the only error we could get is OOM.
6339 ret = AVERROR(ENOMEM);
6344 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6346 ret = AVERROR(ENOMEM);
6349 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6350 side_data, side_data_size);
6355 av_encryption_init_info_free(info);
6359 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6362 MOVStreamContext *sc;
6364 if (c->fc->nb_streams < 1)
6366 st = c->fc->streams[c->fc->nb_streams-1];
6369 if (sc->pseudo_stream_id != 0) {
6370 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6371 return AVERROR_PATCHWELCOME;
6375 return AVERROR_INVALIDDATA;
6377 avio_rb32(pb); /* version and flags */
6379 if (!sc->cenc.default_encrypted_sample) {
6380 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6381 if (!sc->cenc.default_encrypted_sample) {
6382 return AVERROR(ENOMEM);
6386 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6390 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6393 MOVStreamContext *sc;
6394 unsigned int version, pattern, is_protected, iv_size;
6396 if (c->fc->nb_streams < 1)
6398 st = c->fc->streams[c->fc->nb_streams-1];
6401 if (sc->pseudo_stream_id != 0) {
6402 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6403 return AVERROR_PATCHWELCOME;
6406 if (!sc->cenc.default_encrypted_sample) {
6407 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6408 if (!sc->cenc.default_encrypted_sample) {
6409 return AVERROR(ENOMEM);
6414 return AVERROR_INVALIDDATA;
6416 version = avio_r8(pb); /* version */
6417 avio_rb24(pb); /* flags */
6419 avio_r8(pb); /* reserved */
6420 pattern = avio_r8(pb);
6423 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6424 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6427 is_protected = avio_r8(pb);
6428 if (is_protected && !sc->cenc.encryption_index) {
6429 // The whole stream should be by-default encrypted.
6430 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6431 if (!sc->cenc.encryption_index)
6432 return AVERROR(ENOMEM);
6434 sc->cenc.per_sample_iv_size = avio_r8(pb);
6435 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6436 sc->cenc.per_sample_iv_size != 16) {
6437 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6438 return AVERROR_INVALIDDATA;
6440 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6441 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6442 return AVERROR_INVALIDDATA;
6445 if (is_protected && !sc->cenc.per_sample_iv_size) {
6446 iv_size = avio_r8(pb);
6447 if (iv_size != 8 && iv_size != 16) {
6448 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6449 return AVERROR_INVALIDDATA;
6452 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6453 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6454 return AVERROR_INVALIDDATA;
6461 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6464 int last, type, size, ret;
6467 if (c->fc->nb_streams < 1)
6469 st = c->fc->streams[c->fc->nb_streams-1];
6471 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6472 return AVERROR_INVALIDDATA;
6474 /* Check FlacSpecificBox version. */
6475 if (avio_r8(pb) != 0)
6476 return AVERROR_INVALIDDATA;
6478 avio_rb24(pb); /* Flags */
6480 avio_read(pb, buf, sizeof(buf));
6481 flac_parse_block_header(buf, &last, &type, &size);
6483 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6484 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6485 return AVERROR_INVALIDDATA;
6488 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6493 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6498 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6502 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6503 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6504 return AVERROR_PATCHWELCOME;
6507 if (!sc->cenc.aes_ctr) {
6508 /* initialize the cipher */
6509 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6510 if (!sc->cenc.aes_ctr) {
6511 return AVERROR(ENOMEM);
6514 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6520 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6522 if (!sample->subsample_count)
6524 /* decrypt the whole packet */
6525 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6529 for (i = 0; i < sample->subsample_count; i++)
6531 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6532 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6533 return AVERROR_INVALIDDATA;
6536 /* skip the clear bytes */
6537 input += sample->subsamples[i].bytes_of_clear_data;
6538 size -= sample->subsamples[i].bytes_of_clear_data;
6540 /* decrypt the encrypted bytes */
6541 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6542 input += sample->subsamples[i].bytes_of_protected_data;
6543 size -= sample->subsamples[i].bytes_of_protected_data;
6547 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6548 return AVERROR_INVALIDDATA;
6554 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6556 MOVFragmentStreamInfo *frag_stream_info;
6557 MOVEncryptionIndex *encryption_index;
6558 AVEncryptionInfo *encrypted_sample;
6559 int encrypted_index, ret;
6561 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6562 encrypted_index = current_index;
6563 encryption_index = NULL;
6564 if (frag_stream_info) {
6565 // Note this only supports encryption info in the first sample descriptor.
6566 if (mov->fragment.stsd_id == 1) {
6567 if (frag_stream_info->encryption_index) {
6568 encrypted_index = current_index - frag_stream_info->index_entry;
6569 encryption_index = frag_stream_info->encryption_index;
6571 encryption_index = sc->cenc.encryption_index;
6575 encryption_index = sc->cenc.encryption_index;
6578 if (encryption_index) {
6579 if (encryption_index->auxiliary_info_sample_count &&
6580 !encryption_index->nb_encrypted_samples) {
6581 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6582 return AVERROR_INVALIDDATA;
6584 if (encryption_index->auxiliary_offsets_count &&
6585 !encryption_index->nb_encrypted_samples) {
6586 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6587 return AVERROR_INVALIDDATA;
6590 if (!encryption_index->nb_encrypted_samples) {
6591 // Full-sample encryption with default settings.
6592 encrypted_sample = sc->cenc.default_encrypted_sample;
6593 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6594 // Per-sample setting override.
6595 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6597 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6598 return AVERROR_INVALIDDATA;
6601 if (mov->decryption_key) {
6602 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6605 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6607 return AVERROR(ENOMEM);
6608 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6618 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6620 const int OPUS_SEEK_PREROLL_MS = 80;
6625 if (c->fc->nb_streams < 1)
6627 st = c->fc->streams[c->fc->nb_streams-1];
6629 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6630 return AVERROR_INVALIDDATA;
6632 /* Check OpusSpecificBox version. */
6633 if (avio_r8(pb) != 0) {
6634 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6635 return AVERROR_INVALIDDATA;
6638 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6639 size = atom.size + 8;
6641 if (ff_alloc_extradata(st->codecpar, size))
6642 return AVERROR(ENOMEM);
6644 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6645 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6646 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6647 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6649 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6650 little-endian; aside from the preceeding magic and version they're
6651 otherwise currently identical. Data after output gain at offset 16
6652 doesn't need to be bytewapped. */
6653 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6654 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6655 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6656 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6658 st->codecpar->initial_padding = pre_skip;
6659 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6660 (AVRational){1, 1000},
6661 (AVRational){1, 48000});
6666 static const MOVParseTableEntry mov_default_parse_table[] = {
6667 { MKTAG('A','C','L','R'), mov_read_aclr },
6668 { MKTAG('A','P','R','G'), mov_read_avid },
6669 { MKTAG('A','A','L','P'), mov_read_avid },
6670 { MKTAG('A','R','E','S'), mov_read_ares },
6671 { MKTAG('a','v','s','s'), mov_read_avss },
6672 { MKTAG('a','v','1','C'), mov_read_av1c },
6673 { MKTAG('c','h','p','l'), mov_read_chpl },
6674 { MKTAG('c','o','6','4'), mov_read_stco },
6675 { MKTAG('c','o','l','r'), mov_read_colr },
6676 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6677 { MKTAG('d','i','n','f'), mov_read_default },
6678 { MKTAG('D','p','x','E'), mov_read_dpxe },
6679 { MKTAG('d','r','e','f'), mov_read_dref },
6680 { MKTAG('e','d','t','s'), mov_read_default },
6681 { MKTAG('e','l','s','t'), mov_read_elst },
6682 { MKTAG('e','n','d','a'), mov_read_enda },
6683 { MKTAG('f','i','e','l'), mov_read_fiel },
6684 { MKTAG('a','d','r','m'), mov_read_adrm },
6685 { MKTAG('f','t','y','p'), mov_read_ftyp },
6686 { MKTAG('g','l','b','l'), mov_read_glbl },
6687 { MKTAG('h','d','l','r'), mov_read_hdlr },
6688 { MKTAG('i','l','s','t'), mov_read_ilst },
6689 { MKTAG('j','p','2','h'), mov_read_jp2h },
6690 { MKTAG('m','d','a','t'), mov_read_mdat },
6691 { MKTAG('m','d','h','d'), mov_read_mdhd },
6692 { MKTAG('m','d','i','a'), mov_read_default },
6693 { MKTAG('m','e','t','a'), mov_read_meta },
6694 { MKTAG('m','i','n','f'), mov_read_default },
6695 { MKTAG('m','o','o','f'), mov_read_moof },
6696 { MKTAG('m','o','o','v'), mov_read_moov },
6697 { MKTAG('m','v','e','x'), mov_read_default },
6698 { MKTAG('m','v','h','d'), mov_read_mvhd },
6699 { MKTAG('S','M','I',' '), mov_read_svq3 },
6700 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6701 { MKTAG('a','v','c','C'), mov_read_glbl },
6702 { MKTAG('p','a','s','p'), mov_read_pasp },
6703 { MKTAG('s','i','d','x'), mov_read_sidx },
6704 { MKTAG('s','t','b','l'), mov_read_default },
6705 { MKTAG('s','t','c','o'), mov_read_stco },
6706 { MKTAG('s','t','p','s'), mov_read_stps },
6707 { MKTAG('s','t','r','f'), mov_read_strf },
6708 { MKTAG('s','t','s','c'), mov_read_stsc },
6709 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6710 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6711 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6712 { MKTAG('s','t','t','s'), mov_read_stts },
6713 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6714 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6715 { MKTAG('t','f','d','t'), mov_read_tfdt },
6716 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6717 { MKTAG('t','r','a','k'), mov_read_trak },
6718 { MKTAG('t','r','a','f'), mov_read_default },
6719 { MKTAG('t','r','e','f'), mov_read_default },
6720 { MKTAG('t','m','c','d'), mov_read_tmcd },
6721 { MKTAG('c','h','a','p'), mov_read_chap },
6722 { MKTAG('t','r','e','x'), mov_read_trex },
6723 { MKTAG('t','r','u','n'), mov_read_trun },
6724 { MKTAG('u','d','t','a'), mov_read_default },
6725 { MKTAG('w','a','v','e'), mov_read_wave },
6726 { MKTAG('e','s','d','s'), mov_read_esds },
6727 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6728 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6729 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6730 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6731 { MKTAG('w','f','e','x'), mov_read_wfex },
6732 { MKTAG('c','m','o','v'), mov_read_cmov },
6733 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6734 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6735 { MKTAG('s','b','g','p'), mov_read_sbgp },
6736 { MKTAG('h','v','c','C'), mov_read_glbl },
6737 { MKTAG('u','u','i','d'), mov_read_uuid },
6738 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6739 { MKTAG('f','r','e','e'), mov_read_free },
6740 { MKTAG('-','-','-','-'), mov_read_custom },
6741 { MKTAG('s','i','n','f'), mov_read_default },
6742 { MKTAG('f','r','m','a'), mov_read_frma },
6743 { MKTAG('s','e','n','c'), mov_read_senc },
6744 { MKTAG('s','a','i','z'), mov_read_saiz },
6745 { MKTAG('s','a','i','o'), mov_read_saio },
6746 { MKTAG('p','s','s','h'), mov_read_pssh },
6747 { MKTAG('s','c','h','m'), mov_read_schm },
6748 { MKTAG('s','c','h','i'), mov_read_default },
6749 { MKTAG('t','e','n','c'), mov_read_tenc },
6750 { MKTAG('d','f','L','a'), mov_read_dfla },
6751 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6752 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6753 { MKTAG('d','O','p','s'), mov_read_dops },
6754 { MKTAG('S','m','D','m'), mov_read_smdm },
6755 { MKTAG('C','o','L','L'), mov_read_coll },
6756 { MKTAG('v','p','c','C'), mov_read_vpcc },
6757 { MKTAG('m','d','c','v'), mov_read_mdcv },
6758 { MKTAG('c','l','l','i'), mov_read_clli },
6762 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6764 int64_t total_size = 0;
6768 if (c->atom_depth > 10) {
6769 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6770 return AVERROR_INVALIDDATA;
6775 atom.size = INT64_MAX;
6776 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6777 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
6780 if (atom.size >= 8) {
6781 a.size = avio_rb32(pb);
6782 a.type = avio_rl32(pb);
6783 if (a.type == MKTAG('f','r','e','e') &&
6785 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT &&
6788 uint32_t *type = (uint32_t *)buf + 1;
6789 if (avio_read(pb, buf, 8) != 8)
6790 return AVERROR_INVALIDDATA;
6791 avio_seek(pb, -8, SEEK_CUR);
6792 if (*type == MKTAG('m','v','h','d') ||
6793 *type == MKTAG('c','m','o','v')) {
6794 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free atom.\n");
6795 a.type = MKTAG('m','o','o','v');
6798 if (atom.type != MKTAG('r','o','o','t') &&
6799 atom.type != MKTAG('m','o','o','v'))
6801 if (a.type == MKTAG('t','r','a','k') || a.type == MKTAG('m','d','a','t'))
6803 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
6810 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
6811 a.size = avio_rb64(pb) - 8;
6815 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
6816 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
6818 a.size = atom.size - total_size + 8;
6823 a.size = FFMIN(a.size, atom.size - total_size);
6825 for (i = 0; mov_default_parse_table[i].type; i++)
6826 if (mov_default_parse_table[i].type == a.type) {
6827 parse = mov_default_parse_table[i].parse;
6831 // container is user data
6832 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
6833 atom.type == MKTAG('i','l','s','t')))
6834 parse = mov_read_udta_string;
6836 // Supports parsing the QuickTime Metadata Keys.
6837 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
6838 if (!parse && c->found_hdlr_mdta &&
6839 atom.type == MKTAG('m','e','t','a') &&
6840 a.type == MKTAG('k','e','y','s')) {
6841 parse = mov_read_keys;
6844 if (!parse) { /* skip leaf atoms data */
6845 avio_skip(pb, a.size);
6847 int64_t start_pos = avio_tell(pb);
6849 int err = parse(c, pb, a);
6854 if (c->found_moov && c->found_mdat &&
6855 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
6856 start_pos + a.size == avio_size(pb))) {
6857 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
6858 c->next_root_atom = start_pos + a.size;
6862 left = a.size - avio_tell(pb) + start_pos;
6863 if (left > 0) /* skip garbage at atom end */
6864 avio_skip(pb, left);
6865 else if (left < 0) {
6866 av_log(c->fc, AV_LOG_WARNING,
6867 "overread end of atom '%.4s' by %"PRId64" bytes\n",
6868 (char*)&a.type, -left);
6869 avio_seek(pb, left, SEEK_CUR);
6873 total_size += a.size;
6876 if (total_size < atom.size && atom.size < 0x7ffff)
6877 avio_skip(pb, atom.size - total_size);
6883 static int mov_probe(AVProbeData *p)
6888 int moov_offset = -1;
6890 /* check file header */
6893 /* ignore invalid offset */
6894 if ((offset + 8) > (unsigned int)p->buf_size)
6896 tag = AV_RL32(p->buf + offset + 4);
6898 /* check for obvious tags */
6899 case MKTAG('m','o','o','v'):
6900 moov_offset = offset + 4;
6901 case MKTAG('m','d','a','t'):
6902 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
6903 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
6904 case MKTAG('f','t','y','p'):
6905 if (AV_RB32(p->buf+offset) < 8 &&
6906 (AV_RB32(p->buf+offset) != 1 ||
6907 offset + 12 > (unsigned int)p->buf_size ||
6908 AV_RB64(p->buf+offset + 8) == 0)) {
6909 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
6910 } else if (tag == MKTAG('f','t','y','p') &&
6911 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
6912 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
6914 score = FFMAX(score, 5);
6916 score = AVPROBE_SCORE_MAX;
6918 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
6920 /* those are more common words, so rate then a bit less */
6921 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
6922 case MKTAG('w','i','d','e'):
6923 case MKTAG('f','r','e','e'):
6924 case MKTAG('j','u','n','k'):
6925 case MKTAG('p','i','c','t'):
6926 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
6927 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
6929 case MKTAG(0x82,0x82,0x7f,0x7d):
6930 case MKTAG('s','k','i','p'):
6931 case MKTAG('u','u','i','d'):
6932 case MKTAG('p','r','f','l'):
6933 /* if we only find those cause probedata is too small at least rate them */
6934 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
6935 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
6938 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
6941 if(score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
6942 /* moov atom in the header - we should make sure that this is not a
6943 * MOV-packed MPEG-PS */
6944 offset = moov_offset;
6946 while(offset < (p->buf_size - 16)){ /* Sufficient space */
6947 /* We found an actual hdlr atom */
6948 if(AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
6949 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
6950 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')){
6951 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
6952 /* We found a media handler reference atom describing an
6953 * MPEG-PS-in-MOV, return a
6954 * low score to force expanding the probe window until
6955 * mpegps_probe finds what it needs */
6966 // must be done after parsing all trak because there's no order requirement
6967 static void mov_read_chapters(AVFormatContext *s)
6969 MOVContext *mov = s->priv_data;
6971 MOVStreamContext *sc;
6976 for (j = 0; j < mov->nb_chapter_tracks; j++) {
6977 chapter_track = mov->chapter_tracks[j];
6979 for (i = 0; i < s->nb_streams; i++)
6980 if (s->streams[i]->id == chapter_track) {
6985 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
6990 cur_pos = avio_tell(sc->pb);
6992 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
6993 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
6994 if (st->nb_index_entries) {
6995 // Retrieve the first frame, if possible
6997 AVIndexEntry *sample = &st->index_entries[0];
6998 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
6999 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7003 if (av_get_packet(sc->pb, &pkt, sample->size) < 0)
7006 st->attached_pic = pkt;
7007 st->attached_pic.stream_index = st->index;
7008 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
7011 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7012 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7013 st->discard = AVDISCARD_ALL;
7014 for (i = 0; i < st->nb_index_entries; i++) {
7015 AVIndexEntry *sample = &st->index_entries[i];
7016 int64_t end = i+1 < st->nb_index_entries ? st->index_entries[i+1].timestamp : st->duration;
7021 if (end < sample->timestamp) {
7022 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7023 end = AV_NOPTS_VALUE;
7026 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7027 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7031 // the first two bytes are the length of the title
7032 len = avio_rb16(sc->pb);
7033 if (len > sample->size-2)
7035 title_len = 2*len + 1;
7036 if (!(title = av_mallocz(title_len)))
7039 // The samples could theoretically be in any encoding if there's an encd
7040 // atom following, but in practice are only utf-8 or utf-16, distinguished
7041 // instead by the presence of a BOM
7045 ch = avio_rb16(sc->pb);
7047 avio_get_str16be(sc->pb, len, title, title_len);
7048 else if (ch == 0xfffe)
7049 avio_get_str16le(sc->pb, len, title, title_len);
7052 if (len == 1 || len == 2)
7055 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7059 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7064 avio_seek(sc->pb, cur_pos, SEEK_SET);
7068 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7069 uint32_t value, int flags)
7072 char buf[AV_TIMECODE_STR_SIZE];
7073 AVRational rate = st->avg_frame_rate;
7074 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7077 av_dict_set(&st->metadata, "timecode",
7078 av_timecode_make_string(&tc, buf, value), 0);
7082 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7084 MOVStreamContext *sc = st->priv_data;
7085 char buf[AV_TIMECODE_STR_SIZE];
7086 int64_t cur_pos = avio_tell(sc->pb);
7087 int hh, mm, ss, ff, drop;
7089 if (!st->nb_index_entries)
7092 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7093 avio_skip(s->pb, 13);
7094 hh = avio_r8(s->pb);
7095 mm = avio_r8(s->pb);
7096 ss = avio_r8(s->pb);
7097 drop = avio_r8(s->pb);
7098 ff = avio_r8(s->pb);
7099 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7100 hh, mm, ss, drop ? ';' : ':', ff);
7101 av_dict_set(&st->metadata, "timecode", buf, 0);
7103 avio_seek(sc->pb, cur_pos, SEEK_SET);
7107 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7109 MOVStreamContext *sc = st->priv_data;
7111 int64_t cur_pos = avio_tell(sc->pb);
7114 if (!st->nb_index_entries)
7117 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7118 value = avio_rb32(s->pb);
7120 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7121 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7122 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7124 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7125 * not the case) and thus assume "frame number format" instead of QT one.
7126 * No sample with tmcd track can be found with a QT timecode at the moment,
7127 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7129 parse_timecode_in_framenum_format(s, st, value, flags);
7131 avio_seek(sc->pb, cur_pos, SEEK_SET);
7135 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7137 if (!index || !*index) return;
7138 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7139 av_encryption_info_free((*index)->encrypted_samples[i]);
7141 av_freep(&(*index)->encrypted_samples);
7142 av_freep(&(*index)->auxiliary_info_sizes);
7143 av_freep(&(*index)->auxiliary_offsets);
7147 static int mov_read_close(AVFormatContext *s)
7149 MOVContext *mov = s->priv_data;
7152 for (i = 0; i < s->nb_streams; i++) {
7153 AVStream *st = s->streams[i];
7154 MOVStreamContext *sc = st->priv_data;
7159 av_freep(&sc->ctts_data);
7160 for (j = 0; j < sc->drefs_count; j++) {
7161 av_freep(&sc->drefs[j].path);
7162 av_freep(&sc->drefs[j].dir);
7164 av_freep(&sc->drefs);
7166 sc->drefs_count = 0;
7168 if (!sc->pb_is_copied)
7169 ff_format_io_close(s, &sc->pb);
7172 av_freep(&sc->chunk_offsets);
7173 av_freep(&sc->stsc_data);
7174 av_freep(&sc->sample_sizes);
7175 av_freep(&sc->keyframes);
7176 av_freep(&sc->stts_data);
7177 av_freep(&sc->stps_data);
7178 av_freep(&sc->elst_data);
7179 av_freep(&sc->rap_group);
7180 av_freep(&sc->display_matrix);
7181 av_freep(&sc->index_ranges);
7184 for (j = 0; j < sc->stsd_count; j++)
7185 av_free(sc->extradata[j]);
7186 av_freep(&sc->extradata);
7187 av_freep(&sc->extradata_size);
7189 mov_free_encryption_index(&sc->cenc.encryption_index);
7190 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7191 av_aes_ctr_free(sc->cenc.aes_ctr);
7193 av_freep(&sc->stereo3d);
7194 av_freep(&sc->spherical);
7195 av_freep(&sc->mastering);
7196 av_freep(&sc->coll);
7199 if (mov->dv_demux) {
7200 avformat_free_context(mov->dv_fctx);
7201 mov->dv_fctx = NULL;
7204 if (mov->meta_keys) {
7205 for (i = 1; i < mov->meta_keys_count; i++) {
7206 av_freep(&mov->meta_keys[i]);
7208 av_freep(&mov->meta_keys);
7211 av_freep(&mov->trex_data);
7212 av_freep(&mov->bitrates);
7214 for (i = 0; i < mov->frag_index.nb_items; i++) {
7215 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7216 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7217 mov_free_encryption_index(&frag[j].encryption_index);
7219 av_freep(&mov->frag_index.item[i].stream_info);
7221 av_freep(&mov->frag_index.item);
7223 av_freep(&mov->aes_decrypt);
7224 av_freep(&mov->chapter_tracks);
7229 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7233 for (i = 0; i < s->nb_streams; i++) {
7234 AVStream *st = s->streams[i];
7235 MOVStreamContext *sc = st->priv_data;
7237 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7238 sc->timecode_track == tmcd_id)
7244 /* look for a tmcd track not referenced by any video track, and export it globally */
7245 static void export_orphan_timecode(AVFormatContext *s)
7249 for (i = 0; i < s->nb_streams; i++) {
7250 AVStream *st = s->streams[i];
7252 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7253 !tmcd_is_referenced(s, i + 1)) {
7254 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7256 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7263 static int read_tfra(MOVContext *mov, AVIOContext *f)
7265 int version, fieldlength, i, j;
7266 int64_t pos = avio_tell(f);
7267 uint32_t size = avio_rb32(f);
7268 unsigned track_id, item_count;
7270 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7273 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7275 version = avio_r8(f);
7277 track_id = avio_rb32(f);
7278 fieldlength = avio_rb32(f);
7279 item_count = avio_rb32(f);
7280 for (i = 0; i < item_count; i++) {
7281 int64_t time, offset;
7283 MOVFragmentStreamInfo * frag_stream_info;
7286 return AVERROR_INVALIDDATA;
7290 time = avio_rb64(f);
7291 offset = avio_rb64(f);
7293 time = avio_rb32(f);
7294 offset = avio_rb32(f);
7297 // The first sample of each stream in a fragment is always a random
7298 // access sample. So it's entry in the tfra can be used as the
7299 // initial PTS of the fragment.
7300 index = update_frag_index(mov, offset);
7301 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7302 if (frag_stream_info &&
7303 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7304 frag_stream_info->first_tfra_pts = time;
7306 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7308 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7310 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7314 avio_seek(f, pos + size, SEEK_SET);
7318 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7320 int64_t stream_size = avio_size(f);
7321 int64_t original_pos = avio_tell(f);
7325 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7329 mfra_size = avio_rb32(f);
7330 if (mfra_size < 0 || mfra_size > stream_size) {
7331 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7334 if ((seek_ret = avio_seek(f, -mfra_size, SEEK_CUR)) < 0) {
7338 if (avio_rb32(f) != mfra_size) {
7339 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7342 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7343 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7346 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7348 ret = read_tfra(c, f);
7354 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7356 av_log(c->fc, AV_LOG_ERROR,
7357 "failed to seek back after looking for mfra\n");
7363 static int mov_read_header(AVFormatContext *s)
7365 MOVContext *mov = s->priv_data;
7366 AVIOContext *pb = s->pb;
7368 MOVAtom atom = { AV_RL32("root") };
7371 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7372 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7373 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7374 return AVERROR(EINVAL);
7378 mov->trak_index = -1;
7379 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7380 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7381 atom.size = avio_size(pb);
7383 atom.size = INT64_MAX;
7385 /* check MOV header */
7387 if (mov->moov_retry)
7388 avio_seek(pb, 0, SEEK_SET);
7389 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7390 av_log(s, AV_LOG_ERROR, "error reading header\n");
7394 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7395 if (!mov->found_moov) {
7396 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7398 return AVERROR_INVALIDDATA;
7400 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7402 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7403 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7404 mov_read_chapters(s);
7405 for (i = 0; i < s->nb_streams; i++)
7406 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7407 mov_read_timecode_track(s, s->streams[i]);
7408 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7409 mov_read_rtmd_track(s, s->streams[i]);
7413 /* copy timecode metadata from tmcd tracks to the related video streams */
7414 for (i = 0; i < s->nb_streams; i++) {
7415 AVStream *st = s->streams[i];
7416 MOVStreamContext *sc = st->priv_data;
7417 if (sc->timecode_track > 0) {
7418 AVDictionaryEntry *tcr;
7419 int tmcd_st_id = -1;
7421 for (j = 0; j < s->nb_streams; j++)
7422 if (s->streams[j]->id == sc->timecode_track)
7425 if (tmcd_st_id < 0 || tmcd_st_id == i)
7427 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7429 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7432 export_orphan_timecode(s);
7434 for (i = 0; i < s->nb_streams; i++) {
7435 AVStream *st = s->streams[i];
7436 MOVStreamContext *sc = st->priv_data;
7437 fix_timescale(mov, sc);
7438 if(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7439 st->skip_samples = sc->start_pad;
7441 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7442 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7443 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7444 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7445 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7446 st->codecpar->width = sc->width;
7447 st->codecpar->height = sc->height;
7449 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7450 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7454 if (mov->handbrake_version &&
7455 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7456 st->codecpar->codec_id == AV_CODEC_ID_MP3
7458 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7459 st->need_parsing = AVSTREAM_PARSE_FULL;
7463 if (mov->trex_data) {
7464 for (i = 0; i < s->nb_streams; i++) {
7465 AVStream *st = s->streams[i];
7466 MOVStreamContext *sc = st->priv_data;
7467 if (st->duration > 0) {
7468 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7469 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7470 sc->data_size, sc->time_scale);
7472 return AVERROR_INVALIDDATA;
7474 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7479 if (mov->use_mfra_for > 0) {
7480 for (i = 0; i < s->nb_streams; i++) {
7481 AVStream *st = s->streams[i];
7482 MOVStreamContext *sc = st->priv_data;
7483 if (sc->duration_for_fps > 0) {
7484 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7485 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7486 sc->data_size, sc->time_scale);
7488 return AVERROR_INVALIDDATA;
7490 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7491 sc->duration_for_fps;
7496 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7497 if (mov->bitrates[i]) {
7498 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7502 ff_rfps_calculate(s);
7504 for (i = 0; i < s->nb_streams; i++) {
7505 AVStream *st = s->streams[i];
7506 MOVStreamContext *sc = st->priv_data;
7508 switch (st->codecpar->codec_type) {
7509 case AVMEDIA_TYPE_AUDIO:
7510 err = ff_replaygain_export(st, s->metadata);
7516 case AVMEDIA_TYPE_VIDEO:
7517 if (sc->display_matrix) {
7518 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7519 sizeof(int32_t) * 9);
7523 sc->display_matrix = NULL;
7526 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7527 (uint8_t *)sc->stereo3d,
7528 sizeof(*sc->stereo3d));
7532 sc->stereo3d = NULL;
7534 if (sc->spherical) {
7535 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7536 (uint8_t *)sc->spherical,
7537 sc->spherical_size);
7541 sc->spherical = NULL;
7543 if (sc->mastering) {
7544 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7545 (uint8_t *)sc->mastering,
7546 sizeof(*sc->mastering));
7550 sc->mastering = NULL;
7553 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7554 (uint8_t *)sc->coll,
7564 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7566 for (i = 0; i < mov->frag_index.nb_items; i++)
7567 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7568 mov->frag_index.item[i].headers_read = 1;
7573 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7575 AVIndexEntry *sample = NULL;
7576 int64_t best_dts = INT64_MAX;
7578 for (i = 0; i < s->nb_streams; i++) {
7579 AVStream *avst = s->streams[i];
7580 MOVStreamContext *msc = avst->priv_data;
7581 if (msc->pb && msc->current_sample < avst->nb_index_entries) {
7582 AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample];
7583 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7584 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7585 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7586 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7587 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb &&
7588 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7589 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7590 sample = current_sample;
7599 static int should_retry(AVIOContext *pb, int error_code) {
7600 if (error_code == AVERROR_EOF || avio_feof(pb))
7606 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7609 MOVContext *mov = s->priv_data;
7611 if (index >= 0 && index < mov->frag_index.nb_items)
7612 target = mov->frag_index.item[index].moof_offset;
7613 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7614 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7615 return AVERROR_INVALIDDATA;
7618 mov->next_root_atom = 0;
7619 if (index < 0 || index >= mov->frag_index.nb_items)
7620 index = search_frag_moof_offset(&mov->frag_index, target);
7621 if (index < mov->frag_index.nb_items) {
7622 if (index + 1 < mov->frag_index.nb_items)
7623 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7624 if (mov->frag_index.item[index].headers_read)
7626 mov->frag_index.item[index].headers_read = 1;
7629 mov->found_mdat = 0;
7631 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7634 if (avio_feof(s->pb))
7636 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7641 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7643 uint8_t *side, *extradata;
7646 /* Save the current index. */
7647 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7649 /* Notify the decoder that extradata changed. */
7650 extradata_size = sc->extradata_size[sc->last_stsd_index];
7651 extradata = sc->extradata[sc->last_stsd_index];
7652 if (extradata_size > 0 && extradata) {
7653 side = av_packet_new_side_data(pkt,
7654 AV_PKT_DATA_NEW_EXTRADATA,
7657 return AVERROR(ENOMEM);
7658 memcpy(side, extradata, extradata_size);
7664 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7666 MOVContext *mov = s->priv_data;
7667 MOVStreamContext *sc;
7668 AVIndexEntry *sample;
7669 AVStream *st = NULL;
7670 int64_t current_index;
7674 sample = mov_find_next_sample(s, &st);
7675 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7676 if (!mov->next_root_atom)
7678 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7683 /* must be done just before reading, to avoid infinite loop on sample */
7684 current_index = sc->current_index;
7685 mov_current_sample_inc(sc);
7687 if (mov->next_root_atom) {
7688 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7689 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7692 if (st->discard != AVDISCARD_ALL) {
7693 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7694 if (ret64 != sample->pos) {
7695 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7696 sc->ffindex, sample->pos);
7697 if (should_retry(sc->pb, ret64)) {
7698 mov_current_sample_dec(sc);
7700 return AVERROR_INVALIDDATA;
7703 if( st->discard == AVDISCARD_NONKEY && 0==(sample->flags & AVINDEX_KEYFRAME) ) {
7704 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7708 ret = av_get_packet(sc->pb, pkt, sample->size);
7710 if (should_retry(sc->pb, ret)) {
7711 mov_current_sample_dec(sc);
7715 if (sc->has_palette) {
7718 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7720 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7722 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7723 sc->has_palette = 0;
7726 #if CONFIG_DV_DEMUXER
7727 if (mov->dv_demux && sc->dv_audio_container) {
7728 avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7729 av_freep(&pkt->data);
7731 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7736 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7737 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7738 st->need_parsing = AVSTREAM_PARSE_FULL;
7742 pkt->stream_index = sc->ffindex;
7743 pkt->dts = sample->timestamp;
7744 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7745 pkt->flags |= AV_PKT_FLAG_DISCARD;
7747 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7748 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
7749 /* update ctts context */
7751 if (sc->ctts_index < sc->ctts_count &&
7752 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
7754 sc->ctts_sample = 0;
7757 int64_t next_dts = (sc->current_sample < st->nb_index_entries) ?
7758 st->index_entries[sc->current_sample].timestamp : st->duration;
7760 if (next_dts >= pkt->dts)
7761 pkt->duration = next_dts - pkt->dts;
7762 pkt->pts = pkt->dts;
7764 if (st->discard == AVDISCARD_ALL)
7766 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
7767 pkt->pos = sample->pos;
7769 /* Multiple stsd handling. */
7770 if (sc->stsc_data) {
7771 /* Keep track of the stsc index for the given sample, then check
7772 * if the stsd index is different from the last used one. */
7774 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
7775 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
7777 sc->stsc_sample = 0;
7778 /* Do not check indexes after a switch. */
7779 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
7780 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
7781 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
7782 ret = mov_change_extradata(sc, pkt);
7789 aax_filter(pkt->data, pkt->size, mov);
7791 ret = cenc_filter(mov, st, sc, pkt, current_index);
7798 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
7800 MOVContext *mov = s->priv_data;
7803 if (!mov->frag_index.complete)
7806 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
7809 if (!mov->frag_index.item[index].headers_read)
7810 return mov_switch_root(s, -1, index);
7811 if (index + 1 < mov->frag_index.nb_items)
7812 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7817 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
7819 MOVStreamContext *sc = st->priv_data;
7820 int sample, time_sample, ret;
7823 // Here we consider timestamp to be PTS, hence try to offset it so that we
7824 // can search over the DTS timeline.
7825 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
7827 ret = mov_seek_fragment(s, st, timestamp);
7831 sample = av_index_search_timestamp(st, timestamp, flags);
7832 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
7833 if (sample < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp)
7835 if (sample < 0) /* not sure what to do */
7836 return AVERROR_INVALIDDATA;
7837 mov_current_sample_set(sc, sample);
7838 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
7839 /* adjust ctts index */
7840 if (sc->ctts_data) {
7842 for (i = 0; i < sc->ctts_count; i++) {
7843 int next = time_sample + sc->ctts_data[i].count;
7844 if (next > sc->current_sample) {
7846 sc->ctts_sample = sc->current_sample - time_sample;
7853 /* adjust stsd index */
7855 for (i = 0; i < sc->stsc_count; i++) {
7856 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
7857 if (next > sc->current_sample) {
7859 sc->stsc_sample = sc->current_sample - time_sample;
7862 av_assert0(next == (int)next);
7869 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
7871 MOVContext *mc = s->priv_data;
7876 if (stream_index >= s->nb_streams)
7877 return AVERROR_INVALIDDATA;
7879 st = s->streams[stream_index];
7880 sample = mov_seek_stream(s, st, sample_time, flags);
7884 if (mc->seek_individually) {
7885 /* adjust seek timestamp to found sample timestamp */
7886 int64_t seek_timestamp = st->index_entries[sample].timestamp;
7888 for (i = 0; i < s->nb_streams; i++) {
7890 MOVStreamContext *sc = s->streams[i]->priv_data;
7892 st->skip_samples = (sample_time <= 0) ? sc->start_pad : 0;
7894 if (stream_index == i)
7897 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
7898 mov_seek_stream(s, st, timestamp, flags);
7901 for (i = 0; i < s->nb_streams; i++) {
7902 MOVStreamContext *sc;
7905 mov_current_sample_set(sc, 0);
7908 MOVStreamContext *sc;
7909 AVIndexEntry *entry = mov_find_next_sample(s, &st);
7911 return AVERROR_INVALIDDATA;
7913 if (sc->ffindex == stream_index && sc->current_sample == sample)
7915 mov_current_sample_inc(sc);
7921 #define OFFSET(x) offsetof(MOVContext, x)
7922 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
7923 static const AVOption mov_options[] = {
7924 {"use_absolute_path",
7925 "allow using absolute path when opening alias, this is a possible security issue",
7926 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
7928 {"seek_streams_individually",
7929 "Seek each stream individually to the to the closest point",
7930 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
7932 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
7934 {"advanced_editlist",
7935 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
7936 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
7938 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
7941 "use mfra for fragment timestamps",
7942 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
7943 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
7945 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
7946 FLAGS, "use_mfra_for" },
7947 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
7948 FLAGS, "use_mfra_for" },
7949 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
7950 FLAGS, "use_mfra_for" },
7951 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
7952 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
7953 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
7954 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
7955 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
7956 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
7957 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
7958 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
7959 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
7960 .flags = AV_OPT_FLAG_DECODING_PARAM },
7961 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
7962 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
7963 {.i64 = 0}, 0, 1, FLAGS },
7968 static const AVClass mov_class = {
7969 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
7970 .item_name = av_default_item_name,
7971 .option = mov_options,
7972 .version = LIBAVUTIL_VERSION_INT,
7975 AVInputFormat ff_mov_demuxer = {
7976 .name = "mov,mp4,m4a,3gp,3g2,mj2",
7977 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
7978 .priv_class = &mov_class,
7979 .priv_data_size = sizeof(MOVContext),
7980 .extensions = "mov,mp4,m4a,3gp,3g2,mj2",
7981 .read_probe = mov_probe,
7982 .read_header = mov_read_header,
7983 .read_packet = mov_read_packet,
7984 .read_close = mov_read_close,
7985 .read_seek = mov_read_seek,
7986 .flags = AVFMT_NO_BYTE_SEEK,