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->trak_index < 0) {
1982 av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
1985 if (c->fc->nb_streams < 1)
1987 st = c->fc->streams[c->fc->nb_streams-1];
1990 avio_r8(pb); /* version */
1991 avio_rb24(pb); /* flags */
1993 entries = avio_rb32(pb);
1998 if (sc->chunk_offsets)
1999 av_log(c->fc, AV_LOG_WARNING, "Duplicated STCO atom\n");
2000 av_free(sc->chunk_offsets);
2001 sc->chunk_count = 0;
2002 sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2003 if (!sc->chunk_offsets)
2004 return AVERROR(ENOMEM);
2005 sc->chunk_count = entries;
2007 if (atom.type == MKTAG('s','t','c','o'))
2008 for (i = 0; i < entries && !pb->eof_reached; i++)
2009 sc->chunk_offsets[i] = avio_rb32(pb);
2010 else if (atom.type == MKTAG('c','o','6','4'))
2011 for (i = 0; i < entries && !pb->eof_reached; i++)
2012 sc->chunk_offsets[i] = avio_rb64(pb);
2014 return AVERROR_INVALIDDATA;
2016 sc->chunk_count = i;
2018 if (pb->eof_reached) {
2019 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2026 static int mov_codec_id(AVStream *st, uint32_t format)
2028 int id = ff_codec_get_id(ff_codec_movaudio_tags, format);
2031 ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2032 (format & 0xFFFF) == 'T' + ('S' << 8)))
2033 id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format) & 0xFFFF);
2035 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2036 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2037 } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2038 /* skip old ASF MPEG-4 tag */
2039 format && format != MKTAG('m','p','4','s')) {
2040 id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2042 id = ff_codec_get_id(ff_codec_bmp_tags, format);
2044 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
2045 else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2046 (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE &&
2047 st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2048 id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
2050 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
2052 id = ff_codec_get_id(ff_codec_movdata_tags, format);
2056 st->codecpar->codec_tag = format;
2061 static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
2062 AVStream *st, MOVStreamContext *sc)
2064 uint8_t codec_name[32] = { 0 };
2068 /* The first 16 bytes of the video sample description are already
2069 * read in ff_mov_read_stsd_entries() */
2070 stsd_start = avio_tell(pb) - 16;
2072 avio_rb16(pb); /* version */
2073 avio_rb16(pb); /* revision level */
2074 avio_rb32(pb); /* vendor */
2075 avio_rb32(pb); /* temporal quality */
2076 avio_rb32(pb); /* spatial quality */
2078 st->codecpar->width = avio_rb16(pb); /* width */
2079 st->codecpar->height = avio_rb16(pb); /* height */
2081 avio_rb32(pb); /* horiz resolution */
2082 avio_rb32(pb); /* vert resolution */
2083 avio_rb32(pb); /* data size, always 0 */
2084 avio_rb16(pb); /* frames per samples */
2086 len = avio_r8(pb); /* codec name, pascal string */
2089 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2091 avio_skip(pb, 31 - len);
2094 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2096 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2097 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2098 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2099 st->codecpar->width &= ~1;
2100 st->codecpar->height &= ~1;
2102 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2103 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2104 !strncmp(codec_name, "Sorenson H263", 13))
2105 st->codecpar->codec_id = AV_CODEC_ID_FLV1;
2107 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2109 avio_seek(pb, stsd_start, SEEK_SET);
2111 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2112 st->codecpar->bits_per_coded_sample &= 0x1F;
2113 sc->has_palette = 1;
2117 static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
2118 AVStream *st, MOVStreamContext *sc)
2120 int bits_per_sample, flags;
2121 uint16_t version = avio_rb16(pb);
2122 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2124 avio_rb16(pb); /* revision level */
2125 avio_rb32(pb); /* vendor */
2127 st->codecpar->channels = avio_rb16(pb); /* channel count */
2128 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2129 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", st->codecpar->channels);
2131 sc->audio_cid = avio_rb16(pb);
2132 avio_rb16(pb); /* packet size = 0 */
2134 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2136 // Read QT version 1 fields. In version 0 these do not exist.
2137 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2139 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2140 (sc->stsd_version == 0 && version > 0)) {
2142 sc->samples_per_frame = avio_rb32(pb);
2143 avio_rb32(pb); /* bytes per packet */
2144 sc->bytes_per_frame = avio_rb32(pb);
2145 avio_rb32(pb); /* bytes per sample */
2146 } else if (version == 2) {
2147 avio_rb32(pb); /* sizeof struct only */
2148 st->codecpar->sample_rate = av_int2double(avio_rb64(pb));
2149 st->codecpar->channels = avio_rb32(pb);
2150 avio_rb32(pb); /* always 0x7F000000 */
2151 st->codecpar->bits_per_coded_sample = avio_rb32(pb);
2153 flags = avio_rb32(pb); /* lpcm format specific flag */
2154 sc->bytes_per_frame = avio_rb32(pb);
2155 sc->samples_per_frame = avio_rb32(pb);
2156 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2157 st->codecpar->codec_id =
2158 ff_mov_get_lpcm_codec_id(st->codecpar->bits_per_coded_sample,
2161 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2162 /* can't correctly handle variable sized packet as audio unit */
2163 switch (st->codecpar->codec_id) {
2164 case AV_CODEC_ID_MP2:
2165 case AV_CODEC_ID_MP3:
2166 st->need_parsing = AVSTREAM_PARSE_FULL;
2172 if (sc->format == 0) {
2173 if (st->codecpar->bits_per_coded_sample == 8)
2174 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2175 else if (st->codecpar->bits_per_coded_sample == 16)
2176 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2179 switch (st->codecpar->codec_id) {
2180 case AV_CODEC_ID_PCM_S8:
2181 case AV_CODEC_ID_PCM_U8:
2182 if (st->codecpar->bits_per_coded_sample == 16)
2183 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16BE;
2185 case AV_CODEC_ID_PCM_S16LE:
2186 case AV_CODEC_ID_PCM_S16BE:
2187 if (st->codecpar->bits_per_coded_sample == 8)
2188 st->codecpar->codec_id = AV_CODEC_ID_PCM_S8;
2189 else if (st->codecpar->bits_per_coded_sample == 24)
2190 st->codecpar->codec_id =
2191 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2192 AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
2193 else if (st->codecpar->bits_per_coded_sample == 32)
2194 st->codecpar->codec_id =
2195 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2196 AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
2198 /* set values for old format before stsd version 1 appeared */
2199 case AV_CODEC_ID_MACE3:
2200 sc->samples_per_frame = 6;
2201 sc->bytes_per_frame = 2 * st->codecpar->channels;
2203 case AV_CODEC_ID_MACE6:
2204 sc->samples_per_frame = 6;
2205 sc->bytes_per_frame = 1 * st->codecpar->channels;
2207 case AV_CODEC_ID_ADPCM_IMA_QT:
2208 sc->samples_per_frame = 64;
2209 sc->bytes_per_frame = 34 * st->codecpar->channels;
2211 case AV_CODEC_ID_GSM:
2212 sc->samples_per_frame = 160;
2213 sc->bytes_per_frame = 33;
2219 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2220 if (bits_per_sample) {
2221 st->codecpar->bits_per_coded_sample = bits_per_sample;
2222 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->channels;
2226 static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
2227 AVStream *st, MOVStreamContext *sc,
2230 // ttxt stsd contains display flags, justification, background
2231 // color, fonts, and default styles, so fake an atom to read it
2232 MOVAtom fake_atom = { .size = size };
2233 // mp4s contains a regular esds atom
2234 if (st->codecpar->codec_tag != AV_RL32("mp4s"))
2235 mov_read_glbl(c, pb, fake_atom);
2236 st->codecpar->width = sc->width;
2237 st->codecpar->height = sc->height;
2240 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2245 y = (ycbcr >> 16) & 0xFF;
2246 cr = (ycbcr >> 8) & 0xFF;
2249 b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
2250 g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
2251 r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
2253 return (r << 16) | (g << 8) | b;
2256 static int mov_rewrite_dvd_sub_extradata(AVStream *st)
2258 char buf[256] = {0};
2259 uint8_t *src = st->codecpar->extradata;
2262 if (st->codecpar->extradata_size != 64)
2265 if (st->codecpar->width > 0 && st->codecpar->height > 0)
2266 snprintf(buf, sizeof(buf), "size: %dx%d\n",
2267 st->codecpar->width, st->codecpar->height);
2268 av_strlcat(buf, "palette: ", sizeof(buf));
2270 for (i = 0; i < 16; i++) {
2271 uint32_t yuv = AV_RB32(src + i * 4);
2272 uint32_t rgba = yuv_to_rgba(yuv);
2274 av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2277 if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2280 ret = ff_alloc_extradata(st->codecpar, strlen(buf));
2283 memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2288 static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
2289 AVStream *st, MOVStreamContext *sc,
2294 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2295 if ((int)size != size)
2296 return AVERROR(ENOMEM);
2298 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2302 MOVStreamContext *tmcd_ctx = st->priv_data;
2304 val = AV_RB32(st->codecpar->extradata + 4);
2305 tmcd_ctx->tmcd_flags = val;
2306 st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2307 st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2308 #if FF_API_LAVF_AVCTX
2309 FF_DISABLE_DEPRECATION_WARNINGS
2310 st->codec->time_base = av_inv_q(st->avg_frame_rate);
2311 FF_ENABLE_DEPRECATION_WARNINGS
2313 /* adjust for per frame dur in counter mode */
2314 if (tmcd_ctx->tmcd_flags & 0x0008) {
2315 int timescale = AV_RB32(st->codecpar->extradata + 8);
2316 int framedur = AV_RB32(st->codecpar->extradata + 12);
2317 st->avg_frame_rate.num *= timescale;
2318 st->avg_frame_rate.den *= framedur;
2319 #if FF_API_LAVF_AVCTX
2320 FF_DISABLE_DEPRECATION_WARNINGS
2321 st->codec->time_base.den *= timescale;
2322 st->codec->time_base.num *= framedur;
2323 FF_ENABLE_DEPRECATION_WARNINGS
2327 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2328 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2329 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2330 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2331 if (str_size > 0 && size >= (int)str_size + 26) {
2332 char *reel_name = av_malloc(str_size + 1);
2334 return AVERROR(ENOMEM);
2335 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2336 reel_name[str_size] = 0; /* Add null terminator */
2337 /* don't add reel_name if emtpy string */
2338 if (*reel_name == 0) {
2341 av_dict_set(&st->metadata, "reel_name", reel_name, AV_DICT_DONT_STRDUP_VAL);
2348 /* other codec type, just skip (rtp, mp4s ...) */
2349 avio_skip(pb, size);
2354 static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
2355 AVStream *st, MOVStreamContext *sc)
2357 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2358 !st->codecpar->sample_rate && sc->time_scale > 1)
2359 st->codecpar->sample_rate = sc->time_scale;
2361 /* special codec parameters handling */
2362 switch (st->codecpar->codec_id) {
2363 #if CONFIG_DV_DEMUXER
2364 case AV_CODEC_ID_DVAUDIO:
2365 c->dv_fctx = avformat_alloc_context();
2367 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2368 return AVERROR(ENOMEM);
2370 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2372 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2373 return AVERROR(ENOMEM);
2375 sc->dv_audio_container = 1;
2376 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
2379 /* no ifdef since parameters are always those */
2380 case AV_CODEC_ID_QCELP:
2381 st->codecpar->channels = 1;
2382 // force sample rate for qcelp when not stored in mov
2383 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2384 st->codecpar->sample_rate = 8000;
2385 // FIXME: Why is the following needed for some files?
2386 sc->samples_per_frame = 160;
2387 if (!sc->bytes_per_frame)
2388 sc->bytes_per_frame = 35;
2390 case AV_CODEC_ID_AMR_NB:
2391 st->codecpar->channels = 1;
2392 /* force sample rate for amr, stsd in 3gp does not store sample rate */
2393 st->codecpar->sample_rate = 8000;
2395 case AV_CODEC_ID_AMR_WB:
2396 st->codecpar->channels = 1;
2397 st->codecpar->sample_rate = 16000;
2399 case AV_CODEC_ID_MP2:
2400 case AV_CODEC_ID_MP3:
2401 /* force type after stsd for m1a hdlr */
2402 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2404 case AV_CODEC_ID_GSM:
2405 case AV_CODEC_ID_ADPCM_MS:
2406 case AV_CODEC_ID_ADPCM_IMA_WAV:
2407 case AV_CODEC_ID_ILBC:
2408 case AV_CODEC_ID_MACE3:
2409 case AV_CODEC_ID_MACE6:
2410 case AV_CODEC_ID_QDM2:
2411 st->codecpar->block_align = sc->bytes_per_frame;
2413 case AV_CODEC_ID_ALAC:
2414 if (st->codecpar->extradata_size == 36) {
2415 st->codecpar->channels = AV_RB8 (st->codecpar->extradata + 21);
2416 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2419 case AV_CODEC_ID_AC3:
2420 case AV_CODEC_ID_EAC3:
2421 case AV_CODEC_ID_MPEG1VIDEO:
2422 case AV_CODEC_ID_VC1:
2423 case AV_CODEC_ID_VP8:
2424 case AV_CODEC_ID_VP9:
2425 st->need_parsing = AVSTREAM_PARSE_FULL;
2433 static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
2434 int codec_tag, int format,
2437 int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2440 (codec_tag != format &&
2441 // AVID 1:1 samples with differing data format and codec tag exist
2442 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
2443 // prores is allowed to have differing data format and codec tag
2444 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
2446 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
2447 (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id
2448 : codec_tag != MKTAG('j','p','e','g')))) {
2449 /* Multiple fourcc, we skip JPEG. This is not correct, we should
2450 * export it as a separate AVStream but this needs a few changes
2451 * in the MOV demuxer, patch welcome. */
2453 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
2454 avio_skip(pb, size);
2461 int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
2464 MOVStreamContext *sc;
2465 int pseudo_stream_id;
2467 av_assert0 (c->fc->nb_streams >= 1);
2468 st = c->fc->streams[c->fc->nb_streams-1];
2471 for (pseudo_stream_id = 0;
2472 pseudo_stream_id < entries && !pb->eof_reached;
2473 pseudo_stream_id++) {
2474 //Parsing Sample description table
2476 int ret, dref_id = 1;
2477 MOVAtom a = { AV_RL32("stsd") };
2478 int64_t start_pos = avio_tell(pb);
2479 int64_t size = avio_rb32(pb); /* size */
2480 uint32_t format = avio_rl32(pb); /* data format */
2483 avio_rb32(pb); /* reserved */
2484 avio_rb16(pb); /* reserved */
2485 dref_id = avio_rb16(pb);
2486 } else if (size <= 7) {
2487 av_log(c->fc, AV_LOG_ERROR,
2488 "invalid size %"PRId64" in stsd\n", size);
2489 return AVERROR_INVALIDDATA;
2492 if (mov_skip_multiple_stsd(c, pb, st->codecpar->codec_tag, format,
2493 size - (avio_tell(pb) - start_pos))) {
2498 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
2499 sc->dref_id= dref_id;
2500 sc->format = format;
2502 id = mov_codec_id(st, format);
2504 av_log(c->fc, AV_LOG_TRACE,
2505 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
2506 av_fourcc2str(format), st->codecpar->codec_type);
2508 st->codecpar->codec_id = id;
2509 if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) {
2510 mov_parse_stsd_video(c, pb, st, sc);
2511 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
2512 mov_parse_stsd_audio(c, pb, st, sc);
2513 if (st->codecpar->sample_rate < 0) {
2514 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
2515 return AVERROR_INVALIDDATA;
2517 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
2518 mov_parse_stsd_subtitle(c, pb, st, sc,
2519 size - (avio_tell(pb) - start_pos));
2521 ret = mov_parse_stsd_data(c, pb, st, sc,
2522 size - (avio_tell(pb) - start_pos));
2526 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
2527 a.size = size - (avio_tell(pb) - start_pos);
2529 if ((ret = mov_read_default(c, pb, a)) < 0)
2531 } else if (a.size > 0)
2532 avio_skip(pb, a.size);
2534 if (sc->extradata && st->codecpar->extradata) {
2535 int extra_size = st->codecpar->extradata_size;
2537 /* Move the current stream extradata to the stream context one. */
2538 sc->extradata_size[pseudo_stream_id] = extra_size;
2539 sc->extradata[pseudo_stream_id] = av_malloc(extra_size + AV_INPUT_BUFFER_PADDING_SIZE);
2540 if (!sc->extradata[pseudo_stream_id])
2541 return AVERROR(ENOMEM);
2542 memcpy(sc->extradata[pseudo_stream_id], st->codecpar->extradata, extra_size);
2543 av_freep(&st->codecpar->extradata);
2544 st->codecpar->extradata_size = 0;
2549 if (pb->eof_reached) {
2550 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
2557 static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2560 MOVStreamContext *sc;
2563 if (c->fc->nb_streams < 1)
2565 st = c->fc->streams[c->fc->nb_streams - 1];
2568 sc->stsd_version = avio_r8(pb);
2569 avio_rb24(pb); /* flags */
2570 entries = avio_rb32(pb);
2572 /* Each entry contains a size (4 bytes) and format (4 bytes). */
2573 if (entries <= 0 || entries > atom.size / 8) {
2574 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
2575 return AVERROR_INVALIDDATA;
2578 if (sc->extradata) {
2579 av_log(c->fc, AV_LOG_ERROR,
2580 "Duplicate stsd found in this track.\n");
2581 return AVERROR_INVALIDDATA;
2584 /* Prepare space for hosting multiple extradata. */
2585 sc->extradata = av_mallocz_array(entries, sizeof(*sc->extradata));
2587 return AVERROR(ENOMEM);
2589 sc->extradata_size = av_mallocz_array(entries, sizeof(*sc->extradata_size));
2590 if (!sc->extradata_size) {
2591 ret = AVERROR(ENOMEM);
2595 ret = ff_mov_read_stsd_entries(c, pb, entries);
2599 /* Restore back the primary extradata. */
2600 av_freep(&st->codecpar->extradata);
2601 st->codecpar->extradata_size = sc->extradata_size[0];
2602 if (sc->extradata_size[0]) {
2603 st->codecpar->extradata = av_mallocz(sc->extradata_size[0] + AV_INPUT_BUFFER_PADDING_SIZE);
2604 if (!st->codecpar->extradata)
2605 return AVERROR(ENOMEM);
2606 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
2609 return mov_finalize_stsd_codec(c, pb, st, sc);
2611 if (sc->extradata) {
2613 for (j = 0; j < sc->stsd_count; j++)
2614 av_freep(&sc->extradata[j]);
2617 av_freep(&sc->extradata);
2618 av_freep(&sc->extradata_size);
2622 static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2625 MOVStreamContext *sc;
2626 unsigned int i, entries;
2628 if (c->fc->nb_streams < 1)
2630 st = c->fc->streams[c->fc->nb_streams-1];
2633 avio_r8(pb); /* version */
2634 avio_rb24(pb); /* flags */
2636 entries = avio_rb32(pb);
2637 if ((uint64_t)entries * 12 + 4 > atom.size)
2638 return AVERROR_INVALIDDATA;
2640 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
2645 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSC atom\n");
2646 av_free(sc->stsc_data);
2648 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
2650 return AVERROR(ENOMEM);
2652 for (i = 0; i < entries && !pb->eof_reached; i++) {
2653 sc->stsc_data[i].first = avio_rb32(pb);
2654 sc->stsc_data[i].count = avio_rb32(pb);
2655 sc->stsc_data[i].id = avio_rb32(pb);
2659 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
2660 int64_t first_min = i + 1;
2661 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
2662 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
2663 sc->stsc_data[i].first < first_min ||
2664 sc->stsc_data[i].count < 1 ||
2665 sc->stsc_data[i].id < 1) {
2666 av_log(c->fc, AV_LOG_WARNING, "STSC entry %d is invalid (first=%d count=%d id=%d)\n", i, sc->stsc_data[i].first, sc->stsc_data[i].count, sc->stsc_data[i].id);
2667 if (i+1 >= sc->stsc_count) {
2668 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
2669 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
2670 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
2671 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
2672 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
2675 av_assert0(sc->stsc_data[i+1].first >= 2);
2676 // We replace this entry by the next valid
2677 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
2678 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
2679 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
2683 if (pb->eof_reached) {
2684 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
2691 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
2693 return index < count - 1;
2696 /* Compute the samples value for the stsc entry at the given index. */
2697 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
2701 if (mov_stsc_index_valid(index, sc->stsc_count))
2702 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
2704 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
2705 av_assert0(sc->stsc_data[index].first <= sc->chunk_count);
2706 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
2709 return sc->stsc_data[index].count * (int64_t)chunk_count;
2712 static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2715 MOVStreamContext *sc;
2716 unsigned i, entries;
2718 if (c->fc->nb_streams < 1)
2720 st = c->fc->streams[c->fc->nb_streams-1];
2723 avio_rb32(pb); // version + flags
2725 entries = avio_rb32(pb);
2727 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
2728 av_free(sc->stps_data);
2730 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
2732 return AVERROR(ENOMEM);
2734 for (i = 0; i < entries && !pb->eof_reached; i++) {
2735 sc->stps_data[i] = avio_rb32(pb);
2740 if (pb->eof_reached) {
2741 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
2748 static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2751 MOVStreamContext *sc;
2752 unsigned int i, entries;
2754 if (c->fc->nb_streams < 1)
2756 st = c->fc->streams[c->fc->nb_streams-1];
2759 avio_r8(pb); /* version */
2760 avio_rb24(pb); /* flags */
2762 entries = avio_rb32(pb);
2764 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
2768 sc->keyframe_absent = 1;
2769 if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
2770 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2774 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
2775 if (entries >= UINT_MAX / sizeof(int))
2776 return AVERROR_INVALIDDATA;
2777 av_freep(&sc->keyframes);
2778 sc->keyframe_count = 0;
2779 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
2781 return AVERROR(ENOMEM);
2783 for (i = 0; i < entries && !pb->eof_reached; i++) {
2784 sc->keyframes[i] = avio_rb32(pb);
2787 sc->keyframe_count = i;
2789 if (pb->eof_reached) {
2790 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
2797 static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2800 MOVStreamContext *sc;
2801 unsigned int i, entries, sample_size, field_size, num_bytes;
2806 if (c->fc->nb_streams < 1)
2808 st = c->fc->streams[c->fc->nb_streams-1];
2811 avio_r8(pb); /* version */
2812 avio_rb24(pb); /* flags */
2814 if (atom.type == MKTAG('s','t','s','z')) {
2815 sample_size = avio_rb32(pb);
2816 if (!sc->sample_size) /* do not overwrite value computed in stsd */
2817 sc->sample_size = sample_size;
2818 sc->stsz_sample_size = sample_size;
2822 avio_rb24(pb); /* reserved */
2823 field_size = avio_r8(pb);
2825 entries = avio_rb32(pb);
2827 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
2829 sc->sample_count = entries;
2833 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
2834 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
2835 return AVERROR_INVALIDDATA;
2840 if (entries >= (UINT_MAX - 4) / field_size)
2841 return AVERROR_INVALIDDATA;
2842 if (sc->sample_sizes)
2843 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
2844 av_free(sc->sample_sizes);
2845 sc->sample_count = 0;
2846 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
2847 if (!sc->sample_sizes)
2848 return AVERROR(ENOMEM);
2850 num_bytes = (entries*field_size+4)>>3;
2852 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
2854 av_freep(&sc->sample_sizes);
2855 return AVERROR(ENOMEM);
2858 ret = ffio_read_size(pb, buf, num_bytes);
2860 av_freep(&sc->sample_sizes);
2862 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
2866 init_get_bits(&gb, buf, 8*num_bytes);
2868 for (i = 0; i < entries && !pb->eof_reached; i++) {
2869 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
2870 sc->data_size += sc->sample_sizes[i];
2873 sc->sample_count = i;
2877 if (pb->eof_reached) {
2878 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSZ atom\n");
2885 static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2888 MOVStreamContext *sc;
2889 unsigned int i, entries, alloc_size = 0;
2891 int64_t total_sample_count=0;
2893 if (c->fc->nb_streams < 1)
2895 st = c->fc->streams[c->fc->nb_streams-1];
2898 avio_r8(pb); /* version */
2899 avio_rb24(pb); /* flags */
2900 entries = avio_rb32(pb);
2902 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
2903 c->fc->nb_streams-1, entries);
2906 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
2907 av_freep(&sc->stts_data);
2909 if (entries >= INT_MAX / sizeof(*sc->stts_data))
2910 return AVERROR(ENOMEM);
2912 for (i = 0; i < entries && !pb->eof_reached; i++) {
2913 int sample_duration;
2914 unsigned int sample_count;
2915 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
2916 MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
2917 min_entries * sizeof(*sc->stts_data));
2919 av_freep(&sc->stts_data);
2921 return AVERROR(ENOMEM);
2923 sc->stts_count = min_entries;
2924 sc->stts_data = stts_data;
2926 sample_count=avio_rb32(pb);
2927 sample_duration = avio_rb32(pb);
2929 sc->stts_data[i].count= sample_count;
2930 sc->stts_data[i].duration= sample_duration;
2932 av_log(c->fc, AV_LOG_TRACE, "sample_count=%d, sample_duration=%d\n",
2933 sample_count, sample_duration);
2935 duration+=(int64_t)sample_duration*(uint64_t)sample_count;
2936 total_sample_count+=sample_count;
2942 duration <= INT64_MAX - sc->duration_for_fps &&
2943 total_sample_count <= INT_MAX - sc->nb_frames_for_fps
2945 sc->duration_for_fps += duration;
2946 sc->nb_frames_for_fps += total_sample_count;
2949 if (pb->eof_reached) {
2950 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
2954 st->nb_frames= total_sample_count;
2956 st->duration= FFMIN(st->duration, duration);
2957 sc->track_end = duration;
2961 static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2964 MOVStreamContext *sc;
2967 if (c->fc->nb_streams < 1)
2969 st = c->fc->streams[c->fc->nb_streams - 1];
2972 avio_r8(pb); /* version */
2973 avio_rb24(pb); /* flags */
2974 entries = atom.size - 4;
2976 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
2977 c->fc->nb_streams - 1, entries);
2980 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
2981 av_freep(&sc->sdtp_data);
2984 sc->sdtp_data = av_mallocz(entries);
2986 return AVERROR(ENOMEM);
2988 for (i = 0; i < entries && !pb->eof_reached; i++)
2989 sc->sdtp_data[i] = avio_r8(pb);
2995 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
2998 if (duration == INT_MIN) {
2999 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3002 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3006 static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3009 MOVStreamContext *sc;
3010 unsigned int i, entries, ctts_count = 0;
3012 if (c->fc->nb_streams < 1)
3014 st = c->fc->streams[c->fc->nb_streams-1];
3017 avio_r8(pb); /* version */
3018 avio_rb24(pb); /* flags */
3019 entries = avio_rb32(pb);
3021 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3025 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3026 return AVERROR_INVALIDDATA;
3027 av_freep(&sc->ctts_data);
3028 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3030 return AVERROR(ENOMEM);
3032 for (i = 0; i < entries && !pb->eof_reached; i++) {
3033 int count =avio_rb32(pb);
3034 int duration =avio_rb32(pb);
3037 av_log(c->fc, AV_LOG_TRACE,
3038 "ignoring CTTS entry with count=%d duration=%d\n",
3043 add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3046 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3049 if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3050 av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3051 av_freep(&sc->ctts_data);
3057 mov_update_dts_shift(sc, duration, c->fc);
3060 sc->ctts_count = ctts_count;
3062 if (pb->eof_reached) {
3063 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3067 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3072 static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3075 MOVStreamContext *sc;
3076 unsigned int i, entries;
3078 uint32_t grouping_type;
3080 if (c->fc->nb_streams < 1)
3082 st = c->fc->streams[c->fc->nb_streams-1];
3085 version = avio_r8(pb); /* version */
3086 avio_rb24(pb); /* flags */
3087 grouping_type = avio_rl32(pb);
3088 if (grouping_type != MKTAG( 'r','a','p',' '))
3089 return 0; /* only support 'rap ' grouping */
3091 avio_rb32(pb); /* grouping_type_parameter */
3093 entries = avio_rb32(pb);
3097 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP atom\n");
3098 av_free(sc->rap_group);
3099 sc->rap_group_count = 0;
3100 sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group));
3102 return AVERROR(ENOMEM);
3104 for (i = 0; i < entries && !pb->eof_reached; i++) {
3105 sc->rap_group[i].count = avio_rb32(pb); /* sample_count */
3106 sc->rap_group[i].index = avio_rb32(pb); /* group_description_index */
3109 sc->rap_group_count = i;
3111 if (pb->eof_reached) {
3112 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3120 * Get ith edit list entry (media time, duration).
3122 static int get_edit_list_entry(MOVContext *mov,
3123 const MOVStreamContext *msc,
3124 unsigned int edit_list_index,
3125 int64_t *edit_list_media_time,
3126 int64_t *edit_list_duration,
3127 int64_t global_timescale)
3129 if (edit_list_index == msc->elst_count) {
3132 *edit_list_media_time = msc->elst_data[edit_list_index].time;
3133 *edit_list_duration = msc->elst_data[edit_list_index].duration;
3135 /* duration is in global timescale units;convert to msc timescale */
3136 if (global_timescale == 0) {
3137 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3140 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3146 * Find the closest previous frame to the timestamp_pts, in e_old index
3147 * entries. Searching for just any frame / just key frames can be controlled by
3148 * last argument 'flag'.
3149 * Note that if ctts_data is not NULL, we will always search for a key frame
3150 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3151 * return the first frame of the video.
3153 * Here the timestamp_pts is considered to be a presentation timestamp and
3154 * the timestamp of index entries are considered to be decoding timestamps.
3156 * Returns 0 if successful in finding a frame, else returns -1.
3157 * Places the found index corresponding output arg.
3159 * If ctts_old is not NULL, then refines the searched entry by searching
3160 * backwards from the found timestamp, to find the frame with correct PTS.
3162 * Places the found ctts_index and ctts_sample in corresponding output args.
3164 static int find_prev_closest_index(AVStream *st,
3165 AVIndexEntry *e_old,
3169 int64_t timestamp_pts,
3172 int64_t* ctts_index,
3173 int64_t* ctts_sample)
3175 MOVStreamContext *msc = st->priv_data;
3176 AVIndexEntry *e_keep = st->index_entries;
3177 int nb_keep = st->nb_index_entries;
3179 int64_t index_ctts_count;
3183 // If dts_shift > 0, then all the index timestamps will have to be offset by
3184 // at least dts_shift amount to obtain PTS.
3185 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3186 if (msc->dts_shift > 0) {
3187 timestamp_pts -= msc->dts_shift;
3190 st->index_entries = e_old;
3191 st->nb_index_entries = nb_old;
3192 *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3194 // Keep going backwards in the index entries until the timestamp is the same.
3196 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3198 if ((flag & AVSEEK_FLAG_ANY) ||
3199 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3205 // If we have CTTS then refine the search, by searching backwards over PTS
3206 // computed by adding corresponding CTTS durations to index timestamps.
3207 if (ctts_data && *index >= 0) {
3208 av_assert0(ctts_index);
3209 av_assert0(ctts_sample);
3210 // Find out the ctts_index for the found frame.
3213 for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3214 if (*ctts_index < ctts_count) {
3216 if (ctts_data[*ctts_index].count == *ctts_sample) {
3223 while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3224 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3225 // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3226 // compensated by dts_shift above.
3227 if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3228 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3233 if (*ctts_sample == 0) {
3235 if (*ctts_index >= 0)
3236 *ctts_sample = ctts_data[*ctts_index].count - 1;
3243 /* restore AVStream state*/
3244 st->index_entries = e_keep;
3245 st->nb_index_entries = nb_keep;
3246 return *index >= 0 ? 0 : -1;
3250 * Add index entry with the given values, to the end of st->index_entries.
3251 * Returns the new size st->index_entries if successful, else returns -1.
3253 * This function is similar to ff_add_index_entry in libavformat/utils.c
3254 * except that here we are always unconditionally adding an index entry to
3255 * the end, instead of searching the entries list and skipping the add if
3256 * there is an existing entry with the same timestamp.
3257 * This is needed because the mov_fix_index calls this func with the same
3258 * unincremented timestamp for successive discarded frames.
3260 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3261 int size, int distance, int flags)
3263 AVIndexEntry *entries, *ie;
3265 const size_t min_size_needed = (st->nb_index_entries + 1) * sizeof(AVIndexEntry);
3267 // Double the allocation each time, to lower memory fragmentation.
3268 // Another difference from ff_add_index_entry function.
3269 const size_t requested_size =
3270 min_size_needed > st->index_entries_allocated_size ?
3271 FFMAX(min_size_needed, 2 * st->index_entries_allocated_size) :
3274 if((unsigned)st->nb_index_entries + 1 >= UINT_MAX / sizeof(AVIndexEntry))
3277 entries = av_fast_realloc(st->index_entries,
3278 &st->index_entries_allocated_size,
3283 st->index_entries= entries;
3285 index= st->nb_index_entries++;
3286 ie= &entries[index];
3289 ie->timestamp = timestamp;
3290 ie->min_distance= distance;
3297 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3298 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3300 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3301 int64_t* frame_duration_buffer,
3302 int frame_duration_buffer_size) {
3304 av_assert0(end_index >= 0 && end_index <= st->nb_index_entries);
3305 for (i = 0; i < frame_duration_buffer_size; i++) {
3306 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3307 st->index_entries[end_index - 1 - i].timestamp = end_ts;
3312 * Append a new ctts entry to ctts_data.
3313 * Returns the new ctts_count if successful, else returns -1.
3315 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3316 int count, int duration)
3318 MOVStts *ctts_buf_new;
3319 const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVStts);
3320 const size_t requested_size =
3321 min_size_needed > *allocated_size ?
3322 FFMAX(min_size_needed, 2 * (*allocated_size)) :
3325 if((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
3328 ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3333 *ctts_data = ctts_buf_new;
3335 ctts_buf_new[*ctts_count].count = count;
3336 ctts_buf_new[*ctts_count].duration = duration;
3338 *ctts_count = (*ctts_count) + 1;
3342 #define MAX_REORDER_DELAY 16
3343 static void mov_estimate_video_delay(MOVContext *c, AVStream* st) {
3344 MOVStreamContext *msc = st->priv_data;
3347 int ctts_sample = 0;
3348 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3350 int j, r, num_swaps;
3352 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3353 pts_buf[j] = INT64_MIN;
3355 if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3356 st->codecpar->codec_id == AV_CODEC_ID_H264) {
3357 st->codecpar->video_delay = 0;
3358 for(ind = 0; ind < st->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3359 // Point j to the last elem of the buffer and insert the current pts there.
3361 buf_start = (buf_start + 1);
3362 if (buf_start == MAX_REORDER_DELAY + 1)
3365 pts_buf[j] = st->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3367 // The timestamps that are already in the sorted buffer, and are greater than the
3368 // current pts, are exactly the timestamps that need to be buffered to output PTS
3369 // in correct sorted order.
3370 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3371 // can be computed as the maximum no. of swaps any particular timestamp needs to
3372 // go through, to keep this buffer in sorted order.
3374 while (j != buf_start) {
3376 if (r < 0) r = MAX_REORDER_DELAY;
3377 if (pts_buf[j] < pts_buf[r]) {
3378 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3385 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3388 if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3393 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3394 st->codecpar->video_delay, st->index);
3398 static void mov_current_sample_inc(MOVStreamContext *sc)
3400 sc->current_sample++;
3401 sc->current_index++;
3402 if (sc->index_ranges &&
3403 sc->current_index >= sc->current_index_range->end &&
3404 sc->current_index_range->end) {
3405 sc->current_index_range++;
3406 sc->current_index = sc->current_index_range->start;
3410 static void mov_current_sample_dec(MOVStreamContext *sc)
3412 sc->current_sample--;
3413 sc->current_index--;
3414 if (sc->index_ranges &&
3415 sc->current_index < sc->current_index_range->start &&
3416 sc->current_index_range > sc->index_ranges) {
3417 sc->current_index_range--;
3418 sc->current_index = sc->current_index_range->end - 1;
3422 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3426 sc->current_sample = current_sample;
3427 sc->current_index = current_sample;
3428 if (!sc->index_ranges) {
3432 for (sc->current_index_range = sc->index_ranges;
3433 sc->current_index_range->end;
3434 sc->current_index_range++) {
3435 range_size = sc->current_index_range->end - sc->current_index_range->start;
3436 if (range_size > current_sample) {
3437 sc->current_index = sc->current_index_range->start + current_sample;
3440 current_sample -= range_size;
3445 * Fix st->index_entries, so that it contains only the entries (and the entries
3446 * which are needed to decode them) that fall in the edit list time ranges.
3447 * Also fixes the timestamps of the index entries to match the timeline
3448 * specified the edit lists.
3450 static void mov_fix_index(MOVContext *mov, AVStream *st)
3452 MOVStreamContext *msc = st->priv_data;
3453 AVIndexEntry *e_old = st->index_entries;
3454 int nb_old = st->nb_index_entries;
3455 const AVIndexEntry *e_old_end = e_old + nb_old;
3456 const AVIndexEntry *current = NULL;
3457 MOVStts *ctts_data_old = msc->ctts_data;
3458 int64_t ctts_index_old = 0;
3459 int64_t ctts_sample_old = 0;
3460 int64_t ctts_count_old = msc->ctts_count;
3461 int64_t edit_list_media_time = 0;
3462 int64_t edit_list_duration = 0;
3463 int64_t frame_duration = 0;
3464 int64_t edit_list_dts_counter = 0;
3465 int64_t edit_list_dts_entry_end = 0;
3466 int64_t edit_list_start_ctts_sample = 0;
3468 int64_t curr_ctts = 0;
3469 int64_t empty_edits_sum_duration = 0;
3470 int64_t edit_list_index = 0;
3473 int64_t start_dts = 0;
3474 int64_t edit_list_start_encountered = 0;
3475 int64_t search_timestamp = 0;
3476 int64_t* frame_duration_buffer = NULL;
3477 int num_discarded_begin = 0;
3478 int first_non_zero_audio_edit = -1;
3479 int packet_skip_samples = 0;
3480 MOVIndexRange *current_index_range;
3482 int found_keyframe_after_edit = 0;
3483 int found_non_empty_edit = 0;
3485 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
3489 // allocate the index ranges array
3490 msc->index_ranges = av_malloc((msc->elst_count + 1) * sizeof(msc->index_ranges[0]));
3491 if (!msc->index_ranges) {
3492 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
3495 msc->current_index_range = msc->index_ranges;
3496 current_index_range = msc->index_ranges - 1;
3498 // Clean AVStream from traces of old index
3499 st->index_entries = NULL;
3500 st->index_entries_allocated_size = 0;
3501 st->nb_index_entries = 0;
3503 // Clean ctts fields of MOVStreamContext
3504 msc->ctts_data = NULL;
3505 msc->ctts_count = 0;
3506 msc->ctts_index = 0;
3507 msc->ctts_sample = 0;
3508 msc->ctts_allocated_size = 0;
3510 // Reinitialize min_corrected_pts so that it can be computed again.
3511 msc->min_corrected_pts = -1;
3513 // If the dts_shift is positive (in case of negative ctts values in mov),
3514 // then negate the DTS by dts_shift
3515 if (msc->dts_shift > 0) {
3516 edit_list_dts_entry_end -= msc->dts_shift;
3517 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
3520 start_dts = edit_list_dts_entry_end;
3522 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
3523 &edit_list_duration, mov->time_scale)) {
3524 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
3525 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
3527 edit_list_dts_counter = edit_list_dts_entry_end;
3528 edit_list_dts_entry_end += edit_list_duration;
3529 num_discarded_begin = 0;
3530 if (!found_non_empty_edit && edit_list_media_time == -1) {
3531 empty_edits_sum_duration += edit_list_duration;
3534 found_non_empty_edit = 1;
3536 // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
3537 // according to the edit list below.
3538 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3539 if (first_non_zero_audio_edit < 0) {
3540 first_non_zero_audio_edit = 1;
3542 first_non_zero_audio_edit = 0;
3545 if (first_non_zero_audio_edit > 0)
3546 st->skip_samples = msc->start_pad = 0;
3549 // While reordering frame index according to edit list we must handle properly
3550 // the scenario when edit list entry starts from none key frame.
3551 // We find closest previous key frame and preserve it and consequent frames in index.
3552 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
3553 search_timestamp = edit_list_media_time;
3554 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3555 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
3556 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
3557 // edit_list_media_time to cover the decoder delay.
3558 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
3561 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
3562 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3563 av_log(mov->fc, AV_LOG_WARNING,
3564 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
3565 st->index, edit_list_index, search_timestamp);
3566 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
3567 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3568 av_log(mov->fc, AV_LOG_WARNING,
3569 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
3570 st->index, edit_list_index, search_timestamp);
3573 ctts_sample_old = 0;
3576 current = e_old + index;
3577 edit_list_start_ctts_sample = ctts_sample_old;
3579 // Iterate over index and arrange it according to edit list
3580 edit_list_start_encountered = 0;
3581 found_keyframe_after_edit = 0;
3582 for (; current < e_old_end; current++, index++) {
3583 // check if frame outside edit list mark it for discard
3584 frame_duration = (current + 1 < e_old_end) ?
3585 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
3587 flags = current->flags;
3589 // frames (pts) before or after edit list
3590 curr_cts = current->timestamp + msc->dts_shift;
3593 if (ctts_data_old && ctts_index_old < ctts_count_old) {
3594 curr_ctts = ctts_data_old[ctts_index_old].duration;
3595 av_log(mov->fc, AV_LOG_DEBUG, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
3596 curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
3597 curr_cts += curr_ctts;
3599 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
3600 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3601 &msc->ctts_allocated_size,
3602 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3603 ctts_data_old[ctts_index_old].duration) == -1) {
3604 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3606 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3607 ctts_data_old[ctts_index_old].duration);
3611 ctts_sample_old = 0;
3612 edit_list_start_ctts_sample = 0;
3616 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
3617 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
3618 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
3619 first_non_zero_audio_edit > 0) {
3620 packet_skip_samples = edit_list_media_time - curr_cts;
3621 st->skip_samples += packet_skip_samples;
3623 // Shift the index entry timestamp by packet_skip_samples to be correct.
3624 edit_list_dts_counter -= packet_skip_samples;
3625 if (edit_list_start_encountered == 0) {
3626 edit_list_start_encountered = 1;
3627 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
3628 // discarded packets.
3629 if (frame_duration_buffer) {
3630 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3631 frame_duration_buffer, num_discarded_begin);
3632 av_freep(&frame_duration_buffer);
3636 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
3638 flags |= AVINDEX_DISCARD_FRAME;
3639 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
3641 if (edit_list_start_encountered == 0) {
3642 num_discarded_begin++;
3643 frame_duration_buffer = av_realloc(frame_duration_buffer,
3644 num_discarded_begin * sizeof(int64_t));
3645 if (!frame_duration_buffer) {
3646 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
3649 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
3651 // Increment skip_samples for the first non-zero audio edit list
3652 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3653 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
3654 st->skip_samples += frame_duration;
3659 if (msc->min_corrected_pts < 0) {
3660 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
3662 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
3664 if (edit_list_start_encountered == 0) {
3665 edit_list_start_encountered = 1;
3666 // Make timestamps strictly monotonically increasing by rewriting timestamps for
3667 // discarded packets.
3668 if (frame_duration_buffer) {
3669 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3670 frame_duration_buffer, num_discarded_begin);
3671 av_freep(&frame_duration_buffer);
3676 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
3677 current->min_distance, flags) == -1) {
3678 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
3682 // Update the index ranges array
3683 if (current_index_range < msc->index_ranges || index != current_index_range->end) {
3684 current_index_range++;
3685 current_index_range->start = index;
3687 current_index_range->end = index + 1;
3689 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
3690 if (edit_list_start_encountered > 0) {
3691 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
3694 // Break when found first key frame after edit entry completion
3695 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
3696 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
3697 if (ctts_data_old) {
3698 // If we have CTTS and this is the first keyframe after edit elist,
3699 // wait for one more, because there might be trailing B-frames after this I-frame
3700 // that do belong to the edit.
3701 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
3702 found_keyframe_after_edit = 1;
3705 if (ctts_sample_old != 0) {
3706 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3707 &msc->ctts_allocated_size,
3708 ctts_sample_old - edit_list_start_ctts_sample,
3709 ctts_data_old[ctts_index_old].duration) == -1) {
3710 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3711 ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
3712 ctts_data_old[ctts_index_old].duration);
3721 // If there are empty edits, then msc->min_corrected_pts might be positive
3722 // intentionally. So we subtract the sum duration of emtpy edits here.
3723 msc->min_corrected_pts -= empty_edits_sum_duration;
3725 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
3726 // dts by that amount to make the first pts zero.
3727 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
3728 if (msc->min_corrected_pts > 0) {
3729 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
3730 for (i = 0; i < st->nb_index_entries; ++i) {
3731 st->index_entries[i].timestamp -= msc->min_corrected_pts;
3735 // Start time should be equal to zero or the duration of any empty edits.
3736 st->start_time = empty_edits_sum_duration;
3738 // Update av stream length, if it ends up shorter than the track's media duration
3739 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
3740 msc->start_pad = st->skip_samples;
3742 // Free the old index and the old CTTS structures
3744 av_free(ctts_data_old);
3745 av_freep(&frame_duration_buffer);
3747 // Null terminate the index ranges array
3748 current_index_range++;
3749 current_index_range->start = 0;
3750 current_index_range->end = 0;
3751 msc->current_index = msc->index_ranges[0].start;
3754 static void mov_build_index(MOVContext *mov, AVStream *st)
3756 MOVStreamContext *sc = st->priv_data;
3757 int64_t current_offset;
3758 int64_t current_dts = 0;
3759 unsigned int stts_index = 0;
3760 unsigned int stsc_index = 0;
3761 unsigned int stss_index = 0;
3762 unsigned int stps_index = 0;
3764 uint64_t stream_size = 0;
3765 MOVStts *ctts_data_old = sc->ctts_data;
3766 unsigned int ctts_count_old = sc->ctts_count;
3768 if (sc->elst_count) {
3769 int i, edit_start_index = 0, multiple_edits = 0;
3770 int64_t empty_duration = 0; // empty duration of the first edit list entry
3771 int64_t start_time = 0; // start time of the media
3773 for (i = 0; i < sc->elst_count; i++) {
3774 const MOVElst *e = &sc->elst_data[i];
3775 if (i == 0 && e->time == -1) {
3776 /* if empty, the first entry is the start time of the stream
3777 * relative to the presentation itself */
3778 empty_duration = e->duration;
3779 edit_start_index = 1;
3780 } else if (i == edit_start_index && e->time >= 0) {
3781 start_time = e->time;
3787 if (multiple_edits && !mov->advanced_editlist)
3788 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
3789 "Use -advanced_editlist to correctly decode otherwise "
3790 "a/v desync might occur\n");
3792 /* adjust first dts according to edit list */
3793 if ((empty_duration || start_time) && mov->time_scale > 0) {
3795 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
3796 sc->time_offset = start_time - empty_duration;
3797 sc->min_corrected_pts = start_time;
3798 if (!mov->advanced_editlist)
3799 current_dts = -sc->time_offset;
3802 if (!multiple_edits && !mov->advanced_editlist &&
3803 st->codecpar->codec_id == AV_CODEC_ID_AAC && start_time > 0)
3804 sc->start_pad = start_time;
3807 /* only use old uncompressed audio chunk demuxing when stts specifies it */
3808 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3809 sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
3810 unsigned int current_sample = 0;
3811 unsigned int stts_sample = 0;
3812 unsigned int sample_size;
3813 unsigned int distance = 0;
3814 unsigned int rap_group_index = 0;
3815 unsigned int rap_group_sample = 0;
3816 int64_t last_dts = 0;
3817 int64_t dts_correction = 0;
3818 int rap_group_present = sc->rap_group_count && sc->rap_group;
3819 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
3821 current_dts -= sc->dts_shift;
3822 last_dts = current_dts;
3824 if (!sc->sample_count || st->nb_index_entries)
3826 if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
3828 if (av_reallocp_array(&st->index_entries,
3829 st->nb_index_entries + sc->sample_count,
3830 sizeof(*st->index_entries)) < 0) {
3831 st->nb_index_entries = 0;
3834 st->index_entries_allocated_size = (st->nb_index_entries + sc->sample_count) * sizeof(*st->index_entries);
3836 if (ctts_data_old) {
3837 // Expand ctts entries such that we have a 1-1 mapping with samples
3838 if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
3841 sc->ctts_allocated_size = 0;
3842 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size,
3843 sc->sample_count * sizeof(*sc->ctts_data));
3844 if (!sc->ctts_data) {
3845 av_free(ctts_data_old);
3849 memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
3851 for (i = 0; i < ctts_count_old &&
3852 sc->ctts_count < sc->sample_count; i++)
3853 for (j = 0; j < ctts_data_old[i].count &&
3854 sc->ctts_count < sc->sample_count; j++)
3855 add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
3856 &sc->ctts_allocated_size, 1,
3857 ctts_data_old[i].duration);
3858 av_free(ctts_data_old);
3861 for (i = 0; i < sc->chunk_count; i++) {
3862 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
3863 current_offset = sc->chunk_offsets[i];
3864 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3865 i + 1 == sc->stsc_data[stsc_index + 1].first)
3868 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
3869 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
3870 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
3871 sc->stsz_sample_size = sc->sample_size;
3873 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
3874 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
3875 sc->stsz_sample_size = sc->sample_size;
3878 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
3880 if (current_sample >= sc->sample_count) {
3881 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
3885 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
3887 if (stss_index + 1 < sc->keyframe_count)
3889 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
3891 if (stps_index + 1 < sc->stps_count)
3894 if (rap_group_present && rap_group_index < sc->rap_group_count) {
3895 if (sc->rap_group[rap_group_index].index > 0)
3897 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
3898 rap_group_sample = 0;
3902 if (sc->keyframe_absent
3904 && !rap_group_present
3905 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
3909 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
3910 if (sc->pseudo_stream_id == -1 ||
3911 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
3913 if (sample_size > 0x3FFFFFFF) {
3914 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
3917 e = &st->index_entries[st->nb_index_entries++];
3918 e->pos = current_offset;
3919 e->timestamp = current_dts;
3920 e->size = sample_size;
3921 e->min_distance = distance;
3922 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
3923 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
3924 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
3925 current_offset, current_dts, sample_size, distance, keyframe);
3926 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries < 100)
3927 ff_rfps_add_frame(mov->fc, st, current_dts);
3930 current_offset += sample_size;
3931 stream_size += sample_size;
3933 /* A negative sample duration is invalid based on the spec,
3934 * but some samples need it to correct the DTS. */
3935 if (sc->stts_data[stts_index].duration < 0) {
3936 av_log(mov->fc, AV_LOG_WARNING,
3937 "Invalid SampleDelta %d in STTS, at %d st:%d\n",
3938 sc->stts_data[stts_index].duration, stts_index,
3940 dts_correction += sc->stts_data[stts_index].duration - 1;
3941 sc->stts_data[stts_index].duration = 1;
3943 current_dts += sc->stts_data[stts_index].duration;
3944 if (!dts_correction || current_dts + dts_correction > last_dts) {
3945 current_dts += dts_correction;
3948 /* Avoid creating non-monotonous DTS */
3949 dts_correction += current_dts - last_dts - 1;
3950 current_dts = last_dts + 1;
3952 last_dts = current_dts;
3956 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
3962 if (st->duration > 0)
3963 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
3965 unsigned chunk_samples, total = 0;
3967 if (!sc->chunk_count)
3970 // compute total chunk count
3971 for (i = 0; i < sc->stsc_count; i++) {
3972 unsigned count, chunk_count;
3974 chunk_samples = sc->stsc_data[i].count;
3975 if (i != sc->stsc_count - 1 &&
3976 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
3977 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
3981 if (sc->samples_per_frame >= 160) { // gsm
3982 count = chunk_samples / sc->samples_per_frame;
3983 } else if (sc->samples_per_frame > 1) {
3984 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
3985 count = (chunk_samples+samples-1) / samples;
3987 count = (chunk_samples+1023) / 1024;
3990 if (mov_stsc_index_valid(i, sc->stsc_count))
3991 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
3993 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
3994 total += chunk_count * count;
3997 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
3998 if (total >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
4000 if (av_reallocp_array(&st->index_entries,
4001 st->nb_index_entries + total,
4002 sizeof(*st->index_entries)) < 0) {
4003 st->nb_index_entries = 0;
4006 st->index_entries_allocated_size = (st->nb_index_entries + total) * sizeof(*st->index_entries);
4009 for (i = 0; i < sc->chunk_count; i++) {
4010 current_offset = sc->chunk_offsets[i];
4011 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4012 i + 1 == sc->stsc_data[stsc_index + 1].first)
4014 chunk_samples = sc->stsc_data[stsc_index].count;
4016 while (chunk_samples > 0) {
4018 unsigned size, samples;
4020 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4021 avpriv_request_sample(mov->fc,
4022 "Zero bytes per frame, but %d samples per frame",
4023 sc->samples_per_frame);
4027 if (sc->samples_per_frame >= 160) { // gsm
4028 samples = sc->samples_per_frame;
4029 size = sc->bytes_per_frame;
4031 if (sc->samples_per_frame > 1) {
4032 samples = FFMIN((1024 / sc->samples_per_frame)*
4033 sc->samples_per_frame, chunk_samples);
4034 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
4036 samples = FFMIN(1024, chunk_samples);
4037 size = samples * sc->sample_size;
4041 if (st->nb_index_entries >= total) {
4042 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4045 if (size > 0x3FFFFFFF) {
4046 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4049 e = &st->index_entries[st->nb_index_entries++];
4050 e->pos = current_offset;
4051 e->timestamp = current_dts;
4053 e->min_distance = 0;
4054 e->flags = AVINDEX_KEYFRAME;
4055 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4056 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4059 current_offset += size;
4060 current_dts += samples;
4061 chunk_samples -= samples;
4066 if (!mov->ignore_editlist && mov->advanced_editlist) {
4067 // Fix index according to edit lists.
4068 mov_fix_index(mov, st);
4071 // Update start time of the stream.
4072 if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries > 0) {
4073 st->start_time = st->index_entries[0].timestamp + sc->dts_shift;
4074 if (sc->ctts_data) {
4075 st->start_time += sc->ctts_data[0].duration;
4079 mov_estimate_video_delay(mov, st);
4082 static int test_same_origin(const char *src, const char *ref) {
4092 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4093 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4095 if (strlen(src) == 0) {
4097 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4098 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4099 strlen(src_host) + 1 >= sizeof(src_host) ||
4100 strlen(ref_host) + 1 >= sizeof(ref_host)) {
4102 } else if (strcmp(src_proto, ref_proto) ||
4103 strcmp(src_auth, ref_auth) ||
4104 strcmp(src_host, ref_host) ||
4105 src_port != ref_port) {
4111 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4113 /* try relative path, we do not try the absolute because it can leak information about our
4114 system to an attacker */
4115 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4116 char filename[1025];
4117 const char *src_path;
4120 /* find a source dir */
4121 src_path = strrchr(src, '/');
4127 /* find a next level down to target */
4128 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4129 if (ref->path[l] == '/') {
4130 if (i == ref->nlvl_to - 1)
4136 /* compose filename if next level down to target was found */
4137 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4138 memcpy(filename, src, src_path - src);
4139 filename[src_path - src] = 0;
4141 for (i = 1; i < ref->nlvl_from; i++)
4142 av_strlcat(filename, "../", sizeof(filename));
4144 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4145 if (!c->use_absolute_path) {
4146 int same_origin = test_same_origin(src, filename);
4149 av_log(c->fc, AV_LOG_ERROR,
4150 "Reference with mismatching origin, %s not tried for security reasons, "
4151 "set demuxer option use_absolute_path to allow it anyway\n",
4153 return AVERROR(ENOENT);
4156 if(strstr(ref->path + l + 1, "..") ||
4157 strstr(ref->path + l + 1, ":") ||
4158 (ref->nlvl_from > 1 && same_origin < 0) ||
4159 (filename[0] == '/' && src_path == src))
4160 return AVERROR(ENOENT);
4163 if (strlen(filename) + 1 == sizeof(filename))
4164 return AVERROR(ENOENT);
4165 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4168 } else if (c->use_absolute_path) {
4169 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4170 "this is a possible security issue\n");
4171 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4174 av_log(c->fc, AV_LOG_ERROR,
4175 "Absolute path %s not tried for security reasons, "
4176 "set demuxer option use_absolute_path to allow absolute paths\n",
4180 return AVERROR(ENOENT);
4183 static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
4185 if (sc->time_scale <= 0) {
4186 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4187 sc->time_scale = c->time_scale;
4188 if (sc->time_scale <= 0)
4193 static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4196 MOVStreamContext *sc;
4199 st = avformat_new_stream(c->fc, NULL);
4200 if (!st) return AVERROR(ENOMEM);
4202 sc = av_mallocz(sizeof(MOVStreamContext));
4203 if (!sc) return AVERROR(ENOMEM);
4206 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
4207 sc->ffindex = st->index;
4208 c->trak_index = st->index;
4210 if ((ret = mov_read_default(c, pb, atom)) < 0)
4215 // Here stsc refers to a chunk not described in stco. This is technically invalid,
4216 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4217 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4219 av_freep(&sc->stsc_data);
4223 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4224 (!sc->sample_size && !sc->sample_count))) ||
4225 (!sc->chunk_count && sc->sample_count)) {
4226 av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4230 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4231 av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4233 return AVERROR_INVALIDDATA;
4236 fix_timescale(c, sc);
4238 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4240 mov_build_index(c, st);
4242 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4243 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4244 if (c->enable_drefs) {
4245 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4246 av_log(c->fc, AV_LOG_ERROR,
4247 "stream %d, error opening alias: path='%s', dir='%s', "
4248 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4249 st->index, dref->path, dref->dir, dref->filename,
4250 dref->volume, dref->nlvl_from, dref->nlvl_to);
4252 av_log(c->fc, AV_LOG_WARNING,
4253 "Skipped opening external track: "
4254 "stream %d, alias: path='%s', dir='%s', "
4255 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4256 "Set enable_drefs to allow this.\n",
4257 st->index, dref->path, dref->dir, dref->filename,
4258 dref->volume, dref->nlvl_from, dref->nlvl_to);
4262 sc->pb_is_copied = 1;
4265 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4266 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4267 sc->height && sc->width &&
4268 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4269 st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4270 ((double)st->codecpar->width * sc->height), INT_MAX);
4273 #if FF_API_R_FRAME_RATE
4274 if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4275 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
4276 sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4280 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4281 if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4282 TAG_IS_AVCI(st->codecpar->codec_tag)) {
4283 ret = ff_generate_avci_extradata(st);
4288 switch (st->codecpar->codec_id) {
4289 #if CONFIG_H261_DECODER
4290 case AV_CODEC_ID_H261:
4292 #if CONFIG_H263_DECODER
4293 case AV_CODEC_ID_H263:
4295 #if CONFIG_MPEG4_DECODER
4296 case AV_CODEC_ID_MPEG4:
4298 st->codecpar->width = 0; /* let decoder init width/height */
4299 st->codecpar->height= 0;
4303 // If the duration of the mp3 packets is not constant, then they could need a parser
4304 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4305 && sc->stts_count > 3
4306 && sc->stts_count*10 > st->nb_frames
4307 && sc->time_scale == st->codecpar->sample_rate) {
4308 st->need_parsing = AVSTREAM_PARSE_FULL;
4310 /* Do not need those anymore. */
4311 av_freep(&sc->chunk_offsets);
4312 av_freep(&sc->sample_sizes);
4313 av_freep(&sc->keyframes);
4314 av_freep(&sc->stts_data);
4315 av_freep(&sc->stps_data);
4316 av_freep(&sc->elst_data);
4317 av_freep(&sc->rap_group);
4322 static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4325 c->itunes_metadata = 1;
4326 ret = mov_read_default(c, pb, atom);
4327 c->itunes_metadata = 0;
4331 static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4340 count = avio_rb32(pb);
4341 if (count > UINT_MAX / sizeof(*c->meta_keys) - 1) {
4342 av_log(c->fc, AV_LOG_ERROR,
4343 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
4344 return AVERROR_INVALIDDATA;
4347 c->meta_keys_count = count + 1;
4348 c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
4350 return AVERROR(ENOMEM);
4352 for (i = 1; i <= count; ++i) {
4353 uint32_t key_size = avio_rb32(pb);
4354 uint32_t type = avio_rl32(pb);
4356 av_log(c->fc, AV_LOG_ERROR,
4357 "The key# %"PRIu32" in meta has invalid size:"
4358 "%"PRIu32"\n", i, key_size);
4359 return AVERROR_INVALIDDATA;
4362 if (type != MKTAG('m','d','t','a')) {
4363 avio_skip(pb, key_size);
4365 c->meta_keys[i] = av_mallocz(key_size + 1);
4366 if (!c->meta_keys[i])
4367 return AVERROR(ENOMEM);
4368 avio_read(pb, c->meta_keys[i], key_size);
4374 static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4376 int64_t end = avio_tell(pb) + atom.size;
4377 uint8_t *key = NULL, *val = NULL, *mean = NULL;
4381 MOVStreamContext *sc;
4383 if (c->fc->nb_streams < 1)
4385 st = c->fc->streams[c->fc->nb_streams-1];
4388 for (i = 0; i < 3; i++) {
4392 if (end - avio_tell(pb) <= 12)
4395 len = avio_rb32(pb);
4396 tag = avio_rl32(pb);
4397 avio_skip(pb, 4); // flags
4399 if (len < 12 || len - 12 > end - avio_tell(pb))
4403 if (tag == MKTAG('m', 'e', 'a', 'n'))
4405 else if (tag == MKTAG('n', 'a', 'm', 'e'))
4407 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
4414 *p = av_malloc(len + 1);
4416 ret = AVERROR(ENOMEM);
4419 ret = ffio_read_size(pb, *p, len);
4427 if (mean && key && val) {
4428 if (strcmp(key, "iTunSMPB") == 0) {
4429 int priming, remainder, samples;
4430 if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
4431 if(priming>0 && priming<16384)
4432 sc->start_pad = priming;
4435 if (strcmp(key, "cdec") != 0) {
4436 av_dict_set(&c->fc->metadata, key, val,
4437 AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
4441 av_log(c->fc, AV_LOG_VERBOSE,
4442 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
4445 avio_seek(pb, end, SEEK_SET);
4452 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4454 while (atom.size > 8) {
4458 tag = avio_rl32(pb);
4460 if (tag == MKTAG('h','d','l','r')) {
4461 avio_seek(pb, -8, SEEK_CUR);
4463 return mov_read_default(c, pb, atom);
4469 // return 1 when matrix is identity, 0 otherwise
4470 #define IS_MATRIX_IDENT(matrix) \
4471 ( (matrix)[0][0] == (1 << 16) && \
4472 (matrix)[1][1] == (1 << 16) && \
4473 (matrix)[2][2] == (1 << 30) && \
4474 !(matrix)[0][1] && !(matrix)[0][2] && \
4475 !(matrix)[1][0] && !(matrix)[1][2] && \
4476 !(matrix)[2][0] && !(matrix)[2][1])
4478 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4483 int display_matrix[3][3];
4484 int res_display_matrix[3][3] = { { 0 } };
4486 MOVStreamContext *sc;
4490 if (c->fc->nb_streams < 1)
4492 st = c->fc->streams[c->fc->nb_streams-1];
4495 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4496 // avoids corrupting AVStreams mapped to an earlier tkhd.
4498 return AVERROR_INVALIDDATA;
4500 version = avio_r8(pb);
4501 flags = avio_rb24(pb);
4502 st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
4508 avio_rb32(pb); /* creation time */
4509 avio_rb32(pb); /* modification time */
4511 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4512 avio_rb32(pb); /* reserved */
4514 /* highlevel (considering edits) duration in movie timebase */
4515 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4516 avio_rb32(pb); /* reserved */
4517 avio_rb32(pb); /* reserved */
4519 avio_rb16(pb); /* layer */
4520 avio_rb16(pb); /* alternate group */
4521 avio_rb16(pb); /* volume */
4522 avio_rb16(pb); /* reserved */
4524 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4525 // they're kept in fixed point format through all calculations
4526 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4527 // side data, but the scale factor is not needed to calculate aspect ratio
4528 for (i = 0; i < 3; i++) {
4529 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
4530 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
4531 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
4534 width = avio_rb32(pb); // 16.16 fixed point track width
4535 height = avio_rb32(pb); // 16.16 fixed point track height
4536 sc->width = width >> 16;
4537 sc->height = height >> 16;
4539 // apply the moov display matrix (after the tkhd one)
4540 for (i = 0; i < 3; i++) {
4541 const int sh[3] = { 16, 16, 30 };
4542 for (j = 0; j < 3; j++) {
4543 for (e = 0; e < 3; e++) {
4544 res_display_matrix[i][j] +=
4545 ((int64_t) display_matrix[i][e] *
4546 c->movie_display_matrix[e][j]) >> sh[e];
4551 // save the matrix when it is not the default identity
4552 if (!IS_MATRIX_IDENT(res_display_matrix)) {
4555 av_freep(&sc->display_matrix);
4556 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4557 if (!sc->display_matrix)
4558 return AVERROR(ENOMEM);
4560 for (i = 0; i < 3; i++)
4561 for (j = 0; j < 3; j++)
4562 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4564 #if FF_API_OLD_ROTATE_API
4565 rotate = av_display_rotation_get(sc->display_matrix);
4566 if (!isnan(rotate)) {
4567 char rotate_buf[64];
4569 if (rotate < 0) // for backward compatibility
4571 snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate);
4572 av_dict_set(&st->metadata, "rotate", rotate_buf, 0);
4577 // transform the display width/height according to the matrix
4578 // to keep the same scale, use [width height 1<<16]
4579 if (width && height && sc->display_matrix) {
4580 double disp_transform[2];
4582 for (i = 0; i < 2; i++)
4583 disp_transform[i] = hypot(sc->display_matrix[0 + i],
4584 sc->display_matrix[3 + i]);
4586 if (disp_transform[0] > 0 && disp_transform[1] > 0 &&
4587 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4588 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4589 st->sample_aspect_ratio = av_d2q(
4590 disp_transform[0] / disp_transform[1],
4596 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4598 MOVFragment *frag = &c->fragment;
4599 MOVTrackExt *trex = NULL;
4600 int flags, track_id, i;
4602 avio_r8(pb); /* version */
4603 flags = avio_rb24(pb);
4605 track_id = avio_rb32(pb);
4607 return AVERROR_INVALIDDATA;
4608 for (i = 0; i < c->trex_count; i++)
4609 if (c->trex_data[i].track_id == track_id) {
4610 trex = &c->trex_data[i];
4614 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4617 c->fragment.found_tfhd = 1;
4618 frag->track_id = track_id;
4619 set_frag_stream(&c->frag_index, track_id);
4621 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4622 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4623 frag->moof_offset : frag->implicit_offset;
4624 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4626 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4627 avio_rb32(pb) : trex->duration;
4628 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4629 avio_rb32(pb) : trex->size;
4630 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4631 avio_rb32(pb) : trex->flags;
4632 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4637 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4642 num = atom.size / 4;
4643 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4644 return AVERROR(ENOMEM);
4646 av_free(c->chapter_tracks);
4647 c->chapter_tracks = new_tracks;
4648 c->nb_chapter_tracks = num;
4650 for (i = 0; i < num && !pb->eof_reached; i++)
4651 c->chapter_tracks[i] = avio_rb32(pb);
4656 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4661 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4662 return AVERROR_INVALIDDATA;
4663 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4664 sizeof(*c->trex_data))) < 0) {
4669 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4671 trex = &c->trex_data[c->trex_count++];
4672 avio_r8(pb); /* version */
4673 avio_rb24(pb); /* flags */
4674 trex->track_id = avio_rb32(pb);
4675 trex->stsd_id = avio_rb32(pb);
4676 trex->duration = avio_rb32(pb);
4677 trex->size = avio_rb32(pb);
4678 trex->flags = avio_rb32(pb);
4682 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4684 MOVFragment *frag = &c->fragment;
4685 AVStream *st = NULL;
4686 MOVStreamContext *sc;
4688 MOVFragmentStreamInfo * frag_stream_info;
4689 int64_t base_media_decode_time;
4691 for (i = 0; i < c->fc->nb_streams; i++) {
4692 if (c->fc->streams[i]->id == frag->track_id) {
4693 st = c->fc->streams[i];
4698 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4702 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4704 version = avio_r8(pb);
4705 avio_rb24(pb); /* flags */
4707 base_media_decode_time = avio_rb64(pb);
4709 base_media_decode_time = avio_rb32(pb);
4712 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4713 if (frag_stream_info)
4714 frag_stream_info->tfdt_dts = base_media_decode_time;
4715 sc->track_end = base_media_decode_time;
4720 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4722 MOVFragment *frag = &c->fragment;
4723 AVStream *st = NULL;
4724 MOVStreamContext *sc;
4727 int64_t dts, pts = AV_NOPTS_VALUE;
4728 int data_offset = 0;
4729 unsigned entries, first_sample_flags = frag->flags;
4730 int flags, distance, i;
4731 int64_t prev_dts = AV_NOPTS_VALUE;
4732 int next_frag_index = -1, index_entry_pos;
4733 size_t requested_size;
4734 size_t old_ctts_allocated_size;
4735 AVIndexEntry *new_entries;
4736 MOVFragmentStreamInfo * frag_stream_info;
4738 if (!frag->found_tfhd) {
4739 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4740 return AVERROR_INVALIDDATA;
4743 for (i = 0; i < c->fc->nb_streams; i++) {
4744 if (c->fc->streams[i]->id == frag->track_id) {
4745 st = c->fc->streams[i];
4750 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4754 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4757 // Find the next frag_index index that has a valid index_entry for
4758 // the current track_id.
4760 // A valid index_entry means the trun for the fragment was read
4761 // and it's samples are in index_entries at the given position.
4762 // New index entries will be inserted before the index_entry found.
4763 index_entry_pos = st->nb_index_entries;
4764 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4765 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4766 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4767 next_frag_index = i;
4768 index_entry_pos = frag_stream_info->index_entry;
4772 av_assert0(index_entry_pos <= st->nb_index_entries);
4774 avio_r8(pb); /* version */
4775 flags = avio_rb24(pb);
4776 entries = avio_rb32(pb);
4777 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4779 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4780 return AVERROR_INVALIDDATA;
4781 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4782 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4784 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4785 if (frag_stream_info)
4787 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4788 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4789 pts = frag_stream_info->first_tfra_pts;
4790 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4791 ", using it for pts\n", pts);
4792 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4793 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4794 // pts = frag_stream_info->sidx_pts;
4795 dts = frag_stream_info->sidx_pts - sc->time_offset;
4796 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4797 ", using it for pts\n", pts);
4798 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4799 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4800 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4801 ", using it for dts\n", dts);
4803 dts = sc->track_end - sc->time_offset;
4804 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4805 ", using it for dts\n", dts);
4808 dts = sc->track_end - sc->time_offset;
4809 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4810 ", using it for dts\n", dts);
4812 offset = frag->base_data_offset + data_offset;
4814 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4816 // realloc space for new index entries
4817 if((uint64_t)st->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4818 entries = UINT_MAX / sizeof(AVIndexEntry) - st->nb_index_entries;
4819 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4824 requested_size = (st->nb_index_entries + entries) * sizeof(AVIndexEntry);
4825 new_entries = av_fast_realloc(st->index_entries,
4826 &st->index_entries_allocated_size,
4829 return AVERROR(ENOMEM);
4830 st->index_entries= new_entries;
4832 requested_size = (st->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4833 old_ctts_allocated_size = sc->ctts_allocated_size;
4834 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4837 return AVERROR(ENOMEM);
4838 sc->ctts_data = ctts_data;
4840 // In case there were samples without ctts entries, ensure they get
4841 // zero valued entries. This ensures clips which mix boxes with and
4842 // without ctts entries don't pickup uninitialized data.
4843 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4844 sc->ctts_allocated_size - old_ctts_allocated_size);
4846 if (index_entry_pos < st->nb_index_entries) {
4847 // Make hole in index_entries and ctts_data for new samples
4848 memmove(st->index_entries + index_entry_pos + entries,
4849 st->index_entries + index_entry_pos,
4850 sizeof(*st->index_entries) *
4851 (st->nb_index_entries - index_entry_pos));
4852 memmove(sc->ctts_data + index_entry_pos + entries,
4853 sc->ctts_data + index_entry_pos,
4854 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4855 if (index_entry_pos < sc->current_sample) {
4856 sc->current_sample += entries;
4860 st->nb_index_entries += entries;
4861 sc->ctts_count = st->nb_index_entries;
4863 // Record the index_entry position in frag_index of this fragment
4864 if (frag_stream_info)
4865 frag_stream_info->index_entry = index_entry_pos;
4867 if (index_entry_pos > 0)
4868 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4870 for (i = 0; i < entries && !pb->eof_reached; i++) {
4871 unsigned sample_size = frag->size;
4872 int sample_flags = i ? frag->flags : first_sample_flags;
4873 unsigned sample_duration = frag->duration;
4874 unsigned ctts_duration = 0;
4876 int index_entry_flags = 0;
4878 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4879 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4880 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4881 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4883 mov_update_dts_shift(sc, ctts_duration, c->fc);
4884 if (pts != AV_NOPTS_VALUE) {
4885 dts = pts - sc->dts_shift;
4886 if (flags & MOV_TRUN_SAMPLE_CTS) {
4887 dts -= ctts_duration;
4889 dts -= sc->time_offset;
4891 av_log(c->fc, AV_LOG_DEBUG,
4892 "pts %"PRId64" calculated dts %"PRId64
4893 " sc->dts_shift %d ctts.duration %d"
4894 " sc->time_offset %"PRId64
4895 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4897 sc->dts_shift, ctts_duration,
4898 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4899 pts = AV_NOPTS_VALUE;
4902 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4906 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4907 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4910 index_entry_flags |= AVINDEX_KEYFRAME;
4912 // Fragments can overlap in time. Discard overlapping frames after
4914 if (prev_dts >= dts)
4915 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4917 st->index_entries[index_entry_pos].pos = offset;
4918 st->index_entries[index_entry_pos].timestamp = dts;
4919 st->index_entries[index_entry_pos].size= sample_size;
4920 st->index_entries[index_entry_pos].min_distance= distance;
4921 st->index_entries[index_entry_pos].flags = index_entry_flags;
4923 sc->ctts_data[index_entry_pos].count = 1;
4924 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4927 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4928 "size %u, distance %d, keyframe %d\n", st->index,
4929 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4931 dts += sample_duration;
4932 offset += sample_size;
4933 sc->data_size += sample_size;
4935 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4936 1 <= INT_MAX - sc->nb_frames_for_fps
4938 sc->duration_for_fps += sample_duration;
4939 sc->nb_frames_for_fps ++;
4943 // EOF found before reading all entries. Fix the hole this would
4944 // leave in index_entries and ctts_data
4945 int gap = entries - i;
4946 memmove(st->index_entries + index_entry_pos,
4947 st->index_entries + index_entry_pos + gap,
4948 sizeof(*st->index_entries) *
4949 (st->nb_index_entries - (index_entry_pos + gap)));
4950 memmove(sc->ctts_data + index_entry_pos,
4951 sc->ctts_data + index_entry_pos + gap,
4952 sizeof(*sc->ctts_data) *
4953 (sc->ctts_count - (index_entry_pos + gap)));
4955 st->nb_index_entries -= gap;
4956 sc->ctts_count -= gap;
4957 if (index_entry_pos < sc->current_sample) {
4958 sc->current_sample -= gap;
4963 // The end of this new fragment may overlap in time with the start
4964 // of the next fragment in index_entries. Mark the samples in the next
4965 // fragment that overlap with AVINDEX_DISCARD_FRAME
4966 prev_dts = AV_NOPTS_VALUE;
4967 if (index_entry_pos > 0)
4968 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4969 for (i = index_entry_pos; i < st->nb_index_entries; i++) {
4970 if (prev_dts < st->index_entries[i].timestamp)
4972 st->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
4975 // If a hole was created to insert the new index_entries into,
4976 // the index_entry recorded for all subsequent moof must
4977 // be incremented by the number of entries inserted.
4978 fix_frag_index_entries(&c->frag_index, next_frag_index,
4979 frag->track_id, entries);
4981 if (pb->eof_reached) {
4982 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
4986 frag->implicit_offset = offset;
4988 sc->track_end = dts + sc->time_offset;
4989 if (st->duration < sc->track_end)
4990 st->duration = sc->track_end;
4995 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4997 int64_t offset = avio_tell(pb) + atom.size, pts, timestamp;
4999 unsigned i, j, track_id, item_count;
5000 AVStream *st = NULL;
5001 AVStream *ref_st = NULL;
5002 MOVStreamContext *sc, *ref_sc = NULL;
5003 AVRational timescale;
5005 version = avio_r8(pb);
5007 avpriv_request_sample(c->fc, "sidx version %u", version);
5011 avio_rb24(pb); // flags
5013 track_id = avio_rb32(pb); // Reference ID
5014 for (i = 0; i < c->fc->nb_streams; i++) {
5015 if (c->fc->streams[i]->id == track_id) {
5016 st = c->fc->streams[i];
5021 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5027 timescale = av_make_q(1, avio_rb32(pb));
5029 if (timescale.den <= 0) {
5030 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5031 return AVERROR_INVALIDDATA;
5035 pts = avio_rb32(pb);
5036 offset += avio_rb32(pb);
5038 pts = avio_rb64(pb);
5039 offset += avio_rb64(pb);
5042 avio_rb16(pb); // reserved
5044 item_count = avio_rb16(pb);
5046 for (i = 0; i < item_count; i++) {
5048 MOVFragmentStreamInfo * frag_stream_info;
5049 uint32_t size = avio_rb32(pb);
5050 uint32_t duration = avio_rb32(pb);
5051 if (size & 0x80000000) {
5052 avpriv_request_sample(c->fc, "sidx reference_type 1");
5053 return AVERROR_PATCHWELCOME;
5055 avio_rb32(pb); // sap_flags
5056 timestamp = av_rescale_q(pts, timescale, st->time_base);
5058 index = update_frag_index(c, offset);
5059 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5060 if (frag_stream_info)
5061 frag_stream_info->sidx_pts = timestamp;
5067 st->duration = sc->track_end = pts;
5071 if (offset == avio_size(pb)) {
5072 // Find first entry in fragment index that came from an sidx.
5073 // This will pretty much always be the first entry.
5074 for (i = 0; i < c->frag_index.nb_items; i++) {
5075 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5076 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5077 MOVFragmentStreamInfo * si;
5078 si = &item->stream_info[j];
5079 if (si->sidx_pts != AV_NOPTS_VALUE) {
5080 ref_st = c->fc->streams[j];
5081 ref_sc = ref_st->priv_data;
5086 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5087 st = c->fc->streams[i];
5089 if (!sc->has_sidx) {
5090 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5094 c->frag_index.complete = 1;
5100 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5101 /* like the files created with Adobe Premiere 5.0, for samples see */
5102 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5103 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5108 return 0; /* continue */
5109 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5110 avio_skip(pb, atom.size - 4);
5113 atom.type = avio_rl32(pb);
5115 if (atom.type != MKTAG('m','d','a','t')) {
5116 avio_skip(pb, atom.size);
5119 err = mov_read_mdat(c, pb, atom);
5123 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5128 uint8_t *moov_data; /* uncompressed data */
5129 long cmov_len, moov_len;
5132 avio_rb32(pb); /* dcom atom */
5133 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5134 return AVERROR_INVALIDDATA;
5135 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5136 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5137 return AVERROR_INVALIDDATA;
5139 avio_rb32(pb); /* cmvd atom */
5140 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5141 return AVERROR_INVALIDDATA;
5142 moov_len = avio_rb32(pb); /* uncompressed size */
5143 cmov_len = atom.size - 6 * 4;
5145 cmov_data = av_malloc(cmov_len);
5147 return AVERROR(ENOMEM);
5148 moov_data = av_malloc(moov_len);
5151 return AVERROR(ENOMEM);
5153 ret = ffio_read_size(pb, cmov_data, cmov_len);
5155 goto free_and_return;
5157 ret = AVERROR_INVALIDDATA;
5158 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5159 goto free_and_return;
5160 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5161 goto free_and_return;
5162 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5163 atom.type = MKTAG('m','o','o','v');
5164 atom.size = moov_len;
5165 ret = mov_read_default(c, &ctx, atom);
5171 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5172 return AVERROR(ENOSYS);
5176 /* edit list atom */
5177 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5179 MOVStreamContext *sc;
5180 int i, edit_count, version;
5181 int64_t elst_entry_size;
5183 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5185 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5187 version = avio_r8(pb); /* version */
5188 avio_rb24(pb); /* flags */
5189 edit_count = avio_rb32(pb); /* entries */
5192 elst_entry_size = version == 1 ? 20 : 12;
5193 if (atom.size != edit_count * elst_entry_size) {
5194 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5195 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5196 edit_count, atom.size + 8);
5197 return AVERROR_INVALIDDATA;
5199 edit_count = atom.size / elst_entry_size;
5200 if (edit_count * elst_entry_size != atom.size) {
5201 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.", atom.size, edit_count);
5209 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5210 av_free(sc->elst_data);
5212 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5214 return AVERROR(ENOMEM);
5216 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5217 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5218 MOVElst *e = &sc->elst_data[i];
5221 e->duration = avio_rb64(pb);
5222 e->time = avio_rb64(pb);
5225 e->duration = avio_rb32(pb); /* segment duration */
5226 e->time = (int32_t)avio_rb32(pb); /* media time */
5229 e->rate = avio_rb32(pb) / 65536.0;
5231 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5232 e->duration, e->time, e->rate);
5234 if (e->time < 0 && e->time != -1 &&
5235 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5236 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5237 c->fc->nb_streams-1, i, e->time);
5238 return AVERROR_INVALIDDATA;
5246 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5248 MOVStreamContext *sc;
5250 if (c->fc->nb_streams < 1)
5251 return AVERROR_INVALIDDATA;
5252 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5253 sc->timecode_track = avio_rb32(pb);
5257 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5262 if (c->fc->nb_streams < 1)
5264 st = c->fc->streams[c->fc->nb_streams - 1];
5266 if (atom.size < 4) {
5267 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5268 return AVERROR_INVALIDDATA;
5271 /* For now, propagate only the OBUs, if any. Once libavcodec is
5272 updated to handle isobmff style extradata this can be removed. */
5278 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5285 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5288 int version, color_range, color_primaries, color_trc, color_space;
5290 if (c->fc->nb_streams < 1)
5292 st = c->fc->streams[c->fc->nb_streams - 1];
5294 if (atom.size < 5) {
5295 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5296 return AVERROR_INVALIDDATA;
5299 version = avio_r8(pb);
5301 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5304 avio_skip(pb, 3); /* flags */
5306 avio_skip(pb, 2); /* profile + level */
5307 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5308 color_primaries = avio_r8(pb);
5309 color_trc = avio_r8(pb);
5310 color_space = avio_r8(pb);
5311 if (avio_rb16(pb)) /* codecIntializationDataSize */
5312 return AVERROR_INVALIDDATA;
5314 if (!av_color_primaries_name(color_primaries))
5315 color_primaries = AVCOL_PRI_UNSPECIFIED;
5316 if (!av_color_transfer_name(color_trc))
5317 color_trc = AVCOL_TRC_UNSPECIFIED;
5318 if (!av_color_space_name(color_space))
5319 color_space = AVCOL_SPC_UNSPECIFIED;
5321 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5322 st->codecpar->color_primaries = color_primaries;
5323 st->codecpar->color_trc = color_trc;
5324 st->codecpar->color_space = color_space;
5329 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5331 MOVStreamContext *sc;
5334 if (c->fc->nb_streams < 1)
5335 return AVERROR_INVALIDDATA;
5337 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5339 if (atom.size < 5) {
5340 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5341 return AVERROR_INVALIDDATA;
5344 version = avio_r8(pb);
5346 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5349 avio_skip(pb, 3); /* flags */
5351 sc->mastering = av_mastering_display_metadata_alloc();
5353 return AVERROR(ENOMEM);
5355 for (i = 0; i < 3; i++) {
5356 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5357 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5359 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5360 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5362 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5363 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5365 sc->mastering->has_primaries = 1;
5366 sc->mastering->has_luminance = 1;
5371 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5373 MOVStreamContext *sc;
5374 const int mapping[3] = {1, 2, 0};
5375 const int chroma_den = 50000;
5376 const int luma_den = 10000;
5379 if (c->fc->nb_streams < 1)
5380 return AVERROR_INVALIDDATA;
5382 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5384 if (atom.size < 24) {
5385 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5386 return AVERROR_INVALIDDATA;
5389 sc->mastering = av_mastering_display_metadata_alloc();
5391 return AVERROR(ENOMEM);
5393 for (i = 0; i < 3; i++) {
5394 const int j = mapping[i];
5395 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5396 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5398 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5399 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5401 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5402 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5404 sc->mastering->has_luminance = 1;
5405 sc->mastering->has_primaries = 1;
5410 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5412 MOVStreamContext *sc;
5415 if (c->fc->nb_streams < 1)
5416 return AVERROR_INVALIDDATA;
5418 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5420 if (atom.size < 5) {
5421 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5422 return AVERROR_INVALIDDATA;
5425 version = avio_r8(pb);
5427 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5430 avio_skip(pb, 3); /* flags */
5432 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5434 return AVERROR(ENOMEM);
5436 sc->coll->MaxCLL = avio_rb16(pb);
5437 sc->coll->MaxFALL = avio_rb16(pb);
5442 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5444 MOVStreamContext *sc;
5446 if (c->fc->nb_streams < 1)
5447 return AVERROR_INVALIDDATA;
5449 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5451 if (atom.size < 4) {
5452 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5453 return AVERROR_INVALIDDATA;
5456 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5458 return AVERROR(ENOMEM);
5460 sc->coll->MaxCLL = avio_rb16(pb);
5461 sc->coll->MaxFALL = avio_rb16(pb);
5466 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5469 MOVStreamContext *sc;
5470 enum AVStereo3DType type;
5473 if (c->fc->nb_streams < 1)
5476 st = c->fc->streams[c->fc->nb_streams - 1];
5479 if (atom.size < 5) {
5480 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5481 return AVERROR_INVALIDDATA;
5483 avio_skip(pb, 4); /* version + flags */
5488 type = AV_STEREO3D_2D;
5491 type = AV_STEREO3D_TOPBOTTOM;
5494 type = AV_STEREO3D_SIDEBYSIDE;
5497 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5501 sc->stereo3d = av_stereo3d_alloc();
5503 return AVERROR(ENOMEM);
5505 sc->stereo3d->type = type;
5509 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5512 MOVStreamContext *sc;
5513 int size, version, layout;
5514 int32_t yaw, pitch, roll;
5515 uint32_t l = 0, t = 0, r = 0, b = 0;
5516 uint32_t tag, padding = 0;
5517 enum AVSphericalProjection projection;
5519 if (c->fc->nb_streams < 1)
5522 st = c->fc->streams[c->fc->nb_streams - 1];
5525 if (atom.size < 8) {
5526 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5527 return AVERROR_INVALIDDATA;
5530 size = avio_rb32(pb);
5531 if (size <= 12 || size > atom.size)
5532 return AVERROR_INVALIDDATA;
5534 tag = avio_rl32(pb);
5535 if (tag != MKTAG('s','v','h','d')) {
5536 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5539 version = avio_r8(pb);
5541 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5545 avio_skip(pb, 3); /* flags */
5546 avio_skip(pb, size - 12); /* metadata_source */
5548 size = avio_rb32(pb);
5549 if (size > atom.size)
5550 return AVERROR_INVALIDDATA;
5552 tag = avio_rl32(pb);
5553 if (tag != MKTAG('p','r','o','j')) {
5554 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5558 size = avio_rb32(pb);
5559 if (size > atom.size)
5560 return AVERROR_INVALIDDATA;
5562 tag = avio_rl32(pb);
5563 if (tag != MKTAG('p','r','h','d')) {
5564 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5567 version = avio_r8(pb);
5569 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5573 avio_skip(pb, 3); /* flags */
5575 /* 16.16 fixed point */
5576 yaw = avio_rb32(pb);
5577 pitch = avio_rb32(pb);
5578 roll = avio_rb32(pb);
5580 size = avio_rb32(pb);
5581 if (size > atom.size)
5582 return AVERROR_INVALIDDATA;
5584 tag = avio_rl32(pb);
5585 version = avio_r8(pb);
5587 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5591 avio_skip(pb, 3); /* flags */
5593 case MKTAG('c','b','m','p'):
5594 layout = avio_rb32(pb);
5596 av_log(c->fc, AV_LOG_WARNING,
5597 "Unsupported cubemap layout %d\n", layout);
5600 projection = AV_SPHERICAL_CUBEMAP;
5601 padding = avio_rb32(pb);
5603 case MKTAG('e','q','u','i'):
5609 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5610 av_log(c->fc, AV_LOG_ERROR,
5611 "Invalid bounding rectangle coordinates "
5612 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5613 return AVERROR_INVALIDDATA;
5616 if (l || t || r || b)
5617 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5619 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5622 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5626 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5628 return AVERROR(ENOMEM);
5630 sc->spherical->projection = projection;
5632 sc->spherical->yaw = yaw;
5633 sc->spherical->pitch = pitch;
5634 sc->spherical->roll = roll;
5636 sc->spherical->padding = padding;
5638 sc->spherical->bound_left = l;
5639 sc->spherical->bound_top = t;
5640 sc->spherical->bound_right = r;
5641 sc->spherical->bound_bottom = b;
5646 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5649 uint8_t *buffer = av_malloc(len + 1);
5653 return AVERROR(ENOMEM);
5656 ret = ffio_read_size(pb, buffer, len);
5660 /* Check for mandatory keys and values, try to support XML as best-effort */
5661 if (!sc->spherical &&
5662 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5663 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5664 av_stristr(val, "true") &&
5665 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5666 av_stristr(val, "true") &&
5667 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5668 av_stristr(val, "equirectangular")) {
5669 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5673 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5675 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5676 enum AVStereo3DType mode;
5678 if (av_stristr(buffer, "left-right"))
5679 mode = AV_STEREO3D_SIDEBYSIDE;
5680 else if (av_stristr(buffer, "top-bottom"))
5681 mode = AV_STEREO3D_TOPBOTTOM;
5683 mode = AV_STEREO3D_2D;
5685 sc->stereo3d = av_stereo3d_alloc();
5689 sc->stereo3d->type = mode;
5693 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5695 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5696 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5698 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5699 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5701 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5709 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5712 MOVStreamContext *sc;
5715 static const uint8_t uuid_isml_manifest[] = {
5716 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5717 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5719 static const uint8_t uuid_xmp[] = {
5720 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5721 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5723 static const uint8_t uuid_spherical[] = {
5724 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5725 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5728 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5729 return AVERROR_INVALIDDATA;
5731 if (c->fc->nb_streams < 1)
5733 st = c->fc->streams[c->fc->nb_streams - 1];
5736 ret = avio_read(pb, uuid, sizeof(uuid));
5739 } else if (ret != sizeof(uuid)) {
5740 return AVERROR_INVALIDDATA;
5742 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5743 uint8_t *buffer, *ptr;
5745 size_t len = atom.size - sizeof(uuid);
5748 return AVERROR_INVALIDDATA;
5750 ret = avio_skip(pb, 4); // zeroes
5753 buffer = av_mallocz(len + 1);
5755 return AVERROR(ENOMEM);
5757 ret = avio_read(pb, buffer, len);
5761 } else if (ret != len) {
5763 return AVERROR_INVALIDDATA;
5767 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5768 ptr += sizeof("systemBitrate=\"") - 1;
5769 c->bitrates_count++;
5770 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5772 c->bitrates_count = 0;
5774 return AVERROR(ENOMEM);
5777 ret = strtol(ptr, &endptr, 10);
5778 if (ret < 0 || errno || *endptr != '"') {
5779 c->bitrates[c->bitrates_count - 1] = 0;
5781 c->bitrates[c->bitrates_count - 1] = ret;
5786 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5788 size_t len = atom.size - sizeof(uuid);
5789 if (c->export_xmp) {
5790 buffer = av_mallocz(len + 1);
5792 return AVERROR(ENOMEM);
5794 ret = avio_read(pb, buffer, len);
5798 } else if (ret != len) {
5800 return AVERROR_INVALIDDATA;
5803 av_dict_set(&c->fc->metadata, "xmp",
5804 buffer, AV_DICT_DONT_STRDUP_VAL);
5806 // skip all uuid atom, which makes it fast for long uuid-xmp file
5807 ret = avio_skip(pb, len);
5811 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5812 size_t len = atom.size - sizeof(uuid);
5813 ret = mov_parse_uuid_spherical(sc, pb, len);
5817 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5823 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5826 uint8_t content[16];
5831 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5837 && !memcmp(content, "Anevia\x1A\x1A", 8)
5838 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5839 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5845 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5847 uint32_t format = avio_rl32(pb);
5848 MOVStreamContext *sc;
5852 if (c->fc->nb_streams < 1)
5854 st = c->fc->streams[c->fc->nb_streams - 1];
5859 case MKTAG('e','n','c','v'): // encrypted video
5860 case MKTAG('e','n','c','a'): // encrypted audio
5861 id = mov_codec_id(st, format);
5862 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5863 st->codecpar->codec_id != id) {
5864 av_log(c->fc, AV_LOG_WARNING,
5865 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5866 (char*)&format, st->codecpar->codec_id);
5870 st->codecpar->codec_id = id;
5871 sc->format = format;
5875 if (format != sc->format) {
5876 av_log(c->fc, AV_LOG_WARNING,
5877 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5878 (char*)&format, (char*)&sc->format);
5887 * Gets the current encryption info and associated current stream context. If
5888 * we are parsing a track fragment, this will return the specific encryption
5889 * info for this fragment; otherwise this will return the global encryption
5890 * info for the current stream.
5892 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5894 MOVFragmentStreamInfo *frag_stream_info;
5898 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5899 if (frag_stream_info) {
5900 for (i = 0; i < c->fc->nb_streams; i++) {
5901 if (c->fc->streams[i]->id == frag_stream_info->id) {
5902 st = c->fc->streams[i];
5906 if (i == c->fc->nb_streams)
5908 *sc = st->priv_data;
5910 if (!frag_stream_info->encryption_index) {
5911 // If this stream isn't encrypted, don't create the index.
5912 if (!(*sc)->cenc.default_encrypted_sample)
5914 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5915 if (!frag_stream_info->encryption_index)
5916 return AVERROR(ENOMEM);
5918 *encryption_index = frag_stream_info->encryption_index;
5921 // No current track fragment, using stream level encryption info.
5923 if (c->fc->nb_streams < 1)
5925 st = c->fc->streams[c->fc->nb_streams - 1];
5926 *sc = st->priv_data;
5928 if (!(*sc)->cenc.encryption_index) {
5929 // If this stream isn't encrypted, don't create the index.
5930 if (!(*sc)->cenc.default_encrypted_sample)
5932 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5933 if (!(*sc)->cenc.encryption_index)
5934 return AVERROR(ENOMEM);
5937 *encryption_index = (*sc)->cenc.encryption_index;
5942 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
5945 unsigned int subsample_count;
5946 AVSubsampleEncryptionInfo *subsamples;
5948 if (!sc->cenc.default_encrypted_sample) {
5949 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
5950 return AVERROR_INVALIDDATA;
5953 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
5955 return AVERROR(ENOMEM);
5957 if (sc->cenc.per_sample_iv_size != 0) {
5958 if (avio_read(pb, (*sample)->iv, sc->cenc.per_sample_iv_size) != sc->cenc.per_sample_iv_size) {
5959 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
5960 av_encryption_info_free(*sample);
5962 return AVERROR_INVALIDDATA;
5966 if (use_subsamples) {
5967 subsample_count = avio_rb16(pb);
5968 av_free((*sample)->subsamples);
5969 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
5970 if (!(*sample)->subsamples) {
5971 av_encryption_info_free(*sample);
5973 return AVERROR(ENOMEM);
5976 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
5977 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
5978 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
5981 if (pb->eof_reached) {
5982 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
5983 av_encryption_info_free(*sample);
5985 return AVERROR_INVALIDDATA;
5987 (*sample)->subsample_count = subsample_count;
5993 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5995 AVEncryptionInfo **encrypted_samples;
5996 MOVEncryptionIndex *encryption_index;
5997 MOVStreamContext *sc;
5998 int use_subsamples, ret;
5999 unsigned int sample_count, i, alloc_size = 0;
6001 ret = get_current_encryption_info(c, &encryption_index, &sc);
6005 if (encryption_index->nb_encrypted_samples) {
6006 // This can happen if we have both saio/saiz and senc atoms.
6007 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6011 avio_r8(pb); /* version */
6012 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6014 sample_count = avio_rb32(pb);
6015 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6016 return AVERROR(ENOMEM);
6018 for (i = 0; i < sample_count; i++) {
6019 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6020 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6021 min_samples * sizeof(*encrypted_samples));
6022 if (encrypted_samples) {
6023 encryption_index->encrypted_samples = encrypted_samples;
6025 ret = mov_read_sample_encryption_info(
6026 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6028 ret = AVERROR(ENOMEM);
6030 if (pb->eof_reached) {
6031 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6032 ret = AVERROR_INVALIDDATA;
6037 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6038 av_freep(&encryption_index->encrypted_samples);
6042 encryption_index->nb_encrypted_samples = sample_count;
6047 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6049 AVEncryptionInfo **sample, **encrypted_samples;
6051 size_t sample_count, sample_info_size, i;
6053 unsigned int alloc_size = 0;
6055 if (encryption_index->nb_encrypted_samples)
6057 sample_count = encryption_index->auxiliary_info_sample_count;
6058 if (encryption_index->auxiliary_offsets_count != 1) {
6059 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6060 return AVERROR_PATCHWELCOME;
6062 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6063 return AVERROR(ENOMEM);
6065 prev_pos = avio_tell(pb);
6066 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6067 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6068 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6072 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6073 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6074 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6075 min_samples * sizeof(*encrypted_samples));
6076 if (!encrypted_samples) {
6077 ret = AVERROR(ENOMEM);
6080 encryption_index->encrypted_samples = encrypted_samples;
6082 sample = &encryption_index->encrypted_samples[i];
6083 sample_info_size = encryption_index->auxiliary_info_default_size
6084 ? encryption_index->auxiliary_info_default_size
6085 : encryption_index->auxiliary_info_sizes[i];
6087 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6091 if (pb->eof_reached) {
6092 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6093 ret = AVERROR_INVALIDDATA;
6095 encryption_index->nb_encrypted_samples = sample_count;
6099 avio_seek(pb, prev_pos, SEEK_SET);
6101 for (; i > 0; i--) {
6102 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6104 av_freep(&encryption_index->encrypted_samples);
6110 * Tries to read the given number of bytes from the stream and puts it in a
6111 * newly allocated buffer. This reads in small chunks to avoid allocating large
6112 * memory if the file contains an invalid/malicious size value.
6114 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6116 const unsigned int block_size = 1024 * 1024;
6117 uint8_t *buffer = NULL;
6118 unsigned int alloc_size = 0, offset = 0;
6119 while (offset < size) {
6120 unsigned int new_size =
6121 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6122 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6123 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6126 return AVERROR(ENOMEM);
6128 buffer = new_buffer;
6130 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6132 return AVERROR_INVALIDDATA;
6141 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6143 MOVEncryptionIndex *encryption_index;
6144 MOVStreamContext *sc;
6146 unsigned int sample_count, aux_info_type, aux_info_param;
6148 ret = get_current_encryption_info(c, &encryption_index, &sc);
6152 if (encryption_index->nb_encrypted_samples) {
6153 // This can happen if we have both saio/saiz and senc atoms.
6154 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6158 if (encryption_index->auxiliary_info_sample_count) {
6159 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6160 return AVERROR_INVALIDDATA;
6163 avio_r8(pb); /* version */
6164 if (avio_rb24(pb) & 0x01) { /* flags */
6165 aux_info_type = avio_rb32(pb);
6166 aux_info_param = avio_rb32(pb);
6167 if (sc->cenc.default_encrypted_sample) {
6168 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6169 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6172 if (aux_info_param != 0) {
6173 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6177 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6178 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6179 aux_info_type == MKBETAG('c','e','n','s') ||
6180 aux_info_type == MKBETAG('c','b','c','1') ||
6181 aux_info_type == MKBETAG('c','b','c','s')) &&
6182 aux_info_param == 0) {
6183 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6184 return AVERROR_INVALIDDATA;
6189 } else if (!sc->cenc.default_encrypted_sample) {
6190 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6194 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6195 sample_count = avio_rb32(pb);
6196 encryption_index->auxiliary_info_sample_count = sample_count;
6198 if (encryption_index->auxiliary_info_default_size == 0) {
6199 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6201 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6206 if (encryption_index->auxiliary_offsets_count) {
6207 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6213 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6215 uint64_t *auxiliary_offsets;
6216 MOVEncryptionIndex *encryption_index;
6217 MOVStreamContext *sc;
6219 unsigned int version, entry_count, aux_info_type, aux_info_param;
6220 unsigned int alloc_size = 0;
6222 ret = get_current_encryption_info(c, &encryption_index, &sc);
6226 if (encryption_index->nb_encrypted_samples) {
6227 // This can happen if we have both saio/saiz and senc atoms.
6228 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6232 if (encryption_index->auxiliary_offsets_count) {
6233 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6234 return AVERROR_INVALIDDATA;
6237 version = avio_r8(pb); /* version */
6238 if (avio_rb24(pb) & 0x01) { /* flags */
6239 aux_info_type = avio_rb32(pb);
6240 aux_info_param = avio_rb32(pb);
6241 if (sc->cenc.default_encrypted_sample) {
6242 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6243 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6246 if (aux_info_param != 0) {
6247 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6251 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6252 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6253 aux_info_type == MKBETAG('c','e','n','s') ||
6254 aux_info_type == MKBETAG('c','b','c','1') ||
6255 aux_info_type == MKBETAG('c','b','c','s')) &&
6256 aux_info_param == 0) {
6257 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6258 return AVERROR_INVALIDDATA;
6263 } else if (!sc->cenc.default_encrypted_sample) {
6264 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6268 entry_count = avio_rb32(pb);
6269 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6270 return AVERROR(ENOMEM);
6272 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6273 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6274 auxiliary_offsets = av_fast_realloc(
6275 encryption_index->auxiliary_offsets, &alloc_size,
6276 min_offsets * sizeof(*auxiliary_offsets));
6277 if (!auxiliary_offsets) {
6278 av_freep(&encryption_index->auxiliary_offsets);
6279 return AVERROR(ENOMEM);
6281 encryption_index->auxiliary_offsets = auxiliary_offsets;
6284 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6286 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6288 if (c->frag_index.current >= 0) {
6289 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6293 if (pb->eof_reached) {
6294 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6295 av_freep(&encryption_index->auxiliary_offsets);
6296 return AVERROR_INVALIDDATA;
6299 encryption_index->auxiliary_offsets_count = entry_count;
6301 if (encryption_index->auxiliary_info_sample_count) {
6302 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6308 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6310 AVEncryptionInitInfo *info, *old_init_info;
6313 uint8_t *side_data, *extra_data, *old_side_data;
6314 size_t side_data_size;
6315 int ret = 0, old_side_data_size;
6316 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6318 if (c->fc->nb_streams < 1)
6320 st = c->fc->streams[c->fc->nb_streams-1];
6322 version = avio_r8(pb); /* version */
6323 avio_rb24(pb); /* flags */
6325 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6326 /* key_id_size */ 16, /* data_size */ 0);
6328 return AVERROR(ENOMEM);
6330 if (avio_read(pb, info->system_id, 16) != 16) {
6331 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6332 ret = AVERROR_INVALIDDATA;
6337 kid_count = avio_rb32(pb);
6338 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
6339 ret = AVERROR(ENOMEM);
6343 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6344 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6345 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6346 min_kid_count * sizeof(*key_ids));
6348 ret = AVERROR(ENOMEM);
6351 info->key_ids = key_ids;
6353 info->key_ids[i] = av_mallocz(16);
6354 if (!info->key_ids[i]) {
6355 ret = AVERROR(ENOMEM);
6358 info->num_key_ids = i + 1;
6360 if (avio_read(pb, info->key_ids[i], 16) != 16) {
6361 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6362 ret = AVERROR_INVALIDDATA;
6367 if (pb->eof_reached) {
6368 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6369 ret = AVERROR_INVALIDDATA;
6374 extra_data_size = avio_rb32(pb);
6375 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6379 av_freep(&info->data); // malloc(0) may still allocate something.
6380 info->data = extra_data;
6381 info->data_size = extra_data_size;
6383 // If there is existing initialization data, append to the list.
6384 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6385 if (old_side_data) {
6386 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6387 if (old_init_info) {
6388 // Append to the end of the list.
6389 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6395 info = old_init_info;
6397 // Assume existing side-data will be valid, so the only error we could get is OOM.
6398 ret = AVERROR(ENOMEM);
6403 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6405 ret = AVERROR(ENOMEM);
6408 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6409 side_data, side_data_size);
6414 av_encryption_init_info_free(info);
6418 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6421 MOVStreamContext *sc;
6423 if (c->fc->nb_streams < 1)
6425 st = c->fc->streams[c->fc->nb_streams-1];
6428 if (sc->pseudo_stream_id != 0) {
6429 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6430 return AVERROR_PATCHWELCOME;
6434 return AVERROR_INVALIDDATA;
6436 avio_rb32(pb); /* version and flags */
6438 if (!sc->cenc.default_encrypted_sample) {
6439 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6440 if (!sc->cenc.default_encrypted_sample) {
6441 return AVERROR(ENOMEM);
6445 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6449 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6452 MOVStreamContext *sc;
6453 unsigned int version, pattern, is_protected, iv_size;
6455 if (c->fc->nb_streams < 1)
6457 st = c->fc->streams[c->fc->nb_streams-1];
6460 if (sc->pseudo_stream_id != 0) {
6461 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6462 return AVERROR_PATCHWELCOME;
6465 if (!sc->cenc.default_encrypted_sample) {
6466 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6467 if (!sc->cenc.default_encrypted_sample) {
6468 return AVERROR(ENOMEM);
6473 return AVERROR_INVALIDDATA;
6475 version = avio_r8(pb); /* version */
6476 avio_rb24(pb); /* flags */
6478 avio_r8(pb); /* reserved */
6479 pattern = avio_r8(pb);
6482 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6483 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6486 is_protected = avio_r8(pb);
6487 if (is_protected && !sc->cenc.encryption_index) {
6488 // The whole stream should be by-default encrypted.
6489 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6490 if (!sc->cenc.encryption_index)
6491 return AVERROR(ENOMEM);
6493 sc->cenc.per_sample_iv_size = avio_r8(pb);
6494 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6495 sc->cenc.per_sample_iv_size != 16) {
6496 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6497 return AVERROR_INVALIDDATA;
6499 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6500 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6501 return AVERROR_INVALIDDATA;
6504 if (is_protected && !sc->cenc.per_sample_iv_size) {
6505 iv_size = avio_r8(pb);
6506 if (iv_size != 8 && iv_size != 16) {
6507 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6508 return AVERROR_INVALIDDATA;
6511 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6512 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6513 return AVERROR_INVALIDDATA;
6520 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6523 int last, type, size, ret;
6526 if (c->fc->nb_streams < 1)
6528 st = c->fc->streams[c->fc->nb_streams-1];
6530 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6531 return AVERROR_INVALIDDATA;
6533 /* Check FlacSpecificBox version. */
6534 if (avio_r8(pb) != 0)
6535 return AVERROR_INVALIDDATA;
6537 avio_rb24(pb); /* Flags */
6539 avio_read(pb, buf, sizeof(buf));
6540 flac_parse_block_header(buf, &last, &type, &size);
6542 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6543 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6544 return AVERROR_INVALIDDATA;
6547 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6552 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6557 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6561 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6562 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6563 return AVERROR_PATCHWELCOME;
6566 if (!sc->cenc.aes_ctr) {
6567 /* initialize the cipher */
6568 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6569 if (!sc->cenc.aes_ctr) {
6570 return AVERROR(ENOMEM);
6573 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6579 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6581 if (!sample->subsample_count)
6583 /* decrypt the whole packet */
6584 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6588 for (i = 0; i < sample->subsample_count; i++)
6590 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6591 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6592 return AVERROR_INVALIDDATA;
6595 /* skip the clear bytes */
6596 input += sample->subsamples[i].bytes_of_clear_data;
6597 size -= sample->subsamples[i].bytes_of_clear_data;
6599 /* decrypt the encrypted bytes */
6600 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6601 input += sample->subsamples[i].bytes_of_protected_data;
6602 size -= sample->subsamples[i].bytes_of_protected_data;
6606 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6607 return AVERROR_INVALIDDATA;
6613 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6615 MOVFragmentStreamInfo *frag_stream_info;
6616 MOVEncryptionIndex *encryption_index;
6617 AVEncryptionInfo *encrypted_sample;
6618 int encrypted_index, ret;
6620 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6621 encrypted_index = current_index;
6622 encryption_index = NULL;
6623 if (frag_stream_info) {
6624 // Note this only supports encryption info in the first sample descriptor.
6625 if (mov->fragment.stsd_id == 1) {
6626 if (frag_stream_info->encryption_index) {
6627 encrypted_index = current_index - frag_stream_info->index_entry;
6628 encryption_index = frag_stream_info->encryption_index;
6630 encryption_index = sc->cenc.encryption_index;
6634 encryption_index = sc->cenc.encryption_index;
6637 if (encryption_index) {
6638 if (encryption_index->auxiliary_info_sample_count &&
6639 !encryption_index->nb_encrypted_samples) {
6640 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6641 return AVERROR_INVALIDDATA;
6643 if (encryption_index->auxiliary_offsets_count &&
6644 !encryption_index->nb_encrypted_samples) {
6645 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6646 return AVERROR_INVALIDDATA;
6649 if (!encryption_index->nb_encrypted_samples) {
6650 // Full-sample encryption with default settings.
6651 encrypted_sample = sc->cenc.default_encrypted_sample;
6652 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6653 // Per-sample setting override.
6654 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6656 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6657 return AVERROR_INVALIDDATA;
6660 if (mov->decryption_key) {
6661 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6664 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6666 return AVERROR(ENOMEM);
6667 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6677 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6679 const int OPUS_SEEK_PREROLL_MS = 80;
6685 if (c->fc->nb_streams < 1)
6687 st = c->fc->streams[c->fc->nb_streams-1];
6689 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6690 return AVERROR_INVALIDDATA;
6692 /* Check OpusSpecificBox version. */
6693 if (avio_r8(pb) != 0) {
6694 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6695 return AVERROR_INVALIDDATA;
6698 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6699 size = atom.size + 8;
6701 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
6704 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6705 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6706 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6707 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6709 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6710 little-endian; aside from the preceeding magic and version they're
6711 otherwise currently identical. Data after output gain at offset 16
6712 doesn't need to be bytewapped. */
6713 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6714 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6715 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6716 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6718 st->codecpar->initial_padding = pre_skip;
6719 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6720 (AVRational){1, 1000},
6721 (AVRational){1, 48000});
6726 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6729 unsigned format_info;
6730 int channel_assignment, channel_assignment1, channel_assignment2;
6733 if (c->fc->nb_streams < 1)
6735 st = c->fc->streams[c->fc->nb_streams-1];
6738 return AVERROR_INVALIDDATA;
6740 format_info = avio_rb32(pb);
6742 ratebits = (format_info >> 28) & 0xF;
6743 channel_assignment1 = (format_info >> 15) & 0x1F;
6744 channel_assignment2 = format_info & 0x1FFF;
6745 if (channel_assignment2)
6746 channel_assignment = channel_assignment2;
6748 channel_assignment = channel_assignment1;
6750 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6751 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6752 st->codecpar->channels = truehd_channels(channel_assignment);
6753 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6758 static const MOVParseTableEntry mov_default_parse_table[] = {
6759 { MKTAG('A','C','L','R'), mov_read_aclr },
6760 { MKTAG('A','P','R','G'), mov_read_avid },
6761 { MKTAG('A','A','L','P'), mov_read_avid },
6762 { MKTAG('A','R','E','S'), mov_read_ares },
6763 { MKTAG('a','v','s','s'), mov_read_avss },
6764 { MKTAG('a','v','1','C'), mov_read_av1c },
6765 { MKTAG('c','h','p','l'), mov_read_chpl },
6766 { MKTAG('c','o','6','4'), mov_read_stco },
6767 { MKTAG('c','o','l','r'), mov_read_colr },
6768 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6769 { MKTAG('d','i','n','f'), mov_read_default },
6770 { MKTAG('D','p','x','E'), mov_read_dpxe },
6771 { MKTAG('d','r','e','f'), mov_read_dref },
6772 { MKTAG('e','d','t','s'), mov_read_default },
6773 { MKTAG('e','l','s','t'), mov_read_elst },
6774 { MKTAG('e','n','d','a'), mov_read_enda },
6775 { MKTAG('f','i','e','l'), mov_read_fiel },
6776 { MKTAG('a','d','r','m'), mov_read_adrm },
6777 { MKTAG('f','t','y','p'), mov_read_ftyp },
6778 { MKTAG('g','l','b','l'), mov_read_glbl },
6779 { MKTAG('h','d','l','r'), mov_read_hdlr },
6780 { MKTAG('i','l','s','t'), mov_read_ilst },
6781 { MKTAG('j','p','2','h'), mov_read_jp2h },
6782 { MKTAG('m','d','a','t'), mov_read_mdat },
6783 { MKTAG('m','d','h','d'), mov_read_mdhd },
6784 { MKTAG('m','d','i','a'), mov_read_default },
6785 { MKTAG('m','e','t','a'), mov_read_meta },
6786 { MKTAG('m','i','n','f'), mov_read_default },
6787 { MKTAG('m','o','o','f'), mov_read_moof },
6788 { MKTAG('m','o','o','v'), mov_read_moov },
6789 { MKTAG('m','v','e','x'), mov_read_default },
6790 { MKTAG('m','v','h','d'), mov_read_mvhd },
6791 { MKTAG('S','M','I',' '), mov_read_svq3 },
6792 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6793 { MKTAG('a','v','c','C'), mov_read_glbl },
6794 { MKTAG('p','a','s','p'), mov_read_pasp },
6795 { MKTAG('s','i','d','x'), mov_read_sidx },
6796 { MKTAG('s','t','b','l'), mov_read_default },
6797 { MKTAG('s','t','c','o'), mov_read_stco },
6798 { MKTAG('s','t','p','s'), mov_read_stps },
6799 { MKTAG('s','t','r','f'), mov_read_strf },
6800 { MKTAG('s','t','s','c'), mov_read_stsc },
6801 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6802 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6803 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6804 { MKTAG('s','t','t','s'), mov_read_stts },
6805 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6806 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
6807 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6808 { MKTAG('t','f','d','t'), mov_read_tfdt },
6809 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6810 { MKTAG('t','r','a','k'), mov_read_trak },
6811 { MKTAG('t','r','a','f'), mov_read_default },
6812 { MKTAG('t','r','e','f'), mov_read_default },
6813 { MKTAG('t','m','c','d'), mov_read_tmcd },
6814 { MKTAG('c','h','a','p'), mov_read_chap },
6815 { MKTAG('t','r','e','x'), mov_read_trex },
6816 { MKTAG('t','r','u','n'), mov_read_trun },
6817 { MKTAG('u','d','t','a'), mov_read_default },
6818 { MKTAG('w','a','v','e'), mov_read_wave },
6819 { MKTAG('e','s','d','s'), mov_read_esds },
6820 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6821 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6822 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6823 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6824 { MKTAG('w','f','e','x'), mov_read_wfex },
6825 { MKTAG('c','m','o','v'), mov_read_cmov },
6826 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6827 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6828 { MKTAG('s','b','g','p'), mov_read_sbgp },
6829 { MKTAG('h','v','c','C'), mov_read_glbl },
6830 { MKTAG('u','u','i','d'), mov_read_uuid },
6831 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6832 { MKTAG('f','r','e','e'), mov_read_free },
6833 { MKTAG('-','-','-','-'), mov_read_custom },
6834 { MKTAG('s','i','n','f'), mov_read_default },
6835 { MKTAG('f','r','m','a'), mov_read_frma },
6836 { MKTAG('s','e','n','c'), mov_read_senc },
6837 { MKTAG('s','a','i','z'), mov_read_saiz },
6838 { MKTAG('s','a','i','o'), mov_read_saio },
6839 { MKTAG('p','s','s','h'), mov_read_pssh },
6840 { MKTAG('s','c','h','m'), mov_read_schm },
6841 { MKTAG('s','c','h','i'), mov_read_default },
6842 { MKTAG('t','e','n','c'), mov_read_tenc },
6843 { MKTAG('d','f','L','a'), mov_read_dfla },
6844 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6845 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6846 { MKTAG('d','O','p','s'), mov_read_dops },
6847 { MKTAG('d','m','l','p'), mov_read_dmlp },
6848 { MKTAG('S','m','D','m'), mov_read_smdm },
6849 { MKTAG('C','o','L','L'), mov_read_coll },
6850 { MKTAG('v','p','c','C'), mov_read_vpcc },
6851 { MKTAG('m','d','c','v'), mov_read_mdcv },
6852 { MKTAG('c','l','l','i'), mov_read_clli },
6856 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6858 int64_t total_size = 0;
6862 if (c->atom_depth > 10) {
6863 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6864 return AVERROR_INVALIDDATA;
6869 atom.size = INT64_MAX;
6870 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6871 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
6874 if (atom.size >= 8) {
6875 a.size = avio_rb32(pb);
6876 a.type = avio_rl32(pb);
6877 if (a.type == MKTAG('f','r','e','e') &&
6879 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT &&
6882 uint32_t *type = (uint32_t *)buf + 1;
6883 if (avio_read(pb, buf, 8) != 8)
6884 return AVERROR_INVALIDDATA;
6885 avio_seek(pb, -8, SEEK_CUR);
6886 if (*type == MKTAG('m','v','h','d') ||
6887 *type == MKTAG('c','m','o','v')) {
6888 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free atom.\n");
6889 a.type = MKTAG('m','o','o','v');
6892 if (atom.type != MKTAG('r','o','o','t') &&
6893 atom.type != MKTAG('m','o','o','v'))
6895 if (a.type == MKTAG('t','r','a','k') || a.type == MKTAG('m','d','a','t'))
6897 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
6904 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
6905 a.size = avio_rb64(pb) - 8;
6909 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
6910 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
6912 a.size = atom.size - total_size + 8;
6917 a.size = FFMIN(a.size, atom.size - total_size);
6919 for (i = 0; mov_default_parse_table[i].type; i++)
6920 if (mov_default_parse_table[i].type == a.type) {
6921 parse = mov_default_parse_table[i].parse;
6925 // container is user data
6926 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
6927 atom.type == MKTAG('i','l','s','t')))
6928 parse = mov_read_udta_string;
6930 // Supports parsing the QuickTime Metadata Keys.
6931 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
6932 if (!parse && c->found_hdlr_mdta &&
6933 atom.type == MKTAG('m','e','t','a') &&
6934 a.type == MKTAG('k','e','y','s')) {
6935 parse = mov_read_keys;
6938 if (!parse) { /* skip leaf atoms data */
6939 avio_skip(pb, a.size);
6941 int64_t start_pos = avio_tell(pb);
6943 int err = parse(c, pb, a);
6948 if (c->found_moov && c->found_mdat &&
6949 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
6950 start_pos + a.size == avio_size(pb))) {
6951 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
6952 c->next_root_atom = start_pos + a.size;
6956 left = a.size - avio_tell(pb) + start_pos;
6957 if (left > 0) /* skip garbage at atom end */
6958 avio_skip(pb, left);
6959 else if (left < 0) {
6960 av_log(c->fc, AV_LOG_WARNING,
6961 "overread end of atom '%.4s' by %"PRId64" bytes\n",
6962 (char*)&a.type, -left);
6963 avio_seek(pb, left, SEEK_CUR);
6967 total_size += a.size;
6970 if (total_size < atom.size && atom.size < 0x7ffff)
6971 avio_skip(pb, atom.size - total_size);
6977 static int mov_probe(const AVProbeData *p)
6982 int moov_offset = -1;
6984 /* check file header */
6987 /* ignore invalid offset */
6988 if ((offset + 8) > (unsigned int)p->buf_size)
6990 tag = AV_RL32(p->buf + offset + 4);
6992 /* check for obvious tags */
6993 case MKTAG('m','o','o','v'):
6994 moov_offset = offset + 4;
6995 case MKTAG('m','d','a','t'):
6996 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
6997 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
6998 case MKTAG('f','t','y','p'):
6999 if (AV_RB32(p->buf+offset) < 8 &&
7000 (AV_RB32(p->buf+offset) != 1 ||
7001 offset + 12 > (unsigned int)p->buf_size ||
7002 AV_RB64(p->buf+offset + 8) == 0)) {
7003 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7004 } else if (tag == MKTAG('f','t','y','p') &&
7005 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
7006 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
7008 score = FFMAX(score, 5);
7010 score = AVPROBE_SCORE_MAX;
7012 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7014 /* those are more common words, so rate then a bit less */
7015 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
7016 case MKTAG('w','i','d','e'):
7017 case MKTAG('f','r','e','e'):
7018 case MKTAG('j','u','n','k'):
7019 case MKTAG('p','i','c','t'):
7020 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
7021 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7023 case MKTAG(0x82,0x82,0x7f,0x7d):
7024 case MKTAG('s','k','i','p'):
7025 case MKTAG('u','u','i','d'):
7026 case MKTAG('p','r','f','l'):
7027 /* if we only find those cause probedata is too small at least rate them */
7028 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7029 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7032 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7035 if(score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
7036 /* moov atom in the header - we should make sure that this is not a
7037 * MOV-packed MPEG-PS */
7038 offset = moov_offset;
7040 while(offset < (p->buf_size - 16)){ /* Sufficient space */
7041 /* We found an actual hdlr atom */
7042 if(AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7043 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7044 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')){
7045 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7046 /* We found a media handler reference atom describing an
7047 * MPEG-PS-in-MOV, return a
7048 * low score to force expanding the probe window until
7049 * mpegps_probe finds what it needs */
7060 // must be done after parsing all trak because there's no order requirement
7061 static void mov_read_chapters(AVFormatContext *s)
7063 MOVContext *mov = s->priv_data;
7065 MOVStreamContext *sc;
7070 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7071 chapter_track = mov->chapter_tracks[j];
7073 for (i = 0; i < s->nb_streams; i++)
7074 if (s->streams[i]->id == chapter_track) {
7079 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7084 cur_pos = avio_tell(sc->pb);
7086 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7087 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7088 if (st->nb_index_entries) {
7089 // Retrieve the first frame, if possible
7091 AVIndexEntry *sample = &st->index_entries[0];
7092 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7093 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7097 if (av_get_packet(sc->pb, &pkt, sample->size) < 0)
7100 st->attached_pic = pkt;
7101 st->attached_pic.stream_index = st->index;
7102 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
7105 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7106 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7107 st->discard = AVDISCARD_ALL;
7108 for (i = 0; i < st->nb_index_entries; i++) {
7109 AVIndexEntry *sample = &st->index_entries[i];
7110 int64_t end = i+1 < st->nb_index_entries ? st->index_entries[i+1].timestamp : st->duration;
7115 if (end < sample->timestamp) {
7116 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7117 end = AV_NOPTS_VALUE;
7120 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7121 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7125 // the first two bytes are the length of the title
7126 len = avio_rb16(sc->pb);
7127 if (len > sample->size-2)
7129 title_len = 2*len + 1;
7130 if (!(title = av_mallocz(title_len)))
7133 // The samples could theoretically be in any encoding if there's an encd
7134 // atom following, but in practice are only utf-8 or utf-16, distinguished
7135 // instead by the presence of a BOM
7139 ch = avio_rb16(sc->pb);
7141 avio_get_str16be(sc->pb, len, title, title_len);
7142 else if (ch == 0xfffe)
7143 avio_get_str16le(sc->pb, len, title, title_len);
7146 if (len == 1 || len == 2)
7149 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7153 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7158 avio_seek(sc->pb, cur_pos, SEEK_SET);
7162 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7163 uint32_t value, int flags)
7166 char buf[AV_TIMECODE_STR_SIZE];
7167 AVRational rate = st->avg_frame_rate;
7168 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7171 av_dict_set(&st->metadata, "timecode",
7172 av_timecode_make_string(&tc, buf, value), 0);
7176 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7178 MOVStreamContext *sc = st->priv_data;
7179 char buf[AV_TIMECODE_STR_SIZE];
7180 int64_t cur_pos = avio_tell(sc->pb);
7181 int hh, mm, ss, ff, drop;
7183 if (!st->nb_index_entries)
7186 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7187 avio_skip(s->pb, 13);
7188 hh = avio_r8(s->pb);
7189 mm = avio_r8(s->pb);
7190 ss = avio_r8(s->pb);
7191 drop = avio_r8(s->pb);
7192 ff = avio_r8(s->pb);
7193 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7194 hh, mm, ss, drop ? ';' : ':', ff);
7195 av_dict_set(&st->metadata, "timecode", buf, 0);
7197 avio_seek(sc->pb, cur_pos, SEEK_SET);
7201 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7203 MOVStreamContext *sc = st->priv_data;
7205 int64_t cur_pos = avio_tell(sc->pb);
7208 if (!st->nb_index_entries)
7211 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7212 value = avio_rb32(s->pb);
7214 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7215 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7216 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7218 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7219 * not the case) and thus assume "frame number format" instead of QT one.
7220 * No sample with tmcd track can be found with a QT timecode at the moment,
7221 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7223 parse_timecode_in_framenum_format(s, st, value, flags);
7225 avio_seek(sc->pb, cur_pos, SEEK_SET);
7229 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7231 if (!index || !*index) return;
7232 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7233 av_encryption_info_free((*index)->encrypted_samples[i]);
7235 av_freep(&(*index)->encrypted_samples);
7236 av_freep(&(*index)->auxiliary_info_sizes);
7237 av_freep(&(*index)->auxiliary_offsets);
7241 static int mov_read_close(AVFormatContext *s)
7243 MOVContext *mov = s->priv_data;
7246 for (i = 0; i < s->nb_streams; i++) {
7247 AVStream *st = s->streams[i];
7248 MOVStreamContext *sc = st->priv_data;
7253 av_freep(&sc->ctts_data);
7254 for (j = 0; j < sc->drefs_count; j++) {
7255 av_freep(&sc->drefs[j].path);
7256 av_freep(&sc->drefs[j].dir);
7258 av_freep(&sc->drefs);
7260 sc->drefs_count = 0;
7262 if (!sc->pb_is_copied)
7263 ff_format_io_close(s, &sc->pb);
7266 av_freep(&sc->chunk_offsets);
7267 av_freep(&sc->stsc_data);
7268 av_freep(&sc->sample_sizes);
7269 av_freep(&sc->keyframes);
7270 av_freep(&sc->stts_data);
7271 av_freep(&sc->sdtp_data);
7272 av_freep(&sc->stps_data);
7273 av_freep(&sc->elst_data);
7274 av_freep(&sc->rap_group);
7275 av_freep(&sc->display_matrix);
7276 av_freep(&sc->index_ranges);
7279 for (j = 0; j < sc->stsd_count; j++)
7280 av_free(sc->extradata[j]);
7281 av_freep(&sc->extradata);
7282 av_freep(&sc->extradata_size);
7284 mov_free_encryption_index(&sc->cenc.encryption_index);
7285 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7286 av_aes_ctr_free(sc->cenc.aes_ctr);
7288 av_freep(&sc->stereo3d);
7289 av_freep(&sc->spherical);
7290 av_freep(&sc->mastering);
7291 av_freep(&sc->coll);
7294 if (mov->dv_demux) {
7295 avformat_free_context(mov->dv_fctx);
7296 mov->dv_fctx = NULL;
7299 if (mov->meta_keys) {
7300 for (i = 1; i < mov->meta_keys_count; i++) {
7301 av_freep(&mov->meta_keys[i]);
7303 av_freep(&mov->meta_keys);
7306 av_freep(&mov->trex_data);
7307 av_freep(&mov->bitrates);
7309 for (i = 0; i < mov->frag_index.nb_items; i++) {
7310 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7311 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7312 mov_free_encryption_index(&frag[j].encryption_index);
7314 av_freep(&mov->frag_index.item[i].stream_info);
7316 av_freep(&mov->frag_index.item);
7318 av_freep(&mov->aes_decrypt);
7319 av_freep(&mov->chapter_tracks);
7324 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7328 for (i = 0; i < s->nb_streams; i++) {
7329 AVStream *st = s->streams[i];
7330 MOVStreamContext *sc = st->priv_data;
7332 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7333 sc->timecode_track == tmcd_id)
7339 /* look for a tmcd track not referenced by any video track, and export it globally */
7340 static void export_orphan_timecode(AVFormatContext *s)
7344 for (i = 0; i < s->nb_streams; i++) {
7345 AVStream *st = s->streams[i];
7347 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7348 !tmcd_is_referenced(s, i + 1)) {
7349 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7351 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7358 static int read_tfra(MOVContext *mov, AVIOContext *f)
7360 int version, fieldlength, i, j;
7361 int64_t pos = avio_tell(f);
7362 uint32_t size = avio_rb32(f);
7363 unsigned track_id, item_count;
7365 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7368 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7370 version = avio_r8(f);
7372 track_id = avio_rb32(f);
7373 fieldlength = avio_rb32(f);
7374 item_count = avio_rb32(f);
7375 for (i = 0; i < item_count; i++) {
7376 int64_t time, offset;
7378 MOVFragmentStreamInfo * frag_stream_info;
7381 return AVERROR_INVALIDDATA;
7385 time = avio_rb64(f);
7386 offset = avio_rb64(f);
7388 time = avio_rb32(f);
7389 offset = avio_rb32(f);
7392 // The first sample of each stream in a fragment is always a random
7393 // access sample. So it's entry in the tfra can be used as the
7394 // initial PTS of the fragment.
7395 index = update_frag_index(mov, offset);
7396 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7397 if (frag_stream_info &&
7398 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7399 frag_stream_info->first_tfra_pts = time;
7401 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7403 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7405 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7409 avio_seek(f, pos + size, SEEK_SET);
7413 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7415 int64_t stream_size = avio_size(f);
7416 int64_t original_pos = avio_tell(f);
7420 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7424 mfra_size = avio_rb32(f);
7425 if (mfra_size < 0 || mfra_size > stream_size) {
7426 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7429 if ((seek_ret = avio_seek(f, -mfra_size, SEEK_CUR)) < 0) {
7433 if (avio_rb32(f) != mfra_size) {
7434 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7437 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7438 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7441 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7443 ret = read_tfra(c, f);
7449 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7451 av_log(c->fc, AV_LOG_ERROR,
7452 "failed to seek back after looking for mfra\n");
7458 static int mov_read_header(AVFormatContext *s)
7460 MOVContext *mov = s->priv_data;
7461 AVIOContext *pb = s->pb;
7463 MOVAtom atom = { AV_RL32("root") };
7466 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7467 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7468 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7469 return AVERROR(EINVAL);
7473 mov->trak_index = -1;
7474 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7475 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7476 atom.size = avio_size(pb);
7478 atom.size = INT64_MAX;
7480 /* check MOV header */
7482 if (mov->moov_retry)
7483 avio_seek(pb, 0, SEEK_SET);
7484 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7485 av_log(s, AV_LOG_ERROR, "error reading header\n");
7489 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7490 if (!mov->found_moov) {
7491 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7493 return AVERROR_INVALIDDATA;
7495 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7497 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7498 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7499 mov_read_chapters(s);
7500 for (i = 0; i < s->nb_streams; i++)
7501 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7502 mov_read_timecode_track(s, s->streams[i]);
7503 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7504 mov_read_rtmd_track(s, s->streams[i]);
7508 /* copy timecode metadata from tmcd tracks to the related video streams */
7509 for (i = 0; i < s->nb_streams; i++) {
7510 AVStream *st = s->streams[i];
7511 MOVStreamContext *sc = st->priv_data;
7512 if (sc->timecode_track > 0) {
7513 AVDictionaryEntry *tcr;
7514 int tmcd_st_id = -1;
7516 for (j = 0; j < s->nb_streams; j++)
7517 if (s->streams[j]->id == sc->timecode_track)
7520 if (tmcd_st_id < 0 || tmcd_st_id == i)
7522 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7524 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7527 export_orphan_timecode(s);
7529 for (i = 0; i < s->nb_streams; i++) {
7530 AVStream *st = s->streams[i];
7531 MOVStreamContext *sc = st->priv_data;
7532 fix_timescale(mov, sc);
7533 if(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7534 st->skip_samples = sc->start_pad;
7536 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7537 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7538 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7539 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7540 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7541 st->codecpar->width = sc->width;
7542 st->codecpar->height = sc->height;
7544 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7545 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7549 if (mov->handbrake_version &&
7550 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7551 st->codecpar->codec_id == AV_CODEC_ID_MP3
7553 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7554 st->need_parsing = AVSTREAM_PARSE_FULL;
7558 if (mov->trex_data) {
7559 for (i = 0; i < s->nb_streams; i++) {
7560 AVStream *st = s->streams[i];
7561 MOVStreamContext *sc = st->priv_data;
7562 if (st->duration > 0) {
7563 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7564 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7565 sc->data_size, sc->time_scale);
7567 return AVERROR_INVALIDDATA;
7569 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7574 if (mov->use_mfra_for > 0) {
7575 for (i = 0; i < s->nb_streams; i++) {
7576 AVStream *st = s->streams[i];
7577 MOVStreamContext *sc = st->priv_data;
7578 if (sc->duration_for_fps > 0) {
7579 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7580 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7581 sc->data_size, sc->time_scale);
7583 return AVERROR_INVALIDDATA;
7585 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7586 sc->duration_for_fps;
7591 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7592 if (mov->bitrates[i]) {
7593 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7597 ff_rfps_calculate(s);
7599 for (i = 0; i < s->nb_streams; i++) {
7600 AVStream *st = s->streams[i];
7601 MOVStreamContext *sc = st->priv_data;
7603 switch (st->codecpar->codec_type) {
7604 case AVMEDIA_TYPE_AUDIO:
7605 err = ff_replaygain_export(st, s->metadata);
7611 case AVMEDIA_TYPE_VIDEO:
7612 if (sc->display_matrix) {
7613 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7614 sizeof(int32_t) * 9);
7618 sc->display_matrix = NULL;
7621 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7622 (uint8_t *)sc->stereo3d,
7623 sizeof(*sc->stereo3d));
7627 sc->stereo3d = NULL;
7629 if (sc->spherical) {
7630 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7631 (uint8_t *)sc->spherical,
7632 sc->spherical_size);
7636 sc->spherical = NULL;
7638 if (sc->mastering) {
7639 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7640 (uint8_t *)sc->mastering,
7641 sizeof(*sc->mastering));
7645 sc->mastering = NULL;
7648 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7649 (uint8_t *)sc->coll,
7659 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7661 for (i = 0; i < mov->frag_index.nb_items; i++)
7662 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7663 mov->frag_index.item[i].headers_read = 1;
7668 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7670 AVIndexEntry *sample = NULL;
7671 int64_t best_dts = INT64_MAX;
7673 for (i = 0; i < s->nb_streams; i++) {
7674 AVStream *avst = s->streams[i];
7675 MOVStreamContext *msc = avst->priv_data;
7676 if (msc->pb && msc->current_sample < avst->nb_index_entries) {
7677 AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample];
7678 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7679 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7680 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7681 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7682 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb &&
7683 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7684 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7685 sample = current_sample;
7694 static int should_retry(AVIOContext *pb, int error_code) {
7695 if (error_code == AVERROR_EOF || avio_feof(pb))
7701 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7704 MOVContext *mov = s->priv_data;
7706 if (index >= 0 && index < mov->frag_index.nb_items)
7707 target = mov->frag_index.item[index].moof_offset;
7708 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7709 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7710 return AVERROR_INVALIDDATA;
7713 mov->next_root_atom = 0;
7714 if (index < 0 || index >= mov->frag_index.nb_items)
7715 index = search_frag_moof_offset(&mov->frag_index, target);
7716 if (index < mov->frag_index.nb_items) {
7717 if (index + 1 < mov->frag_index.nb_items)
7718 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7719 if (mov->frag_index.item[index].headers_read)
7721 mov->frag_index.item[index].headers_read = 1;
7724 mov->found_mdat = 0;
7726 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7729 if (avio_feof(s->pb))
7731 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7736 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7738 uint8_t *side, *extradata;
7741 /* Save the current index. */
7742 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7744 /* Notify the decoder that extradata changed. */
7745 extradata_size = sc->extradata_size[sc->last_stsd_index];
7746 extradata = sc->extradata[sc->last_stsd_index];
7747 if (extradata_size > 0 && extradata) {
7748 side = av_packet_new_side_data(pkt,
7749 AV_PKT_DATA_NEW_EXTRADATA,
7752 return AVERROR(ENOMEM);
7753 memcpy(side, extradata, extradata_size);
7759 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7761 MOVContext *mov = s->priv_data;
7762 MOVStreamContext *sc;
7763 AVIndexEntry *sample;
7764 AVStream *st = NULL;
7765 int64_t current_index;
7769 sample = mov_find_next_sample(s, &st);
7770 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7771 if (!mov->next_root_atom)
7773 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7778 /* must be done just before reading, to avoid infinite loop on sample */
7779 current_index = sc->current_index;
7780 mov_current_sample_inc(sc);
7782 if (mov->next_root_atom) {
7783 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7784 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7787 if (st->discard != AVDISCARD_ALL) {
7788 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7789 if (ret64 != sample->pos) {
7790 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7791 sc->ffindex, sample->pos);
7792 if (should_retry(sc->pb, ret64)) {
7793 mov_current_sample_dec(sc);
7795 return AVERROR_INVALIDDATA;
7798 if( st->discard == AVDISCARD_NONKEY && 0==(sample->flags & AVINDEX_KEYFRAME) ) {
7799 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7803 ret = av_get_packet(sc->pb, pkt, sample->size);
7805 if (should_retry(sc->pb, ret)) {
7806 mov_current_sample_dec(sc);
7810 if (sc->has_palette) {
7813 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7815 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7817 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7818 sc->has_palette = 0;
7821 #if CONFIG_DV_DEMUXER
7822 if (mov->dv_demux && sc->dv_audio_container) {
7823 avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7824 av_freep(&pkt->data);
7826 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7831 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7832 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7833 st->need_parsing = AVSTREAM_PARSE_FULL;
7837 pkt->stream_index = sc->ffindex;
7838 pkt->dts = sample->timestamp;
7839 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7840 pkt->flags |= AV_PKT_FLAG_DISCARD;
7842 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7843 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
7844 /* update ctts context */
7846 if (sc->ctts_index < sc->ctts_count &&
7847 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
7849 sc->ctts_sample = 0;
7852 int64_t next_dts = (sc->current_sample < st->nb_index_entries) ?
7853 st->index_entries[sc->current_sample].timestamp : st->duration;
7855 if (next_dts >= pkt->dts)
7856 pkt->duration = next_dts - pkt->dts;
7857 pkt->pts = pkt->dts;
7859 if (st->discard == AVDISCARD_ALL)
7861 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
7862 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
7863 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
7864 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
7866 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
7867 pkt->pos = sample->pos;
7869 /* Multiple stsd handling. */
7870 if (sc->stsc_data) {
7871 /* Keep track of the stsc index for the given sample, then check
7872 * if the stsd index is different from the last used one. */
7874 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
7875 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
7877 sc->stsc_sample = 0;
7878 /* Do not check indexes after a switch. */
7879 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
7880 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
7881 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
7882 ret = mov_change_extradata(sc, pkt);
7889 aax_filter(pkt->data, pkt->size, mov);
7891 ret = cenc_filter(mov, st, sc, pkt, current_index);
7893 av_packet_unref(pkt);
7900 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
7902 MOVContext *mov = s->priv_data;
7905 if (!mov->frag_index.complete)
7908 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
7911 if (!mov->frag_index.item[index].headers_read)
7912 return mov_switch_root(s, -1, index);
7913 if (index + 1 < mov->frag_index.nb_items)
7914 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7919 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
7921 MOVStreamContext *sc = st->priv_data;
7922 int sample, time_sample, ret;
7925 // Here we consider timestamp to be PTS, hence try to offset it so that we
7926 // can search over the DTS timeline.
7927 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
7929 ret = mov_seek_fragment(s, st, timestamp);
7933 sample = av_index_search_timestamp(st, timestamp, flags);
7934 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
7935 if (sample < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp)
7937 if (sample < 0) /* not sure what to do */
7938 return AVERROR_INVALIDDATA;
7939 mov_current_sample_set(sc, sample);
7940 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
7941 /* adjust ctts index */
7942 if (sc->ctts_data) {
7944 for (i = 0; i < sc->ctts_count; i++) {
7945 int next = time_sample + sc->ctts_data[i].count;
7946 if (next > sc->current_sample) {
7948 sc->ctts_sample = sc->current_sample - time_sample;
7955 /* adjust stsd index */
7956 if (sc->chunk_count) {
7958 for (i = 0; i < sc->stsc_count; i++) {
7959 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
7960 if (next > sc->current_sample) {
7962 sc->stsc_sample = sc->current_sample - time_sample;
7965 av_assert0(next == (int)next);
7973 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
7975 MOVContext *mc = s->priv_data;
7980 if (stream_index >= s->nb_streams)
7981 return AVERROR_INVALIDDATA;
7983 st = s->streams[stream_index];
7984 sample = mov_seek_stream(s, st, sample_time, flags);
7988 if (mc->seek_individually) {
7989 /* adjust seek timestamp to found sample timestamp */
7990 int64_t seek_timestamp = st->index_entries[sample].timestamp;
7992 for (i = 0; i < s->nb_streams; i++) {
7994 MOVStreamContext *sc = s->streams[i]->priv_data;
7996 st->skip_samples = (sample_time <= 0) ? sc->start_pad : 0;
7998 if (stream_index == i)
8001 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
8002 mov_seek_stream(s, st, timestamp, flags);
8005 for (i = 0; i < s->nb_streams; i++) {
8006 MOVStreamContext *sc;
8009 mov_current_sample_set(sc, 0);
8012 MOVStreamContext *sc;
8013 AVIndexEntry *entry = mov_find_next_sample(s, &st);
8015 return AVERROR_INVALIDDATA;
8017 if (sc->ffindex == stream_index && sc->current_sample == sample)
8019 mov_current_sample_inc(sc);
8025 #define OFFSET(x) offsetof(MOVContext, x)
8026 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
8027 static const AVOption mov_options[] = {
8028 {"use_absolute_path",
8029 "allow using absolute path when opening alias, this is a possible security issue",
8030 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
8032 {"seek_streams_individually",
8033 "Seek each stream individually to the closest point",
8034 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
8036 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
8038 {"advanced_editlist",
8039 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
8040 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
8042 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8045 "use mfra for fragment timestamps",
8046 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8047 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8049 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8050 FLAGS, "use_mfra_for" },
8051 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8052 FLAGS, "use_mfra_for" },
8053 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8054 FLAGS, "use_mfra_for" },
8055 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8056 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8057 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8058 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8059 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8060 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8061 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8062 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8063 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8064 .flags = AV_OPT_FLAG_DECODING_PARAM },
8065 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8066 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8067 {.i64 = 0}, 0, 1, FLAGS },
8072 static const AVClass mov_class = {
8073 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8074 .item_name = av_default_item_name,
8075 .option = mov_options,
8076 .version = LIBAVUTIL_VERSION_INT,
8079 AVInputFormat ff_mov_demuxer = {
8080 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8081 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8082 .priv_class = &mov_class,
8083 .priv_data_size = sizeof(MOVContext),
8084 .extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
8085 .read_probe = mov_probe,
8086 .read_header = mov_read_header,
8087 .read_packet = mov_read_packet,
8088 .read_close = mov_read_close,
8089 .read_seek = mov_read_seek,
8090 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,