3 * Copyright (c) 2001 Fabrice Bellard
4 * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
6 * first version by Francois Revol <revol@free.fr>
7 * seek function by Gael Chardon <gael.dev@4now.net>
9 * This file is part of FFmpeg.
11 * FFmpeg is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * FFmpeg is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with FFmpeg; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30 #include "libavutil/attributes.h"
31 #include "libavutil/channel_layout.h"
32 #include "libavutil/internal.h"
33 #include "libavutil/intreadwrite.h"
34 #include "libavutil/intfloat.h"
35 #include "libavutil/mathematics.h"
36 #include "libavutil/time_internal.h"
37 #include "libavutil/avassert.h"
38 #include "libavutil/avstring.h"
39 #include "libavutil/dict.h"
40 #include "libavutil/display.h"
41 #include "libavutil/opt.h"
42 #include "libavutil/aes.h"
43 #include "libavutil/aes_ctr.h"
44 #include "libavutil/pixdesc.h"
45 #include "libavutil/sha.h"
46 #include "libavutil/spherical.h"
47 #include "libavutil/stereo3d.h"
48 #include "libavutil/timecode.h"
49 #include "libavcodec/ac3tab.h"
50 #include "libavcodec/flac.h"
51 #include "libavcodec/mpegaudiodecheader.h"
52 #include "libavcodec/mlp_parse.h"
55 #include "avio_internal.h"
58 #include "libavcodec/get_bits.h"
61 #include "replaygain.h"
67 #include "qtpalette.h"
69 /* those functions parse an atom */
70 /* links atom IDs to parse functions */
71 typedef struct MOVParseTableEntry {
73 int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
76 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
77 static int mov_read_mfra(MOVContext *c, AVIOContext *f);
78 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
79 int count, int duration);
81 static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb,
82 unsigned len, const char *key)
86 short current, total = 0;
87 avio_rb16(pb); // unknown
88 current = avio_rb16(pb);
90 total = avio_rb16(pb);
92 snprintf(buf, sizeof(buf), "%d", current);
94 snprintf(buf, sizeof(buf), "%d/%d", current, total);
95 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
96 av_dict_set(&c->fc->metadata, key, buf, 0);
101 static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb,
102 unsigned len, const char *key)
104 /* bypass padding bytes */
109 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
110 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
115 static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb,
116 unsigned len, const char *key)
118 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
119 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
124 static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb,
125 unsigned len, const char *key)
129 avio_r8(pb); // unknown
132 if (genre < 1 || genre > ID3v1_GENRE_MAX)
134 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
135 av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
140 static const uint32_t mac_to_unicode[128] = {
141 0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
142 0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
143 0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
144 0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
145 0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
146 0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
147 0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
148 0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
149 0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
150 0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
151 0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
152 0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
153 0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
154 0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
155 0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
156 0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
159 static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len,
160 char *dst, int dstlen)
163 char *end = dst+dstlen-1;
166 for (i = 0; i < len; i++) {
167 uint8_t t, c = avio_r8(pb);
175 PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
181 static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
185 MOVStreamContext *sc;
190 case 0xd: id = AV_CODEC_ID_MJPEG; break;
191 case 0xe: id = AV_CODEC_ID_PNG; break;
192 case 0x1b: id = AV_CODEC_ID_BMP; break;
194 av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
199 st = avformat_new_stream(c->fc, NULL);
201 return AVERROR(ENOMEM);
202 sc = av_mallocz(sizeof(*sc));
204 return AVERROR(ENOMEM);
207 ret = av_get_packet(pb, &pkt, len);
211 if (pkt.size >= 8 && id != AV_CODEC_ID_BMP) {
212 if (AV_RB64(pkt.data) == 0x89504e470d0a1a0a) {
213 id = AV_CODEC_ID_PNG;
215 id = AV_CODEC_ID_MJPEG;
219 st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
221 st->attached_pic = pkt;
222 st->attached_pic.stream_index = st->index;
223 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
225 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
226 st->codecpar->codec_id = id;
232 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
234 char language[4] = { 0 };
235 char buf[200], place[100];
236 uint16_t langcode = 0;
237 double longitude, latitude, altitude;
238 const char *key = "location";
240 if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
241 av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
242 return AVERROR_INVALIDDATA;
245 avio_skip(pb, 4); // version+flags
246 langcode = avio_rb16(pb);
247 ff_mov_lang_to_iso639(langcode, language);
250 len -= avio_get_str(pb, len, place, sizeof(place));
252 av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
253 return AVERROR_INVALIDDATA;
255 avio_skip(pb, 1); // role
259 av_log(c->fc, AV_LOG_ERROR,
260 "loci too short (%u bytes left, need at least %d)\n", len, 12);
261 return AVERROR_INVALIDDATA;
263 longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
264 latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
265 altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
267 // Try to output in the same format as the ?xyz field
268 snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
270 av_strlcatf(buf, sizeof(buf), "%+f", altitude);
271 av_strlcatf(buf, sizeof(buf), "/%s", place);
273 if (*language && strcmp(language, "und")) {
275 snprintf(key2, sizeof(key2), "%s-%s", key, language);
276 av_dict_set(&c->fc->metadata, key2, buf, 0);
278 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
279 return av_dict_set(&c->fc->metadata, key, buf, 0);
282 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
288 if (c->ignore_chapters)
291 n_hmmt = avio_rb32(pb);
292 for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
293 int moment_time = avio_rb32(pb);
294 avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
299 static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
302 char key2[32], language[4] = {0};
304 const char *key = NULL;
305 uint16_t langcode = 0;
306 uint32_t data_type = 0, str_size, str_size_alloc;
307 int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
312 case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
313 case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
314 case MKTAG( 'X','M','P','_'):
315 if (c->export_xmp) { key = "xmp"; raw = 1; } break;
316 case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
317 case MKTAG( 'a','k','I','D'): key = "account_type";
318 parse = mov_metadata_int8_no_padding; break;
319 case MKTAG( 'a','p','I','D'): key = "account_id"; break;
320 case MKTAG( 'c','a','t','g'): key = "category"; break;
321 case MKTAG( 'c','p','i','l'): key = "compilation";
322 parse = mov_metadata_int8_no_padding; break;
323 case MKTAG( 'c','p','r','t'): key = "copyright"; break;
324 case MKTAG( 'd','e','s','c'): key = "description"; break;
325 case MKTAG( 'd','i','s','k'): key = "disc";
326 parse = mov_metadata_track_or_disc_number; break;
327 case MKTAG( 'e','g','i','d'): key = "episode_uid";
328 parse = mov_metadata_int8_no_padding; break;
329 case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
330 case MKTAG( 'g','n','r','e'): key = "genre";
331 parse = mov_metadata_gnre; break;
332 case MKTAG( 'h','d','v','d'): key = "hd_video";
333 parse = mov_metadata_int8_no_padding; break;
334 case MKTAG( 'H','M','M','T'):
335 return mov_metadata_hmmt(c, pb, atom.size);
336 case MKTAG( 'k','e','y','w'): key = "keywords"; break;
337 case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
338 case MKTAG( 'l','o','c','i'):
339 return mov_metadata_loci(c, pb, atom.size);
340 case MKTAG( 'm','a','n','u'): key = "make"; break;
341 case MKTAG( 'm','o','d','l'): key = "model"; break;
342 case MKTAG( 'p','c','s','t'): key = "podcast";
343 parse = mov_metadata_int8_no_padding; break;
344 case MKTAG( 'p','g','a','p'): key = "gapless_playback";
345 parse = mov_metadata_int8_no_padding; break;
346 case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
347 case MKTAG( 'r','t','n','g'): key = "rating";
348 parse = mov_metadata_int8_no_padding; break;
349 case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
350 case MKTAG( 's','o','a','l'): key = "sort_album"; break;
351 case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
352 case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
353 case MKTAG( 's','o','n','m'): key = "sort_name"; break;
354 case MKTAG( 's','o','s','n'): key = "sort_show"; break;
355 case MKTAG( 's','t','i','k'): key = "media_type";
356 parse = mov_metadata_int8_no_padding; break;
357 case MKTAG( 't','r','k','n'): key = "track";
358 parse = mov_metadata_track_or_disc_number; break;
359 case MKTAG( 't','v','e','n'): key = "episode_id"; break;
360 case MKTAG( 't','v','e','s'): key = "episode_sort";
361 parse = mov_metadata_int8_bypass_padding; break;
362 case MKTAG( 't','v','n','n'): key = "network"; break;
363 case MKTAG( 't','v','s','h'): key = "show"; break;
364 case MKTAG( 't','v','s','n'): key = "season_number";
365 parse = mov_metadata_int8_bypass_padding; break;
366 case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
367 case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
368 case MKTAG(0xa9,'a','l','b'): key = "album"; break;
369 case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
370 case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
371 case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
372 case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
373 case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
374 case MKTAG(0xa9,'d','a','y'): key = "date"; break;
375 case MKTAG(0xa9,'d','i','r'): key = "director"; break;
376 case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
377 case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
378 case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
379 case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
380 case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
381 case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
382 case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
383 case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
384 case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
385 case MKTAG(0xa9,'m','a','k'): key = "make"; break;
386 case MKTAG(0xa9,'m','o','d'): key = "model"; break;
387 case MKTAG(0xa9,'n','a','m'): key = "title"; break;
388 case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
389 case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
390 case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
391 case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
392 case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
393 case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
394 case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
395 case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
396 case MKTAG(0xa9,'t','r','k'): key = "track"; break;
397 case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
398 case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
399 case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
400 case MKTAG(0xa9,'x','y','z'): key = "location"; break;
403 if (c->itunes_metadata && atom.size > 8) {
404 int data_size = avio_rb32(pb);
405 int tag = avio_rl32(pb);
406 if (tag == MKTAG('d','a','t','a') && data_size <= atom.size) {
407 data_type = avio_rb32(pb); // type
408 avio_rb32(pb); // unknown
409 str_size = data_size - 16;
412 if (atom.type == MKTAG('c', 'o', 'v', 'r')) {
413 int ret = mov_read_covr(c, pb, data_type, str_size);
415 av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
418 atom.size -= str_size;
422 } else if (!key && c->found_hdlr_mdta && c->meta_keys) {
423 uint32_t index = AV_RB32(&atom.type);
424 if (index < c->meta_keys_count && index > 0) {
425 key = c->meta_keys[index];
427 av_log(c->fc, AV_LOG_WARNING,
428 "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
429 index, c->meta_keys_count);
433 } else if (atom.size > 4 && key && !c->itunes_metadata && !raw) {
434 str_size = avio_rb16(pb); // string length
435 if (str_size > atom.size) {
437 avio_seek(pb, -2, SEEK_CUR);
438 av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
441 langcode = avio_rb16(pb);
442 ff_mov_lang_to_iso639(langcode, language);
445 str_size = atom.size;
447 if (c->export_all && !key) {
448 snprintf(tmp_key, 5, "%.4s", (char*)&atom.type);
454 if (atom.size < 0 || str_size >= INT_MAX/2)
455 return AVERROR_INVALIDDATA;
457 // Allocates enough space if data_type is a int32 or float32 number, otherwise
458 // worst-case requirement for output string in case of utf8 coded input
459 num = (data_type >= 21 && data_type <= 23);
460 str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
461 str = av_mallocz(str_size_alloc);
463 return AVERROR(ENOMEM);
466 parse(c, pb, str_size, key);
468 if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
469 mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
470 } else if (data_type == 21) { // BE signed integer, variable size
473 val = (int8_t)avio_r8(pb);
474 else if (str_size == 2)
475 val = (int16_t)avio_rb16(pb);
476 else if (str_size == 3)
477 val = ((int32_t)(avio_rb24(pb)<<8))>>8;
478 else if (str_size == 4)
479 val = (int32_t)avio_rb32(pb);
480 if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
481 av_log(c->fc, AV_LOG_ERROR,
482 "Failed to store the number (%d) in string.\n", val);
484 return AVERROR_INVALIDDATA;
486 } else if (data_type == 22) { // BE unsigned integer, variable size
487 unsigned int val = 0;
490 else if (str_size == 2)
492 else if (str_size == 3)
494 else if (str_size == 4)
496 if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
497 av_log(c->fc, AV_LOG_ERROR,
498 "Failed to store the number (%u) in string.\n", val);
500 return AVERROR_INVALIDDATA;
502 } else if (data_type == 23 && str_size >= 4) { // BE float32
503 float val = av_int2float(avio_rb32(pb));
504 if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
505 av_log(c->fc, AV_LOG_ERROR,
506 "Failed to store the float32 number (%f) in string.\n", val);
508 return AVERROR_INVALIDDATA;
511 int ret = ffio_read_size(pb, str, str_size);
518 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
519 av_dict_set(&c->fc->metadata, key, str, 0);
520 if (*language && strcmp(language, "und")) {
521 snprintf(key2, sizeof(key2), "%s-%s", key, language);
522 av_dict_set(&c->fc->metadata, key2, str, 0);
524 if (!strcmp(key, "encoder")) {
525 int major, minor, micro;
526 if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, µ) == 3) {
527 c->handbrake_version = 1000000*major + 1000*minor + micro;
536 static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
539 int i, nb_chapters, str_len, version;
543 if (c->ignore_chapters)
546 if ((atom.size -= 5) < 0)
549 version = avio_r8(pb);
552 avio_rb32(pb); // ???
553 nb_chapters = avio_r8(pb);
555 for (i = 0; i < nb_chapters; i++) {
559 start = avio_rb64(pb);
560 str_len = avio_r8(pb);
562 if ((atom.size -= 9+str_len) < 0)
565 ret = ffio_read_size(pb, str, str_len);
569 avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
574 #define MIN_DATA_ENTRY_BOX_SIZE 12
575 static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
578 MOVStreamContext *sc;
581 if (c->fc->nb_streams < 1)
583 st = c->fc->streams[c->fc->nb_streams-1];
586 avio_rb32(pb); // version + flags
587 entries = avio_rb32(pb);
589 entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
590 entries >= UINT_MAX / sizeof(*sc->drefs))
591 return AVERROR_INVALIDDATA;
595 sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
597 return AVERROR(ENOMEM);
598 sc->drefs_count = entries;
600 for (i = 0; i < entries; i++) {
601 MOVDref *dref = &sc->drefs[i];
602 uint32_t size = avio_rb32(pb);
603 int64_t next = avio_tell(pb) + size - 4;
606 return AVERROR_INVALIDDATA;
608 dref->type = avio_rl32(pb);
609 avio_rb32(pb); // version + flags
611 if (dref->type == MKTAG('a','l','i','s') && size > 150) {
612 /* macintosh alias record */
613 uint16_t volume_len, len;
619 volume_len = avio_r8(pb);
620 volume_len = FFMIN(volume_len, 27);
621 ret = ffio_read_size(pb, dref->volume, 27);
624 dref->volume[volume_len] = 0;
625 av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
630 len = FFMIN(len, 63);
631 ret = ffio_read_size(pb, dref->filename, 63);
634 dref->filename[len] = 0;
635 av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
639 /* read next level up_from_alias/down_to_target */
640 dref->nlvl_from = avio_rb16(pb);
641 dref->nlvl_to = avio_rb16(pb);
642 av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
643 dref->nlvl_from, dref->nlvl_to);
647 for (type = 0; type != -1 && avio_tell(pb) < next; ) {
650 type = avio_rb16(pb);
652 av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
655 if (type == 2) { // absolute path
657 dref->path = av_mallocz(len+1);
659 return AVERROR(ENOMEM);
661 ret = ffio_read_size(pb, dref->path, len);
663 av_freep(&dref->path);
666 if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
668 memmove(dref->path, dref->path+volume_len, len);
671 // trim string of any ending zeros
672 for (j = len - 1; j >= 0; j--) {
673 if (dref->path[j] == 0)
678 for (j = 0; j < len; j++)
679 if (dref->path[j] == ':' || dref->path[j] == 0)
681 av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
682 } else if (type == 0) { // directory name
684 dref->dir = av_malloc(len+1);
686 return AVERROR(ENOMEM);
688 ret = ffio_read_size(pb, dref->dir, len);
690 av_freep(&dref->dir);
694 for (j = 0; j < len; j++)
695 if (dref->dir[j] == ':')
697 av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
702 av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
707 avio_seek(pb, next, SEEK_SET);
712 static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
721 avio_r8(pb); /* version */
722 avio_rb24(pb); /* flags */
725 ctype = avio_rl32(pb);
726 type = avio_rl32(pb); /* component subtype */
728 av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
729 av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
731 if (c->trak_index < 0) { // meta not inside a trak
732 if (type == MKTAG('m','d','t','a')) {
733 c->found_hdlr_mdta = 1;
738 st = c->fc->streams[c->fc->nb_streams-1];
740 if (type == MKTAG('v','i','d','e'))
741 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
742 else if (type == MKTAG('s','o','u','n'))
743 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
744 else if (type == MKTAG('m','1','a',' '))
745 st->codecpar->codec_id = AV_CODEC_ID_MP2;
746 else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
747 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
749 avio_rb32(pb); /* component manufacture */
750 avio_rb32(pb); /* component flags */
751 avio_rb32(pb); /* component flags mask */
753 title_size = atom.size - 24;
754 if (title_size > 0) {
755 if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
756 return AVERROR_INVALIDDATA;
757 title_str = av_malloc(title_size + 1); /* Add null terminator */
759 return AVERROR(ENOMEM);
761 ret = ffio_read_size(pb, title_str, title_size);
763 av_freep(&title_str);
766 title_str[title_size] = 0;
768 int off = (!c->isom && title_str[0] == title_size - 1);
769 // flag added so as to not set stream handler name if already set from mdia->hdlr
770 av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
772 av_freep(&title_str);
778 static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
780 return ff_mov_read_esds(c->fc, pb);
783 static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
786 enum AVAudioServiceType *ast;
787 int ac3info, acmod, lfeon, bsmod;
789 if (c->fc->nb_streams < 1)
791 st = c->fc->streams[c->fc->nb_streams-1];
793 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
796 return AVERROR(ENOMEM);
798 ac3info = avio_rb24(pb);
799 bsmod = (ac3info >> 14) & 0x7;
800 acmod = (ac3info >> 11) & 0x7;
801 lfeon = (ac3info >> 10) & 0x1;
802 st->codecpar->channels = ((int[]){2,1,2,3,3,4,4,5})[acmod] + lfeon;
803 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
805 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
807 if (st->codecpar->channels > 1 && bsmod == 0x7)
808 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
810 #if FF_API_LAVF_AVCTX
811 FF_DISABLE_DEPRECATION_WARNINGS
812 st->codec->audio_service_type = *ast;
813 FF_ENABLE_DEPRECATION_WARNINGS
819 static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
822 enum AVAudioServiceType *ast;
823 int eac3info, acmod, lfeon, bsmod;
825 if (c->fc->nb_streams < 1)
827 st = c->fc->streams[c->fc->nb_streams-1];
829 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
832 return AVERROR(ENOMEM);
834 /* No need to parse fields for additional independent substreams and its
835 * associated dependent substreams since libavcodec's E-AC-3 decoder
836 * does not support them yet. */
837 avio_rb16(pb); /* data_rate and num_ind_sub */
838 eac3info = avio_rb24(pb);
839 bsmod = (eac3info >> 12) & 0x1f;
840 acmod = (eac3info >> 9) & 0x7;
841 lfeon = (eac3info >> 8) & 0x1;
842 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
844 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
845 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
847 if (st->codecpar->channels > 1 && bsmod == 0x7)
848 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
850 #if FF_API_LAVF_AVCTX
851 FF_DISABLE_DEPRECATION_WARNINGS
852 st->codec->audio_service_type = *ast;
853 FF_ENABLE_DEPRECATION_WARNINGS
859 static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
861 const uint32_t ddts_size = 20;
864 uint32_t frame_duration_code = 0;
865 uint32_t channel_layout_code = 0;
868 buf = av_malloc(ddts_size + AV_INPUT_BUFFER_PADDING_SIZE);
870 return AVERROR(ENOMEM);
872 if (avio_read(pb, buf, ddts_size) < ddts_size) {
874 return AVERROR_INVALIDDATA;
877 init_get_bits(&gb, buf, 8*ddts_size);
879 if (c->fc->nb_streams < 1) {
883 st = c->fc->streams[c->fc->nb_streams-1];
885 st->codecpar->sample_rate = get_bits_long(&gb, 32);
886 if (st->codecpar->sample_rate <= 0) {
887 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
889 return AVERROR_INVALIDDATA;
891 skip_bits_long(&gb, 32); /* max bitrate */
892 st->codecpar->bit_rate = get_bits_long(&gb, 32);
893 st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
894 frame_duration_code = get_bits(&gb, 2);
895 skip_bits(&gb, 30); /* various fields */
896 channel_layout_code = get_bits(&gb, 16);
898 st->codecpar->frame_size =
899 (frame_duration_code == 0) ? 512 :
900 (frame_duration_code == 1) ? 1024 :
901 (frame_duration_code == 2) ? 2048 :
902 (frame_duration_code == 3) ? 4096 : 0;
904 if (channel_layout_code > 0xff) {
905 av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout");
907 st->codecpar->channel_layout =
908 ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
909 ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
910 ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
911 ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
912 ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
913 ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0);
915 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
921 static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
925 if (c->fc->nb_streams < 1)
927 st = c->fc->streams[c->fc->nb_streams-1];
932 /* skip version and flags */
935 ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
940 static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
945 if (c->fc->nb_streams < 1)
947 st = c->fc->streams[c->fc->nb_streams-1];
949 if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
950 av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
955 static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
957 const int num = avio_rb32(pb);
958 const int den = avio_rb32(pb);
961 if (c->fc->nb_streams < 1)
963 st = c->fc->streams[c->fc->nb_streams-1];
965 if ((st->sample_aspect_ratio.den != 1 || st->sample_aspect_ratio.num) && // default
966 (den != st->sample_aspect_ratio.den || num != st->sample_aspect_ratio.num)) {
967 av_log(c->fc, AV_LOG_WARNING,
968 "sample aspect ratio already set to %d:%d, ignoring 'pasp' atom (%d:%d)\n",
969 st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
971 } else if (den != 0) {
972 av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den,
978 /* this atom contains actual media data */
979 static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
981 if (atom.size == 0) /* wrong one (MP4) */
984 return 0; /* now go for moov */
987 #define DRM_BLOB_SIZE 56
989 static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
991 uint8_t intermediate_key[20];
992 uint8_t intermediate_iv[20];
995 uint8_t file_checksum[20];
996 uint8_t calculated_checksum[20];
1000 uint8_t *activation_bytes = c->activation_bytes;
1001 uint8_t *fixed_key = c->audible_fixed_key;
1005 sha = av_sha_alloc();
1007 return AVERROR(ENOMEM);
1008 c->aes_decrypt = av_aes_alloc();
1009 if (!c->aes_decrypt) {
1010 ret = AVERROR(ENOMEM);
1014 /* drm blob processing */
1015 avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1016 avio_read(pb, input, DRM_BLOB_SIZE);
1017 avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1018 avio_read(pb, file_checksum, 20);
1020 av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == "); // required by external tools
1021 for (i = 0; i < 20; i++)
1022 av_log(c->fc, AV_LOG_INFO, "%02x", file_checksum[i]);
1023 av_log(c->fc, AV_LOG_INFO, "\n");
1025 /* verify activation data */
1026 if (!activation_bytes) {
1027 av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1028 ret = 0; /* allow ffprobe to continue working on .aax files */
1031 if (c->activation_bytes_size != 4) {
1032 av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1033 ret = AVERROR(EINVAL);
1037 /* verify fixed key */
1038 if (c->audible_fixed_key_size != 16) {
1039 av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1040 ret = AVERROR(EINVAL);
1044 /* AAX (and AAX+) key derivation */
1045 av_sha_init(sha, 160);
1046 av_sha_update(sha, fixed_key, 16);
1047 av_sha_update(sha, activation_bytes, 4);
1048 av_sha_final(sha, intermediate_key);
1049 av_sha_init(sha, 160);
1050 av_sha_update(sha, fixed_key, 16);
1051 av_sha_update(sha, intermediate_key, 20);
1052 av_sha_update(sha, activation_bytes, 4);
1053 av_sha_final(sha, intermediate_iv);
1054 av_sha_init(sha, 160);
1055 av_sha_update(sha, intermediate_key, 16);
1056 av_sha_update(sha, intermediate_iv, 16);
1057 av_sha_final(sha, calculated_checksum);
1058 if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1059 av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1060 ret = AVERROR_INVALIDDATA;
1063 av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1064 av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1065 for (i = 0; i < 4; i++) {
1066 // file data (in output) is stored in big-endian mode
1067 if (activation_bytes[i] != output[3 - i]) { // critical error
1068 av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1069 ret = AVERROR_INVALIDDATA;
1073 memcpy(c->file_key, output + 8, 16);
1074 memcpy(input, output + 26, 16);
1075 av_sha_init(sha, 160);
1076 av_sha_update(sha, input, 16);
1077 av_sha_update(sha, c->file_key, 16);
1078 av_sha_update(sha, fixed_key, 16);
1079 av_sha_final(sha, c->file_iv);
1087 // Audible AAX (and AAX+) bytestream decryption
1088 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1091 unsigned char iv[16];
1093 memcpy(iv, c->file_iv, 16); // iv is overwritten
1094 blocks = size >> 4; // trailing bytes are not encrypted!
1095 av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1096 av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1101 /* read major brand, minor version and compatible brands and store them as metadata */
1102 static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1105 int comp_brand_size;
1106 char* comp_brands_str;
1107 uint8_t type[5] = {0};
1108 int ret = ffio_read_size(pb, type, 4);
1112 if (strcmp(type, "qt "))
1114 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1115 av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1116 minor_ver = avio_rb32(pb); /* minor version */
1117 av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1119 comp_brand_size = atom.size - 8;
1120 if (comp_brand_size < 0)
1121 return AVERROR_INVALIDDATA;
1122 comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1123 if (!comp_brands_str)
1124 return AVERROR(ENOMEM);
1126 ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1128 av_freep(&comp_brands_str);
1131 comp_brands_str[comp_brand_size] = 0;
1132 av_dict_set(&c->fc->metadata, "compatible_brands",
1133 comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1138 /* this atom should contain all header atoms */
1139 static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1143 if (c->found_moov) {
1144 av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1145 avio_skip(pb, atom.size);
1149 if ((ret = mov_read_default(c, pb, atom)) < 0)
1151 /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1152 /* so we don't parse the whole file if over a network */
1154 return 0; /* now go for mdat */
1157 static MOVFragmentStreamInfo * get_frag_stream_info(
1158 MOVFragmentIndex *frag_index,
1163 MOVFragmentIndexItem * item;
1165 if (index < 0 || index >= frag_index->nb_items)
1167 item = &frag_index->item[index];
1168 for (i = 0; i < item->nb_stream_info; i++)
1169 if (item->stream_info[i].id == id)
1170 return &item->stream_info[i];
1172 // This shouldn't happen
1176 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1179 MOVFragmentIndexItem * item;
1181 if (frag_index->current < 0 ||
1182 frag_index->current >= frag_index->nb_items)
1185 item = &frag_index->item[frag_index->current];
1186 for (i = 0; i < item->nb_stream_info; i++)
1187 if (item->stream_info[i].id == id) {
1192 // id not found. This shouldn't happen.
1196 static MOVFragmentStreamInfo * get_current_frag_stream_info(
1197 MOVFragmentIndex *frag_index)
1199 MOVFragmentIndexItem *item;
1200 if (frag_index->current < 0 ||
1201 frag_index->current >= frag_index->nb_items)
1204 item = &frag_index->item[frag_index->current];
1205 if (item->current >= 0 && item->current < item->nb_stream_info)
1206 return &item->stream_info[item->current];
1208 // This shouldn't happen
1212 static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
1215 int64_t moof_offset;
1217 // Optimize for appending new entries
1218 if (!frag_index->nb_items ||
1219 frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1220 return frag_index->nb_items;
1223 b = frag_index->nb_items;
1227 moof_offset = frag_index->item[m].moof_offset;
1228 if (moof_offset >= offset)
1230 if (moof_offset <= offset)
1236 static int64_t get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
1238 av_assert0(frag_stream_info);
1239 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1240 return frag_stream_info->sidx_pts;
1241 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1242 return frag_stream_info->first_tfra_pts;
1243 return frag_stream_info->tfdt_dts;
1246 static int64_t get_frag_time(MOVFragmentIndex *frag_index,
1247 int index, int track_id)
1249 MOVFragmentStreamInfo * frag_stream_info;
1253 if (track_id >= 0) {
1254 frag_stream_info = get_frag_stream_info(frag_index, index, track_id);
1255 return frag_stream_info->sidx_pts;
1258 for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1259 frag_stream_info = &frag_index->item[index].stream_info[i];
1260 timestamp = get_stream_info_time(frag_stream_info);
1261 if (timestamp != AV_NOPTS_VALUE)
1264 return AV_NOPTS_VALUE;
1267 static int search_frag_timestamp(MOVFragmentIndex *frag_index,
1268 AVStream *st, int64_t timestamp)
1275 // If the stream is referenced by any sidx, limit the search
1276 // to fragments that referenced this stream in the sidx
1277 MOVStreamContext *sc = st->priv_data;
1283 b = frag_index->nb_items;
1286 m0 = m = (a + b) >> 1;
1289 (frag_time = get_frag_time(frag_index, m, id)) == AV_NOPTS_VALUE)
1292 if (m < b && frag_time <= timestamp)
1301 static int update_frag_index(MOVContext *c, int64_t offset)
1304 MOVFragmentIndexItem * item;
1305 MOVFragmentStreamInfo * frag_stream_info;
1307 // If moof_offset already exists in frag_index, return index to it
1308 index = search_frag_moof_offset(&c->frag_index, offset);
1309 if (index < c->frag_index.nb_items &&
1310 c->frag_index.item[index].moof_offset == offset)
1313 // offset is not yet in frag index.
1314 // Insert new item at index (sorted by moof offset)
1315 item = av_fast_realloc(c->frag_index.item,
1316 &c->frag_index.allocated_size,
1317 (c->frag_index.nb_items + 1) *
1318 sizeof(*c->frag_index.item));
1321 c->frag_index.item = item;
1323 frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1324 sizeof(*item->stream_info));
1325 if (!frag_stream_info)
1328 for (i = 0; i < c->fc->nb_streams; i++) {
1329 // Avoid building frag index if streams lack track id.
1330 if (c->fc->streams[i]->id < 0) {
1331 av_free(frag_stream_info);
1332 return AVERROR_INVALIDDATA;
1335 frag_stream_info[i].id = c->fc->streams[i]->id;
1336 frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1337 frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1338 frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1339 frag_stream_info[i].index_entry = -1;
1340 frag_stream_info[i].encryption_index = NULL;
1343 if (index < c->frag_index.nb_items)
1344 memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1345 (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1347 item = &c->frag_index.item[index];
1348 item->headers_read = 0;
1350 item->nb_stream_info = c->fc->nb_streams;
1351 item->moof_offset = offset;
1352 item->stream_info = frag_stream_info;
1353 c->frag_index.nb_items++;
1358 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1359 int id, int entries)
1362 MOVFragmentStreamInfo * frag_stream_info;
1366 for (i = index; i < frag_index->nb_items; i++) {
1367 frag_stream_info = get_frag_stream_info(frag_index, i, id);
1368 if (frag_stream_info && frag_stream_info->index_entry >= 0)
1369 frag_stream_info->index_entry += entries;
1373 static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1375 // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1376 c->fragment.found_tfhd = 0;
1378 if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1379 c->has_looked_for_mfra = 1;
1380 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1382 av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1384 if ((ret = mov_read_mfra(c, pb)) < 0) {
1385 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1386 "read the mfra (may be a live ismv)\n");
1389 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1390 "seekable, can not look for mfra\n");
1393 c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1394 av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1395 c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1396 return mov_read_default(c, pb, atom);
1399 static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time, void *logctx)
1402 if(time >= 2082844800)
1403 time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1405 if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1406 av_log(logctx, AV_LOG_DEBUG, "creation_time is not representable\n");
1410 avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1414 static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1417 MOVStreamContext *sc;
1419 char language[4] = {0};
1421 int64_t creation_time;
1423 if (c->fc->nb_streams < 1)
1425 st = c->fc->streams[c->fc->nb_streams-1];
1428 if (sc->time_scale) {
1429 av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1430 return AVERROR_INVALIDDATA;
1433 version = avio_r8(pb);
1435 avpriv_request_sample(c->fc, "Version %d", version);
1436 return AVERROR_PATCHWELCOME;
1438 avio_rb24(pb); /* flags */
1440 creation_time = avio_rb64(pb);
1443 creation_time = avio_rb32(pb);
1444 avio_rb32(pb); /* modification time */
1446 mov_metadata_creation_time(&st->metadata, creation_time, c->fc);
1448 sc->time_scale = avio_rb32(pb);
1449 if (sc->time_scale <= 0) {
1450 av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1453 st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1455 lang = avio_rb16(pb); /* language */
1456 if (ff_mov_lang_to_iso639(lang, language))
1457 av_dict_set(&st->metadata, "language", language, 0);
1458 avio_rb16(pb); /* quality */
1463 static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1466 int64_t creation_time;
1467 int version = avio_r8(pb); /* version */
1468 avio_rb24(pb); /* flags */
1471 creation_time = avio_rb64(pb);
1474 creation_time = avio_rb32(pb);
1475 avio_rb32(pb); /* modification time */
1477 mov_metadata_creation_time(&c->fc->metadata, creation_time, c->fc);
1478 c->time_scale = avio_rb32(pb); /* time scale */
1479 if (c->time_scale <= 0) {
1480 av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1483 av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1485 c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1486 // set the AVCodecContext duration because the duration of individual tracks
1487 // may be inaccurate
1488 if (c->time_scale > 0 && !c->trex_data)
1489 c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale);
1490 avio_rb32(pb); /* preferred scale */
1492 avio_rb16(pb); /* preferred volume */
1494 avio_skip(pb, 10); /* reserved */
1496 /* movie display matrix, store it in main context and use it later on */
1497 for (i = 0; i < 3; i++) {
1498 c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1499 c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1500 c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1503 avio_rb32(pb); /* preview time */
1504 avio_rb32(pb); /* preview duration */
1505 avio_rb32(pb); /* poster time */
1506 avio_rb32(pb); /* selection time */
1507 avio_rb32(pb); /* selection duration */
1508 avio_rb32(pb); /* current time */
1509 avio_rb32(pb); /* next track ID */
1514 static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1519 if (c->fc->nb_streams < 1)
1521 st = c->fc->streams[c->fc->nb_streams-1];
1523 little_endian = avio_rb16(pb) & 0xFF;
1524 av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1525 if (little_endian == 1) {
1526 switch (st->codecpar->codec_id) {
1527 case AV_CODEC_ID_PCM_S24BE:
1528 st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE;
1530 case AV_CODEC_ID_PCM_S32BE:
1531 st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE;
1533 case AV_CODEC_ID_PCM_F32BE:
1534 st->codecpar->codec_id = AV_CODEC_ID_PCM_F32LE;
1536 case AV_CODEC_ID_PCM_F64BE:
1537 st->codecpar->codec_id = AV_CODEC_ID_PCM_F64LE;
1546 static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1549 char color_parameter_type[5] = { 0 };
1550 uint16_t color_primaries, color_trc, color_matrix;
1553 if (c->fc->nb_streams < 1)
1555 st = c->fc->streams[c->fc->nb_streams - 1];
1557 ret = ffio_read_size(pb, color_parameter_type, 4);
1560 if (strncmp(color_parameter_type, "nclx", 4) &&
1561 strncmp(color_parameter_type, "nclc", 4)) {
1562 av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
1563 color_parameter_type);
1567 color_primaries = avio_rb16(pb);
1568 color_trc = avio_rb16(pb);
1569 color_matrix = avio_rb16(pb);
1571 av_log(c->fc, AV_LOG_TRACE,
1572 "%s: pri %d trc %d matrix %d",
1573 color_parameter_type, color_primaries, color_trc, color_matrix);
1575 if (!strncmp(color_parameter_type, "nclx", 4)) {
1576 uint8_t color_range = avio_r8(pb) >> 7;
1577 av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
1579 st->codecpar->color_range = AVCOL_RANGE_JPEG;
1581 st->codecpar->color_range = AVCOL_RANGE_MPEG;
1584 if (!av_color_primaries_name(color_primaries))
1585 color_primaries = AVCOL_PRI_UNSPECIFIED;
1586 if (!av_color_transfer_name(color_trc))
1587 color_trc = AVCOL_TRC_UNSPECIFIED;
1588 if (!av_color_space_name(color_matrix))
1589 color_matrix = AVCOL_SPC_UNSPECIFIED;
1591 st->codecpar->color_primaries = color_primaries;
1592 st->codecpar->color_trc = color_trc;
1593 st->codecpar->color_space = color_matrix;
1594 av_log(c->fc, AV_LOG_TRACE, "\n");
1599 static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1602 unsigned mov_field_order;
1603 enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
1605 if (c->fc->nb_streams < 1) // will happen with jp2 files
1607 st = c->fc->streams[c->fc->nb_streams-1];
1609 return AVERROR_INVALIDDATA;
1610 mov_field_order = avio_rb16(pb);
1611 if ((mov_field_order & 0xFF00) == 0x0100)
1612 decoded_field_order = AV_FIELD_PROGRESSIVE;
1613 else if ((mov_field_order & 0xFF00) == 0x0200) {
1614 switch (mov_field_order & 0xFF) {
1615 case 0x01: decoded_field_order = AV_FIELD_TT;
1617 case 0x06: decoded_field_order = AV_FIELD_BB;
1619 case 0x09: decoded_field_order = AV_FIELD_TB;
1621 case 0x0E: decoded_field_order = AV_FIELD_BT;
1625 if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
1626 av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
1628 st->codecpar->field_order = decoded_field_order;
1633 static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
1636 uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
1637 if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
1638 return AVERROR_INVALIDDATA;
1639 if ((err = av_reallocp(&par->extradata, size)) < 0) {
1640 par->extradata_size = 0;
1643 par->extradata_size = size - AV_INPUT_BUFFER_PADDING_SIZE;
1647 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
1648 static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1649 AVCodecParameters *par, uint8_t *buf)
1651 int64_t result = atom.size;
1654 AV_WB32(buf , atom.size + 8);
1655 AV_WL32(buf + 4, atom.type);
1656 err = ffio_read_size(pb, buf + 8, atom.size);
1658 par->extradata_size -= atom.size;
1660 } else if (err < atom.size) {
1661 av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
1662 par->extradata_size -= atom.size - err;
1665 memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1669 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
1670 static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1671 enum AVCodecID codec_id)
1674 uint64_t original_size;
1677 if (c->fc->nb_streams < 1) // will happen with jp2 files
1679 st = c->fc->streams[c->fc->nb_streams-1];
1681 if (st->codecpar->codec_id != codec_id)
1682 return 0; /* unexpected codec_id - don't mess with extradata */
1684 original_size = st->codecpar->extradata_size;
1685 err = mov_realloc_extradata(st->codecpar, atom);
1689 err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
1692 return 0; // Note: this is the original behavior to ignore truncation.
1695 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
1696 static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1698 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
1701 static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1703 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS);
1706 static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1708 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
1711 static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1713 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
1716 static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1718 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
1720 ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
1724 static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1726 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
1728 if (!ret && c->fc->nb_streams >= 1) {
1729 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1730 if (par->extradata_size >= 40) {
1731 par->height = AV_RB16(&par->extradata[36]);
1732 par->width = AV_RB16(&par->extradata[38]);
1738 static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1740 if (c->fc->nb_streams >= 1) {
1741 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1742 if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
1743 par->codec_id == AV_CODEC_ID_H264 &&
1747 cid = avio_rb16(pb);
1748 /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
1749 if (cid == 0xd4d || cid == 0xd4e)
1752 } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
1753 par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
1754 par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
1758 num = avio_rb32(pb);
1759 den = avio_rb32(pb);
1760 if (num <= 0 || den <= 0)
1762 switch (avio_rb32(pb)) {
1764 if (den >= INT_MAX / 2)
1768 c->fc->streams[c->fc->nb_streams-1]->display_aspect_ratio.num = num;
1769 c->fc->streams[c->fc->nb_streams-1]->display_aspect_ratio.den = den;
1776 return mov_read_avid(c, pb, atom);
1779 static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1783 uint64_t original_size;
1784 if (c->fc->nb_streams >= 1) {
1785 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1786 if (par->codec_id == AV_CODEC_ID_H264)
1788 if (atom.size == 16) {
1789 original_size = par->extradata_size;
1790 ret = mov_realloc_extradata(par, atom);
1792 length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
1793 if (length == atom.size) {
1794 const uint8_t range_value = par->extradata[original_size + 19];
1795 switch (range_value) {
1797 par->color_range = AVCOL_RANGE_MPEG;
1800 par->color_range = AVCOL_RANGE_JPEG;
1803 av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
1806 ff_dlog(c->fc, "color_range: %d\n", par->color_range);
1808 /* For some reason the whole atom was not added to the extradata */
1809 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
1812 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
1815 av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
1822 static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1824 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
1827 static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1832 if (c->fc->nb_streams < 1)
1834 st = c->fc->streams[c->fc->nb_streams-1];
1836 if ((uint64_t)atom.size > (1<<30))
1837 return AVERROR_INVALIDDATA;
1839 if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
1840 st->codecpar->codec_id == AV_CODEC_ID_QDMC ||
1841 st->codecpar->codec_id == AV_CODEC_ID_SPEEX) {
1842 // pass all frma atom to codec, needed at least for QDMC and QDM2
1843 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1846 } else if (atom.size > 8) { /* to read frma, esds atoms */
1847 if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
1849 ret = ffio_ensure_seekback(pb, 8);
1852 buffer = avio_rb64(pb);
1854 if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
1855 && buffer >> 32 <= atom.size
1856 && buffer >> 32 >= 8) {
1859 } else if (!st->codecpar->extradata_size) {
1860 #define ALAC_EXTRADATA_SIZE 36
1861 st->codecpar->extradata = av_mallocz(ALAC_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
1862 if (!st->codecpar->extradata)
1863 return AVERROR(ENOMEM);
1864 st->codecpar->extradata_size = ALAC_EXTRADATA_SIZE;
1865 AV_WB32(st->codecpar->extradata , ALAC_EXTRADATA_SIZE);
1866 AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
1867 AV_WB64(st->codecpar->extradata + 12, buffer);
1868 avio_read(pb, st->codecpar->extradata + 20, 16);
1869 avio_skip(pb, atom.size - 24);
1873 if ((ret = mov_read_default(c, pb, atom)) < 0)
1876 avio_skip(pb, atom.size);
1881 * This function reads atom content and puts data in extradata without tag
1882 * nor size unlike mov_read_extradata.
1884 static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1889 if (c->fc->nb_streams < 1)
1891 st = c->fc->streams[c->fc->nb_streams-1];
1893 if ((uint64_t)atom.size > (1<<30))
1894 return AVERROR_INVALIDDATA;
1896 if (atom.size >= 10) {
1897 // Broken files created by legacy versions of libavformat will
1898 // wrap a whole fiel atom inside of a glbl atom.
1899 unsigned size = avio_rb32(pb);
1900 unsigned type = avio_rl32(pb);
1901 avio_seek(pb, -8, SEEK_CUR);
1902 if (type == MKTAG('f','i','e','l') && size == atom.size)
1903 return mov_read_default(c, pb, atom);
1905 if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
1906 av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
1909 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1912 if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
1913 /* HEVC-based Dolby Vision derived from hvc1.
1914 Happens to match with an identifier
1915 previously utilized for DV. Thus, if we have
1916 the hvcC extradata box available as specified,
1917 set codec to HEVC */
1918 st->codecpar->codec_id = AV_CODEC_ID_HEVC;
1923 static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1926 uint8_t profile_level;
1929 if (c->fc->nb_streams < 1)
1931 st = c->fc->streams[c->fc->nb_streams-1];
1933 if (atom.size >= (1<<28) || atom.size < 7)
1934 return AVERROR_INVALIDDATA;
1936 profile_level = avio_r8(pb);
1937 if ((profile_level & 0xf0) != 0xc0)
1940 avio_seek(pb, 6, SEEK_CUR);
1941 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
1949 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
1950 * but can have extradata appended at the end after the 40 bytes belonging
1953 static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1958 if (c->fc->nb_streams < 1)
1960 if (atom.size <= 40)
1962 st = c->fc->streams[c->fc->nb_streams-1];
1964 if ((uint64_t)atom.size > (1<<30))
1965 return AVERROR_INVALIDDATA;
1968 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
1975 static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1978 MOVStreamContext *sc;
1979 unsigned int i, entries;
1981 if (c->fc->nb_streams < 1)
1983 st = c->fc->streams[c->fc->nb_streams-1];
1986 avio_r8(pb); /* version */
1987 avio_rb24(pb); /* flags */
1989 entries = avio_rb32(pb);
1994 if (sc->chunk_offsets)
1995 av_log(c->fc, AV_LOG_WARNING, "Duplicated STCO atom\n");
1996 av_free(sc->chunk_offsets);
1997 sc->chunk_count = 0;
1998 sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
1999 if (!sc->chunk_offsets)
2000 return AVERROR(ENOMEM);
2001 sc->chunk_count = entries;
2003 if (atom.type == MKTAG('s','t','c','o'))
2004 for (i = 0; i < entries && !pb->eof_reached; i++)
2005 sc->chunk_offsets[i] = avio_rb32(pb);
2006 else if (atom.type == MKTAG('c','o','6','4'))
2007 for (i = 0; i < entries && !pb->eof_reached; i++)
2008 sc->chunk_offsets[i] = avio_rb64(pb);
2010 return AVERROR_INVALIDDATA;
2012 sc->chunk_count = i;
2014 if (pb->eof_reached) {
2015 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2022 static int mov_codec_id(AVStream *st, uint32_t format)
2024 int id = ff_codec_get_id(ff_codec_movaudio_tags, format);
2027 ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2028 (format & 0xFFFF) == 'T' + ('S' << 8)))
2029 id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format) & 0xFFFF);
2031 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2032 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2033 } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2034 /* skip old ASF MPEG-4 tag */
2035 format && format != MKTAG('m','p','4','s')) {
2036 id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2038 id = ff_codec_get_id(ff_codec_bmp_tags, format);
2040 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
2041 else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2042 (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE &&
2043 st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2044 id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
2046 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
2048 id = ff_codec_get_id(ff_codec_movdata_tags, format);
2052 st->codecpar->codec_tag = format;
2057 static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
2058 AVStream *st, MOVStreamContext *sc)
2060 uint8_t codec_name[32] = { 0 };
2064 /* The first 16 bytes of the video sample description are already
2065 * read in ff_mov_read_stsd_entries() */
2066 stsd_start = avio_tell(pb) - 16;
2068 avio_rb16(pb); /* version */
2069 avio_rb16(pb); /* revision level */
2070 avio_rb32(pb); /* vendor */
2071 avio_rb32(pb); /* temporal quality */
2072 avio_rb32(pb); /* spatial quality */
2074 st->codecpar->width = avio_rb16(pb); /* width */
2075 st->codecpar->height = avio_rb16(pb); /* height */
2077 avio_rb32(pb); /* horiz resolution */
2078 avio_rb32(pb); /* vert resolution */
2079 avio_rb32(pb); /* data size, always 0 */
2080 avio_rb16(pb); /* frames per samples */
2082 len = avio_r8(pb); /* codec name, pascal string */
2085 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2087 avio_skip(pb, 31 - len);
2090 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2092 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2093 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2094 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2095 st->codecpar->width &= ~1;
2096 st->codecpar->height &= ~1;
2098 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2099 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2100 !strncmp(codec_name, "Sorenson H263", 13))
2101 st->codecpar->codec_id = AV_CODEC_ID_FLV1;
2103 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2105 avio_seek(pb, stsd_start, SEEK_SET);
2107 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2108 st->codecpar->bits_per_coded_sample &= 0x1F;
2109 sc->has_palette = 1;
2113 static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
2114 AVStream *st, MOVStreamContext *sc)
2116 int bits_per_sample, flags;
2117 uint16_t version = avio_rb16(pb);
2118 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2120 avio_rb16(pb); /* revision level */
2121 avio_rb32(pb); /* vendor */
2123 st->codecpar->channels = avio_rb16(pb); /* channel count */
2124 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2125 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", st->codecpar->channels);
2127 sc->audio_cid = avio_rb16(pb);
2128 avio_rb16(pb); /* packet size = 0 */
2130 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2132 // Read QT version 1 fields. In version 0 these do not exist.
2133 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2135 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2136 (sc->stsd_version == 0 && version > 0)) {
2138 sc->samples_per_frame = avio_rb32(pb);
2139 avio_rb32(pb); /* bytes per packet */
2140 sc->bytes_per_frame = avio_rb32(pb);
2141 avio_rb32(pb); /* bytes per sample */
2142 } else if (version == 2) {
2143 avio_rb32(pb); /* sizeof struct only */
2144 st->codecpar->sample_rate = av_int2double(avio_rb64(pb));
2145 st->codecpar->channels = avio_rb32(pb);
2146 avio_rb32(pb); /* always 0x7F000000 */
2147 st->codecpar->bits_per_coded_sample = avio_rb32(pb);
2149 flags = avio_rb32(pb); /* lpcm format specific flag */
2150 sc->bytes_per_frame = avio_rb32(pb);
2151 sc->samples_per_frame = avio_rb32(pb);
2152 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2153 st->codecpar->codec_id =
2154 ff_mov_get_lpcm_codec_id(st->codecpar->bits_per_coded_sample,
2157 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2158 /* can't correctly handle variable sized packet as audio unit */
2159 switch (st->codecpar->codec_id) {
2160 case AV_CODEC_ID_MP2:
2161 case AV_CODEC_ID_MP3:
2162 st->need_parsing = AVSTREAM_PARSE_FULL;
2168 if (sc->format == 0) {
2169 if (st->codecpar->bits_per_coded_sample == 8)
2170 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2171 else if (st->codecpar->bits_per_coded_sample == 16)
2172 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2175 switch (st->codecpar->codec_id) {
2176 case AV_CODEC_ID_PCM_S8:
2177 case AV_CODEC_ID_PCM_U8:
2178 if (st->codecpar->bits_per_coded_sample == 16)
2179 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16BE;
2181 case AV_CODEC_ID_PCM_S16LE:
2182 case AV_CODEC_ID_PCM_S16BE:
2183 if (st->codecpar->bits_per_coded_sample == 8)
2184 st->codecpar->codec_id = AV_CODEC_ID_PCM_S8;
2185 else if (st->codecpar->bits_per_coded_sample == 24)
2186 st->codecpar->codec_id =
2187 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2188 AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
2189 else if (st->codecpar->bits_per_coded_sample == 32)
2190 st->codecpar->codec_id =
2191 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2192 AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
2194 /* set values for old format before stsd version 1 appeared */
2195 case AV_CODEC_ID_MACE3:
2196 sc->samples_per_frame = 6;
2197 sc->bytes_per_frame = 2 * st->codecpar->channels;
2199 case AV_CODEC_ID_MACE6:
2200 sc->samples_per_frame = 6;
2201 sc->bytes_per_frame = 1 * st->codecpar->channels;
2203 case AV_CODEC_ID_ADPCM_IMA_QT:
2204 sc->samples_per_frame = 64;
2205 sc->bytes_per_frame = 34 * st->codecpar->channels;
2207 case AV_CODEC_ID_GSM:
2208 sc->samples_per_frame = 160;
2209 sc->bytes_per_frame = 33;
2215 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2216 if (bits_per_sample) {
2217 st->codecpar->bits_per_coded_sample = bits_per_sample;
2218 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->channels;
2222 static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
2223 AVStream *st, MOVStreamContext *sc,
2226 // ttxt stsd contains display flags, justification, background
2227 // color, fonts, and default styles, so fake an atom to read it
2228 MOVAtom fake_atom = { .size = size };
2229 // mp4s contains a regular esds atom
2230 if (st->codecpar->codec_tag != AV_RL32("mp4s"))
2231 mov_read_glbl(c, pb, fake_atom);
2232 st->codecpar->width = sc->width;
2233 st->codecpar->height = sc->height;
2236 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2241 y = (ycbcr >> 16) & 0xFF;
2242 cr = (ycbcr >> 8) & 0xFF;
2245 b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
2246 g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
2247 r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
2249 return (r << 16) | (g << 8) | b;
2252 static int mov_rewrite_dvd_sub_extradata(AVStream *st)
2254 char buf[256] = {0};
2255 uint8_t *src = st->codecpar->extradata;
2258 if (st->codecpar->extradata_size != 64)
2261 if (st->codecpar->width > 0 && st->codecpar->height > 0)
2262 snprintf(buf, sizeof(buf), "size: %dx%d\n",
2263 st->codecpar->width, st->codecpar->height);
2264 av_strlcat(buf, "palette: ", sizeof(buf));
2266 for (i = 0; i < 16; i++) {
2267 uint32_t yuv = AV_RB32(src + i * 4);
2268 uint32_t rgba = yuv_to_rgba(yuv);
2270 av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2273 if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2276 ret = ff_alloc_extradata(st->codecpar, strlen(buf));
2279 memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2284 static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
2285 AVStream *st, MOVStreamContext *sc,
2290 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2291 if ((int)size != size)
2292 return AVERROR(ENOMEM);
2294 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2298 MOVStreamContext *tmcd_ctx = st->priv_data;
2300 val = AV_RB32(st->codecpar->extradata + 4);
2301 tmcd_ctx->tmcd_flags = val;
2302 st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2303 st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2304 #if FF_API_LAVF_AVCTX
2305 FF_DISABLE_DEPRECATION_WARNINGS
2306 st->codec->time_base = av_inv_q(st->avg_frame_rate);
2307 FF_ENABLE_DEPRECATION_WARNINGS
2309 /* adjust for per frame dur in counter mode */
2310 if (tmcd_ctx->tmcd_flags & 0x0008) {
2311 int timescale = AV_RB32(st->codecpar->extradata + 8);
2312 int framedur = AV_RB32(st->codecpar->extradata + 12);
2313 st->avg_frame_rate.num *= timescale;
2314 st->avg_frame_rate.den *= framedur;
2315 #if FF_API_LAVF_AVCTX
2316 FF_DISABLE_DEPRECATION_WARNINGS
2317 st->codec->time_base.den *= timescale;
2318 st->codec->time_base.num *= framedur;
2319 FF_ENABLE_DEPRECATION_WARNINGS
2323 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2324 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2325 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2326 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2327 if (str_size > 0 && size >= (int)str_size + 26) {
2328 char *reel_name = av_malloc(str_size + 1);
2330 return AVERROR(ENOMEM);
2331 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2332 reel_name[str_size] = 0; /* Add null terminator */
2333 /* don't add reel_name if emtpy string */
2334 if (*reel_name == 0) {
2337 av_dict_set(&st->metadata, "reel_name", reel_name, AV_DICT_DONT_STRDUP_VAL);
2344 /* other codec type, just skip (rtp, mp4s ...) */
2345 avio_skip(pb, size);
2350 static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
2351 AVStream *st, MOVStreamContext *sc)
2353 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2354 !st->codecpar->sample_rate && sc->time_scale > 1)
2355 st->codecpar->sample_rate = sc->time_scale;
2357 /* special codec parameters handling */
2358 switch (st->codecpar->codec_id) {
2359 #if CONFIG_DV_DEMUXER
2360 case AV_CODEC_ID_DVAUDIO:
2361 c->dv_fctx = avformat_alloc_context();
2363 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2364 return AVERROR(ENOMEM);
2366 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2368 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2369 return AVERROR(ENOMEM);
2371 sc->dv_audio_container = 1;
2372 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
2375 /* no ifdef since parameters are always those */
2376 case AV_CODEC_ID_QCELP:
2377 st->codecpar->channels = 1;
2378 // force sample rate for qcelp when not stored in mov
2379 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2380 st->codecpar->sample_rate = 8000;
2381 // FIXME: Why is the following needed for some files?
2382 sc->samples_per_frame = 160;
2383 if (!sc->bytes_per_frame)
2384 sc->bytes_per_frame = 35;
2386 case AV_CODEC_ID_AMR_NB:
2387 st->codecpar->channels = 1;
2388 /* force sample rate for amr, stsd in 3gp does not store sample rate */
2389 st->codecpar->sample_rate = 8000;
2391 case AV_CODEC_ID_AMR_WB:
2392 st->codecpar->channels = 1;
2393 st->codecpar->sample_rate = 16000;
2395 case AV_CODEC_ID_MP2:
2396 case AV_CODEC_ID_MP3:
2397 /* force type after stsd for m1a hdlr */
2398 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2400 case AV_CODEC_ID_GSM:
2401 case AV_CODEC_ID_ADPCM_MS:
2402 case AV_CODEC_ID_ADPCM_IMA_WAV:
2403 case AV_CODEC_ID_ILBC:
2404 case AV_CODEC_ID_MACE3:
2405 case AV_CODEC_ID_MACE6:
2406 case AV_CODEC_ID_QDM2:
2407 st->codecpar->block_align = sc->bytes_per_frame;
2409 case AV_CODEC_ID_ALAC:
2410 if (st->codecpar->extradata_size == 36) {
2411 st->codecpar->channels = AV_RB8 (st->codecpar->extradata + 21);
2412 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2415 case AV_CODEC_ID_AC3:
2416 case AV_CODEC_ID_EAC3:
2417 case AV_CODEC_ID_MPEG1VIDEO:
2418 case AV_CODEC_ID_VC1:
2419 case AV_CODEC_ID_VP8:
2420 case AV_CODEC_ID_VP9:
2421 st->need_parsing = AVSTREAM_PARSE_FULL;
2429 static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
2430 int codec_tag, int format,
2433 int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2436 (codec_tag != format &&
2437 // AVID 1:1 samples with differing data format and codec tag exist
2438 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
2439 // prores is allowed to have differing data format and codec tag
2440 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
2442 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
2443 (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id
2444 : codec_tag != MKTAG('j','p','e','g')))) {
2445 /* Multiple fourcc, we skip JPEG. This is not correct, we should
2446 * export it as a separate AVStream but this needs a few changes
2447 * in the MOV demuxer, patch welcome. */
2449 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
2450 avio_skip(pb, size);
2457 int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
2460 MOVStreamContext *sc;
2461 int pseudo_stream_id;
2463 av_assert0 (c->fc->nb_streams >= 1);
2464 st = c->fc->streams[c->fc->nb_streams-1];
2467 for (pseudo_stream_id = 0;
2468 pseudo_stream_id < entries && !pb->eof_reached;
2469 pseudo_stream_id++) {
2470 //Parsing Sample description table
2472 int ret, dref_id = 1;
2473 MOVAtom a = { AV_RL32("stsd") };
2474 int64_t start_pos = avio_tell(pb);
2475 int64_t size = avio_rb32(pb); /* size */
2476 uint32_t format = avio_rl32(pb); /* data format */
2479 avio_rb32(pb); /* reserved */
2480 avio_rb16(pb); /* reserved */
2481 dref_id = avio_rb16(pb);
2482 } else if (size <= 7) {
2483 av_log(c->fc, AV_LOG_ERROR,
2484 "invalid size %"PRId64" in stsd\n", size);
2485 return AVERROR_INVALIDDATA;
2488 if (mov_skip_multiple_stsd(c, pb, st->codecpar->codec_tag, format,
2489 size - (avio_tell(pb) - start_pos))) {
2494 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
2495 sc->dref_id= dref_id;
2496 sc->format = format;
2498 id = mov_codec_id(st, format);
2500 av_log(c->fc, AV_LOG_TRACE,
2501 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
2502 av_fourcc2str(format), st->codecpar->codec_type);
2504 st->codecpar->codec_id = id;
2505 if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) {
2506 mov_parse_stsd_video(c, pb, st, sc);
2507 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
2508 mov_parse_stsd_audio(c, pb, st, sc);
2509 if (st->codecpar->sample_rate < 0) {
2510 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
2511 return AVERROR_INVALIDDATA;
2513 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
2514 mov_parse_stsd_subtitle(c, pb, st, sc,
2515 size - (avio_tell(pb) - start_pos));
2517 ret = mov_parse_stsd_data(c, pb, st, sc,
2518 size - (avio_tell(pb) - start_pos));
2522 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
2523 a.size = size - (avio_tell(pb) - start_pos);
2525 if ((ret = mov_read_default(c, pb, a)) < 0)
2527 } else if (a.size > 0)
2528 avio_skip(pb, a.size);
2530 if (sc->extradata && st->codecpar->extradata) {
2531 int extra_size = st->codecpar->extradata_size;
2533 /* Move the current stream extradata to the stream context one. */
2534 sc->extradata_size[pseudo_stream_id] = extra_size;
2535 sc->extradata[pseudo_stream_id] = av_malloc(extra_size + AV_INPUT_BUFFER_PADDING_SIZE);
2536 if (!sc->extradata[pseudo_stream_id])
2537 return AVERROR(ENOMEM);
2538 memcpy(sc->extradata[pseudo_stream_id], st->codecpar->extradata, extra_size);
2539 av_freep(&st->codecpar->extradata);
2540 st->codecpar->extradata_size = 0;
2545 if (pb->eof_reached) {
2546 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
2553 static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2556 MOVStreamContext *sc;
2559 if (c->fc->nb_streams < 1)
2561 st = c->fc->streams[c->fc->nb_streams - 1];
2564 sc->stsd_version = avio_r8(pb);
2565 avio_rb24(pb); /* flags */
2566 entries = avio_rb32(pb);
2568 /* Each entry contains a size (4 bytes) and format (4 bytes). */
2569 if (entries <= 0 || entries > atom.size / 8) {
2570 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
2571 return AVERROR_INVALIDDATA;
2574 if (sc->extradata) {
2575 av_log(c->fc, AV_LOG_ERROR,
2576 "Duplicate stsd found in this track.\n");
2577 return AVERROR_INVALIDDATA;
2580 /* Prepare space for hosting multiple extradata. */
2581 sc->extradata = av_mallocz_array(entries, sizeof(*sc->extradata));
2583 return AVERROR(ENOMEM);
2585 sc->extradata_size = av_mallocz_array(entries, sizeof(*sc->extradata_size));
2586 if (!sc->extradata_size) {
2587 ret = AVERROR(ENOMEM);
2591 ret = ff_mov_read_stsd_entries(c, pb, entries);
2595 /* Restore back the primary extradata. */
2596 av_freep(&st->codecpar->extradata);
2597 st->codecpar->extradata_size = sc->extradata_size[0];
2598 if (sc->extradata_size[0]) {
2599 st->codecpar->extradata = av_mallocz(sc->extradata_size[0] + AV_INPUT_BUFFER_PADDING_SIZE);
2600 if (!st->codecpar->extradata)
2601 return AVERROR(ENOMEM);
2602 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
2605 return mov_finalize_stsd_codec(c, pb, st, sc);
2607 if (sc->extradata) {
2609 for (j = 0; j < sc->stsd_count; j++)
2610 av_freep(&sc->extradata[j]);
2613 av_freep(&sc->extradata);
2614 av_freep(&sc->extradata_size);
2618 static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2621 MOVStreamContext *sc;
2622 unsigned int i, entries;
2624 if (c->fc->nb_streams < 1)
2626 st = c->fc->streams[c->fc->nb_streams-1];
2629 avio_r8(pb); /* version */
2630 avio_rb24(pb); /* flags */
2632 entries = avio_rb32(pb);
2633 if ((uint64_t)entries * 12 + 4 > atom.size)
2634 return AVERROR_INVALIDDATA;
2636 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
2641 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSC atom\n");
2642 av_free(sc->stsc_data);
2644 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
2646 return AVERROR(ENOMEM);
2648 for (i = 0; i < entries && !pb->eof_reached; i++) {
2649 sc->stsc_data[i].first = avio_rb32(pb);
2650 sc->stsc_data[i].count = avio_rb32(pb);
2651 sc->stsc_data[i].id = avio_rb32(pb);
2655 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
2656 int64_t first_min = i + 1;
2657 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
2658 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
2659 sc->stsc_data[i].first < first_min ||
2660 sc->stsc_data[i].count < 1 ||
2661 sc->stsc_data[i].id < 1) {
2662 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);
2663 if (i+1 >= sc->stsc_count) {
2664 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
2665 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
2666 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
2667 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
2668 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
2671 av_assert0(sc->stsc_data[i+1].first >= 2);
2672 // We replace this entry by the next valid
2673 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
2674 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
2675 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
2679 if (pb->eof_reached) {
2680 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
2687 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
2689 return index < count - 1;
2692 /* Compute the samples value for the stsc entry at the given index. */
2693 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
2697 if (mov_stsc_index_valid(index, sc->stsc_count))
2698 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
2700 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
2701 av_assert0(sc->stsc_data[index].first <= sc->chunk_count);
2702 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
2705 return sc->stsc_data[index].count * (int64_t)chunk_count;
2708 static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2711 MOVStreamContext *sc;
2712 unsigned i, entries;
2714 if (c->fc->nb_streams < 1)
2716 st = c->fc->streams[c->fc->nb_streams-1];
2719 avio_rb32(pb); // version + flags
2721 entries = avio_rb32(pb);
2723 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
2724 av_free(sc->stps_data);
2726 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
2728 return AVERROR(ENOMEM);
2730 for (i = 0; i < entries && !pb->eof_reached; i++) {
2731 sc->stps_data[i] = avio_rb32(pb);
2736 if (pb->eof_reached) {
2737 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
2744 static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2747 MOVStreamContext *sc;
2748 unsigned int i, entries;
2750 if (c->fc->nb_streams < 1)
2752 st = c->fc->streams[c->fc->nb_streams-1];
2755 avio_r8(pb); /* version */
2756 avio_rb24(pb); /* flags */
2758 entries = avio_rb32(pb);
2760 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
2764 sc->keyframe_absent = 1;
2765 if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
2766 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2770 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
2771 if (entries >= UINT_MAX / sizeof(int))
2772 return AVERROR_INVALIDDATA;
2773 av_freep(&sc->keyframes);
2774 sc->keyframe_count = 0;
2775 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
2777 return AVERROR(ENOMEM);
2779 for (i = 0; i < entries && !pb->eof_reached; i++) {
2780 sc->keyframes[i] = avio_rb32(pb);
2783 sc->keyframe_count = i;
2785 if (pb->eof_reached) {
2786 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
2793 static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2796 MOVStreamContext *sc;
2797 unsigned int i, entries, sample_size, field_size, num_bytes;
2802 if (c->fc->nb_streams < 1)
2804 st = c->fc->streams[c->fc->nb_streams-1];
2807 avio_r8(pb); /* version */
2808 avio_rb24(pb); /* flags */
2810 if (atom.type == MKTAG('s','t','s','z')) {
2811 sample_size = avio_rb32(pb);
2812 if (!sc->sample_size) /* do not overwrite value computed in stsd */
2813 sc->sample_size = sample_size;
2814 sc->stsz_sample_size = sample_size;
2818 avio_rb24(pb); /* reserved */
2819 field_size = avio_r8(pb);
2821 entries = avio_rb32(pb);
2823 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
2825 sc->sample_count = entries;
2829 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
2830 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
2831 return AVERROR_INVALIDDATA;
2836 if (entries >= (UINT_MAX - 4) / field_size)
2837 return AVERROR_INVALIDDATA;
2838 if (sc->sample_sizes)
2839 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
2840 av_free(sc->sample_sizes);
2841 sc->sample_count = 0;
2842 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
2843 if (!sc->sample_sizes)
2844 return AVERROR(ENOMEM);
2846 num_bytes = (entries*field_size+4)>>3;
2848 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
2850 av_freep(&sc->sample_sizes);
2851 return AVERROR(ENOMEM);
2854 ret = ffio_read_size(pb, buf, num_bytes);
2856 av_freep(&sc->sample_sizes);
2858 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
2862 init_get_bits(&gb, buf, 8*num_bytes);
2864 for (i = 0; i < entries && !pb->eof_reached; i++) {
2865 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
2866 sc->data_size += sc->sample_sizes[i];
2869 sc->sample_count = i;
2873 if (pb->eof_reached) {
2874 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSZ atom\n");
2881 static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2884 MOVStreamContext *sc;
2885 unsigned int i, entries, alloc_size = 0;
2887 int64_t total_sample_count=0;
2889 if (c->fc->nb_streams < 1)
2891 st = c->fc->streams[c->fc->nb_streams-1];
2894 avio_r8(pb); /* version */
2895 avio_rb24(pb); /* flags */
2896 entries = avio_rb32(pb);
2898 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
2899 c->fc->nb_streams-1, entries);
2902 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
2903 av_freep(&sc->stts_data);
2905 if (entries >= INT_MAX / sizeof(*sc->stts_data))
2906 return AVERROR(ENOMEM);
2908 for (i = 0; i < entries && !pb->eof_reached; i++) {
2909 int sample_duration;
2910 unsigned int sample_count;
2911 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
2912 MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
2913 min_entries * sizeof(*sc->stts_data));
2915 av_freep(&sc->stts_data);
2917 return AVERROR(ENOMEM);
2919 sc->stts_count = min_entries;
2920 sc->stts_data = stts_data;
2922 sample_count=avio_rb32(pb);
2923 sample_duration = avio_rb32(pb);
2925 sc->stts_data[i].count= sample_count;
2926 sc->stts_data[i].duration= sample_duration;
2928 av_log(c->fc, AV_LOG_TRACE, "sample_count=%d, sample_duration=%d\n",
2929 sample_count, sample_duration);
2931 duration+=(int64_t)sample_duration*(uint64_t)sample_count;
2932 total_sample_count+=sample_count;
2938 duration <= INT64_MAX - sc->duration_for_fps &&
2939 total_sample_count <= INT_MAX - sc->nb_frames_for_fps
2941 sc->duration_for_fps += duration;
2942 sc->nb_frames_for_fps += total_sample_count;
2945 if (pb->eof_reached) {
2946 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
2950 st->nb_frames= total_sample_count;
2952 st->duration= FFMIN(st->duration, duration);
2953 sc->track_end = duration;
2957 static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2960 MOVStreamContext *sc;
2963 if (c->fc->nb_streams < 1)
2965 st = c->fc->streams[c->fc->nb_streams - 1];
2968 avio_r8(pb); /* version */
2969 avio_rb24(pb); /* flags */
2970 entries = atom.size - 4;
2972 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
2973 c->fc->nb_streams - 1, entries);
2976 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
2977 av_freep(&sc->sdtp_data);
2980 sc->sdtp_data = av_mallocz(entries);
2982 return AVERROR(ENOMEM);
2984 for (i = 0; i < entries && !pb->eof_reached; i++)
2985 sc->sdtp_data[i] = avio_r8(pb);
2991 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
2994 if (duration == INT_MIN) {
2995 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
2998 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3002 static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3005 MOVStreamContext *sc;
3006 unsigned int i, entries, ctts_count = 0;
3008 if (c->fc->nb_streams < 1)
3010 st = c->fc->streams[c->fc->nb_streams-1];
3013 avio_r8(pb); /* version */
3014 avio_rb24(pb); /* flags */
3015 entries = avio_rb32(pb);
3017 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3021 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3022 return AVERROR_INVALIDDATA;
3023 av_freep(&sc->ctts_data);
3024 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3026 return AVERROR(ENOMEM);
3028 for (i = 0; i < entries && !pb->eof_reached; i++) {
3029 int count =avio_rb32(pb);
3030 int duration =avio_rb32(pb);
3033 av_log(c->fc, AV_LOG_TRACE,
3034 "ignoring CTTS entry with count=%d duration=%d\n",
3039 add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3042 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3045 if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3046 av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3047 av_freep(&sc->ctts_data);
3053 mov_update_dts_shift(sc, duration, c->fc);
3056 sc->ctts_count = ctts_count;
3058 if (pb->eof_reached) {
3059 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3063 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3068 static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3071 MOVStreamContext *sc;
3072 unsigned int i, entries;
3074 uint32_t grouping_type;
3076 if (c->fc->nb_streams < 1)
3078 st = c->fc->streams[c->fc->nb_streams-1];
3081 version = avio_r8(pb); /* version */
3082 avio_rb24(pb); /* flags */
3083 grouping_type = avio_rl32(pb);
3084 if (grouping_type != MKTAG( 'r','a','p',' '))
3085 return 0; /* only support 'rap ' grouping */
3087 avio_rb32(pb); /* grouping_type_parameter */
3089 entries = avio_rb32(pb);
3093 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP atom\n");
3094 av_free(sc->rap_group);
3095 sc->rap_group_count = 0;
3096 sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group));
3098 return AVERROR(ENOMEM);
3100 for (i = 0; i < entries && !pb->eof_reached; i++) {
3101 sc->rap_group[i].count = avio_rb32(pb); /* sample_count */
3102 sc->rap_group[i].index = avio_rb32(pb); /* group_description_index */
3105 sc->rap_group_count = i;
3107 if (pb->eof_reached) {
3108 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3116 * Get ith edit list entry (media time, duration).
3118 static int get_edit_list_entry(MOVContext *mov,
3119 const MOVStreamContext *msc,
3120 unsigned int edit_list_index,
3121 int64_t *edit_list_media_time,
3122 int64_t *edit_list_duration,
3123 int64_t global_timescale)
3125 if (edit_list_index == msc->elst_count) {
3128 *edit_list_media_time = msc->elst_data[edit_list_index].time;
3129 *edit_list_duration = msc->elst_data[edit_list_index].duration;
3131 /* duration is in global timescale units;convert to msc timescale */
3132 if (global_timescale == 0) {
3133 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3136 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3142 * Find the closest previous frame to the timestamp_pts, in e_old index
3143 * entries. Searching for just any frame / just key frames can be controlled by
3144 * last argument 'flag'.
3145 * Note that if ctts_data is not NULL, we will always search for a key frame
3146 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3147 * return the first frame of the video.
3149 * Here the timestamp_pts is considered to be a presentation timestamp and
3150 * the timestamp of index entries are considered to be decoding timestamps.
3152 * Returns 0 if successful in finding a frame, else returns -1.
3153 * Places the found index corresponding output arg.
3155 * If ctts_old is not NULL, then refines the searched entry by searching
3156 * backwards from the found timestamp, to find the frame with correct PTS.
3158 * Places the found ctts_index and ctts_sample in corresponding output args.
3160 static int find_prev_closest_index(AVStream *st,
3161 AVIndexEntry *e_old,
3165 int64_t timestamp_pts,
3168 int64_t* ctts_index,
3169 int64_t* ctts_sample)
3171 MOVStreamContext *msc = st->priv_data;
3172 AVIndexEntry *e_keep = st->index_entries;
3173 int nb_keep = st->nb_index_entries;
3175 int64_t index_ctts_count;
3179 // If dts_shift > 0, then all the index timestamps will have to be offset by
3180 // at least dts_shift amount to obtain PTS.
3181 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3182 if (msc->dts_shift > 0) {
3183 timestamp_pts -= msc->dts_shift;
3186 st->index_entries = e_old;
3187 st->nb_index_entries = nb_old;
3188 *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3190 // Keep going backwards in the index entries until the timestamp is the same.
3192 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3194 if ((flag & AVSEEK_FLAG_ANY) ||
3195 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3201 // If we have CTTS then refine the search, by searching backwards over PTS
3202 // computed by adding corresponding CTTS durations to index timestamps.
3203 if (ctts_data && *index >= 0) {
3204 av_assert0(ctts_index);
3205 av_assert0(ctts_sample);
3206 // Find out the ctts_index for the found frame.
3209 for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3210 if (*ctts_index < ctts_count) {
3212 if (ctts_data[*ctts_index].count == *ctts_sample) {
3219 while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3220 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3221 // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3222 // compensated by dts_shift above.
3223 if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3224 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3229 if (*ctts_sample == 0) {
3231 if (*ctts_index >= 0)
3232 *ctts_sample = ctts_data[*ctts_index].count - 1;
3239 /* restore AVStream state*/
3240 st->index_entries = e_keep;
3241 st->nb_index_entries = nb_keep;
3242 return *index >= 0 ? 0 : -1;
3246 * Add index entry with the given values, to the end of st->index_entries.
3247 * Returns the new size st->index_entries if successful, else returns -1.
3249 * This function is similar to ff_add_index_entry in libavformat/utils.c
3250 * except that here we are always unconditionally adding an index entry to
3251 * the end, instead of searching the entries list and skipping the add if
3252 * there is an existing entry with the same timestamp.
3253 * This is needed because the mov_fix_index calls this func with the same
3254 * unincremented timestamp for successive discarded frames.
3256 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3257 int size, int distance, int flags)
3259 AVIndexEntry *entries, *ie;
3261 const size_t min_size_needed = (st->nb_index_entries + 1) * sizeof(AVIndexEntry);
3263 // Double the allocation each time, to lower memory fragmentation.
3264 // Another difference from ff_add_index_entry function.
3265 const size_t requested_size =
3266 min_size_needed > st->index_entries_allocated_size ?
3267 FFMAX(min_size_needed, 2 * st->index_entries_allocated_size) :
3270 if((unsigned)st->nb_index_entries + 1 >= UINT_MAX / sizeof(AVIndexEntry))
3273 entries = av_fast_realloc(st->index_entries,
3274 &st->index_entries_allocated_size,
3279 st->index_entries= entries;
3281 index= st->nb_index_entries++;
3282 ie= &entries[index];
3285 ie->timestamp = timestamp;
3286 ie->min_distance= distance;
3293 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3294 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3296 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3297 int64_t* frame_duration_buffer,
3298 int frame_duration_buffer_size) {
3300 av_assert0(end_index >= 0 && end_index <= st->nb_index_entries);
3301 for (i = 0; i < frame_duration_buffer_size; i++) {
3302 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3303 st->index_entries[end_index - 1 - i].timestamp = end_ts;
3308 * Append a new ctts entry to ctts_data.
3309 * Returns the new ctts_count if successful, else returns -1.
3311 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3312 int count, int duration)
3314 MOVStts *ctts_buf_new;
3315 const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVStts);
3316 const size_t requested_size =
3317 min_size_needed > *allocated_size ?
3318 FFMAX(min_size_needed, 2 * (*allocated_size)) :
3321 if((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
3324 ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3329 *ctts_data = ctts_buf_new;
3331 ctts_buf_new[*ctts_count].count = count;
3332 ctts_buf_new[*ctts_count].duration = duration;
3334 *ctts_count = (*ctts_count) + 1;
3338 #define MAX_REORDER_DELAY 16
3339 static void mov_estimate_video_delay(MOVContext *c, AVStream* st) {
3340 MOVStreamContext *msc = st->priv_data;
3343 int ctts_sample = 0;
3344 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3346 int j, r, num_swaps;
3348 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3349 pts_buf[j] = INT64_MIN;
3351 if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3352 st->codecpar->codec_id == AV_CODEC_ID_H264) {
3353 st->codecpar->video_delay = 0;
3354 for(ind = 0; ind < st->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3355 // Point j to the last elem of the buffer and insert the current pts there.
3357 buf_start = (buf_start + 1);
3358 if (buf_start == MAX_REORDER_DELAY + 1)
3361 pts_buf[j] = st->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3363 // The timestamps that are already in the sorted buffer, and are greater than the
3364 // current pts, are exactly the timestamps that need to be buffered to output PTS
3365 // in correct sorted order.
3366 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3367 // can be computed as the maximum no. of swaps any particular timestamp needs to
3368 // go through, to keep this buffer in sorted order.
3370 while (j != buf_start) {
3372 if (r < 0) r = MAX_REORDER_DELAY;
3373 if (pts_buf[j] < pts_buf[r]) {
3374 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3381 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3384 if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3389 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3390 st->codecpar->video_delay, st->index);
3394 static void mov_current_sample_inc(MOVStreamContext *sc)
3396 sc->current_sample++;
3397 sc->current_index++;
3398 if (sc->index_ranges &&
3399 sc->current_index >= sc->current_index_range->end &&
3400 sc->current_index_range->end) {
3401 sc->current_index_range++;
3402 sc->current_index = sc->current_index_range->start;
3406 static void mov_current_sample_dec(MOVStreamContext *sc)
3408 sc->current_sample--;
3409 sc->current_index--;
3410 if (sc->index_ranges &&
3411 sc->current_index < sc->current_index_range->start &&
3412 sc->current_index_range > sc->index_ranges) {
3413 sc->current_index_range--;
3414 sc->current_index = sc->current_index_range->end - 1;
3418 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3422 sc->current_sample = current_sample;
3423 sc->current_index = current_sample;
3424 if (!sc->index_ranges) {
3428 for (sc->current_index_range = sc->index_ranges;
3429 sc->current_index_range->end;
3430 sc->current_index_range++) {
3431 range_size = sc->current_index_range->end - sc->current_index_range->start;
3432 if (range_size > current_sample) {
3433 sc->current_index = sc->current_index_range->start + current_sample;
3436 current_sample -= range_size;
3441 * Fix st->index_entries, so that it contains only the entries (and the entries
3442 * which are needed to decode them) that fall in the edit list time ranges.
3443 * Also fixes the timestamps of the index entries to match the timeline
3444 * specified the edit lists.
3446 static void mov_fix_index(MOVContext *mov, AVStream *st)
3448 MOVStreamContext *msc = st->priv_data;
3449 AVIndexEntry *e_old = st->index_entries;
3450 int nb_old = st->nb_index_entries;
3451 const AVIndexEntry *e_old_end = e_old + nb_old;
3452 const AVIndexEntry *current = NULL;
3453 MOVStts *ctts_data_old = msc->ctts_data;
3454 int64_t ctts_index_old = 0;
3455 int64_t ctts_sample_old = 0;
3456 int64_t ctts_count_old = msc->ctts_count;
3457 int64_t edit_list_media_time = 0;
3458 int64_t edit_list_duration = 0;
3459 int64_t frame_duration = 0;
3460 int64_t edit_list_dts_counter = 0;
3461 int64_t edit_list_dts_entry_end = 0;
3462 int64_t edit_list_start_ctts_sample = 0;
3464 int64_t curr_ctts = 0;
3465 int64_t empty_edits_sum_duration = 0;
3466 int64_t edit_list_index = 0;
3469 int64_t start_dts = 0;
3470 int64_t edit_list_start_encountered = 0;
3471 int64_t search_timestamp = 0;
3472 int64_t* frame_duration_buffer = NULL;
3473 int num_discarded_begin = 0;
3474 int first_non_zero_audio_edit = -1;
3475 int packet_skip_samples = 0;
3476 MOVIndexRange *current_index_range;
3478 int found_keyframe_after_edit = 0;
3479 int found_non_empty_edit = 0;
3481 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
3485 // allocate the index ranges array
3486 msc->index_ranges = av_malloc((msc->elst_count + 1) * sizeof(msc->index_ranges[0]));
3487 if (!msc->index_ranges) {
3488 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
3491 msc->current_index_range = msc->index_ranges;
3492 current_index_range = msc->index_ranges - 1;
3494 // Clean AVStream from traces of old index
3495 st->index_entries = NULL;
3496 st->index_entries_allocated_size = 0;
3497 st->nb_index_entries = 0;
3499 // Clean ctts fields of MOVStreamContext
3500 msc->ctts_data = NULL;
3501 msc->ctts_count = 0;
3502 msc->ctts_index = 0;
3503 msc->ctts_sample = 0;
3504 msc->ctts_allocated_size = 0;
3506 // Reinitialize min_corrected_pts so that it can be computed again.
3507 msc->min_corrected_pts = -1;
3509 // If the dts_shift is positive (in case of negative ctts values in mov),
3510 // then negate the DTS by dts_shift
3511 if (msc->dts_shift > 0) {
3512 edit_list_dts_entry_end -= msc->dts_shift;
3513 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
3516 start_dts = edit_list_dts_entry_end;
3518 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
3519 &edit_list_duration, mov->time_scale)) {
3520 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
3521 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
3523 edit_list_dts_counter = edit_list_dts_entry_end;
3524 edit_list_dts_entry_end += edit_list_duration;
3525 num_discarded_begin = 0;
3526 if (!found_non_empty_edit && edit_list_media_time == -1) {
3527 empty_edits_sum_duration += edit_list_duration;
3530 found_non_empty_edit = 1;
3532 // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
3533 // according to the edit list below.
3534 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3535 if (first_non_zero_audio_edit < 0) {
3536 first_non_zero_audio_edit = 1;
3538 first_non_zero_audio_edit = 0;
3541 if (first_non_zero_audio_edit > 0)
3542 st->skip_samples = msc->start_pad = 0;
3545 // While reordering frame index according to edit list we must handle properly
3546 // the scenario when edit list entry starts from none key frame.
3547 // We find closest previous key frame and preserve it and consequent frames in index.
3548 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
3549 search_timestamp = edit_list_media_time;
3550 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3551 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
3552 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
3553 // edit_list_media_time to cover the decoder delay.
3554 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
3557 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
3558 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3559 av_log(mov->fc, AV_LOG_WARNING,
3560 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
3561 st->index, edit_list_index, search_timestamp);
3562 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
3563 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3564 av_log(mov->fc, AV_LOG_WARNING,
3565 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
3566 st->index, edit_list_index, search_timestamp);
3569 ctts_sample_old = 0;
3572 current = e_old + index;
3573 edit_list_start_ctts_sample = ctts_sample_old;
3575 // Iterate over index and arrange it according to edit list
3576 edit_list_start_encountered = 0;
3577 found_keyframe_after_edit = 0;
3578 for (; current < e_old_end; current++, index++) {
3579 // check if frame outside edit list mark it for discard
3580 frame_duration = (current + 1 < e_old_end) ?
3581 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
3583 flags = current->flags;
3585 // frames (pts) before or after edit list
3586 curr_cts = current->timestamp + msc->dts_shift;
3589 if (ctts_data_old && ctts_index_old < ctts_count_old) {
3590 curr_ctts = ctts_data_old[ctts_index_old].duration;
3591 av_log(mov->fc, AV_LOG_DEBUG, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
3592 curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
3593 curr_cts += curr_ctts;
3595 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
3596 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3597 &msc->ctts_allocated_size,
3598 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3599 ctts_data_old[ctts_index_old].duration) == -1) {
3600 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3602 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3603 ctts_data_old[ctts_index_old].duration);
3607 ctts_sample_old = 0;
3608 edit_list_start_ctts_sample = 0;
3612 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
3613 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
3614 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
3615 first_non_zero_audio_edit > 0) {
3616 packet_skip_samples = edit_list_media_time - curr_cts;
3617 st->skip_samples += packet_skip_samples;
3619 // Shift the index entry timestamp by packet_skip_samples to be correct.
3620 edit_list_dts_counter -= packet_skip_samples;
3621 if (edit_list_start_encountered == 0) {
3622 edit_list_start_encountered = 1;
3623 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
3624 // discarded packets.
3625 if (frame_duration_buffer) {
3626 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3627 frame_duration_buffer, num_discarded_begin);
3628 av_freep(&frame_duration_buffer);
3632 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
3634 flags |= AVINDEX_DISCARD_FRAME;
3635 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
3637 if (edit_list_start_encountered == 0) {
3638 num_discarded_begin++;
3639 frame_duration_buffer = av_realloc(frame_duration_buffer,
3640 num_discarded_begin * sizeof(int64_t));
3641 if (!frame_duration_buffer) {
3642 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
3645 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
3647 // Increment skip_samples for the first non-zero audio edit list
3648 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3649 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
3650 st->skip_samples += frame_duration;
3655 if (msc->min_corrected_pts < 0) {
3656 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
3658 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
3660 if (edit_list_start_encountered == 0) {
3661 edit_list_start_encountered = 1;
3662 // Make timestamps strictly monotonically increasing by rewriting timestamps for
3663 // discarded packets.
3664 if (frame_duration_buffer) {
3665 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3666 frame_duration_buffer, num_discarded_begin);
3667 av_freep(&frame_duration_buffer);
3672 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
3673 current->min_distance, flags) == -1) {
3674 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
3678 // Update the index ranges array
3679 if (current_index_range < msc->index_ranges || index != current_index_range->end) {
3680 current_index_range++;
3681 current_index_range->start = index;
3683 current_index_range->end = index + 1;
3685 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
3686 if (edit_list_start_encountered > 0) {
3687 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
3690 // Break when found first key frame after edit entry completion
3691 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
3692 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
3693 if (ctts_data_old) {
3694 // If we have CTTS and this is the first keyframe after edit elist,
3695 // wait for one more, because there might be trailing B-frames after this I-frame
3696 // that do belong to the edit.
3697 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
3698 found_keyframe_after_edit = 1;
3701 if (ctts_sample_old != 0) {
3702 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3703 &msc->ctts_allocated_size,
3704 ctts_sample_old - edit_list_start_ctts_sample,
3705 ctts_data_old[ctts_index_old].duration) == -1) {
3706 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3707 ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
3708 ctts_data_old[ctts_index_old].duration);
3717 // If there are empty edits, then msc->min_corrected_pts might be positive
3718 // intentionally. So we subtract the sum duration of emtpy edits here.
3719 msc->min_corrected_pts -= empty_edits_sum_duration;
3721 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
3722 // dts by that amount to make the first pts zero.
3723 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
3724 if (msc->min_corrected_pts > 0) {
3725 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
3726 for (i = 0; i < st->nb_index_entries; ++i) {
3727 st->index_entries[i].timestamp -= msc->min_corrected_pts;
3731 // Start time should be equal to zero or the duration of any empty edits.
3732 st->start_time = empty_edits_sum_duration;
3734 // Update av stream length, if it ends up shorter than the track's media duration
3735 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
3736 msc->start_pad = st->skip_samples;
3738 // Free the old index and the old CTTS structures
3740 av_free(ctts_data_old);
3741 av_freep(&frame_duration_buffer);
3743 // Null terminate the index ranges array
3744 current_index_range++;
3745 current_index_range->start = 0;
3746 current_index_range->end = 0;
3747 msc->current_index = msc->index_ranges[0].start;
3750 static void mov_build_index(MOVContext *mov, AVStream *st)
3752 MOVStreamContext *sc = st->priv_data;
3753 int64_t current_offset;
3754 int64_t current_dts = 0;
3755 unsigned int stts_index = 0;
3756 unsigned int stsc_index = 0;
3757 unsigned int stss_index = 0;
3758 unsigned int stps_index = 0;
3760 uint64_t stream_size = 0;
3761 MOVStts *ctts_data_old = sc->ctts_data;
3762 unsigned int ctts_count_old = sc->ctts_count;
3764 if (sc->elst_count) {
3765 int i, edit_start_index = 0, multiple_edits = 0;
3766 int64_t empty_duration = 0; // empty duration of the first edit list entry
3767 int64_t start_time = 0; // start time of the media
3769 for (i = 0; i < sc->elst_count; i++) {
3770 const MOVElst *e = &sc->elst_data[i];
3771 if (i == 0 && e->time == -1) {
3772 /* if empty, the first entry is the start time of the stream
3773 * relative to the presentation itself */
3774 empty_duration = e->duration;
3775 edit_start_index = 1;
3776 } else if (i == edit_start_index && e->time >= 0) {
3777 start_time = e->time;
3783 if (multiple_edits && !mov->advanced_editlist)
3784 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
3785 "Use -advanced_editlist to correctly decode otherwise "
3786 "a/v desync might occur\n");
3788 /* adjust first dts according to edit list */
3789 if ((empty_duration || start_time) && mov->time_scale > 0) {
3791 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
3792 sc->time_offset = start_time - empty_duration;
3793 sc->min_corrected_pts = start_time;
3794 if (!mov->advanced_editlist)
3795 current_dts = -sc->time_offset;
3798 if (!multiple_edits && !mov->advanced_editlist &&
3799 st->codecpar->codec_id == AV_CODEC_ID_AAC && start_time > 0)
3800 sc->start_pad = start_time;
3803 /* only use old uncompressed audio chunk demuxing when stts specifies it */
3804 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3805 sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
3806 unsigned int current_sample = 0;
3807 unsigned int stts_sample = 0;
3808 unsigned int sample_size;
3809 unsigned int distance = 0;
3810 unsigned int rap_group_index = 0;
3811 unsigned int rap_group_sample = 0;
3812 int64_t last_dts = 0;
3813 int64_t dts_correction = 0;
3814 int rap_group_present = sc->rap_group_count && sc->rap_group;
3815 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
3817 current_dts -= sc->dts_shift;
3818 last_dts = current_dts;
3820 if (!sc->sample_count || st->nb_index_entries)
3822 if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
3824 if (av_reallocp_array(&st->index_entries,
3825 st->nb_index_entries + sc->sample_count,
3826 sizeof(*st->index_entries)) < 0) {
3827 st->nb_index_entries = 0;
3830 st->index_entries_allocated_size = (st->nb_index_entries + sc->sample_count) * sizeof(*st->index_entries);
3832 if (ctts_data_old) {
3833 // Expand ctts entries such that we have a 1-1 mapping with samples
3834 if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
3837 sc->ctts_allocated_size = 0;
3838 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size,
3839 sc->sample_count * sizeof(*sc->ctts_data));
3840 if (!sc->ctts_data) {
3841 av_free(ctts_data_old);
3845 memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
3847 for (i = 0; i < ctts_count_old &&
3848 sc->ctts_count < sc->sample_count; i++)
3849 for (j = 0; j < ctts_data_old[i].count &&
3850 sc->ctts_count < sc->sample_count; j++)
3851 add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
3852 &sc->ctts_allocated_size, 1,
3853 ctts_data_old[i].duration);
3854 av_free(ctts_data_old);
3857 for (i = 0; i < sc->chunk_count; i++) {
3858 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
3859 current_offset = sc->chunk_offsets[i];
3860 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3861 i + 1 == sc->stsc_data[stsc_index + 1].first)
3864 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
3865 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
3866 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
3867 sc->stsz_sample_size = sc->sample_size;
3869 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
3870 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
3871 sc->stsz_sample_size = sc->sample_size;
3874 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
3876 if (current_sample >= sc->sample_count) {
3877 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
3881 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
3883 if (stss_index + 1 < sc->keyframe_count)
3885 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
3887 if (stps_index + 1 < sc->stps_count)
3890 if (rap_group_present && rap_group_index < sc->rap_group_count) {
3891 if (sc->rap_group[rap_group_index].index > 0)
3893 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
3894 rap_group_sample = 0;
3898 if (sc->keyframe_absent
3900 && !rap_group_present
3901 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
3905 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
3906 if (sc->pseudo_stream_id == -1 ||
3907 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
3909 if (sample_size > 0x3FFFFFFF) {
3910 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
3913 e = &st->index_entries[st->nb_index_entries++];
3914 e->pos = current_offset;
3915 e->timestamp = current_dts;
3916 e->size = sample_size;
3917 e->min_distance = distance;
3918 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
3919 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
3920 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
3921 current_offset, current_dts, sample_size, distance, keyframe);
3922 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries < 100)
3923 ff_rfps_add_frame(mov->fc, st, current_dts);
3926 current_offset += sample_size;
3927 stream_size += sample_size;
3929 /* A negative sample duration is invalid based on the spec,
3930 * but some samples need it to correct the DTS. */
3931 if (sc->stts_data[stts_index].duration < 0) {
3932 av_log(mov->fc, AV_LOG_WARNING,
3933 "Invalid SampleDelta %d in STTS, at %d st:%d\n",
3934 sc->stts_data[stts_index].duration, stts_index,
3936 dts_correction += sc->stts_data[stts_index].duration - 1;
3937 sc->stts_data[stts_index].duration = 1;
3939 current_dts += sc->stts_data[stts_index].duration;
3940 if (!dts_correction || current_dts + dts_correction > last_dts) {
3941 current_dts += dts_correction;
3944 /* Avoid creating non-monotonous DTS */
3945 dts_correction += current_dts - last_dts - 1;
3946 current_dts = last_dts + 1;
3948 last_dts = current_dts;
3952 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
3958 if (st->duration > 0)
3959 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
3961 unsigned chunk_samples, total = 0;
3963 if (!sc->chunk_count)
3966 // compute total chunk count
3967 for (i = 0; i < sc->stsc_count; i++) {
3968 unsigned count, chunk_count;
3970 chunk_samples = sc->stsc_data[i].count;
3971 if (i != sc->stsc_count - 1 &&
3972 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
3973 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
3977 if (sc->samples_per_frame >= 160) { // gsm
3978 count = chunk_samples / sc->samples_per_frame;
3979 } else if (sc->samples_per_frame > 1) {
3980 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
3981 count = (chunk_samples+samples-1) / samples;
3983 count = (chunk_samples+1023) / 1024;
3986 if (mov_stsc_index_valid(i, sc->stsc_count))
3987 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
3989 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
3990 total += chunk_count * count;
3993 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
3994 if (total >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
3996 if (av_reallocp_array(&st->index_entries,
3997 st->nb_index_entries + total,
3998 sizeof(*st->index_entries)) < 0) {
3999 st->nb_index_entries = 0;
4002 st->index_entries_allocated_size = (st->nb_index_entries + total) * sizeof(*st->index_entries);
4005 for (i = 0; i < sc->chunk_count; i++) {
4006 current_offset = sc->chunk_offsets[i];
4007 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4008 i + 1 == sc->stsc_data[stsc_index + 1].first)
4010 chunk_samples = sc->stsc_data[stsc_index].count;
4012 while (chunk_samples > 0) {
4014 unsigned size, samples;
4016 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4017 avpriv_request_sample(mov->fc,
4018 "Zero bytes per frame, but %d samples per frame",
4019 sc->samples_per_frame);
4023 if (sc->samples_per_frame >= 160) { // gsm
4024 samples = sc->samples_per_frame;
4025 size = sc->bytes_per_frame;
4027 if (sc->samples_per_frame > 1) {
4028 samples = FFMIN((1024 / sc->samples_per_frame)*
4029 sc->samples_per_frame, chunk_samples);
4030 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
4032 samples = FFMIN(1024, chunk_samples);
4033 size = samples * sc->sample_size;
4037 if (st->nb_index_entries >= total) {
4038 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4041 if (size > 0x3FFFFFFF) {
4042 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4045 e = &st->index_entries[st->nb_index_entries++];
4046 e->pos = current_offset;
4047 e->timestamp = current_dts;
4049 e->min_distance = 0;
4050 e->flags = AVINDEX_KEYFRAME;
4051 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4052 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4055 current_offset += size;
4056 current_dts += samples;
4057 chunk_samples -= samples;
4062 if (!mov->ignore_editlist && mov->advanced_editlist) {
4063 // Fix index according to edit lists.
4064 mov_fix_index(mov, st);
4067 // Update start time of the stream.
4068 if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries > 0) {
4069 st->start_time = st->index_entries[0].timestamp + sc->dts_shift;
4070 if (sc->ctts_data) {
4071 st->start_time += sc->ctts_data[0].duration;
4075 mov_estimate_video_delay(mov, st);
4078 static int test_same_origin(const char *src, const char *ref) {
4088 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4089 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4091 if (strlen(src) == 0) {
4093 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4094 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4095 strlen(src_host) + 1 >= sizeof(src_host) ||
4096 strlen(ref_host) + 1 >= sizeof(ref_host)) {
4098 } else if (strcmp(src_proto, ref_proto) ||
4099 strcmp(src_auth, ref_auth) ||
4100 strcmp(src_host, ref_host) ||
4101 src_port != ref_port) {
4107 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4109 /* try relative path, we do not try the absolute because it can leak information about our
4110 system to an attacker */
4111 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4112 char filename[1025];
4113 const char *src_path;
4116 /* find a source dir */
4117 src_path = strrchr(src, '/');
4123 /* find a next level down to target */
4124 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4125 if (ref->path[l] == '/') {
4126 if (i == ref->nlvl_to - 1)
4132 /* compose filename if next level down to target was found */
4133 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4134 memcpy(filename, src, src_path - src);
4135 filename[src_path - src] = 0;
4137 for (i = 1; i < ref->nlvl_from; i++)
4138 av_strlcat(filename, "../", sizeof(filename));
4140 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4141 if (!c->use_absolute_path) {
4142 int same_origin = test_same_origin(src, filename);
4145 av_log(c->fc, AV_LOG_ERROR,
4146 "Reference with mismatching origin, %s not tried for security reasons, "
4147 "set demuxer option use_absolute_path to allow it anyway\n",
4149 return AVERROR(ENOENT);
4152 if(strstr(ref->path + l + 1, "..") ||
4153 strstr(ref->path + l + 1, ":") ||
4154 (ref->nlvl_from > 1 && same_origin < 0) ||
4155 (filename[0] == '/' && src_path == src))
4156 return AVERROR(ENOENT);
4159 if (strlen(filename) + 1 == sizeof(filename))
4160 return AVERROR(ENOENT);
4161 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4164 } else if (c->use_absolute_path) {
4165 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4166 "this is a possible security issue\n");
4167 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4170 av_log(c->fc, AV_LOG_ERROR,
4171 "Absolute path %s not tried for security reasons, "
4172 "set demuxer option use_absolute_path to allow absolute paths\n",
4176 return AVERROR(ENOENT);
4179 static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
4181 if (sc->time_scale <= 0) {
4182 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4183 sc->time_scale = c->time_scale;
4184 if (sc->time_scale <= 0)
4189 static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4192 MOVStreamContext *sc;
4195 st = avformat_new_stream(c->fc, NULL);
4196 if (!st) return AVERROR(ENOMEM);
4198 sc = av_mallocz(sizeof(MOVStreamContext));
4199 if (!sc) return AVERROR(ENOMEM);
4202 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
4203 sc->ffindex = st->index;
4204 c->trak_index = st->index;
4206 if ((ret = mov_read_default(c, pb, atom)) < 0)
4211 // Here stsc refers to a chunk not described in stco. This is technically invalid,
4212 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4213 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4215 av_freep(&sc->stsc_data);
4219 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4220 (!sc->sample_size && !sc->sample_count))) ||
4221 (!sc->chunk_count && sc->sample_count)) {
4222 av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4226 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4227 av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4229 return AVERROR_INVALIDDATA;
4232 fix_timescale(c, sc);
4234 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4236 mov_build_index(c, st);
4238 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4239 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4240 if (c->enable_drefs) {
4241 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4242 av_log(c->fc, AV_LOG_ERROR,
4243 "stream %d, error opening alias: path='%s', dir='%s', "
4244 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4245 st->index, dref->path, dref->dir, dref->filename,
4246 dref->volume, dref->nlvl_from, dref->nlvl_to);
4248 av_log(c->fc, AV_LOG_WARNING,
4249 "Skipped opening external track: "
4250 "stream %d, alias: path='%s', dir='%s', "
4251 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4252 "Set enable_drefs to allow this.\n",
4253 st->index, dref->path, dref->dir, dref->filename,
4254 dref->volume, dref->nlvl_from, dref->nlvl_to);
4258 sc->pb_is_copied = 1;
4261 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4262 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4263 sc->height && sc->width &&
4264 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4265 st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4266 ((double)st->codecpar->width * sc->height), INT_MAX);
4269 #if FF_API_R_FRAME_RATE
4270 if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4271 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
4272 sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4276 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4277 if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4278 TAG_IS_AVCI(st->codecpar->codec_tag)) {
4279 ret = ff_generate_avci_extradata(st);
4284 switch (st->codecpar->codec_id) {
4285 #if CONFIG_H261_DECODER
4286 case AV_CODEC_ID_H261:
4288 #if CONFIG_H263_DECODER
4289 case AV_CODEC_ID_H263:
4291 #if CONFIG_MPEG4_DECODER
4292 case AV_CODEC_ID_MPEG4:
4294 st->codecpar->width = 0; /* let decoder init width/height */
4295 st->codecpar->height= 0;
4299 // If the duration of the mp3 packets is not constant, then they could need a parser
4300 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4301 && sc->stts_count > 3
4302 && sc->stts_count*10 > st->nb_frames
4303 && sc->time_scale == st->codecpar->sample_rate) {
4304 st->need_parsing = AVSTREAM_PARSE_FULL;
4306 /* Do not need those anymore. */
4307 av_freep(&sc->chunk_offsets);
4308 av_freep(&sc->sample_sizes);
4309 av_freep(&sc->keyframes);
4310 av_freep(&sc->stts_data);
4311 av_freep(&sc->stps_data);
4312 av_freep(&sc->elst_data);
4313 av_freep(&sc->rap_group);
4318 static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4321 c->itunes_metadata = 1;
4322 ret = mov_read_default(c, pb, atom);
4323 c->itunes_metadata = 0;
4327 static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4336 count = avio_rb32(pb);
4337 if (count > UINT_MAX / sizeof(*c->meta_keys) - 1) {
4338 av_log(c->fc, AV_LOG_ERROR,
4339 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
4340 return AVERROR_INVALIDDATA;
4343 c->meta_keys_count = count + 1;
4344 c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
4346 return AVERROR(ENOMEM);
4348 for (i = 1; i <= count; ++i) {
4349 uint32_t key_size = avio_rb32(pb);
4350 uint32_t type = avio_rl32(pb);
4352 av_log(c->fc, AV_LOG_ERROR,
4353 "The key# %"PRIu32" in meta has invalid size:"
4354 "%"PRIu32"\n", i, key_size);
4355 return AVERROR_INVALIDDATA;
4358 if (type != MKTAG('m','d','t','a')) {
4359 avio_skip(pb, key_size);
4361 c->meta_keys[i] = av_mallocz(key_size + 1);
4362 if (!c->meta_keys[i])
4363 return AVERROR(ENOMEM);
4364 avio_read(pb, c->meta_keys[i], key_size);
4370 static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4372 int64_t end = avio_tell(pb) + atom.size;
4373 uint8_t *key = NULL, *val = NULL, *mean = NULL;
4377 MOVStreamContext *sc;
4379 if (c->fc->nb_streams < 1)
4381 st = c->fc->streams[c->fc->nb_streams-1];
4384 for (i = 0; i < 3; i++) {
4388 if (end - avio_tell(pb) <= 12)
4391 len = avio_rb32(pb);
4392 tag = avio_rl32(pb);
4393 avio_skip(pb, 4); // flags
4395 if (len < 12 || len - 12 > end - avio_tell(pb))
4399 if (tag == MKTAG('m', 'e', 'a', 'n'))
4401 else if (tag == MKTAG('n', 'a', 'm', 'e'))
4403 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
4410 *p = av_malloc(len + 1);
4412 ret = AVERROR(ENOMEM);
4415 ret = ffio_read_size(pb, *p, len);
4423 if (mean && key && val) {
4424 if (strcmp(key, "iTunSMPB") == 0) {
4425 int priming, remainder, samples;
4426 if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
4427 if(priming>0 && priming<16384)
4428 sc->start_pad = priming;
4431 if (strcmp(key, "cdec") != 0) {
4432 av_dict_set(&c->fc->metadata, key, val,
4433 AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
4437 av_log(c->fc, AV_LOG_VERBOSE,
4438 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
4441 avio_seek(pb, end, SEEK_SET);
4448 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4450 while (atom.size > 8) {
4454 tag = avio_rl32(pb);
4456 if (tag == MKTAG('h','d','l','r')) {
4457 avio_seek(pb, -8, SEEK_CUR);
4459 return mov_read_default(c, pb, atom);
4465 // return 1 when matrix is identity, 0 otherwise
4466 #define IS_MATRIX_IDENT(matrix) \
4467 ( (matrix)[0][0] == (1 << 16) && \
4468 (matrix)[1][1] == (1 << 16) && \
4469 (matrix)[2][2] == (1 << 30) && \
4470 !(matrix)[0][1] && !(matrix)[0][2] && \
4471 !(matrix)[1][0] && !(matrix)[1][2] && \
4472 !(matrix)[2][0] && !(matrix)[2][1])
4474 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4479 int display_matrix[3][3];
4480 int res_display_matrix[3][3] = { { 0 } };
4482 MOVStreamContext *sc;
4486 if (c->fc->nb_streams < 1)
4488 st = c->fc->streams[c->fc->nb_streams-1];
4491 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4492 // avoids corrupting AVStreams mapped to an earlier tkhd.
4494 return AVERROR_INVALIDDATA;
4496 version = avio_r8(pb);
4497 flags = avio_rb24(pb);
4498 st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
4504 avio_rb32(pb); /* creation time */
4505 avio_rb32(pb); /* modification time */
4507 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4508 avio_rb32(pb); /* reserved */
4510 /* highlevel (considering edits) duration in movie timebase */
4511 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4512 avio_rb32(pb); /* reserved */
4513 avio_rb32(pb); /* reserved */
4515 avio_rb16(pb); /* layer */
4516 avio_rb16(pb); /* alternate group */
4517 avio_rb16(pb); /* volume */
4518 avio_rb16(pb); /* reserved */
4520 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4521 // they're kept in fixed point format through all calculations
4522 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4523 // side data, but the scale factor is not needed to calculate aspect ratio
4524 for (i = 0; i < 3; i++) {
4525 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
4526 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
4527 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
4530 width = avio_rb32(pb); // 16.16 fixed point track width
4531 height = avio_rb32(pb); // 16.16 fixed point track height
4532 sc->width = width >> 16;
4533 sc->height = height >> 16;
4535 // apply the moov display matrix (after the tkhd one)
4536 for (i = 0; i < 3; i++) {
4537 const int sh[3] = { 16, 16, 30 };
4538 for (j = 0; j < 3; j++) {
4539 for (e = 0; e < 3; e++) {
4540 res_display_matrix[i][j] +=
4541 ((int64_t) display_matrix[i][e] *
4542 c->movie_display_matrix[e][j]) >> sh[e];
4547 // save the matrix when it is not the default identity
4548 if (!IS_MATRIX_IDENT(res_display_matrix)) {
4551 av_freep(&sc->display_matrix);
4552 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4553 if (!sc->display_matrix)
4554 return AVERROR(ENOMEM);
4556 for (i = 0; i < 3; i++)
4557 for (j = 0; j < 3; j++)
4558 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4560 #if FF_API_OLD_ROTATE_API
4561 rotate = av_display_rotation_get(sc->display_matrix);
4562 if (!isnan(rotate)) {
4563 char rotate_buf[64];
4565 if (rotate < 0) // for backward compatibility
4567 snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate);
4568 av_dict_set(&st->metadata, "rotate", rotate_buf, 0);
4573 // transform the display width/height according to the matrix
4574 // to keep the same scale, use [width height 1<<16]
4575 if (width && height && sc->display_matrix) {
4576 double disp_transform[2];
4578 for (i = 0; i < 2; i++)
4579 disp_transform[i] = hypot(sc->display_matrix[0 + i],
4580 sc->display_matrix[3 + i]);
4582 if (disp_transform[0] > 0 && disp_transform[1] > 0 &&
4583 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4584 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4585 st->sample_aspect_ratio = av_d2q(
4586 disp_transform[0] / disp_transform[1],
4592 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4594 MOVFragment *frag = &c->fragment;
4595 MOVTrackExt *trex = NULL;
4596 int flags, track_id, i;
4598 avio_r8(pb); /* version */
4599 flags = avio_rb24(pb);
4601 track_id = avio_rb32(pb);
4603 return AVERROR_INVALIDDATA;
4604 for (i = 0; i < c->trex_count; i++)
4605 if (c->trex_data[i].track_id == track_id) {
4606 trex = &c->trex_data[i];
4610 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4613 c->fragment.found_tfhd = 1;
4614 frag->track_id = track_id;
4615 set_frag_stream(&c->frag_index, track_id);
4617 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4618 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4619 frag->moof_offset : frag->implicit_offset;
4620 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4622 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4623 avio_rb32(pb) : trex->duration;
4624 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4625 avio_rb32(pb) : trex->size;
4626 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4627 avio_rb32(pb) : trex->flags;
4628 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4633 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4638 num = atom.size / 4;
4639 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4640 return AVERROR(ENOMEM);
4642 av_free(c->chapter_tracks);
4643 c->chapter_tracks = new_tracks;
4644 c->nb_chapter_tracks = num;
4646 for (i = 0; i < num && !pb->eof_reached; i++)
4647 c->chapter_tracks[i] = avio_rb32(pb);
4652 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4657 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4658 return AVERROR_INVALIDDATA;
4659 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4660 sizeof(*c->trex_data))) < 0) {
4665 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4667 trex = &c->trex_data[c->trex_count++];
4668 avio_r8(pb); /* version */
4669 avio_rb24(pb); /* flags */
4670 trex->track_id = avio_rb32(pb);
4671 trex->stsd_id = avio_rb32(pb);
4672 trex->duration = avio_rb32(pb);
4673 trex->size = avio_rb32(pb);
4674 trex->flags = avio_rb32(pb);
4678 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4680 MOVFragment *frag = &c->fragment;
4681 AVStream *st = NULL;
4682 MOVStreamContext *sc;
4684 MOVFragmentStreamInfo * frag_stream_info;
4685 int64_t base_media_decode_time;
4687 for (i = 0; i < c->fc->nb_streams; i++) {
4688 if (c->fc->streams[i]->id == frag->track_id) {
4689 st = c->fc->streams[i];
4694 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4698 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4700 version = avio_r8(pb);
4701 avio_rb24(pb); /* flags */
4703 base_media_decode_time = avio_rb64(pb);
4705 base_media_decode_time = avio_rb32(pb);
4708 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4709 if (frag_stream_info)
4710 frag_stream_info->tfdt_dts = base_media_decode_time;
4711 sc->track_end = base_media_decode_time;
4716 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4718 MOVFragment *frag = &c->fragment;
4719 AVStream *st = NULL;
4720 MOVStreamContext *sc;
4723 int64_t dts, pts = AV_NOPTS_VALUE;
4724 int data_offset = 0;
4725 unsigned entries, first_sample_flags = frag->flags;
4726 int flags, distance, i;
4727 int64_t prev_dts = AV_NOPTS_VALUE;
4728 int next_frag_index = -1, index_entry_pos;
4729 size_t requested_size;
4730 size_t old_ctts_allocated_size;
4731 AVIndexEntry *new_entries;
4732 MOVFragmentStreamInfo * frag_stream_info;
4734 if (!frag->found_tfhd) {
4735 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4736 return AVERROR_INVALIDDATA;
4739 for (i = 0; i < c->fc->nb_streams; i++) {
4740 if (c->fc->streams[i]->id == frag->track_id) {
4741 st = c->fc->streams[i];
4746 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4750 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4753 // Find the next frag_index index that has a valid index_entry for
4754 // the current track_id.
4756 // A valid index_entry means the trun for the fragment was read
4757 // and it's samples are in index_entries at the given position.
4758 // New index entries will be inserted before the index_entry found.
4759 index_entry_pos = st->nb_index_entries;
4760 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4761 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4762 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4763 next_frag_index = i;
4764 index_entry_pos = frag_stream_info->index_entry;
4768 av_assert0(index_entry_pos <= st->nb_index_entries);
4770 avio_r8(pb); /* version */
4771 flags = avio_rb24(pb);
4772 entries = avio_rb32(pb);
4773 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4775 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4776 return AVERROR_INVALIDDATA;
4777 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4778 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4780 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4781 if (frag_stream_info)
4783 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4784 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4785 pts = frag_stream_info->first_tfra_pts;
4786 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4787 ", using it for pts\n", pts);
4788 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4789 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4790 // pts = frag_stream_info->sidx_pts;
4791 dts = frag_stream_info->sidx_pts - sc->time_offset;
4792 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4793 ", using it for pts\n", pts);
4794 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4795 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4796 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4797 ", using it for dts\n", dts);
4799 dts = sc->track_end - sc->time_offset;
4800 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4801 ", using it for dts\n", dts);
4804 dts = sc->track_end - sc->time_offset;
4805 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4806 ", using it for dts\n", dts);
4808 offset = frag->base_data_offset + data_offset;
4810 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4812 // realloc space for new index entries
4813 if((uint64_t)st->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4814 entries = UINT_MAX / sizeof(AVIndexEntry) - st->nb_index_entries;
4815 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4820 requested_size = (st->nb_index_entries + entries) * sizeof(AVIndexEntry);
4821 new_entries = av_fast_realloc(st->index_entries,
4822 &st->index_entries_allocated_size,
4825 return AVERROR(ENOMEM);
4826 st->index_entries= new_entries;
4828 requested_size = (st->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4829 old_ctts_allocated_size = sc->ctts_allocated_size;
4830 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4833 return AVERROR(ENOMEM);
4834 sc->ctts_data = ctts_data;
4836 // In case there were samples without ctts entries, ensure they get
4837 // zero valued entries. This ensures clips which mix boxes with and
4838 // without ctts entries don't pickup uninitialized data.
4839 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4840 sc->ctts_allocated_size - old_ctts_allocated_size);
4842 if (index_entry_pos < st->nb_index_entries) {
4843 // Make hole in index_entries and ctts_data for new samples
4844 memmove(st->index_entries + index_entry_pos + entries,
4845 st->index_entries + index_entry_pos,
4846 sizeof(*st->index_entries) *
4847 (st->nb_index_entries - index_entry_pos));
4848 memmove(sc->ctts_data + index_entry_pos + entries,
4849 sc->ctts_data + index_entry_pos,
4850 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4851 if (index_entry_pos < sc->current_sample) {
4852 sc->current_sample += entries;
4856 st->nb_index_entries += entries;
4857 sc->ctts_count = st->nb_index_entries;
4859 // Record the index_entry position in frag_index of this fragment
4860 if (frag_stream_info)
4861 frag_stream_info->index_entry = index_entry_pos;
4863 if (index_entry_pos > 0)
4864 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4866 for (i = 0; i < entries && !pb->eof_reached; i++) {
4867 unsigned sample_size = frag->size;
4868 int sample_flags = i ? frag->flags : first_sample_flags;
4869 unsigned sample_duration = frag->duration;
4870 unsigned ctts_duration = 0;
4872 int index_entry_flags = 0;
4874 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4875 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4876 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4877 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4879 mov_update_dts_shift(sc, ctts_duration, c->fc);
4880 if (pts != AV_NOPTS_VALUE) {
4881 dts = pts - sc->dts_shift;
4882 if (flags & MOV_TRUN_SAMPLE_CTS) {
4883 dts -= ctts_duration;
4885 dts -= sc->time_offset;
4887 av_log(c->fc, AV_LOG_DEBUG,
4888 "pts %"PRId64" calculated dts %"PRId64
4889 " sc->dts_shift %d ctts.duration %d"
4890 " sc->time_offset %"PRId64
4891 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4893 sc->dts_shift, ctts_duration,
4894 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4895 pts = AV_NOPTS_VALUE;
4898 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4902 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4903 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4906 index_entry_flags |= AVINDEX_KEYFRAME;
4908 // Fragments can overlap in time. Discard overlapping frames after
4910 if (prev_dts >= dts)
4911 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4913 st->index_entries[index_entry_pos].pos = offset;
4914 st->index_entries[index_entry_pos].timestamp = dts;
4915 st->index_entries[index_entry_pos].size= sample_size;
4916 st->index_entries[index_entry_pos].min_distance= distance;
4917 st->index_entries[index_entry_pos].flags = index_entry_flags;
4919 sc->ctts_data[index_entry_pos].count = 1;
4920 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4923 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4924 "size %u, distance %d, keyframe %d\n", st->index,
4925 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4927 dts += sample_duration;
4928 offset += sample_size;
4929 sc->data_size += sample_size;
4931 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4932 1 <= INT_MAX - sc->nb_frames_for_fps
4934 sc->duration_for_fps += sample_duration;
4935 sc->nb_frames_for_fps ++;
4939 // EOF found before reading all entries. Fix the hole this would
4940 // leave in index_entries and ctts_data
4941 int gap = entries - i;
4942 memmove(st->index_entries + index_entry_pos,
4943 st->index_entries + index_entry_pos + gap,
4944 sizeof(*st->index_entries) *
4945 (st->nb_index_entries - (index_entry_pos + gap)));
4946 memmove(sc->ctts_data + index_entry_pos,
4947 sc->ctts_data + index_entry_pos + gap,
4948 sizeof(*sc->ctts_data) *
4949 (sc->ctts_count - (index_entry_pos + gap)));
4951 st->nb_index_entries -= gap;
4952 sc->ctts_count -= gap;
4953 if (index_entry_pos < sc->current_sample) {
4954 sc->current_sample -= gap;
4959 // The end of this new fragment may overlap in time with the start
4960 // of the next fragment in index_entries. Mark the samples in the next
4961 // fragment that overlap with AVINDEX_DISCARD_FRAME
4962 prev_dts = AV_NOPTS_VALUE;
4963 if (index_entry_pos > 0)
4964 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4965 for (i = index_entry_pos; i < st->nb_index_entries; i++) {
4966 if (prev_dts < st->index_entries[i].timestamp)
4968 st->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
4971 // If a hole was created to insert the new index_entries into,
4972 // the index_entry recorded for all subsequent moof must
4973 // be incremented by the number of entries inserted.
4974 fix_frag_index_entries(&c->frag_index, next_frag_index,
4975 frag->track_id, entries);
4977 if (pb->eof_reached) {
4978 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
4982 frag->implicit_offset = offset;
4984 sc->track_end = dts + sc->time_offset;
4985 if (st->duration < sc->track_end)
4986 st->duration = sc->track_end;
4991 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4993 int64_t offset = avio_tell(pb) + atom.size, pts, timestamp;
4995 unsigned i, j, track_id, item_count;
4996 AVStream *st = NULL;
4997 AVStream *ref_st = NULL;
4998 MOVStreamContext *sc, *ref_sc = NULL;
4999 AVRational timescale;
5001 version = avio_r8(pb);
5003 avpriv_request_sample(c->fc, "sidx version %u", version);
5007 avio_rb24(pb); // flags
5009 track_id = avio_rb32(pb); // Reference ID
5010 for (i = 0; i < c->fc->nb_streams; i++) {
5011 if (c->fc->streams[i]->id == track_id) {
5012 st = c->fc->streams[i];
5017 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5023 timescale = av_make_q(1, avio_rb32(pb));
5025 if (timescale.den <= 0) {
5026 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5027 return AVERROR_INVALIDDATA;
5031 pts = avio_rb32(pb);
5032 offset += avio_rb32(pb);
5034 pts = avio_rb64(pb);
5035 offset += avio_rb64(pb);
5038 avio_rb16(pb); // reserved
5040 item_count = avio_rb16(pb);
5042 for (i = 0; i < item_count; i++) {
5044 MOVFragmentStreamInfo * frag_stream_info;
5045 uint32_t size = avio_rb32(pb);
5046 uint32_t duration = avio_rb32(pb);
5047 if (size & 0x80000000) {
5048 avpriv_request_sample(c->fc, "sidx reference_type 1");
5049 return AVERROR_PATCHWELCOME;
5051 avio_rb32(pb); // sap_flags
5052 timestamp = av_rescale_q(pts, timescale, st->time_base);
5054 index = update_frag_index(c, offset);
5055 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5056 if (frag_stream_info)
5057 frag_stream_info->sidx_pts = timestamp;
5063 st->duration = sc->track_end = pts;
5067 if (offset == avio_size(pb)) {
5068 // Find first entry in fragment index that came from an sidx.
5069 // This will pretty much always be the first entry.
5070 for (i = 0; i < c->frag_index.nb_items; i++) {
5071 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5072 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5073 MOVFragmentStreamInfo * si;
5074 si = &item->stream_info[j];
5075 if (si->sidx_pts != AV_NOPTS_VALUE) {
5076 ref_st = c->fc->streams[j];
5077 ref_sc = ref_st->priv_data;
5082 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5083 st = c->fc->streams[i];
5085 if (!sc->has_sidx) {
5086 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5090 c->frag_index.complete = 1;
5096 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5097 /* like the files created with Adobe Premiere 5.0, for samples see */
5098 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5099 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5104 return 0; /* continue */
5105 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5106 avio_skip(pb, atom.size - 4);
5109 atom.type = avio_rl32(pb);
5111 if (atom.type != MKTAG('m','d','a','t')) {
5112 avio_skip(pb, atom.size);
5115 err = mov_read_mdat(c, pb, atom);
5119 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5124 uint8_t *moov_data; /* uncompressed data */
5125 long cmov_len, moov_len;
5128 avio_rb32(pb); /* dcom atom */
5129 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5130 return AVERROR_INVALIDDATA;
5131 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5132 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5133 return AVERROR_INVALIDDATA;
5135 avio_rb32(pb); /* cmvd atom */
5136 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5137 return AVERROR_INVALIDDATA;
5138 moov_len = avio_rb32(pb); /* uncompressed size */
5139 cmov_len = atom.size - 6 * 4;
5141 cmov_data = av_malloc(cmov_len);
5143 return AVERROR(ENOMEM);
5144 moov_data = av_malloc(moov_len);
5147 return AVERROR(ENOMEM);
5149 ret = ffio_read_size(pb, cmov_data, cmov_len);
5151 goto free_and_return;
5153 ret = AVERROR_INVALIDDATA;
5154 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5155 goto free_and_return;
5156 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5157 goto free_and_return;
5158 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5159 atom.type = MKTAG('m','o','o','v');
5160 atom.size = moov_len;
5161 ret = mov_read_default(c, &ctx, atom);
5167 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5168 return AVERROR(ENOSYS);
5172 /* edit list atom */
5173 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5175 MOVStreamContext *sc;
5176 int i, edit_count, version;
5177 int64_t elst_entry_size;
5179 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5181 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5183 version = avio_r8(pb); /* version */
5184 avio_rb24(pb); /* flags */
5185 edit_count = avio_rb32(pb); /* entries */
5188 elst_entry_size = version == 1 ? 20 : 12;
5189 if (atom.size != edit_count * elst_entry_size) {
5190 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5191 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5192 edit_count, atom.size + 8);
5193 return AVERROR_INVALIDDATA;
5195 edit_count = atom.size / elst_entry_size;
5196 if (edit_count * elst_entry_size != atom.size) {
5197 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.", atom.size, edit_count);
5205 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5206 av_free(sc->elst_data);
5208 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5210 return AVERROR(ENOMEM);
5212 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5213 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5214 MOVElst *e = &sc->elst_data[i];
5217 e->duration = avio_rb64(pb);
5218 e->time = avio_rb64(pb);
5221 e->duration = avio_rb32(pb); /* segment duration */
5222 e->time = (int32_t)avio_rb32(pb); /* media time */
5225 e->rate = avio_rb32(pb) / 65536.0;
5227 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5228 e->duration, e->time, e->rate);
5230 if (e->time < 0 && e->time != -1 &&
5231 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5232 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5233 c->fc->nb_streams-1, i, e->time);
5234 return AVERROR_INVALIDDATA;
5242 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5244 MOVStreamContext *sc;
5246 if (c->fc->nb_streams < 1)
5247 return AVERROR_INVALIDDATA;
5248 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5249 sc->timecode_track = avio_rb32(pb);
5253 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5258 if (c->fc->nb_streams < 1)
5260 st = c->fc->streams[c->fc->nb_streams - 1];
5262 if (atom.size < 4) {
5263 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5264 return AVERROR_INVALIDDATA;
5267 /* For now, propagate only the OBUs, if any. Once libavcodec is
5268 updated to handle isobmff style extradata this can be removed. */
5274 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5281 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5284 int version, color_range, color_primaries, color_trc, color_space;
5286 if (c->fc->nb_streams < 1)
5288 st = c->fc->streams[c->fc->nb_streams - 1];
5290 if (atom.size < 5) {
5291 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5292 return AVERROR_INVALIDDATA;
5295 version = avio_r8(pb);
5297 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5300 avio_skip(pb, 3); /* flags */
5302 avio_skip(pb, 2); /* profile + level */
5303 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5304 color_primaries = avio_r8(pb);
5305 color_trc = avio_r8(pb);
5306 color_space = avio_r8(pb);
5307 if (avio_rb16(pb)) /* codecIntializationDataSize */
5308 return AVERROR_INVALIDDATA;
5310 if (!av_color_primaries_name(color_primaries))
5311 color_primaries = AVCOL_PRI_UNSPECIFIED;
5312 if (!av_color_transfer_name(color_trc))
5313 color_trc = AVCOL_TRC_UNSPECIFIED;
5314 if (!av_color_space_name(color_space))
5315 color_space = AVCOL_SPC_UNSPECIFIED;
5317 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5318 st->codecpar->color_primaries = color_primaries;
5319 st->codecpar->color_trc = color_trc;
5320 st->codecpar->color_space = color_space;
5325 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5327 MOVStreamContext *sc;
5330 if (c->fc->nb_streams < 1)
5331 return AVERROR_INVALIDDATA;
5333 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5335 if (atom.size < 5) {
5336 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5337 return AVERROR_INVALIDDATA;
5340 version = avio_r8(pb);
5342 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5345 avio_skip(pb, 3); /* flags */
5347 sc->mastering = av_mastering_display_metadata_alloc();
5349 return AVERROR(ENOMEM);
5351 for (i = 0; i < 3; i++) {
5352 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5353 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5355 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5356 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5358 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5359 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5361 sc->mastering->has_primaries = 1;
5362 sc->mastering->has_luminance = 1;
5367 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5369 MOVStreamContext *sc;
5370 const int mapping[3] = {1, 2, 0};
5371 const int chroma_den = 50000;
5372 const int luma_den = 10000;
5375 if (c->fc->nb_streams < 1)
5376 return AVERROR_INVALIDDATA;
5378 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5380 if (atom.size < 24) {
5381 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5382 return AVERROR_INVALIDDATA;
5385 sc->mastering = av_mastering_display_metadata_alloc();
5387 return AVERROR(ENOMEM);
5389 for (i = 0; i < 3; i++) {
5390 const int j = mapping[i];
5391 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5392 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5394 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5395 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5397 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5398 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5400 sc->mastering->has_luminance = 1;
5401 sc->mastering->has_primaries = 1;
5406 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5408 MOVStreamContext *sc;
5411 if (c->fc->nb_streams < 1)
5412 return AVERROR_INVALIDDATA;
5414 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5416 if (atom.size < 5) {
5417 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5418 return AVERROR_INVALIDDATA;
5421 version = avio_r8(pb);
5423 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5426 avio_skip(pb, 3); /* flags */
5428 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5430 return AVERROR(ENOMEM);
5432 sc->coll->MaxCLL = avio_rb16(pb);
5433 sc->coll->MaxFALL = avio_rb16(pb);
5438 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5440 MOVStreamContext *sc;
5442 if (c->fc->nb_streams < 1)
5443 return AVERROR_INVALIDDATA;
5445 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5447 if (atom.size < 4) {
5448 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5449 return AVERROR_INVALIDDATA;
5452 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5454 return AVERROR(ENOMEM);
5456 sc->coll->MaxCLL = avio_rb16(pb);
5457 sc->coll->MaxFALL = avio_rb16(pb);
5462 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5465 MOVStreamContext *sc;
5466 enum AVStereo3DType type;
5469 if (c->fc->nb_streams < 1)
5472 st = c->fc->streams[c->fc->nb_streams - 1];
5475 if (atom.size < 5) {
5476 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5477 return AVERROR_INVALIDDATA;
5479 avio_skip(pb, 4); /* version + flags */
5484 type = AV_STEREO3D_2D;
5487 type = AV_STEREO3D_TOPBOTTOM;
5490 type = AV_STEREO3D_SIDEBYSIDE;
5493 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5497 sc->stereo3d = av_stereo3d_alloc();
5499 return AVERROR(ENOMEM);
5501 sc->stereo3d->type = type;
5505 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5508 MOVStreamContext *sc;
5509 int size, version, layout;
5510 int32_t yaw, pitch, roll;
5511 uint32_t l = 0, t = 0, r = 0, b = 0;
5512 uint32_t tag, padding = 0;
5513 enum AVSphericalProjection projection;
5515 if (c->fc->nb_streams < 1)
5518 st = c->fc->streams[c->fc->nb_streams - 1];
5521 if (atom.size < 8) {
5522 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5523 return AVERROR_INVALIDDATA;
5526 size = avio_rb32(pb);
5527 if (size <= 12 || size > atom.size)
5528 return AVERROR_INVALIDDATA;
5530 tag = avio_rl32(pb);
5531 if (tag != MKTAG('s','v','h','d')) {
5532 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5535 version = avio_r8(pb);
5537 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5541 avio_skip(pb, 3); /* flags */
5542 avio_skip(pb, size - 12); /* metadata_source */
5544 size = avio_rb32(pb);
5545 if (size > atom.size)
5546 return AVERROR_INVALIDDATA;
5548 tag = avio_rl32(pb);
5549 if (tag != MKTAG('p','r','o','j')) {
5550 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5554 size = avio_rb32(pb);
5555 if (size > atom.size)
5556 return AVERROR_INVALIDDATA;
5558 tag = avio_rl32(pb);
5559 if (tag != MKTAG('p','r','h','d')) {
5560 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5563 version = avio_r8(pb);
5565 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5569 avio_skip(pb, 3); /* flags */
5571 /* 16.16 fixed point */
5572 yaw = avio_rb32(pb);
5573 pitch = avio_rb32(pb);
5574 roll = avio_rb32(pb);
5576 size = avio_rb32(pb);
5577 if (size > atom.size)
5578 return AVERROR_INVALIDDATA;
5580 tag = avio_rl32(pb);
5581 version = avio_r8(pb);
5583 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5587 avio_skip(pb, 3); /* flags */
5589 case MKTAG('c','b','m','p'):
5590 layout = avio_rb32(pb);
5592 av_log(c->fc, AV_LOG_WARNING,
5593 "Unsupported cubemap layout %d\n", layout);
5596 projection = AV_SPHERICAL_CUBEMAP;
5597 padding = avio_rb32(pb);
5599 case MKTAG('e','q','u','i'):
5605 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5606 av_log(c->fc, AV_LOG_ERROR,
5607 "Invalid bounding rectangle coordinates "
5608 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5609 return AVERROR_INVALIDDATA;
5612 if (l || t || r || b)
5613 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5615 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5618 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5622 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5624 return AVERROR(ENOMEM);
5626 sc->spherical->projection = projection;
5628 sc->spherical->yaw = yaw;
5629 sc->spherical->pitch = pitch;
5630 sc->spherical->roll = roll;
5632 sc->spherical->padding = padding;
5634 sc->spherical->bound_left = l;
5635 sc->spherical->bound_top = t;
5636 sc->spherical->bound_right = r;
5637 sc->spherical->bound_bottom = b;
5642 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5645 uint8_t *buffer = av_malloc(len + 1);
5649 return AVERROR(ENOMEM);
5652 ret = ffio_read_size(pb, buffer, len);
5656 /* Check for mandatory keys and values, try to support XML as best-effort */
5657 if (!sc->spherical &&
5658 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5659 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5660 av_stristr(val, "true") &&
5661 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5662 av_stristr(val, "true") &&
5663 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5664 av_stristr(val, "equirectangular")) {
5665 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5669 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5671 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5672 enum AVStereo3DType mode;
5674 if (av_stristr(buffer, "left-right"))
5675 mode = AV_STEREO3D_SIDEBYSIDE;
5676 else if (av_stristr(buffer, "top-bottom"))
5677 mode = AV_STEREO3D_TOPBOTTOM;
5679 mode = AV_STEREO3D_2D;
5681 sc->stereo3d = av_stereo3d_alloc();
5685 sc->stereo3d->type = mode;
5689 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5691 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5692 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5694 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5695 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5697 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5705 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5708 MOVStreamContext *sc;
5711 static const uint8_t uuid_isml_manifest[] = {
5712 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5713 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5715 static const uint8_t uuid_xmp[] = {
5716 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5717 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5719 static const uint8_t uuid_spherical[] = {
5720 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5721 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5724 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5725 return AVERROR_INVALIDDATA;
5727 if (c->fc->nb_streams < 1)
5729 st = c->fc->streams[c->fc->nb_streams - 1];
5732 ret = avio_read(pb, uuid, sizeof(uuid));
5735 } else if (ret != sizeof(uuid)) {
5736 return AVERROR_INVALIDDATA;
5738 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5739 uint8_t *buffer, *ptr;
5741 size_t len = atom.size - sizeof(uuid);
5744 return AVERROR_INVALIDDATA;
5746 ret = avio_skip(pb, 4); // zeroes
5749 buffer = av_mallocz(len + 1);
5751 return AVERROR(ENOMEM);
5753 ret = avio_read(pb, buffer, len);
5757 } else if (ret != len) {
5759 return AVERROR_INVALIDDATA;
5763 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5764 ptr += sizeof("systemBitrate=\"") - 1;
5765 c->bitrates_count++;
5766 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5768 c->bitrates_count = 0;
5770 return AVERROR(ENOMEM);
5773 ret = strtol(ptr, &endptr, 10);
5774 if (ret < 0 || errno || *endptr != '"') {
5775 c->bitrates[c->bitrates_count - 1] = 0;
5777 c->bitrates[c->bitrates_count - 1] = ret;
5782 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5784 size_t len = atom.size - sizeof(uuid);
5785 if (c->export_xmp) {
5786 buffer = av_mallocz(len + 1);
5788 return AVERROR(ENOMEM);
5790 ret = avio_read(pb, buffer, len);
5794 } else if (ret != len) {
5796 return AVERROR_INVALIDDATA;
5799 av_dict_set(&c->fc->metadata, "xmp",
5800 buffer, AV_DICT_DONT_STRDUP_VAL);
5802 // skip all uuid atom, which makes it fast for long uuid-xmp file
5803 ret = avio_skip(pb, len);
5807 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5808 size_t len = atom.size - sizeof(uuid);
5809 ret = mov_parse_uuid_spherical(sc, pb, len);
5813 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5819 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5822 uint8_t content[16];
5827 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5833 && !memcmp(content, "Anevia\x1A\x1A", 8)
5834 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5835 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5841 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5843 uint32_t format = avio_rl32(pb);
5844 MOVStreamContext *sc;
5848 if (c->fc->nb_streams < 1)
5850 st = c->fc->streams[c->fc->nb_streams - 1];
5855 case MKTAG('e','n','c','v'): // encrypted video
5856 case MKTAG('e','n','c','a'): // encrypted audio
5857 id = mov_codec_id(st, format);
5858 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5859 st->codecpar->codec_id != id) {
5860 av_log(c->fc, AV_LOG_WARNING,
5861 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5862 (char*)&format, st->codecpar->codec_id);
5866 st->codecpar->codec_id = id;
5867 sc->format = format;
5871 if (format != sc->format) {
5872 av_log(c->fc, AV_LOG_WARNING,
5873 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5874 (char*)&format, (char*)&sc->format);
5883 * Gets the current encryption info and associated current stream context. If
5884 * we are parsing a track fragment, this will return the specific encryption
5885 * info for this fragment; otherwise this will return the global encryption
5886 * info for the current stream.
5888 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5890 MOVFragmentStreamInfo *frag_stream_info;
5894 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5895 if (frag_stream_info) {
5896 for (i = 0; i < c->fc->nb_streams; i++) {
5897 if (c->fc->streams[i]->id == frag_stream_info->id) {
5898 st = c->fc->streams[i];
5902 if (i == c->fc->nb_streams)
5904 *sc = st->priv_data;
5906 if (!frag_stream_info->encryption_index) {
5907 // If this stream isn't encrypted, don't create the index.
5908 if (!(*sc)->cenc.default_encrypted_sample)
5910 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5911 if (!frag_stream_info->encryption_index)
5912 return AVERROR(ENOMEM);
5914 *encryption_index = frag_stream_info->encryption_index;
5917 // No current track fragment, using stream level encryption info.
5919 if (c->fc->nb_streams < 1)
5921 st = c->fc->streams[c->fc->nb_streams - 1];
5922 *sc = st->priv_data;
5924 if (!(*sc)->cenc.encryption_index) {
5925 // If this stream isn't encrypted, don't create the index.
5926 if (!(*sc)->cenc.default_encrypted_sample)
5928 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5929 if (!(*sc)->cenc.encryption_index)
5930 return AVERROR(ENOMEM);
5933 *encryption_index = (*sc)->cenc.encryption_index;
5938 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
5941 unsigned int subsample_count;
5942 AVSubsampleEncryptionInfo *subsamples;
5944 if (!sc->cenc.default_encrypted_sample) {
5945 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
5946 return AVERROR_INVALIDDATA;
5949 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
5951 return AVERROR(ENOMEM);
5953 if (sc->cenc.per_sample_iv_size != 0) {
5954 if (avio_read(pb, (*sample)->iv, sc->cenc.per_sample_iv_size) != sc->cenc.per_sample_iv_size) {
5955 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
5956 av_encryption_info_free(*sample);
5958 return AVERROR_INVALIDDATA;
5962 if (use_subsamples) {
5963 subsample_count = avio_rb16(pb);
5964 av_free((*sample)->subsamples);
5965 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
5966 if (!(*sample)->subsamples) {
5967 av_encryption_info_free(*sample);
5969 return AVERROR(ENOMEM);
5972 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
5973 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
5974 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
5977 if (pb->eof_reached) {
5978 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
5979 av_encryption_info_free(*sample);
5981 return AVERROR_INVALIDDATA;
5983 (*sample)->subsample_count = subsample_count;
5989 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5991 AVEncryptionInfo **encrypted_samples;
5992 MOVEncryptionIndex *encryption_index;
5993 MOVStreamContext *sc;
5994 int use_subsamples, ret;
5995 unsigned int sample_count, i, alloc_size = 0;
5997 ret = get_current_encryption_info(c, &encryption_index, &sc);
6001 if (encryption_index->nb_encrypted_samples) {
6002 // This can happen if we have both saio/saiz and senc atoms.
6003 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6007 avio_r8(pb); /* version */
6008 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6010 sample_count = avio_rb32(pb);
6011 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6012 return AVERROR(ENOMEM);
6014 for (i = 0; i < sample_count; i++) {
6015 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6016 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6017 min_samples * sizeof(*encrypted_samples));
6018 if (encrypted_samples) {
6019 encryption_index->encrypted_samples = encrypted_samples;
6021 ret = mov_read_sample_encryption_info(
6022 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6024 ret = AVERROR(ENOMEM);
6026 if (pb->eof_reached) {
6027 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6028 ret = AVERROR_INVALIDDATA;
6033 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6034 av_freep(&encryption_index->encrypted_samples);
6038 encryption_index->nb_encrypted_samples = sample_count;
6043 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6045 AVEncryptionInfo **sample, **encrypted_samples;
6047 size_t sample_count, sample_info_size, i;
6049 unsigned int alloc_size = 0;
6051 if (encryption_index->nb_encrypted_samples)
6053 sample_count = encryption_index->auxiliary_info_sample_count;
6054 if (encryption_index->auxiliary_offsets_count != 1) {
6055 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6056 return AVERROR_PATCHWELCOME;
6058 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6059 return AVERROR(ENOMEM);
6061 prev_pos = avio_tell(pb);
6062 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6063 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6064 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6068 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6069 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6070 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6071 min_samples * sizeof(*encrypted_samples));
6072 if (!encrypted_samples) {
6073 ret = AVERROR(ENOMEM);
6076 encryption_index->encrypted_samples = encrypted_samples;
6078 sample = &encryption_index->encrypted_samples[i];
6079 sample_info_size = encryption_index->auxiliary_info_default_size
6080 ? encryption_index->auxiliary_info_default_size
6081 : encryption_index->auxiliary_info_sizes[i];
6083 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6087 if (pb->eof_reached) {
6088 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6089 ret = AVERROR_INVALIDDATA;
6091 encryption_index->nb_encrypted_samples = sample_count;
6095 avio_seek(pb, prev_pos, SEEK_SET);
6097 for (; i > 0; i--) {
6098 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6100 av_freep(&encryption_index->encrypted_samples);
6106 * Tries to read the given number of bytes from the stream and puts it in a
6107 * newly allocated buffer. This reads in small chunks to avoid allocating large
6108 * memory if the file contains an invalid/malicious size value.
6110 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6112 const unsigned int block_size = 1024 * 1024;
6113 uint8_t *buffer = NULL;
6114 unsigned int alloc_size = 0, offset = 0;
6115 while (offset < size) {
6116 unsigned int new_size =
6117 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6118 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6119 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6122 return AVERROR(ENOMEM);
6124 buffer = new_buffer;
6126 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6128 return AVERROR_INVALIDDATA;
6137 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6139 MOVEncryptionIndex *encryption_index;
6140 MOVStreamContext *sc;
6142 unsigned int sample_count, aux_info_type, aux_info_param;
6144 ret = get_current_encryption_info(c, &encryption_index, &sc);
6148 if (encryption_index->nb_encrypted_samples) {
6149 // This can happen if we have both saio/saiz and senc atoms.
6150 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6154 if (encryption_index->auxiliary_info_sample_count) {
6155 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6156 return AVERROR_INVALIDDATA;
6159 avio_r8(pb); /* version */
6160 if (avio_rb24(pb) & 0x01) { /* flags */
6161 aux_info_type = avio_rb32(pb);
6162 aux_info_param = avio_rb32(pb);
6163 if (sc->cenc.default_encrypted_sample) {
6164 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6165 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6168 if (aux_info_param != 0) {
6169 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6173 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6174 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6175 aux_info_type == MKBETAG('c','e','n','s') ||
6176 aux_info_type == MKBETAG('c','b','c','1') ||
6177 aux_info_type == MKBETAG('c','b','c','s')) &&
6178 aux_info_param == 0) {
6179 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6180 return AVERROR_INVALIDDATA;
6185 } else if (!sc->cenc.default_encrypted_sample) {
6186 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6190 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6191 sample_count = avio_rb32(pb);
6192 encryption_index->auxiliary_info_sample_count = sample_count;
6194 if (encryption_index->auxiliary_info_default_size == 0) {
6195 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6197 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6202 if (encryption_index->auxiliary_offsets_count) {
6203 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6209 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6211 uint64_t *auxiliary_offsets;
6212 MOVEncryptionIndex *encryption_index;
6213 MOVStreamContext *sc;
6215 unsigned int version, entry_count, aux_info_type, aux_info_param;
6216 unsigned int alloc_size = 0;
6218 ret = get_current_encryption_info(c, &encryption_index, &sc);
6222 if (encryption_index->nb_encrypted_samples) {
6223 // This can happen if we have both saio/saiz and senc atoms.
6224 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6228 if (encryption_index->auxiliary_offsets_count) {
6229 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6230 return AVERROR_INVALIDDATA;
6233 version = avio_r8(pb); /* version */
6234 if (avio_rb24(pb) & 0x01) { /* flags */
6235 aux_info_type = avio_rb32(pb);
6236 aux_info_param = avio_rb32(pb);
6237 if (sc->cenc.default_encrypted_sample) {
6238 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6239 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6242 if (aux_info_param != 0) {
6243 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6247 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6248 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6249 aux_info_type == MKBETAG('c','e','n','s') ||
6250 aux_info_type == MKBETAG('c','b','c','1') ||
6251 aux_info_type == MKBETAG('c','b','c','s')) &&
6252 aux_info_param == 0) {
6253 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6254 return AVERROR_INVALIDDATA;
6259 } else if (!sc->cenc.default_encrypted_sample) {
6260 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6264 entry_count = avio_rb32(pb);
6265 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6266 return AVERROR(ENOMEM);
6268 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6269 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6270 auxiliary_offsets = av_fast_realloc(
6271 encryption_index->auxiliary_offsets, &alloc_size,
6272 min_offsets * sizeof(*auxiliary_offsets));
6273 if (!auxiliary_offsets) {
6274 av_freep(&encryption_index->auxiliary_offsets);
6275 return AVERROR(ENOMEM);
6277 encryption_index->auxiliary_offsets = auxiliary_offsets;
6280 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6282 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6284 if (c->frag_index.current >= 0) {
6285 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6289 if (pb->eof_reached) {
6290 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6291 av_freep(&encryption_index->auxiliary_offsets);
6292 return AVERROR_INVALIDDATA;
6295 encryption_index->auxiliary_offsets_count = entry_count;
6297 if (encryption_index->auxiliary_info_sample_count) {
6298 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6304 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6306 AVEncryptionInitInfo *info, *old_init_info;
6309 uint8_t *side_data, *extra_data, *old_side_data;
6310 size_t side_data_size;
6311 int ret = 0, old_side_data_size;
6312 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6314 if (c->fc->nb_streams < 1)
6316 st = c->fc->streams[c->fc->nb_streams-1];
6318 version = avio_r8(pb); /* version */
6319 avio_rb24(pb); /* flags */
6321 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6322 /* key_id_size */ 16, /* data_size */ 0);
6324 return AVERROR(ENOMEM);
6326 if (avio_read(pb, info->system_id, 16) != 16) {
6327 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6328 ret = AVERROR_INVALIDDATA;
6333 kid_count = avio_rb32(pb);
6334 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
6335 ret = AVERROR(ENOMEM);
6339 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6340 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6341 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6342 min_kid_count * sizeof(*key_ids));
6344 ret = AVERROR(ENOMEM);
6347 info->key_ids = key_ids;
6349 info->key_ids[i] = av_mallocz(16);
6350 if (!info->key_ids[i]) {
6351 ret = AVERROR(ENOMEM);
6354 info->num_key_ids = i + 1;
6356 if (avio_read(pb, info->key_ids[i], 16) != 16) {
6357 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6358 ret = AVERROR_INVALIDDATA;
6363 if (pb->eof_reached) {
6364 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6365 ret = AVERROR_INVALIDDATA;
6370 extra_data_size = avio_rb32(pb);
6371 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6375 av_freep(&info->data); // malloc(0) may still allocate something.
6376 info->data = extra_data;
6377 info->data_size = extra_data_size;
6379 // If there is existing initialization data, append to the list.
6380 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6381 if (old_side_data) {
6382 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6383 if (old_init_info) {
6384 // Append to the end of the list.
6385 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6391 info = old_init_info;
6393 // Assume existing side-data will be valid, so the only error we could get is OOM.
6394 ret = AVERROR(ENOMEM);
6399 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6401 ret = AVERROR(ENOMEM);
6404 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6405 side_data, side_data_size);
6410 av_encryption_init_info_free(info);
6414 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6417 MOVStreamContext *sc;
6419 if (c->fc->nb_streams < 1)
6421 st = c->fc->streams[c->fc->nb_streams-1];
6424 if (sc->pseudo_stream_id != 0) {
6425 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6426 return AVERROR_PATCHWELCOME;
6430 return AVERROR_INVALIDDATA;
6432 avio_rb32(pb); /* version and flags */
6434 if (!sc->cenc.default_encrypted_sample) {
6435 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6436 if (!sc->cenc.default_encrypted_sample) {
6437 return AVERROR(ENOMEM);
6441 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6445 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6448 MOVStreamContext *sc;
6449 unsigned int version, pattern, is_protected, iv_size;
6451 if (c->fc->nb_streams < 1)
6453 st = c->fc->streams[c->fc->nb_streams-1];
6456 if (sc->pseudo_stream_id != 0) {
6457 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6458 return AVERROR_PATCHWELCOME;
6461 if (!sc->cenc.default_encrypted_sample) {
6462 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6463 if (!sc->cenc.default_encrypted_sample) {
6464 return AVERROR(ENOMEM);
6469 return AVERROR_INVALIDDATA;
6471 version = avio_r8(pb); /* version */
6472 avio_rb24(pb); /* flags */
6474 avio_r8(pb); /* reserved */
6475 pattern = avio_r8(pb);
6478 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6479 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6482 is_protected = avio_r8(pb);
6483 if (is_protected && !sc->cenc.encryption_index) {
6484 // The whole stream should be by-default encrypted.
6485 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6486 if (!sc->cenc.encryption_index)
6487 return AVERROR(ENOMEM);
6489 sc->cenc.per_sample_iv_size = avio_r8(pb);
6490 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6491 sc->cenc.per_sample_iv_size != 16) {
6492 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6493 return AVERROR_INVALIDDATA;
6495 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6496 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6497 return AVERROR_INVALIDDATA;
6500 if (is_protected && !sc->cenc.per_sample_iv_size) {
6501 iv_size = avio_r8(pb);
6502 if (iv_size != 8 && iv_size != 16) {
6503 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6504 return AVERROR_INVALIDDATA;
6507 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6508 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6509 return AVERROR_INVALIDDATA;
6516 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6519 int last, type, size, ret;
6522 if (c->fc->nb_streams < 1)
6524 st = c->fc->streams[c->fc->nb_streams-1];
6526 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6527 return AVERROR_INVALIDDATA;
6529 /* Check FlacSpecificBox version. */
6530 if (avio_r8(pb) != 0)
6531 return AVERROR_INVALIDDATA;
6533 avio_rb24(pb); /* Flags */
6535 avio_read(pb, buf, sizeof(buf));
6536 flac_parse_block_header(buf, &last, &type, &size);
6538 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6539 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6540 return AVERROR_INVALIDDATA;
6543 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6548 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6553 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6557 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6558 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6559 return AVERROR_PATCHWELCOME;
6562 if (!sc->cenc.aes_ctr) {
6563 /* initialize the cipher */
6564 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6565 if (!sc->cenc.aes_ctr) {
6566 return AVERROR(ENOMEM);
6569 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6575 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6577 if (!sample->subsample_count)
6579 /* decrypt the whole packet */
6580 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6584 for (i = 0; i < sample->subsample_count; i++)
6586 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6587 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6588 return AVERROR_INVALIDDATA;
6591 /* skip the clear bytes */
6592 input += sample->subsamples[i].bytes_of_clear_data;
6593 size -= sample->subsamples[i].bytes_of_clear_data;
6595 /* decrypt the encrypted bytes */
6596 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6597 input += sample->subsamples[i].bytes_of_protected_data;
6598 size -= sample->subsamples[i].bytes_of_protected_data;
6602 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6603 return AVERROR_INVALIDDATA;
6609 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6611 MOVFragmentStreamInfo *frag_stream_info;
6612 MOVEncryptionIndex *encryption_index;
6613 AVEncryptionInfo *encrypted_sample;
6614 int encrypted_index, ret;
6616 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6617 encrypted_index = current_index;
6618 encryption_index = NULL;
6619 if (frag_stream_info) {
6620 // Note this only supports encryption info in the first sample descriptor.
6621 if (mov->fragment.stsd_id == 1) {
6622 if (frag_stream_info->encryption_index) {
6623 encrypted_index = current_index - frag_stream_info->index_entry;
6624 encryption_index = frag_stream_info->encryption_index;
6626 encryption_index = sc->cenc.encryption_index;
6630 encryption_index = sc->cenc.encryption_index;
6633 if (encryption_index) {
6634 if (encryption_index->auxiliary_info_sample_count &&
6635 !encryption_index->nb_encrypted_samples) {
6636 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6637 return AVERROR_INVALIDDATA;
6639 if (encryption_index->auxiliary_offsets_count &&
6640 !encryption_index->nb_encrypted_samples) {
6641 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6642 return AVERROR_INVALIDDATA;
6645 if (!encryption_index->nb_encrypted_samples) {
6646 // Full-sample encryption with default settings.
6647 encrypted_sample = sc->cenc.default_encrypted_sample;
6648 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6649 // Per-sample setting override.
6650 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6652 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6653 return AVERROR_INVALIDDATA;
6656 if (mov->decryption_key) {
6657 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6660 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6662 return AVERROR(ENOMEM);
6663 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6673 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6675 const int OPUS_SEEK_PREROLL_MS = 80;
6681 if (c->fc->nb_streams < 1)
6683 st = c->fc->streams[c->fc->nb_streams-1];
6685 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6686 return AVERROR_INVALIDDATA;
6688 /* Check OpusSpecificBox version. */
6689 if (avio_r8(pb) != 0) {
6690 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6691 return AVERROR_INVALIDDATA;
6694 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6695 size = atom.size + 8;
6697 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
6700 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6701 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6702 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6703 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6705 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6706 little-endian; aside from the preceeding magic and version they're
6707 otherwise currently identical. Data after output gain at offset 16
6708 doesn't need to be bytewapped. */
6709 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6710 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6711 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6712 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6714 st->codecpar->initial_padding = pre_skip;
6715 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6716 (AVRational){1, 1000},
6717 (AVRational){1, 48000});
6722 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6725 unsigned format_info;
6726 int channel_assignment, channel_assignment1, channel_assignment2;
6729 if (c->fc->nb_streams < 1)
6731 st = c->fc->streams[c->fc->nb_streams-1];
6734 return AVERROR_INVALIDDATA;
6736 format_info = avio_rb32(pb);
6738 ratebits = (format_info >> 28) & 0xF;
6739 channel_assignment1 = (format_info >> 15) & 0x1F;
6740 channel_assignment2 = format_info & 0x1FFF;
6741 if (channel_assignment2)
6742 channel_assignment = channel_assignment2;
6744 channel_assignment = channel_assignment1;
6746 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6747 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6748 st->codecpar->channels = truehd_channels(channel_assignment);
6749 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6754 static const MOVParseTableEntry mov_default_parse_table[] = {
6755 { MKTAG('A','C','L','R'), mov_read_aclr },
6756 { MKTAG('A','P','R','G'), mov_read_avid },
6757 { MKTAG('A','A','L','P'), mov_read_avid },
6758 { MKTAG('A','R','E','S'), mov_read_ares },
6759 { MKTAG('a','v','s','s'), mov_read_avss },
6760 { MKTAG('a','v','1','C'), mov_read_av1c },
6761 { MKTAG('c','h','p','l'), mov_read_chpl },
6762 { MKTAG('c','o','6','4'), mov_read_stco },
6763 { MKTAG('c','o','l','r'), mov_read_colr },
6764 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6765 { MKTAG('d','i','n','f'), mov_read_default },
6766 { MKTAG('D','p','x','E'), mov_read_dpxe },
6767 { MKTAG('d','r','e','f'), mov_read_dref },
6768 { MKTAG('e','d','t','s'), mov_read_default },
6769 { MKTAG('e','l','s','t'), mov_read_elst },
6770 { MKTAG('e','n','d','a'), mov_read_enda },
6771 { MKTAG('f','i','e','l'), mov_read_fiel },
6772 { MKTAG('a','d','r','m'), mov_read_adrm },
6773 { MKTAG('f','t','y','p'), mov_read_ftyp },
6774 { MKTAG('g','l','b','l'), mov_read_glbl },
6775 { MKTAG('h','d','l','r'), mov_read_hdlr },
6776 { MKTAG('i','l','s','t'), mov_read_ilst },
6777 { MKTAG('j','p','2','h'), mov_read_jp2h },
6778 { MKTAG('m','d','a','t'), mov_read_mdat },
6779 { MKTAG('m','d','h','d'), mov_read_mdhd },
6780 { MKTAG('m','d','i','a'), mov_read_default },
6781 { MKTAG('m','e','t','a'), mov_read_meta },
6782 { MKTAG('m','i','n','f'), mov_read_default },
6783 { MKTAG('m','o','o','f'), mov_read_moof },
6784 { MKTAG('m','o','o','v'), mov_read_moov },
6785 { MKTAG('m','v','e','x'), mov_read_default },
6786 { MKTAG('m','v','h','d'), mov_read_mvhd },
6787 { MKTAG('S','M','I',' '), mov_read_svq3 },
6788 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6789 { MKTAG('a','v','c','C'), mov_read_glbl },
6790 { MKTAG('p','a','s','p'), mov_read_pasp },
6791 { MKTAG('s','i','d','x'), mov_read_sidx },
6792 { MKTAG('s','t','b','l'), mov_read_default },
6793 { MKTAG('s','t','c','o'), mov_read_stco },
6794 { MKTAG('s','t','p','s'), mov_read_stps },
6795 { MKTAG('s','t','r','f'), mov_read_strf },
6796 { MKTAG('s','t','s','c'), mov_read_stsc },
6797 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6798 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6799 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6800 { MKTAG('s','t','t','s'), mov_read_stts },
6801 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6802 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
6803 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6804 { MKTAG('t','f','d','t'), mov_read_tfdt },
6805 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6806 { MKTAG('t','r','a','k'), mov_read_trak },
6807 { MKTAG('t','r','a','f'), mov_read_default },
6808 { MKTAG('t','r','e','f'), mov_read_default },
6809 { MKTAG('t','m','c','d'), mov_read_tmcd },
6810 { MKTAG('c','h','a','p'), mov_read_chap },
6811 { MKTAG('t','r','e','x'), mov_read_trex },
6812 { MKTAG('t','r','u','n'), mov_read_trun },
6813 { MKTAG('u','d','t','a'), mov_read_default },
6814 { MKTAG('w','a','v','e'), mov_read_wave },
6815 { MKTAG('e','s','d','s'), mov_read_esds },
6816 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6817 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6818 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6819 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6820 { MKTAG('w','f','e','x'), mov_read_wfex },
6821 { MKTAG('c','m','o','v'), mov_read_cmov },
6822 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6823 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6824 { MKTAG('s','b','g','p'), mov_read_sbgp },
6825 { MKTAG('h','v','c','C'), mov_read_glbl },
6826 { MKTAG('u','u','i','d'), mov_read_uuid },
6827 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6828 { MKTAG('f','r','e','e'), mov_read_free },
6829 { MKTAG('-','-','-','-'), mov_read_custom },
6830 { MKTAG('s','i','n','f'), mov_read_default },
6831 { MKTAG('f','r','m','a'), mov_read_frma },
6832 { MKTAG('s','e','n','c'), mov_read_senc },
6833 { MKTAG('s','a','i','z'), mov_read_saiz },
6834 { MKTAG('s','a','i','o'), mov_read_saio },
6835 { MKTAG('p','s','s','h'), mov_read_pssh },
6836 { MKTAG('s','c','h','m'), mov_read_schm },
6837 { MKTAG('s','c','h','i'), mov_read_default },
6838 { MKTAG('t','e','n','c'), mov_read_tenc },
6839 { MKTAG('d','f','L','a'), mov_read_dfla },
6840 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6841 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6842 { MKTAG('d','O','p','s'), mov_read_dops },
6843 { MKTAG('d','m','l','p'), mov_read_dmlp },
6844 { MKTAG('S','m','D','m'), mov_read_smdm },
6845 { MKTAG('C','o','L','L'), mov_read_coll },
6846 { MKTAG('v','p','c','C'), mov_read_vpcc },
6847 { MKTAG('m','d','c','v'), mov_read_mdcv },
6848 { MKTAG('c','l','l','i'), mov_read_clli },
6852 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6854 int64_t total_size = 0;
6858 if (c->atom_depth > 10) {
6859 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6860 return AVERROR_INVALIDDATA;
6865 atom.size = INT64_MAX;
6866 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6867 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
6870 if (atom.size >= 8) {
6871 a.size = avio_rb32(pb);
6872 a.type = avio_rl32(pb);
6873 if (a.type == MKTAG('f','r','e','e') &&
6875 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT &&
6878 uint32_t *type = (uint32_t *)buf + 1;
6879 if (avio_read(pb, buf, 8) != 8)
6880 return AVERROR_INVALIDDATA;
6881 avio_seek(pb, -8, SEEK_CUR);
6882 if (*type == MKTAG('m','v','h','d') ||
6883 *type == MKTAG('c','m','o','v')) {
6884 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free atom.\n");
6885 a.type = MKTAG('m','o','o','v');
6888 if (atom.type != MKTAG('r','o','o','t') &&
6889 atom.type != MKTAG('m','o','o','v'))
6891 if (a.type == MKTAG('t','r','a','k') || a.type == MKTAG('m','d','a','t'))
6893 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
6900 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
6901 a.size = avio_rb64(pb) - 8;
6905 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
6906 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
6908 a.size = atom.size - total_size + 8;
6913 a.size = FFMIN(a.size, atom.size - total_size);
6915 for (i = 0; mov_default_parse_table[i].type; i++)
6916 if (mov_default_parse_table[i].type == a.type) {
6917 parse = mov_default_parse_table[i].parse;
6921 // container is user data
6922 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
6923 atom.type == MKTAG('i','l','s','t')))
6924 parse = mov_read_udta_string;
6926 // Supports parsing the QuickTime Metadata Keys.
6927 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
6928 if (!parse && c->found_hdlr_mdta &&
6929 atom.type == MKTAG('m','e','t','a') &&
6930 a.type == MKTAG('k','e','y','s')) {
6931 parse = mov_read_keys;
6934 if (!parse) { /* skip leaf atoms data */
6935 avio_skip(pb, a.size);
6937 int64_t start_pos = avio_tell(pb);
6939 int err = parse(c, pb, a);
6944 if (c->found_moov && c->found_mdat &&
6945 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
6946 start_pos + a.size == avio_size(pb))) {
6947 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
6948 c->next_root_atom = start_pos + a.size;
6952 left = a.size - avio_tell(pb) + start_pos;
6953 if (left > 0) /* skip garbage at atom end */
6954 avio_skip(pb, left);
6955 else if (left < 0) {
6956 av_log(c->fc, AV_LOG_WARNING,
6957 "overread end of atom '%.4s' by %"PRId64" bytes\n",
6958 (char*)&a.type, -left);
6959 avio_seek(pb, left, SEEK_CUR);
6963 total_size += a.size;
6966 if (total_size < atom.size && atom.size < 0x7ffff)
6967 avio_skip(pb, atom.size - total_size);
6973 static int mov_probe(const AVProbeData *p)
6978 int moov_offset = -1;
6980 /* check file header */
6983 /* ignore invalid offset */
6984 if ((offset + 8) > (unsigned int)p->buf_size)
6986 tag = AV_RL32(p->buf + offset + 4);
6988 /* check for obvious tags */
6989 case MKTAG('m','o','o','v'):
6990 moov_offset = offset + 4;
6991 case MKTAG('m','d','a','t'):
6992 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
6993 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
6994 case MKTAG('f','t','y','p'):
6995 if (AV_RB32(p->buf+offset) < 8 &&
6996 (AV_RB32(p->buf+offset) != 1 ||
6997 offset + 12 > (unsigned int)p->buf_size ||
6998 AV_RB64(p->buf+offset + 8) == 0)) {
6999 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7000 } else if (tag == MKTAG('f','t','y','p') &&
7001 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
7002 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
7004 score = FFMAX(score, 5);
7006 score = AVPROBE_SCORE_MAX;
7008 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7010 /* those are more common words, so rate then a bit less */
7011 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
7012 case MKTAG('w','i','d','e'):
7013 case MKTAG('f','r','e','e'):
7014 case MKTAG('j','u','n','k'):
7015 case MKTAG('p','i','c','t'):
7016 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
7017 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7019 case MKTAG(0x82,0x82,0x7f,0x7d):
7020 case MKTAG('s','k','i','p'):
7021 case MKTAG('u','u','i','d'):
7022 case MKTAG('p','r','f','l'):
7023 /* if we only find those cause probedata is too small at least rate them */
7024 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7025 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7028 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7031 if(score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
7032 /* moov atom in the header - we should make sure that this is not a
7033 * MOV-packed MPEG-PS */
7034 offset = moov_offset;
7036 while(offset < (p->buf_size - 16)){ /* Sufficient space */
7037 /* We found an actual hdlr atom */
7038 if(AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7039 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7040 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')){
7041 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7042 /* We found a media handler reference atom describing an
7043 * MPEG-PS-in-MOV, return a
7044 * low score to force expanding the probe window until
7045 * mpegps_probe finds what it needs */
7056 // must be done after parsing all trak because there's no order requirement
7057 static void mov_read_chapters(AVFormatContext *s)
7059 MOVContext *mov = s->priv_data;
7061 MOVStreamContext *sc;
7066 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7067 chapter_track = mov->chapter_tracks[j];
7069 for (i = 0; i < s->nb_streams; i++)
7070 if (s->streams[i]->id == chapter_track) {
7075 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7080 cur_pos = avio_tell(sc->pb);
7082 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7083 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7084 if (st->nb_index_entries) {
7085 // Retrieve the first frame, if possible
7087 AVIndexEntry *sample = &st->index_entries[0];
7088 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7089 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7093 if (av_get_packet(sc->pb, &pkt, sample->size) < 0)
7096 st->attached_pic = pkt;
7097 st->attached_pic.stream_index = st->index;
7098 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
7101 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7102 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7103 st->discard = AVDISCARD_ALL;
7104 for (i = 0; i < st->nb_index_entries; i++) {
7105 AVIndexEntry *sample = &st->index_entries[i];
7106 int64_t end = i+1 < st->nb_index_entries ? st->index_entries[i+1].timestamp : st->duration;
7111 if (end < sample->timestamp) {
7112 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7113 end = AV_NOPTS_VALUE;
7116 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7117 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7121 // the first two bytes are the length of the title
7122 len = avio_rb16(sc->pb);
7123 if (len > sample->size-2)
7125 title_len = 2*len + 1;
7126 if (!(title = av_mallocz(title_len)))
7129 // The samples could theoretically be in any encoding if there's an encd
7130 // atom following, but in practice are only utf-8 or utf-16, distinguished
7131 // instead by the presence of a BOM
7135 ch = avio_rb16(sc->pb);
7137 avio_get_str16be(sc->pb, len, title, title_len);
7138 else if (ch == 0xfffe)
7139 avio_get_str16le(sc->pb, len, title, title_len);
7142 if (len == 1 || len == 2)
7145 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7149 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7154 avio_seek(sc->pb, cur_pos, SEEK_SET);
7158 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7159 uint32_t value, int flags)
7162 char buf[AV_TIMECODE_STR_SIZE];
7163 AVRational rate = st->avg_frame_rate;
7164 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7167 av_dict_set(&st->metadata, "timecode",
7168 av_timecode_make_string(&tc, buf, value), 0);
7172 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7174 MOVStreamContext *sc = st->priv_data;
7175 char buf[AV_TIMECODE_STR_SIZE];
7176 int64_t cur_pos = avio_tell(sc->pb);
7177 int hh, mm, ss, ff, drop;
7179 if (!st->nb_index_entries)
7182 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7183 avio_skip(s->pb, 13);
7184 hh = avio_r8(s->pb);
7185 mm = avio_r8(s->pb);
7186 ss = avio_r8(s->pb);
7187 drop = avio_r8(s->pb);
7188 ff = avio_r8(s->pb);
7189 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7190 hh, mm, ss, drop ? ';' : ':', ff);
7191 av_dict_set(&st->metadata, "timecode", buf, 0);
7193 avio_seek(sc->pb, cur_pos, SEEK_SET);
7197 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7199 MOVStreamContext *sc = st->priv_data;
7201 int64_t cur_pos = avio_tell(sc->pb);
7204 if (!st->nb_index_entries)
7207 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7208 value = avio_rb32(s->pb);
7210 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7211 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7212 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7214 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7215 * not the case) and thus assume "frame number format" instead of QT one.
7216 * No sample with tmcd track can be found with a QT timecode at the moment,
7217 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7219 parse_timecode_in_framenum_format(s, st, value, flags);
7221 avio_seek(sc->pb, cur_pos, SEEK_SET);
7225 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7227 if (!index || !*index) return;
7228 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7229 av_encryption_info_free((*index)->encrypted_samples[i]);
7231 av_freep(&(*index)->encrypted_samples);
7232 av_freep(&(*index)->auxiliary_info_sizes);
7233 av_freep(&(*index)->auxiliary_offsets);
7237 static int mov_read_close(AVFormatContext *s)
7239 MOVContext *mov = s->priv_data;
7242 for (i = 0; i < s->nb_streams; i++) {
7243 AVStream *st = s->streams[i];
7244 MOVStreamContext *sc = st->priv_data;
7249 av_freep(&sc->ctts_data);
7250 for (j = 0; j < sc->drefs_count; j++) {
7251 av_freep(&sc->drefs[j].path);
7252 av_freep(&sc->drefs[j].dir);
7254 av_freep(&sc->drefs);
7256 sc->drefs_count = 0;
7258 if (!sc->pb_is_copied)
7259 ff_format_io_close(s, &sc->pb);
7262 av_freep(&sc->chunk_offsets);
7263 av_freep(&sc->stsc_data);
7264 av_freep(&sc->sample_sizes);
7265 av_freep(&sc->keyframes);
7266 av_freep(&sc->stts_data);
7267 av_freep(&sc->sdtp_data);
7268 av_freep(&sc->stps_data);
7269 av_freep(&sc->elst_data);
7270 av_freep(&sc->rap_group);
7271 av_freep(&sc->display_matrix);
7272 av_freep(&sc->index_ranges);
7275 for (j = 0; j < sc->stsd_count; j++)
7276 av_free(sc->extradata[j]);
7277 av_freep(&sc->extradata);
7278 av_freep(&sc->extradata_size);
7280 mov_free_encryption_index(&sc->cenc.encryption_index);
7281 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7282 av_aes_ctr_free(sc->cenc.aes_ctr);
7284 av_freep(&sc->stereo3d);
7285 av_freep(&sc->spherical);
7286 av_freep(&sc->mastering);
7287 av_freep(&sc->coll);
7290 if (mov->dv_demux) {
7291 avformat_free_context(mov->dv_fctx);
7292 mov->dv_fctx = NULL;
7295 if (mov->meta_keys) {
7296 for (i = 1; i < mov->meta_keys_count; i++) {
7297 av_freep(&mov->meta_keys[i]);
7299 av_freep(&mov->meta_keys);
7302 av_freep(&mov->trex_data);
7303 av_freep(&mov->bitrates);
7305 for (i = 0; i < mov->frag_index.nb_items; i++) {
7306 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7307 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7308 mov_free_encryption_index(&frag[j].encryption_index);
7310 av_freep(&mov->frag_index.item[i].stream_info);
7312 av_freep(&mov->frag_index.item);
7314 av_freep(&mov->aes_decrypt);
7315 av_freep(&mov->chapter_tracks);
7320 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7324 for (i = 0; i < s->nb_streams; i++) {
7325 AVStream *st = s->streams[i];
7326 MOVStreamContext *sc = st->priv_data;
7328 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7329 sc->timecode_track == tmcd_id)
7335 /* look for a tmcd track not referenced by any video track, and export it globally */
7336 static void export_orphan_timecode(AVFormatContext *s)
7340 for (i = 0; i < s->nb_streams; i++) {
7341 AVStream *st = s->streams[i];
7343 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7344 !tmcd_is_referenced(s, i + 1)) {
7345 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7347 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7354 static int read_tfra(MOVContext *mov, AVIOContext *f)
7356 int version, fieldlength, i, j;
7357 int64_t pos = avio_tell(f);
7358 uint32_t size = avio_rb32(f);
7359 unsigned track_id, item_count;
7361 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7364 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7366 version = avio_r8(f);
7368 track_id = avio_rb32(f);
7369 fieldlength = avio_rb32(f);
7370 item_count = avio_rb32(f);
7371 for (i = 0; i < item_count; i++) {
7372 int64_t time, offset;
7374 MOVFragmentStreamInfo * frag_stream_info;
7377 return AVERROR_INVALIDDATA;
7381 time = avio_rb64(f);
7382 offset = avio_rb64(f);
7384 time = avio_rb32(f);
7385 offset = avio_rb32(f);
7388 // The first sample of each stream in a fragment is always a random
7389 // access sample. So it's entry in the tfra can be used as the
7390 // initial PTS of the fragment.
7391 index = update_frag_index(mov, offset);
7392 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7393 if (frag_stream_info &&
7394 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7395 frag_stream_info->first_tfra_pts = time;
7397 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7399 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7401 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7405 avio_seek(f, pos + size, SEEK_SET);
7409 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7411 int64_t stream_size = avio_size(f);
7412 int64_t original_pos = avio_tell(f);
7416 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7420 mfra_size = avio_rb32(f);
7421 if (mfra_size < 0 || mfra_size > stream_size) {
7422 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7425 if ((seek_ret = avio_seek(f, -mfra_size, SEEK_CUR)) < 0) {
7429 if (avio_rb32(f) != mfra_size) {
7430 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7433 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7434 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7437 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7439 ret = read_tfra(c, f);
7445 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7447 av_log(c->fc, AV_LOG_ERROR,
7448 "failed to seek back after looking for mfra\n");
7454 static int mov_read_header(AVFormatContext *s)
7456 MOVContext *mov = s->priv_data;
7457 AVIOContext *pb = s->pb;
7459 MOVAtom atom = { AV_RL32("root") };
7462 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7463 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7464 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7465 return AVERROR(EINVAL);
7469 mov->trak_index = -1;
7470 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7471 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7472 atom.size = avio_size(pb);
7474 atom.size = INT64_MAX;
7476 /* check MOV header */
7478 if (mov->moov_retry)
7479 avio_seek(pb, 0, SEEK_SET);
7480 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7481 av_log(s, AV_LOG_ERROR, "error reading header\n");
7485 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7486 if (!mov->found_moov) {
7487 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7489 return AVERROR_INVALIDDATA;
7491 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7493 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7494 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7495 mov_read_chapters(s);
7496 for (i = 0; i < s->nb_streams; i++)
7497 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7498 mov_read_timecode_track(s, s->streams[i]);
7499 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7500 mov_read_rtmd_track(s, s->streams[i]);
7504 /* copy timecode metadata from tmcd tracks to the related video streams */
7505 for (i = 0; i < s->nb_streams; i++) {
7506 AVStream *st = s->streams[i];
7507 MOVStreamContext *sc = st->priv_data;
7508 if (sc->timecode_track > 0) {
7509 AVDictionaryEntry *tcr;
7510 int tmcd_st_id = -1;
7512 for (j = 0; j < s->nb_streams; j++)
7513 if (s->streams[j]->id == sc->timecode_track)
7516 if (tmcd_st_id < 0 || tmcd_st_id == i)
7518 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7520 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7523 export_orphan_timecode(s);
7525 for (i = 0; i < s->nb_streams; i++) {
7526 AVStream *st = s->streams[i];
7527 MOVStreamContext *sc = st->priv_data;
7528 fix_timescale(mov, sc);
7529 if(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7530 st->skip_samples = sc->start_pad;
7532 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7533 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7534 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7535 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7536 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7537 st->codecpar->width = sc->width;
7538 st->codecpar->height = sc->height;
7540 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7541 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7545 if (mov->handbrake_version &&
7546 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7547 st->codecpar->codec_id == AV_CODEC_ID_MP3
7549 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7550 st->need_parsing = AVSTREAM_PARSE_FULL;
7554 if (mov->trex_data) {
7555 for (i = 0; i < s->nb_streams; i++) {
7556 AVStream *st = s->streams[i];
7557 MOVStreamContext *sc = st->priv_data;
7558 if (st->duration > 0) {
7559 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7560 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7561 sc->data_size, sc->time_scale);
7563 return AVERROR_INVALIDDATA;
7565 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7570 if (mov->use_mfra_for > 0) {
7571 for (i = 0; i < s->nb_streams; i++) {
7572 AVStream *st = s->streams[i];
7573 MOVStreamContext *sc = st->priv_data;
7574 if (sc->duration_for_fps > 0) {
7575 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7576 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7577 sc->data_size, sc->time_scale);
7579 return AVERROR_INVALIDDATA;
7581 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7582 sc->duration_for_fps;
7587 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7588 if (mov->bitrates[i]) {
7589 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7593 ff_rfps_calculate(s);
7595 for (i = 0; i < s->nb_streams; i++) {
7596 AVStream *st = s->streams[i];
7597 MOVStreamContext *sc = st->priv_data;
7599 switch (st->codecpar->codec_type) {
7600 case AVMEDIA_TYPE_AUDIO:
7601 err = ff_replaygain_export(st, s->metadata);
7607 case AVMEDIA_TYPE_VIDEO:
7608 if (sc->display_matrix) {
7609 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7610 sizeof(int32_t) * 9);
7614 sc->display_matrix = NULL;
7617 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7618 (uint8_t *)sc->stereo3d,
7619 sizeof(*sc->stereo3d));
7623 sc->stereo3d = NULL;
7625 if (sc->spherical) {
7626 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7627 (uint8_t *)sc->spherical,
7628 sc->spherical_size);
7632 sc->spherical = NULL;
7634 if (sc->mastering) {
7635 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7636 (uint8_t *)sc->mastering,
7637 sizeof(*sc->mastering));
7641 sc->mastering = NULL;
7644 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7645 (uint8_t *)sc->coll,
7655 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7657 for (i = 0; i < mov->frag_index.nb_items; i++)
7658 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7659 mov->frag_index.item[i].headers_read = 1;
7664 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7666 AVIndexEntry *sample = NULL;
7667 int64_t best_dts = INT64_MAX;
7669 for (i = 0; i < s->nb_streams; i++) {
7670 AVStream *avst = s->streams[i];
7671 MOVStreamContext *msc = avst->priv_data;
7672 if (msc->pb && msc->current_sample < avst->nb_index_entries) {
7673 AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample];
7674 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7675 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7676 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7677 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7678 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb &&
7679 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7680 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7681 sample = current_sample;
7690 static int should_retry(AVIOContext *pb, int error_code) {
7691 if (error_code == AVERROR_EOF || avio_feof(pb))
7697 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7700 MOVContext *mov = s->priv_data;
7702 if (index >= 0 && index < mov->frag_index.nb_items)
7703 target = mov->frag_index.item[index].moof_offset;
7704 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7705 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7706 return AVERROR_INVALIDDATA;
7709 mov->next_root_atom = 0;
7710 if (index < 0 || index >= mov->frag_index.nb_items)
7711 index = search_frag_moof_offset(&mov->frag_index, target);
7712 if (index < mov->frag_index.nb_items) {
7713 if (index + 1 < mov->frag_index.nb_items)
7714 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7715 if (mov->frag_index.item[index].headers_read)
7717 mov->frag_index.item[index].headers_read = 1;
7720 mov->found_mdat = 0;
7722 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7725 if (avio_feof(s->pb))
7727 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7732 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7734 uint8_t *side, *extradata;
7737 /* Save the current index. */
7738 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7740 /* Notify the decoder that extradata changed. */
7741 extradata_size = sc->extradata_size[sc->last_stsd_index];
7742 extradata = sc->extradata[sc->last_stsd_index];
7743 if (extradata_size > 0 && extradata) {
7744 side = av_packet_new_side_data(pkt,
7745 AV_PKT_DATA_NEW_EXTRADATA,
7748 return AVERROR(ENOMEM);
7749 memcpy(side, extradata, extradata_size);
7755 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7757 MOVContext *mov = s->priv_data;
7758 MOVStreamContext *sc;
7759 AVIndexEntry *sample;
7760 AVStream *st = NULL;
7761 int64_t current_index;
7765 sample = mov_find_next_sample(s, &st);
7766 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7767 if (!mov->next_root_atom)
7769 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7774 /* must be done just before reading, to avoid infinite loop on sample */
7775 current_index = sc->current_index;
7776 mov_current_sample_inc(sc);
7778 if (mov->next_root_atom) {
7779 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7780 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7783 if (st->discard != AVDISCARD_ALL) {
7784 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7785 if (ret64 != sample->pos) {
7786 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7787 sc->ffindex, sample->pos);
7788 if (should_retry(sc->pb, ret64)) {
7789 mov_current_sample_dec(sc);
7791 return AVERROR_INVALIDDATA;
7794 if( st->discard == AVDISCARD_NONKEY && 0==(sample->flags & AVINDEX_KEYFRAME) ) {
7795 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7799 ret = av_get_packet(sc->pb, pkt, sample->size);
7801 if (should_retry(sc->pb, ret)) {
7802 mov_current_sample_dec(sc);
7806 if (sc->has_palette) {
7809 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7811 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7813 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7814 sc->has_palette = 0;
7817 #if CONFIG_DV_DEMUXER
7818 if (mov->dv_demux && sc->dv_audio_container) {
7819 avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7820 av_freep(&pkt->data);
7822 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7827 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7828 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7829 st->need_parsing = AVSTREAM_PARSE_FULL;
7833 pkt->stream_index = sc->ffindex;
7834 pkt->dts = sample->timestamp;
7835 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7836 pkt->flags |= AV_PKT_FLAG_DISCARD;
7838 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7839 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
7840 /* update ctts context */
7842 if (sc->ctts_index < sc->ctts_count &&
7843 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
7845 sc->ctts_sample = 0;
7848 int64_t next_dts = (sc->current_sample < st->nb_index_entries) ?
7849 st->index_entries[sc->current_sample].timestamp : st->duration;
7851 if (next_dts >= pkt->dts)
7852 pkt->duration = next_dts - pkt->dts;
7853 pkt->pts = pkt->dts;
7855 if (st->discard == AVDISCARD_ALL)
7857 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
7858 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
7859 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
7860 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
7862 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
7863 pkt->pos = sample->pos;
7865 /* Multiple stsd handling. */
7866 if (sc->stsc_data) {
7867 /* Keep track of the stsc index for the given sample, then check
7868 * if the stsd index is different from the last used one. */
7870 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
7871 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
7873 sc->stsc_sample = 0;
7874 /* Do not check indexes after a switch. */
7875 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
7876 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
7877 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
7878 ret = mov_change_extradata(sc, pkt);
7885 aax_filter(pkt->data, pkt->size, mov);
7887 ret = cenc_filter(mov, st, sc, pkt, current_index);
7889 av_packet_unref(pkt);
7896 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
7898 MOVContext *mov = s->priv_data;
7901 if (!mov->frag_index.complete)
7904 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
7907 if (!mov->frag_index.item[index].headers_read)
7908 return mov_switch_root(s, -1, index);
7909 if (index + 1 < mov->frag_index.nb_items)
7910 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7915 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
7917 MOVStreamContext *sc = st->priv_data;
7918 int sample, time_sample, ret;
7921 // Here we consider timestamp to be PTS, hence try to offset it so that we
7922 // can search over the DTS timeline.
7923 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
7925 ret = mov_seek_fragment(s, st, timestamp);
7929 sample = av_index_search_timestamp(st, timestamp, flags);
7930 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
7931 if (sample < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp)
7933 if (sample < 0) /* not sure what to do */
7934 return AVERROR_INVALIDDATA;
7935 mov_current_sample_set(sc, sample);
7936 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
7937 /* adjust ctts index */
7938 if (sc->ctts_data) {
7940 for (i = 0; i < sc->ctts_count; i++) {
7941 int next = time_sample + sc->ctts_data[i].count;
7942 if (next > sc->current_sample) {
7944 sc->ctts_sample = sc->current_sample - time_sample;
7951 /* adjust stsd index */
7952 if (sc->chunk_count) {
7954 for (i = 0; i < sc->stsc_count; i++) {
7955 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
7956 if (next > sc->current_sample) {
7958 sc->stsc_sample = sc->current_sample - time_sample;
7961 av_assert0(next == (int)next);
7969 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
7971 MOVContext *mc = s->priv_data;
7976 if (stream_index >= s->nb_streams)
7977 return AVERROR_INVALIDDATA;
7979 st = s->streams[stream_index];
7980 sample = mov_seek_stream(s, st, sample_time, flags);
7984 if (mc->seek_individually) {
7985 /* adjust seek timestamp to found sample timestamp */
7986 int64_t seek_timestamp = st->index_entries[sample].timestamp;
7988 for (i = 0; i < s->nb_streams; i++) {
7990 MOVStreamContext *sc = s->streams[i]->priv_data;
7992 st->skip_samples = (sample_time <= 0) ? sc->start_pad : 0;
7994 if (stream_index == i)
7997 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
7998 mov_seek_stream(s, st, timestamp, flags);
8001 for (i = 0; i < s->nb_streams; i++) {
8002 MOVStreamContext *sc;
8005 mov_current_sample_set(sc, 0);
8008 MOVStreamContext *sc;
8009 AVIndexEntry *entry = mov_find_next_sample(s, &st);
8011 return AVERROR_INVALIDDATA;
8013 if (sc->ffindex == stream_index && sc->current_sample == sample)
8015 mov_current_sample_inc(sc);
8021 #define OFFSET(x) offsetof(MOVContext, x)
8022 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
8023 static const AVOption mov_options[] = {
8024 {"use_absolute_path",
8025 "allow using absolute path when opening alias, this is a possible security issue",
8026 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
8028 {"seek_streams_individually",
8029 "Seek each stream individually to the closest point",
8030 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
8032 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
8034 {"advanced_editlist",
8035 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
8036 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
8038 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8041 "use mfra for fragment timestamps",
8042 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8043 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8045 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8046 FLAGS, "use_mfra_for" },
8047 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8048 FLAGS, "use_mfra_for" },
8049 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8050 FLAGS, "use_mfra_for" },
8051 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8052 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8053 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8054 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8055 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8056 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8057 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8058 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8059 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8060 .flags = AV_OPT_FLAG_DECODING_PARAM },
8061 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8062 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8063 {.i64 = 0}, 0, 1, FLAGS },
8068 static const AVClass mov_class = {
8069 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8070 .item_name = av_default_item_name,
8071 .option = mov_options,
8072 .version = LIBAVUTIL_VERSION_INT,
8075 AVInputFormat ff_mov_demuxer = {
8076 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8077 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8078 .priv_class = &mov_class,
8079 .priv_data_size = sizeof(MOVContext),
8080 .extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
8081 .read_probe = mov_probe,
8082 .read_header = mov_read_header,
8083 .read_packet = mov_read_packet,
8084 .read_close = mov_read_close,
8085 .read_seek = mov_read_seek,
8086 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,