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 "libavutil/dovi_meta.h"
50 #include "libavcodec/ac3tab.h"
51 #include "libavcodec/flac.h"
52 #include "libavcodec/mpegaudiodecheader.h"
53 #include "libavcodec/mlp_parse.h"
56 #include "avio_internal.h"
59 #include "libavcodec/get_bits.h"
62 #include "replaygain.h"
68 #include "qtpalette.h"
70 /* those functions parse an atom */
71 /* links atom IDs to parse functions */
72 typedef struct MOVParseTableEntry {
74 int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
77 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
78 static int mov_read_mfra(MOVContext *c, AVIOContext *f);
79 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
80 int count, int duration);
82 static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb,
83 unsigned len, const char *key)
87 short current, total = 0;
88 avio_rb16(pb); // unknown
89 current = avio_rb16(pb);
91 total = avio_rb16(pb);
93 snprintf(buf, sizeof(buf), "%d", current);
95 snprintf(buf, sizeof(buf), "%d/%d", current, total);
96 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
97 av_dict_set(&c->fc->metadata, key, buf, 0);
102 static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb,
103 unsigned len, const char *key)
105 /* bypass padding bytes */
110 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
111 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
116 static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb,
117 unsigned len, const char *key)
119 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
120 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
125 static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb,
126 unsigned len, const char *key)
130 avio_r8(pb); // unknown
133 if (genre < 1 || genre > ID3v1_GENRE_MAX)
135 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
136 av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
141 static const uint32_t mac_to_unicode[128] = {
142 0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
143 0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
144 0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
145 0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
146 0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
147 0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
148 0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
149 0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
150 0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
151 0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
152 0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
153 0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
154 0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
155 0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
156 0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
157 0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
160 static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len,
161 char *dst, int dstlen)
164 char *end = dst+dstlen-1;
167 for (i = 0; i < len; i++) {
168 uint8_t t, c = avio_r8(pb);
176 PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
182 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, &st->attached_pic, len);
211 if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) {
212 if (AV_RB64(st->attached_pic.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.stream_index = st->index;
222 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
224 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
225 st->codecpar->codec_id = id;
231 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
233 char language[4] = { 0 };
234 char buf[200], place[100];
235 uint16_t langcode = 0;
236 double longitude, latitude, altitude;
237 const char *key = "location";
239 if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
240 av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
241 return AVERROR_INVALIDDATA;
244 avio_skip(pb, 4); // version+flags
245 langcode = avio_rb16(pb);
246 ff_mov_lang_to_iso639(langcode, language);
249 len -= avio_get_str(pb, len, place, sizeof(place));
251 av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
252 return AVERROR_INVALIDDATA;
254 avio_skip(pb, 1); // role
258 av_log(c->fc, AV_LOG_ERROR,
259 "loci too short (%u bytes left, need at least %d)\n", len, 12);
260 return AVERROR_INVALIDDATA;
262 longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
263 latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
264 altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
266 // Try to output in the same format as the ?xyz field
267 snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
269 av_strlcatf(buf, sizeof(buf), "%+f", altitude);
270 av_strlcatf(buf, sizeof(buf), "/%s", place);
272 if (*language && strcmp(language, "und")) {
274 snprintf(key2, sizeof(key2), "%s-%s", key, language);
275 av_dict_set(&c->fc->metadata, key2, buf, 0);
277 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
278 return av_dict_set(&c->fc->metadata, key, buf, 0);
281 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
287 if (c->ignore_chapters)
290 n_hmmt = avio_rb32(pb);
291 for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
292 int moment_time = avio_rb32(pb);
293 avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
298 static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
301 char key2[32], language[4] = {0};
303 const char *key = NULL;
304 uint16_t langcode = 0;
305 uint32_t data_type = 0, str_size, str_size_alloc;
306 int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
311 case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
312 case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
313 case MKTAG( 'X','M','P','_'):
314 if (c->export_xmp) { key = "xmp"; raw = 1; } break;
315 case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
316 case MKTAG( 'a','k','I','D'): key = "account_type";
317 parse = mov_metadata_int8_no_padding; break;
318 case MKTAG( 'a','p','I','D'): key = "account_id"; break;
319 case MKTAG( 'c','a','t','g'): key = "category"; break;
320 case MKTAG( 'c','p','i','l'): key = "compilation";
321 parse = mov_metadata_int8_no_padding; break;
322 case MKTAG( 'c','p','r','t'): key = "copyright"; break;
323 case MKTAG( 'd','e','s','c'): key = "description"; break;
324 case MKTAG( 'd','i','s','k'): key = "disc";
325 parse = mov_metadata_track_or_disc_number; break;
326 case MKTAG( 'e','g','i','d'): key = "episode_uid";
327 parse = mov_metadata_int8_no_padding; break;
328 case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
329 case MKTAG( 'g','n','r','e'): key = "genre";
330 parse = mov_metadata_gnre; break;
331 case MKTAG( 'h','d','v','d'): key = "hd_video";
332 parse = mov_metadata_int8_no_padding; break;
333 case MKTAG( 'H','M','M','T'):
334 return mov_metadata_hmmt(c, pb, atom.size);
335 case MKTAG( 'k','e','y','w'): key = "keywords"; break;
336 case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
337 case MKTAG( 'l','o','c','i'):
338 return mov_metadata_loci(c, pb, atom.size);
339 case MKTAG( 'm','a','n','u'): key = "make"; break;
340 case MKTAG( 'm','o','d','l'): key = "model"; break;
341 case MKTAG( 'p','c','s','t'): key = "podcast";
342 parse = mov_metadata_int8_no_padding; break;
343 case MKTAG( 'p','g','a','p'): key = "gapless_playback";
344 parse = mov_metadata_int8_no_padding; break;
345 case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
346 case MKTAG( 'r','t','n','g'): key = "rating";
347 parse = mov_metadata_int8_no_padding; break;
348 case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
349 case MKTAG( 's','o','a','l'): key = "sort_album"; break;
350 case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
351 case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
352 case MKTAG( 's','o','n','m'): key = "sort_name"; break;
353 case MKTAG( 's','o','s','n'): key = "sort_show"; break;
354 case MKTAG( 's','t','i','k'): key = "media_type";
355 parse = mov_metadata_int8_no_padding; break;
356 case MKTAG( 't','r','k','n'): key = "track";
357 parse = mov_metadata_track_or_disc_number; break;
358 case MKTAG( 't','v','e','n'): key = "episode_id"; break;
359 case MKTAG( 't','v','e','s'): key = "episode_sort";
360 parse = mov_metadata_int8_bypass_padding; break;
361 case MKTAG( 't','v','n','n'): key = "network"; break;
362 case MKTAG( 't','v','s','h'): key = "show"; break;
363 case MKTAG( 't','v','s','n'): key = "season_number";
364 parse = mov_metadata_int8_bypass_padding; break;
365 case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
366 case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
367 case MKTAG(0xa9,'a','l','b'): key = "album"; break;
368 case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
369 case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
370 case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
371 case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
372 case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
373 case MKTAG(0xa9,'d','a','y'): key = "date"; break;
374 case MKTAG(0xa9,'d','i','r'): key = "director"; break;
375 case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
376 case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
377 case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
378 case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
379 case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
380 case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
381 case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
382 case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
383 case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
384 case MKTAG(0xa9,'m','a','k'): key = "make"; break;
385 case MKTAG(0xa9,'m','o','d'): key = "model"; break;
386 case MKTAG(0xa9,'n','a','m'): key = "title"; break;
387 case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
388 case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
389 case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
390 case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
391 case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
392 case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
393 case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
394 case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
395 case MKTAG(0xa9,'t','r','k'): key = "track"; break;
396 case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
397 case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
398 case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
399 case MKTAG(0xa9,'x','y','z'): key = "location"; break;
402 if (c->itunes_metadata && atom.size > 8) {
403 int data_size = avio_rb32(pb);
404 int tag = avio_rl32(pb);
405 if (tag == MKTAG('d','a','t','a') && data_size <= atom.size) {
406 data_type = avio_rb32(pb); // type
407 avio_rb32(pb); // unknown
408 str_size = data_size - 16;
411 if (atom.type == MKTAG('c', 'o', 'v', 'r')) {
412 int ret = mov_read_covr(c, pb, data_type, str_size);
414 av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
417 atom.size -= str_size;
421 } else if (!key && c->found_hdlr_mdta && c->meta_keys) {
422 uint32_t index = AV_RB32(&atom.type);
423 if (index < c->meta_keys_count && index > 0) {
424 key = c->meta_keys[index];
426 av_log(c->fc, AV_LOG_WARNING,
427 "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
428 index, c->meta_keys_count);
432 } else if (atom.size > 4 && key && !c->itunes_metadata && !raw) {
433 str_size = avio_rb16(pb); // string length
434 if (str_size > atom.size) {
436 avio_seek(pb, -2, SEEK_CUR);
437 av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
440 langcode = avio_rb16(pb);
441 ff_mov_lang_to_iso639(langcode, language);
444 str_size = atom.size;
446 if (c->export_all && !key) {
447 snprintf(tmp_key, 5, "%.4s", (char*)&atom.type);
453 if (atom.size < 0 || str_size >= INT_MAX/2)
454 return AVERROR_INVALIDDATA;
456 // Allocates enough space if data_type is a int32 or float32 number, otherwise
457 // worst-case requirement for output string in case of utf8 coded input
458 num = (data_type >= 21 && data_type <= 23);
459 str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
460 str = av_mallocz(str_size_alloc);
462 return AVERROR(ENOMEM);
465 parse(c, pb, str_size, key);
467 if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
468 mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
469 } else if (data_type == 21) { // BE signed integer, variable size
472 val = (int8_t)avio_r8(pb);
473 else if (str_size == 2)
474 val = (int16_t)avio_rb16(pb);
475 else if (str_size == 3)
476 val = ((int32_t)(avio_rb24(pb)<<8))>>8;
477 else if (str_size == 4)
478 val = (int32_t)avio_rb32(pb);
479 if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
480 av_log(c->fc, AV_LOG_ERROR,
481 "Failed to store the number (%d) in string.\n", val);
483 return AVERROR_INVALIDDATA;
485 } else if (data_type == 22) { // BE unsigned integer, variable size
486 unsigned int val = 0;
489 else if (str_size == 2)
491 else if (str_size == 3)
493 else if (str_size == 4)
495 if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
496 av_log(c->fc, AV_LOG_ERROR,
497 "Failed to store the number (%u) in string.\n", val);
499 return AVERROR_INVALIDDATA;
501 } else if (data_type == 23 && str_size >= 4) { // BE float32
502 float val = av_int2float(avio_rb32(pb));
503 if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
504 av_log(c->fc, AV_LOG_ERROR,
505 "Failed to store the float32 number (%f) in string.\n", val);
507 return AVERROR_INVALIDDATA;
510 int ret = ffio_read_size(pb, str, str_size);
517 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
518 av_dict_set(&c->fc->metadata, key, str, 0);
519 if (*language && strcmp(language, "und")) {
520 snprintf(key2, sizeof(key2), "%s-%s", key, language);
521 av_dict_set(&c->fc->metadata, key2, str, 0);
523 if (!strcmp(key, "encoder")) {
524 int major, minor, micro;
525 if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, µ) == 3) {
526 c->handbrake_version = 1000000*major + 1000*minor + micro;
535 static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
538 int i, nb_chapters, str_len, version;
542 if (c->ignore_chapters)
545 if ((atom.size -= 5) < 0)
548 version = avio_r8(pb);
551 avio_rb32(pb); // ???
552 nb_chapters = avio_r8(pb);
554 for (i = 0; i < nb_chapters; i++) {
558 start = avio_rb64(pb);
559 str_len = avio_r8(pb);
561 if ((atom.size -= 9+str_len) < 0)
564 ret = ffio_read_size(pb, str, str_len);
568 avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
573 #define MIN_DATA_ENTRY_BOX_SIZE 12
574 static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
577 MOVStreamContext *sc;
580 if (c->fc->nb_streams < 1)
582 st = c->fc->streams[c->fc->nb_streams-1];
585 avio_rb32(pb); // version + flags
586 entries = avio_rb32(pb);
588 entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
589 entries >= UINT_MAX / sizeof(*sc->drefs))
590 return AVERROR_INVALIDDATA;
594 sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
596 return AVERROR(ENOMEM);
597 sc->drefs_count = entries;
599 for (i = 0; i < entries; i++) {
600 MOVDref *dref = &sc->drefs[i];
601 uint32_t size = avio_rb32(pb);
602 int64_t next = avio_tell(pb) + size - 4;
605 return AVERROR_INVALIDDATA;
607 dref->type = avio_rl32(pb);
608 avio_rb32(pb); // version + flags
610 if (dref->type == MKTAG('a','l','i','s') && size > 150) {
611 /* macintosh alias record */
612 uint16_t volume_len, len;
618 volume_len = avio_r8(pb);
619 volume_len = FFMIN(volume_len, 27);
620 ret = ffio_read_size(pb, dref->volume, 27);
623 dref->volume[volume_len] = 0;
624 av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
629 len = FFMIN(len, 63);
630 ret = ffio_read_size(pb, dref->filename, 63);
633 dref->filename[len] = 0;
634 av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
638 /* read next level up_from_alias/down_to_target */
639 dref->nlvl_from = avio_rb16(pb);
640 dref->nlvl_to = avio_rb16(pb);
641 av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
642 dref->nlvl_from, dref->nlvl_to);
646 for (type = 0; type != -1 && avio_tell(pb) < next; ) {
649 type = avio_rb16(pb);
651 av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
654 if (type == 2) { // absolute path
656 dref->path = av_mallocz(len+1);
658 return AVERROR(ENOMEM);
660 ret = ffio_read_size(pb, dref->path, len);
662 av_freep(&dref->path);
665 if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
667 memmove(dref->path, dref->path+volume_len, len);
670 // trim string of any ending zeros
671 for (j = len - 1; j >= 0; j--) {
672 if (dref->path[j] == 0)
677 for (j = 0; j < len; j++)
678 if (dref->path[j] == ':' || dref->path[j] == 0)
680 av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
681 } else if (type == 0) { // directory name
683 dref->dir = av_malloc(len+1);
685 return AVERROR(ENOMEM);
687 ret = ffio_read_size(pb, dref->dir, len);
689 av_freep(&dref->dir);
693 for (j = 0; j < len; j++)
694 if (dref->dir[j] == ':')
696 av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
701 av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
706 avio_seek(pb, next, SEEK_SET);
711 static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
720 avio_r8(pb); /* version */
721 avio_rb24(pb); /* flags */
724 ctype = avio_rl32(pb);
725 type = avio_rl32(pb); /* component subtype */
727 av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
728 av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
730 if (c->trak_index < 0) { // meta not inside a trak
731 if (type == MKTAG('m','d','t','a')) {
732 c->found_hdlr_mdta = 1;
737 st = c->fc->streams[c->fc->nb_streams-1];
739 if (type == MKTAG('v','i','d','e'))
740 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
741 else if (type == MKTAG('s','o','u','n'))
742 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
743 else if (type == MKTAG('m','1','a',' '))
744 st->codecpar->codec_id = AV_CODEC_ID_MP2;
745 else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
746 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
748 avio_rb32(pb); /* component manufacture */
749 avio_rb32(pb); /* component flags */
750 avio_rb32(pb); /* component flags mask */
752 title_size = atom.size - 24;
753 if (title_size > 0) {
754 if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
755 return AVERROR_INVALIDDATA;
756 title_str = av_malloc(title_size + 1); /* Add null terminator */
758 return AVERROR(ENOMEM);
760 ret = ffio_read_size(pb, title_str, title_size);
762 av_freep(&title_str);
765 title_str[title_size] = 0;
767 int off = (!c->isom && title_str[0] == title_size - 1);
768 // flag added so as to not set stream handler name if already set from mdia->hdlr
769 av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
771 av_freep(&title_str);
777 static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
779 return ff_mov_read_esds(c->fc, pb);
782 static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
785 enum AVAudioServiceType *ast;
786 int ac3info, acmod, lfeon, bsmod;
788 if (c->fc->nb_streams < 1)
790 st = c->fc->streams[c->fc->nb_streams-1];
792 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
795 return AVERROR(ENOMEM);
797 ac3info = avio_rb24(pb);
798 bsmod = (ac3info >> 14) & 0x7;
799 acmod = (ac3info >> 11) & 0x7;
800 lfeon = (ac3info >> 10) & 0x1;
801 st->codecpar->channels = ((int[]){2,1,2,3,3,4,4,5})[acmod] + lfeon;
802 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
804 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
806 if (st->codecpar->channels > 1 && bsmod == 0x7)
807 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
809 #if FF_API_LAVF_AVCTX
810 FF_DISABLE_DEPRECATION_WARNINGS
811 st->codec->audio_service_type = *ast;
812 FF_ENABLE_DEPRECATION_WARNINGS
818 static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
821 enum AVAudioServiceType *ast;
822 int eac3info, acmod, lfeon, bsmod;
824 if (c->fc->nb_streams < 1)
826 st = c->fc->streams[c->fc->nb_streams-1];
828 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
831 return AVERROR(ENOMEM);
833 /* No need to parse fields for additional independent substreams and its
834 * associated dependent substreams since libavcodec's E-AC-3 decoder
835 * does not support them yet. */
836 avio_rb16(pb); /* data_rate and num_ind_sub */
837 eac3info = avio_rb24(pb);
838 bsmod = (eac3info >> 12) & 0x1f;
839 acmod = (eac3info >> 9) & 0x7;
840 lfeon = (eac3info >> 8) & 0x1;
841 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
843 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
844 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
846 if (st->codecpar->channels > 1 && bsmod == 0x7)
847 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
849 #if FF_API_LAVF_AVCTX
850 FF_DISABLE_DEPRECATION_WARNINGS
851 st->codec->audio_service_type = *ast;
852 FF_ENABLE_DEPRECATION_WARNINGS
858 static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
860 const uint32_t ddts_size = 20;
863 uint32_t frame_duration_code = 0;
864 uint32_t channel_layout_code = 0;
867 buf = av_malloc(ddts_size + AV_INPUT_BUFFER_PADDING_SIZE);
869 return AVERROR(ENOMEM);
871 if (avio_read(pb, buf, ddts_size) < ddts_size) {
873 return AVERROR_INVALIDDATA;
876 init_get_bits(&gb, buf, 8*ddts_size);
878 if (c->fc->nb_streams < 1) {
882 st = c->fc->streams[c->fc->nb_streams-1];
884 st->codecpar->sample_rate = get_bits_long(&gb, 32);
885 if (st->codecpar->sample_rate <= 0) {
886 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
888 return AVERROR_INVALIDDATA;
890 skip_bits_long(&gb, 32); /* max bitrate */
891 st->codecpar->bit_rate = get_bits_long(&gb, 32);
892 st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
893 frame_duration_code = get_bits(&gb, 2);
894 skip_bits(&gb, 30); /* various fields */
895 channel_layout_code = get_bits(&gb, 16);
897 st->codecpar->frame_size =
898 (frame_duration_code == 0) ? 512 :
899 (frame_duration_code == 1) ? 1024 :
900 (frame_duration_code == 2) ? 2048 :
901 (frame_duration_code == 3) ? 4096 : 0;
903 if (channel_layout_code > 0xff) {
904 av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout");
906 st->codecpar->channel_layout =
907 ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
908 ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
909 ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
910 ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
911 ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
912 ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0);
914 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
920 static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
924 if (c->fc->nb_streams < 1)
926 st = c->fc->streams[c->fc->nb_streams-1];
931 /* skip version and flags */
934 ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
939 static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
944 if (c->fc->nb_streams < 1)
946 st = c->fc->streams[c->fc->nb_streams-1];
948 if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
949 av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
954 static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
956 const int num = avio_rb32(pb);
957 const int den = avio_rb32(pb);
960 if (c->fc->nb_streams < 1)
962 st = c->fc->streams[c->fc->nb_streams-1];
964 if ((st->sample_aspect_ratio.den != 1 || st->sample_aspect_ratio.num) && // default
965 (den != st->sample_aspect_ratio.den || num != st->sample_aspect_ratio.num)) {
966 av_log(c->fc, AV_LOG_WARNING,
967 "sample aspect ratio already set to %d:%d, ignoring 'pasp' atom (%d:%d)\n",
968 st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
970 } else if (den != 0) {
971 av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den,
977 /* this atom contains actual media data */
978 static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
980 if (atom.size == 0) /* wrong one (MP4) */
983 return 0; /* now go for moov */
986 #define DRM_BLOB_SIZE 56
988 static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
990 uint8_t intermediate_key[20];
991 uint8_t intermediate_iv[20];
994 uint8_t file_checksum[20];
995 uint8_t calculated_checksum[20];
999 uint8_t *activation_bytes = c->activation_bytes;
1000 uint8_t *fixed_key = c->audible_fixed_key;
1004 sha = av_sha_alloc();
1006 return AVERROR(ENOMEM);
1007 av_free(c->aes_decrypt);
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].next_trun_dts = AV_NOPTS_VALUE;
1339 frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1340 frag_stream_info[i].index_entry = -1;
1341 frag_stream_info[i].encryption_index = NULL;
1344 if (index < c->frag_index.nb_items)
1345 memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1346 (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1348 item = &c->frag_index.item[index];
1349 item->headers_read = 0;
1351 item->nb_stream_info = c->fc->nb_streams;
1352 item->moof_offset = offset;
1353 item->stream_info = frag_stream_info;
1354 c->frag_index.nb_items++;
1359 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1360 int id, int entries)
1363 MOVFragmentStreamInfo * frag_stream_info;
1367 for (i = index; i < frag_index->nb_items; i++) {
1368 frag_stream_info = get_frag_stream_info(frag_index, i, id);
1369 if (frag_stream_info && frag_stream_info->index_entry >= 0)
1370 frag_stream_info->index_entry += entries;
1374 static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1376 // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1377 c->fragment.found_tfhd = 0;
1379 if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1380 c->has_looked_for_mfra = 1;
1381 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1383 av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1385 if ((ret = mov_read_mfra(c, pb)) < 0) {
1386 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1387 "read the mfra (may be a live ismv)\n");
1390 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1391 "seekable, can not look for mfra\n");
1394 c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1395 av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1396 c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1397 return mov_read_default(c, pb, atom);
1400 static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time, void *logctx)
1403 if(time >= 2082844800)
1404 time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1406 if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1407 av_log(logctx, AV_LOG_DEBUG, "creation_time is not representable\n");
1411 avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1415 static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1418 MOVStreamContext *sc;
1420 char language[4] = {0};
1422 int64_t creation_time;
1424 if (c->fc->nb_streams < 1)
1426 st = c->fc->streams[c->fc->nb_streams-1];
1429 if (sc->time_scale) {
1430 av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1431 return AVERROR_INVALIDDATA;
1434 version = avio_r8(pb);
1436 avpriv_request_sample(c->fc, "Version %d", version);
1437 return AVERROR_PATCHWELCOME;
1439 avio_rb24(pb); /* flags */
1441 creation_time = avio_rb64(pb);
1444 creation_time = avio_rb32(pb);
1445 avio_rb32(pb); /* modification time */
1447 mov_metadata_creation_time(&st->metadata, creation_time, c->fc);
1449 sc->time_scale = avio_rb32(pb);
1450 if (sc->time_scale <= 0) {
1451 av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1454 st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1456 lang = avio_rb16(pb); /* language */
1457 if (ff_mov_lang_to_iso639(lang, language))
1458 av_dict_set(&st->metadata, "language", language, 0);
1459 avio_rb16(pb); /* quality */
1464 static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1467 int64_t creation_time;
1468 int version = avio_r8(pb); /* version */
1469 avio_rb24(pb); /* flags */
1472 creation_time = avio_rb64(pb);
1475 creation_time = avio_rb32(pb);
1476 avio_rb32(pb); /* modification time */
1478 mov_metadata_creation_time(&c->fc->metadata, creation_time, c->fc);
1479 c->time_scale = avio_rb32(pb); /* time scale */
1480 if (c->time_scale <= 0) {
1481 av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1484 av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1486 c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1487 // set the AVCodecContext duration because the duration of individual tracks
1488 // may be inaccurate
1489 if (c->time_scale > 0 && !c->trex_data)
1490 c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale);
1491 avio_rb32(pb); /* preferred scale */
1493 avio_rb16(pb); /* preferred volume */
1495 avio_skip(pb, 10); /* reserved */
1497 /* movie display matrix, store it in main context and use it later on */
1498 for (i = 0; i < 3; i++) {
1499 c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1500 c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1501 c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1504 avio_rb32(pb); /* preview time */
1505 avio_rb32(pb); /* preview duration */
1506 avio_rb32(pb); /* poster time */
1507 avio_rb32(pb); /* selection time */
1508 avio_rb32(pb); /* selection duration */
1509 avio_rb32(pb); /* current time */
1510 avio_rb32(pb); /* next track ID */
1515 static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1520 if (c->fc->nb_streams < 1)
1522 st = c->fc->streams[c->fc->nb_streams-1];
1524 little_endian = avio_rb16(pb) & 0xFF;
1525 av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1526 if (little_endian == 1) {
1527 switch (st->codecpar->codec_id) {
1528 case AV_CODEC_ID_PCM_S24BE:
1529 st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE;
1531 case AV_CODEC_ID_PCM_S32BE:
1532 st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE;
1534 case AV_CODEC_ID_PCM_F32BE:
1535 st->codecpar->codec_id = AV_CODEC_ID_PCM_F32LE;
1537 case AV_CODEC_ID_PCM_F64BE:
1538 st->codecpar->codec_id = AV_CODEC_ID_PCM_F64LE;
1547 static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1550 uint8_t *icc_profile;
1551 char color_parameter_type[5] = { 0 };
1552 uint16_t color_primaries, color_trc, color_matrix;
1555 if (c->fc->nb_streams < 1)
1557 st = c->fc->streams[c->fc->nb_streams - 1];
1559 ret = ffio_read_size(pb, color_parameter_type, 4);
1562 if (strncmp(color_parameter_type, "nclx", 4) &&
1563 strncmp(color_parameter_type, "nclc", 4) &&
1564 strncmp(color_parameter_type, "prof", 4)) {
1565 av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
1566 color_parameter_type);
1570 if (!strncmp(color_parameter_type, "prof", 4)) {
1571 icc_profile = av_stream_new_side_data(st, AV_PKT_DATA_ICC_PROFILE, atom.size - 4);
1573 return AVERROR(ENOMEM);
1574 ret = ffio_read_size(pb, icc_profile, atom.size - 4);
1579 color_primaries = avio_rb16(pb);
1580 color_trc = avio_rb16(pb);
1581 color_matrix = avio_rb16(pb);
1583 av_log(c->fc, AV_LOG_TRACE,
1584 "%s: pri %d trc %d matrix %d",
1585 color_parameter_type, color_primaries, color_trc, color_matrix);
1587 if (!strncmp(color_parameter_type, "nclx", 4)) {
1588 uint8_t color_range = avio_r8(pb) >> 7;
1589 av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
1591 st->codecpar->color_range = AVCOL_RANGE_JPEG;
1593 st->codecpar->color_range = AVCOL_RANGE_MPEG;
1596 if (!av_color_primaries_name(color_primaries))
1597 color_primaries = AVCOL_PRI_UNSPECIFIED;
1598 if (!av_color_transfer_name(color_trc))
1599 color_trc = AVCOL_TRC_UNSPECIFIED;
1600 if (!av_color_space_name(color_matrix))
1601 color_matrix = AVCOL_SPC_UNSPECIFIED;
1603 st->codecpar->color_primaries = color_primaries;
1604 st->codecpar->color_trc = color_trc;
1605 st->codecpar->color_space = color_matrix;
1606 av_log(c->fc, AV_LOG_TRACE, "\n");
1611 static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1614 unsigned mov_field_order;
1615 enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
1617 if (c->fc->nb_streams < 1) // will happen with jp2 files
1619 st = c->fc->streams[c->fc->nb_streams-1];
1621 return AVERROR_INVALIDDATA;
1622 mov_field_order = avio_rb16(pb);
1623 if ((mov_field_order & 0xFF00) == 0x0100)
1624 decoded_field_order = AV_FIELD_PROGRESSIVE;
1625 else if ((mov_field_order & 0xFF00) == 0x0200) {
1626 switch (mov_field_order & 0xFF) {
1627 case 0x01: decoded_field_order = AV_FIELD_TT;
1629 case 0x06: decoded_field_order = AV_FIELD_BB;
1631 case 0x09: decoded_field_order = AV_FIELD_TB;
1633 case 0x0E: decoded_field_order = AV_FIELD_BT;
1637 if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
1638 av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
1640 st->codecpar->field_order = decoded_field_order;
1645 static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
1648 uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
1649 if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
1650 return AVERROR_INVALIDDATA;
1651 if ((err = av_reallocp(&par->extradata, size)) < 0) {
1652 par->extradata_size = 0;
1655 par->extradata_size = size - AV_INPUT_BUFFER_PADDING_SIZE;
1659 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
1660 static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1661 AVCodecParameters *par, uint8_t *buf)
1663 int64_t result = atom.size;
1666 AV_WB32(buf , atom.size + 8);
1667 AV_WL32(buf + 4, atom.type);
1668 err = ffio_read_size(pb, buf + 8, atom.size);
1670 par->extradata_size -= atom.size;
1672 } else if (err < atom.size) {
1673 av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
1674 par->extradata_size -= atom.size - err;
1677 memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1681 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
1682 static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1683 enum AVCodecID codec_id)
1686 uint64_t original_size;
1689 if (c->fc->nb_streams < 1) // will happen with jp2 files
1691 st = c->fc->streams[c->fc->nb_streams-1];
1693 if (st->codecpar->codec_id != codec_id)
1694 return 0; /* unexpected codec_id - don't mess with extradata */
1696 original_size = st->codecpar->extradata_size;
1697 err = mov_realloc_extradata(st->codecpar, atom);
1701 err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
1704 return 0; // Note: this is the original behavior to ignore truncation.
1707 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
1708 static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1710 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
1713 static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1715 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS);
1718 static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1720 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
1723 static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1725 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
1728 static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1730 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
1732 ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
1736 static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1738 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
1740 if (!ret && c->fc->nb_streams >= 1) {
1741 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1742 if (par->extradata_size >= 40) {
1743 par->height = AV_RB16(&par->extradata[36]);
1744 par->width = AV_RB16(&par->extradata[38]);
1750 static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1752 if (c->fc->nb_streams >= 1) {
1753 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1754 if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
1755 par->codec_id == AV_CODEC_ID_H264 &&
1759 cid = avio_rb16(pb);
1760 /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
1761 if (cid == 0xd4d || cid == 0xd4e)
1764 } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
1765 par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
1766 par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
1770 num = avio_rb32(pb);
1771 den = avio_rb32(pb);
1772 if (num <= 0 || den <= 0)
1774 switch (avio_rb32(pb)) {
1776 if (den >= INT_MAX / 2)
1780 c->fc->streams[c->fc->nb_streams-1]->display_aspect_ratio.num = num;
1781 c->fc->streams[c->fc->nb_streams-1]->display_aspect_ratio.den = den;
1788 return mov_read_avid(c, pb, atom);
1791 static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1795 uint64_t original_size;
1796 if (c->fc->nb_streams >= 1) {
1797 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1798 if (par->codec_id == AV_CODEC_ID_H264)
1800 if (atom.size == 16) {
1801 original_size = par->extradata_size;
1802 ret = mov_realloc_extradata(par, atom);
1804 length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
1805 if (length == atom.size) {
1806 const uint8_t range_value = par->extradata[original_size + 19];
1807 switch (range_value) {
1809 par->color_range = AVCOL_RANGE_MPEG;
1812 par->color_range = AVCOL_RANGE_JPEG;
1815 av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
1818 ff_dlog(c->fc, "color_range: %d\n", par->color_range);
1820 /* For some reason the whole atom was not added to the extradata */
1821 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
1824 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
1827 av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
1834 static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1836 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
1839 static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1844 if (c->fc->nb_streams < 1)
1846 st = c->fc->streams[c->fc->nb_streams-1];
1848 if ((uint64_t)atom.size > (1<<30))
1849 return AVERROR_INVALIDDATA;
1851 if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
1852 st->codecpar->codec_id == AV_CODEC_ID_QDMC ||
1853 st->codecpar->codec_id == AV_CODEC_ID_SPEEX) {
1854 // pass all frma atom to codec, needed at least for QDMC and QDM2
1855 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1858 } else if (atom.size > 8) { /* to read frma, esds atoms */
1859 if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
1861 ret = ffio_ensure_seekback(pb, 8);
1864 buffer = avio_rb64(pb);
1866 if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
1867 && buffer >> 32 <= atom.size
1868 && buffer >> 32 >= 8) {
1871 } else if (!st->codecpar->extradata_size) {
1872 #define ALAC_EXTRADATA_SIZE 36
1873 st->codecpar->extradata = av_mallocz(ALAC_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
1874 if (!st->codecpar->extradata)
1875 return AVERROR(ENOMEM);
1876 st->codecpar->extradata_size = ALAC_EXTRADATA_SIZE;
1877 AV_WB32(st->codecpar->extradata , ALAC_EXTRADATA_SIZE);
1878 AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
1879 AV_WB64(st->codecpar->extradata + 12, buffer);
1880 avio_read(pb, st->codecpar->extradata + 20, 16);
1881 avio_skip(pb, atom.size - 24);
1885 if ((ret = mov_read_default(c, pb, atom)) < 0)
1888 avio_skip(pb, atom.size);
1893 * This function reads atom content and puts data in extradata without tag
1894 * nor size unlike mov_read_extradata.
1896 static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1901 if (c->fc->nb_streams < 1)
1903 st = c->fc->streams[c->fc->nb_streams-1];
1905 if ((uint64_t)atom.size > (1<<30))
1906 return AVERROR_INVALIDDATA;
1908 if (atom.size >= 10) {
1909 // Broken files created by legacy versions of libavformat will
1910 // wrap a whole fiel atom inside of a glbl atom.
1911 unsigned size = avio_rb32(pb);
1912 unsigned type = avio_rl32(pb);
1913 avio_seek(pb, -8, SEEK_CUR);
1914 if (type == MKTAG('f','i','e','l') && size == atom.size)
1915 return mov_read_default(c, pb, atom);
1917 if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
1918 av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
1921 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1924 if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
1925 /* HEVC-based Dolby Vision derived from hvc1.
1926 Happens to match with an identifier
1927 previously utilized for DV. Thus, if we have
1928 the hvcC extradata box available as specified,
1929 set codec to HEVC */
1930 st->codecpar->codec_id = AV_CODEC_ID_HEVC;
1935 static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1938 uint8_t profile_level;
1941 if (c->fc->nb_streams < 1)
1943 st = c->fc->streams[c->fc->nb_streams-1];
1945 if (atom.size >= (1<<28) || atom.size < 7)
1946 return AVERROR_INVALIDDATA;
1948 profile_level = avio_r8(pb);
1949 if ((profile_level & 0xf0) != 0xc0)
1952 avio_seek(pb, 6, SEEK_CUR);
1953 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
1961 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
1962 * but can have extradata appended at the end after the 40 bytes belonging
1965 static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1970 if (c->fc->nb_streams < 1)
1972 if (atom.size <= 40)
1974 st = c->fc->streams[c->fc->nb_streams-1];
1976 if ((uint64_t)atom.size > (1<<30))
1977 return AVERROR_INVALIDDATA;
1980 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
1987 static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1990 MOVStreamContext *sc;
1991 unsigned int i, entries;
1993 if (c->trak_index < 0) {
1994 av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
1997 if (c->fc->nb_streams < 1)
1999 st = c->fc->streams[c->fc->nb_streams-1];
2002 avio_r8(pb); /* version */
2003 avio_rb24(pb); /* flags */
2005 entries = avio_rb32(pb);
2010 if (sc->chunk_offsets)
2011 av_log(c->fc, AV_LOG_WARNING, "Duplicated STCO atom\n");
2012 av_free(sc->chunk_offsets);
2013 sc->chunk_count = 0;
2014 sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2015 if (!sc->chunk_offsets)
2016 return AVERROR(ENOMEM);
2017 sc->chunk_count = entries;
2019 if (atom.type == MKTAG('s','t','c','o'))
2020 for (i = 0; i < entries && !pb->eof_reached; i++)
2021 sc->chunk_offsets[i] = avio_rb32(pb);
2022 else if (atom.type == MKTAG('c','o','6','4'))
2023 for (i = 0; i < entries && !pb->eof_reached; i++)
2024 sc->chunk_offsets[i] = avio_rb64(pb);
2026 return AVERROR_INVALIDDATA;
2028 sc->chunk_count = i;
2030 if (pb->eof_reached) {
2031 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2038 static int mov_codec_id(AVStream *st, uint32_t format)
2040 int id = ff_codec_get_id(ff_codec_movaudio_tags, format);
2043 ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2044 (format & 0xFFFF) == 'T' + ('S' << 8)))
2045 id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format) & 0xFFFF);
2047 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2048 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2049 } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2050 /* skip old ASF MPEG-4 tag */
2051 format && format != MKTAG('m','p','4','s')) {
2052 id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2054 id = ff_codec_get_id(ff_codec_bmp_tags, format);
2056 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
2057 else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2058 (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE &&
2059 st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2060 id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
2062 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
2064 id = ff_codec_get_id(ff_codec_movdata_tags, format);
2068 st->codecpar->codec_tag = format;
2073 static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
2074 AVStream *st, MOVStreamContext *sc)
2076 uint8_t codec_name[32] = { 0 };
2080 /* The first 16 bytes of the video sample description are already
2081 * read in ff_mov_read_stsd_entries() */
2082 stsd_start = avio_tell(pb) - 16;
2084 avio_rb16(pb); /* version */
2085 avio_rb16(pb); /* revision level */
2086 avio_rb32(pb); /* vendor */
2087 avio_rb32(pb); /* temporal quality */
2088 avio_rb32(pb); /* spatial quality */
2090 st->codecpar->width = avio_rb16(pb); /* width */
2091 st->codecpar->height = avio_rb16(pb); /* height */
2093 avio_rb32(pb); /* horiz resolution */
2094 avio_rb32(pb); /* vert resolution */
2095 avio_rb32(pb); /* data size, always 0 */
2096 avio_rb16(pb); /* frames per samples */
2098 len = avio_r8(pb); /* codec name, pascal string */
2101 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2103 avio_skip(pb, 31 - len);
2106 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2108 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2109 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2110 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2111 st->codecpar->width &= ~1;
2112 st->codecpar->height &= ~1;
2114 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2115 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2116 !strncmp(codec_name, "Sorenson H263", 13))
2117 st->codecpar->codec_id = AV_CODEC_ID_FLV1;
2119 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2121 avio_seek(pb, stsd_start, SEEK_SET);
2123 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2124 st->codecpar->bits_per_coded_sample &= 0x1F;
2125 sc->has_palette = 1;
2129 static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
2130 AVStream *st, MOVStreamContext *sc)
2132 int bits_per_sample, flags;
2133 uint16_t version = avio_rb16(pb);
2134 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2136 avio_rb16(pb); /* revision level */
2137 avio_rb32(pb); /* vendor */
2139 st->codecpar->channels = avio_rb16(pb); /* channel count */
2140 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2141 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", st->codecpar->channels);
2143 sc->audio_cid = avio_rb16(pb);
2144 avio_rb16(pb); /* packet size = 0 */
2146 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2148 // Read QT version 1 fields. In version 0 these do not exist.
2149 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2151 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2152 (sc->stsd_version == 0 && version > 0)) {
2154 sc->samples_per_frame = avio_rb32(pb);
2155 avio_rb32(pb); /* bytes per packet */
2156 sc->bytes_per_frame = avio_rb32(pb);
2157 avio_rb32(pb); /* bytes per sample */
2158 } else if (version == 2) {
2159 avio_rb32(pb); /* sizeof struct only */
2160 st->codecpar->sample_rate = av_int2double(avio_rb64(pb));
2161 st->codecpar->channels = avio_rb32(pb);
2162 avio_rb32(pb); /* always 0x7F000000 */
2163 st->codecpar->bits_per_coded_sample = avio_rb32(pb);
2165 flags = avio_rb32(pb); /* lpcm format specific flag */
2166 sc->bytes_per_frame = avio_rb32(pb);
2167 sc->samples_per_frame = avio_rb32(pb);
2168 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2169 st->codecpar->codec_id =
2170 ff_mov_get_lpcm_codec_id(st->codecpar->bits_per_coded_sample,
2173 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2174 /* can't correctly handle variable sized packet as audio unit */
2175 switch (st->codecpar->codec_id) {
2176 case AV_CODEC_ID_MP2:
2177 case AV_CODEC_ID_MP3:
2178 st->need_parsing = AVSTREAM_PARSE_FULL;
2184 if (sc->format == 0) {
2185 if (st->codecpar->bits_per_coded_sample == 8)
2186 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2187 else if (st->codecpar->bits_per_coded_sample == 16)
2188 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2191 switch (st->codecpar->codec_id) {
2192 case AV_CODEC_ID_PCM_S8:
2193 case AV_CODEC_ID_PCM_U8:
2194 if (st->codecpar->bits_per_coded_sample == 16)
2195 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16BE;
2197 case AV_CODEC_ID_PCM_S16LE:
2198 case AV_CODEC_ID_PCM_S16BE:
2199 if (st->codecpar->bits_per_coded_sample == 8)
2200 st->codecpar->codec_id = AV_CODEC_ID_PCM_S8;
2201 else if (st->codecpar->bits_per_coded_sample == 24)
2202 st->codecpar->codec_id =
2203 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2204 AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
2205 else if (st->codecpar->bits_per_coded_sample == 32)
2206 st->codecpar->codec_id =
2207 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2208 AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
2210 /* set values for old format before stsd version 1 appeared */
2211 case AV_CODEC_ID_MACE3:
2212 sc->samples_per_frame = 6;
2213 sc->bytes_per_frame = 2 * st->codecpar->channels;
2215 case AV_CODEC_ID_MACE6:
2216 sc->samples_per_frame = 6;
2217 sc->bytes_per_frame = 1 * st->codecpar->channels;
2219 case AV_CODEC_ID_ADPCM_IMA_QT:
2220 sc->samples_per_frame = 64;
2221 sc->bytes_per_frame = 34 * st->codecpar->channels;
2223 case AV_CODEC_ID_GSM:
2224 sc->samples_per_frame = 160;
2225 sc->bytes_per_frame = 33;
2231 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2232 if (bits_per_sample) {
2233 st->codecpar->bits_per_coded_sample = bits_per_sample;
2234 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->channels;
2238 static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
2239 AVStream *st, MOVStreamContext *sc,
2242 // ttxt stsd contains display flags, justification, background
2243 // color, fonts, and default styles, so fake an atom to read it
2244 MOVAtom fake_atom = { .size = size };
2245 // mp4s contains a regular esds atom
2246 if (st->codecpar->codec_tag != AV_RL32("mp4s"))
2247 mov_read_glbl(c, pb, fake_atom);
2248 st->codecpar->width = sc->width;
2249 st->codecpar->height = sc->height;
2252 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2257 y = (ycbcr >> 16) & 0xFF;
2258 cr = (ycbcr >> 8) & 0xFF;
2261 b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
2262 g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
2263 r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
2265 return (r << 16) | (g << 8) | b;
2268 static int mov_rewrite_dvd_sub_extradata(AVStream *st)
2270 char buf[256] = {0};
2271 uint8_t *src = st->codecpar->extradata;
2274 if (st->codecpar->extradata_size != 64)
2277 if (st->codecpar->width > 0 && st->codecpar->height > 0)
2278 snprintf(buf, sizeof(buf), "size: %dx%d\n",
2279 st->codecpar->width, st->codecpar->height);
2280 av_strlcat(buf, "palette: ", sizeof(buf));
2282 for (i = 0; i < 16; i++) {
2283 uint32_t yuv = AV_RB32(src + i * 4);
2284 uint32_t rgba = yuv_to_rgba(yuv);
2286 av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2289 if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2292 ret = ff_alloc_extradata(st->codecpar, strlen(buf));
2295 memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2300 static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
2301 AVStream *st, MOVStreamContext *sc,
2306 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2307 if ((int)size != size)
2308 return AVERROR(ENOMEM);
2310 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2314 MOVStreamContext *tmcd_ctx = st->priv_data;
2316 val = AV_RB32(st->codecpar->extradata + 4);
2317 tmcd_ctx->tmcd_flags = val;
2318 st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2319 st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2320 #if FF_API_LAVF_AVCTX
2321 FF_DISABLE_DEPRECATION_WARNINGS
2322 st->codec->time_base = av_inv_q(st->avg_frame_rate);
2323 FF_ENABLE_DEPRECATION_WARNINGS
2325 /* adjust for per frame dur in counter mode */
2326 if (tmcd_ctx->tmcd_flags & 0x0008) {
2327 int timescale = AV_RB32(st->codecpar->extradata + 8);
2328 int framedur = AV_RB32(st->codecpar->extradata + 12);
2329 st->avg_frame_rate.num *= timescale;
2330 st->avg_frame_rate.den *= framedur;
2331 #if FF_API_LAVF_AVCTX
2332 FF_DISABLE_DEPRECATION_WARNINGS
2333 st->codec->time_base.den *= timescale;
2334 st->codec->time_base.num *= framedur;
2335 FF_ENABLE_DEPRECATION_WARNINGS
2339 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2340 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2341 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2342 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2343 if (str_size > 0 && size >= (int)str_size + 30 &&
2344 st->codecpar->extradata[30] /* Don't add empty string */) {
2345 char *reel_name = av_malloc(str_size + 1);
2347 return AVERROR(ENOMEM);
2348 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2349 reel_name[str_size] = 0; /* Add null terminator */
2350 av_dict_set(&st->metadata, "reel_name", reel_name,
2351 AV_DICT_DONT_STRDUP_VAL);
2357 /* other codec type, just skip (rtp, mp4s ...) */
2358 avio_skip(pb, size);
2363 static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
2364 AVStream *st, MOVStreamContext *sc)
2366 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2367 !st->codecpar->sample_rate && sc->time_scale > 1)
2368 st->codecpar->sample_rate = sc->time_scale;
2370 /* special codec parameters handling */
2371 switch (st->codecpar->codec_id) {
2372 #if CONFIG_DV_DEMUXER
2373 case AV_CODEC_ID_DVAUDIO:
2374 c->dv_fctx = avformat_alloc_context();
2376 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2377 return AVERROR(ENOMEM);
2379 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2381 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2382 return AVERROR(ENOMEM);
2384 sc->dv_audio_container = 1;
2385 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
2388 /* no ifdef since parameters are always those */
2389 case AV_CODEC_ID_QCELP:
2390 st->codecpar->channels = 1;
2391 // force sample rate for qcelp when not stored in mov
2392 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2393 st->codecpar->sample_rate = 8000;
2394 // FIXME: Why is the following needed for some files?
2395 sc->samples_per_frame = 160;
2396 if (!sc->bytes_per_frame)
2397 sc->bytes_per_frame = 35;
2399 case AV_CODEC_ID_AMR_NB:
2400 st->codecpar->channels = 1;
2401 /* force sample rate for amr, stsd in 3gp does not store sample rate */
2402 st->codecpar->sample_rate = 8000;
2404 case AV_CODEC_ID_AMR_WB:
2405 st->codecpar->channels = 1;
2406 st->codecpar->sample_rate = 16000;
2408 case AV_CODEC_ID_MP2:
2409 case AV_CODEC_ID_MP3:
2410 /* force type after stsd for m1a hdlr */
2411 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2413 case AV_CODEC_ID_GSM:
2414 case AV_CODEC_ID_ADPCM_MS:
2415 case AV_CODEC_ID_ADPCM_IMA_WAV:
2416 case AV_CODEC_ID_ILBC:
2417 case AV_CODEC_ID_MACE3:
2418 case AV_CODEC_ID_MACE6:
2419 case AV_CODEC_ID_QDM2:
2420 st->codecpar->block_align = sc->bytes_per_frame;
2422 case AV_CODEC_ID_ALAC:
2423 if (st->codecpar->extradata_size == 36) {
2424 st->codecpar->channels = AV_RB8 (st->codecpar->extradata + 21);
2425 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2428 case AV_CODEC_ID_AC3:
2429 case AV_CODEC_ID_EAC3:
2430 case AV_CODEC_ID_MPEG1VIDEO:
2431 case AV_CODEC_ID_VC1:
2432 case AV_CODEC_ID_VP8:
2433 case AV_CODEC_ID_VP9:
2434 st->need_parsing = AVSTREAM_PARSE_FULL;
2442 static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
2443 int codec_tag, int format,
2446 int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2449 (codec_tag != format &&
2450 // AVID 1:1 samples with differing data format and codec tag exist
2451 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
2452 // prores is allowed to have differing data format and codec tag
2453 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
2455 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
2456 (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id
2457 : codec_tag != MKTAG('j','p','e','g')))) {
2458 /* Multiple fourcc, we skip JPEG. This is not correct, we should
2459 * export it as a separate AVStream but this needs a few changes
2460 * in the MOV demuxer, patch welcome. */
2462 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
2463 avio_skip(pb, size);
2470 int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
2473 MOVStreamContext *sc;
2474 int pseudo_stream_id;
2476 av_assert0 (c->fc->nb_streams >= 1);
2477 st = c->fc->streams[c->fc->nb_streams-1];
2480 for (pseudo_stream_id = 0;
2481 pseudo_stream_id < entries && !pb->eof_reached;
2482 pseudo_stream_id++) {
2483 //Parsing Sample description table
2485 int ret, dref_id = 1;
2486 MOVAtom a = { AV_RL32("stsd") };
2487 int64_t start_pos = avio_tell(pb);
2488 int64_t size = avio_rb32(pb); /* size */
2489 uint32_t format = avio_rl32(pb); /* data format */
2492 avio_rb32(pb); /* reserved */
2493 avio_rb16(pb); /* reserved */
2494 dref_id = avio_rb16(pb);
2495 } else if (size <= 7) {
2496 av_log(c->fc, AV_LOG_ERROR,
2497 "invalid size %"PRId64" in stsd\n", size);
2498 return AVERROR_INVALIDDATA;
2501 if (mov_skip_multiple_stsd(c, pb, st->codecpar->codec_tag, format,
2502 size - (avio_tell(pb) - start_pos))) {
2507 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
2508 sc->dref_id= dref_id;
2509 sc->format = format;
2511 id = mov_codec_id(st, format);
2513 av_log(c->fc, AV_LOG_TRACE,
2514 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
2515 av_fourcc2str(format), st->codecpar->codec_type);
2517 st->codecpar->codec_id = id;
2518 if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) {
2519 mov_parse_stsd_video(c, pb, st, sc);
2520 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
2521 mov_parse_stsd_audio(c, pb, st, sc);
2522 if (st->codecpar->sample_rate < 0) {
2523 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
2524 return AVERROR_INVALIDDATA;
2526 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
2527 mov_parse_stsd_subtitle(c, pb, st, sc,
2528 size - (avio_tell(pb) - start_pos));
2530 ret = mov_parse_stsd_data(c, pb, st, sc,
2531 size - (avio_tell(pb) - start_pos));
2535 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
2536 a.size = size - (avio_tell(pb) - start_pos);
2538 if ((ret = mov_read_default(c, pb, a)) < 0)
2540 } else if (a.size > 0)
2541 avio_skip(pb, a.size);
2543 if (sc->extradata && st->codecpar->extradata) {
2544 int extra_size = st->codecpar->extradata_size;
2546 /* Move the current stream extradata to the stream context one. */
2547 sc->extradata_size[pseudo_stream_id] = extra_size;
2548 sc->extradata[pseudo_stream_id] = av_malloc(extra_size + AV_INPUT_BUFFER_PADDING_SIZE);
2549 if (!sc->extradata[pseudo_stream_id])
2550 return AVERROR(ENOMEM);
2551 memcpy(sc->extradata[pseudo_stream_id], st->codecpar->extradata, extra_size);
2552 av_freep(&st->codecpar->extradata);
2553 st->codecpar->extradata_size = 0;
2558 if (pb->eof_reached) {
2559 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
2566 static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2569 MOVStreamContext *sc;
2572 if (c->fc->nb_streams < 1)
2574 st = c->fc->streams[c->fc->nb_streams - 1];
2577 sc->stsd_version = avio_r8(pb);
2578 avio_rb24(pb); /* flags */
2579 entries = avio_rb32(pb);
2581 /* Each entry contains a size (4 bytes) and format (4 bytes). */
2582 if (entries <= 0 || entries > atom.size / 8) {
2583 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
2584 return AVERROR_INVALIDDATA;
2587 if (sc->extradata) {
2588 av_log(c->fc, AV_LOG_ERROR,
2589 "Duplicate stsd found in this track.\n");
2590 return AVERROR_INVALIDDATA;
2593 /* Prepare space for hosting multiple extradata. */
2594 sc->extradata = av_mallocz_array(entries, sizeof(*sc->extradata));
2596 return AVERROR(ENOMEM);
2598 sc->extradata_size = av_mallocz_array(entries, sizeof(*sc->extradata_size));
2599 if (!sc->extradata_size) {
2600 ret = AVERROR(ENOMEM);
2604 ret = ff_mov_read_stsd_entries(c, pb, entries);
2608 /* Restore back the primary extradata. */
2609 av_freep(&st->codecpar->extradata);
2610 st->codecpar->extradata_size = sc->extradata_size[0];
2611 if (sc->extradata_size[0]) {
2612 st->codecpar->extradata = av_mallocz(sc->extradata_size[0] + AV_INPUT_BUFFER_PADDING_SIZE);
2613 if (!st->codecpar->extradata)
2614 return AVERROR(ENOMEM);
2615 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
2618 return mov_finalize_stsd_codec(c, pb, st, sc);
2620 if (sc->extradata) {
2622 for (j = 0; j < sc->stsd_count; j++)
2623 av_freep(&sc->extradata[j]);
2626 av_freep(&sc->extradata);
2627 av_freep(&sc->extradata_size);
2631 static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2634 MOVStreamContext *sc;
2635 unsigned int i, entries;
2637 if (c->fc->nb_streams < 1)
2639 st = c->fc->streams[c->fc->nb_streams-1];
2642 avio_r8(pb); /* version */
2643 avio_rb24(pb); /* flags */
2645 entries = avio_rb32(pb);
2646 if ((uint64_t)entries * 12 + 4 > atom.size)
2647 return AVERROR_INVALIDDATA;
2649 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
2654 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSC atom\n");
2655 av_free(sc->stsc_data);
2657 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
2659 return AVERROR(ENOMEM);
2661 for (i = 0; i < entries && !pb->eof_reached; i++) {
2662 sc->stsc_data[i].first = avio_rb32(pb);
2663 sc->stsc_data[i].count = avio_rb32(pb);
2664 sc->stsc_data[i].id = avio_rb32(pb);
2668 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
2669 int64_t first_min = i + 1;
2670 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
2671 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
2672 sc->stsc_data[i].first < first_min ||
2673 sc->stsc_data[i].count < 1 ||
2674 sc->stsc_data[i].id < 1) {
2675 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);
2676 if (i+1 >= sc->stsc_count) {
2677 if (sc->stsc_data[i].count == 0 && i > 0) {
2681 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
2682 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
2683 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
2684 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
2685 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
2688 av_assert0(sc->stsc_data[i+1].first >= 2);
2689 // We replace this entry by the next valid
2690 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
2691 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
2692 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
2696 if (pb->eof_reached) {
2697 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
2704 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
2706 return index < count - 1;
2709 /* Compute the samples value for the stsc entry at the given index. */
2710 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
2714 if (mov_stsc_index_valid(index, sc->stsc_count))
2715 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
2717 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
2718 av_assert0(sc->stsc_data[index].first <= sc->chunk_count);
2719 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
2722 return sc->stsc_data[index].count * (int64_t)chunk_count;
2725 static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2728 MOVStreamContext *sc;
2729 unsigned i, entries;
2731 if (c->fc->nb_streams < 1)
2733 st = c->fc->streams[c->fc->nb_streams-1];
2736 avio_rb32(pb); // version + flags
2738 entries = avio_rb32(pb);
2740 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
2741 av_free(sc->stps_data);
2743 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
2745 return AVERROR(ENOMEM);
2747 for (i = 0; i < entries && !pb->eof_reached; i++) {
2748 sc->stps_data[i] = avio_rb32(pb);
2753 if (pb->eof_reached) {
2754 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
2761 static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2764 MOVStreamContext *sc;
2765 unsigned int i, entries;
2767 if (c->fc->nb_streams < 1)
2769 st = c->fc->streams[c->fc->nb_streams-1];
2772 avio_r8(pb); /* version */
2773 avio_rb24(pb); /* flags */
2775 entries = avio_rb32(pb);
2777 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
2781 sc->keyframe_absent = 1;
2782 if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
2783 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2787 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
2788 if (entries >= UINT_MAX / sizeof(int))
2789 return AVERROR_INVALIDDATA;
2790 av_freep(&sc->keyframes);
2791 sc->keyframe_count = 0;
2792 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
2794 return AVERROR(ENOMEM);
2796 for (i = 0; i < entries && !pb->eof_reached; i++) {
2797 sc->keyframes[i] = avio_rb32(pb);
2800 sc->keyframe_count = i;
2802 if (pb->eof_reached) {
2803 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
2810 static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2813 MOVStreamContext *sc;
2814 unsigned int i, entries, sample_size, field_size, num_bytes;
2819 if (c->fc->nb_streams < 1)
2821 st = c->fc->streams[c->fc->nb_streams-1];
2824 avio_r8(pb); /* version */
2825 avio_rb24(pb); /* flags */
2827 if (atom.type == MKTAG('s','t','s','z')) {
2828 sample_size = avio_rb32(pb);
2829 if (!sc->sample_size) /* do not overwrite value computed in stsd */
2830 sc->sample_size = sample_size;
2831 sc->stsz_sample_size = sample_size;
2835 avio_rb24(pb); /* reserved */
2836 field_size = avio_r8(pb);
2838 entries = avio_rb32(pb);
2840 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
2842 sc->sample_count = entries;
2846 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
2847 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
2848 return AVERROR_INVALIDDATA;
2853 if (entries >= (UINT_MAX - 4) / field_size)
2854 return AVERROR_INVALIDDATA;
2855 if (sc->sample_sizes)
2856 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
2857 av_free(sc->sample_sizes);
2858 sc->sample_count = 0;
2859 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
2860 if (!sc->sample_sizes)
2861 return AVERROR(ENOMEM);
2863 num_bytes = (entries*field_size+4)>>3;
2865 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
2867 av_freep(&sc->sample_sizes);
2868 return AVERROR(ENOMEM);
2871 ret = ffio_read_size(pb, buf, num_bytes);
2873 av_freep(&sc->sample_sizes);
2875 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
2879 init_get_bits(&gb, buf, 8*num_bytes);
2881 for (i = 0; i < entries && !pb->eof_reached; i++) {
2882 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
2883 if (sc->sample_sizes[i] < 0) {
2885 av_log(c->fc, AV_LOG_ERROR, "Invalid sample size %d\n", sc->sample_sizes[i]);
2886 return AVERROR_INVALIDDATA;
2888 sc->data_size += sc->sample_sizes[i];
2891 sc->sample_count = i;
2895 if (pb->eof_reached) {
2896 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSZ atom\n");
2903 static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2906 MOVStreamContext *sc;
2907 unsigned int i, entries, alloc_size = 0;
2909 int64_t total_sample_count=0;
2911 if (c->fc->nb_streams < 1)
2913 st = c->fc->streams[c->fc->nb_streams-1];
2916 avio_r8(pb); /* version */
2917 avio_rb24(pb); /* flags */
2918 entries = avio_rb32(pb);
2920 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
2921 c->fc->nb_streams-1, entries);
2924 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
2925 av_freep(&sc->stts_data);
2927 if (entries >= INT_MAX / sizeof(*sc->stts_data))
2928 return AVERROR(ENOMEM);
2930 for (i = 0; i < entries && !pb->eof_reached; i++) {
2931 int sample_duration;
2932 unsigned int sample_count;
2933 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
2934 MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
2935 min_entries * sizeof(*sc->stts_data));
2937 av_freep(&sc->stts_data);
2939 return AVERROR(ENOMEM);
2941 sc->stts_count = min_entries;
2942 sc->stts_data = stts_data;
2944 sample_count=avio_rb32(pb);
2945 sample_duration = avio_rb32(pb);
2947 sc->stts_data[i].count= sample_count;
2948 sc->stts_data[i].duration= sample_duration;
2950 av_log(c->fc, AV_LOG_TRACE, "sample_count=%d, sample_duration=%d\n",
2951 sample_count, sample_duration);
2953 duration+=(int64_t)sample_duration*(uint64_t)sample_count;
2954 total_sample_count+=sample_count;
2960 duration <= INT64_MAX - sc->duration_for_fps &&
2961 total_sample_count <= INT_MAX - sc->nb_frames_for_fps
2963 sc->duration_for_fps += duration;
2964 sc->nb_frames_for_fps += total_sample_count;
2967 if (pb->eof_reached) {
2968 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
2972 st->nb_frames= total_sample_count;
2974 st->duration= FFMIN(st->duration, duration);
2975 sc->track_end = duration;
2979 static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2982 MOVStreamContext *sc;
2985 if (c->fc->nb_streams < 1)
2987 st = c->fc->streams[c->fc->nb_streams - 1];
2990 avio_r8(pb); /* version */
2991 avio_rb24(pb); /* flags */
2992 entries = atom.size - 4;
2994 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
2995 c->fc->nb_streams - 1, entries);
2998 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
2999 av_freep(&sc->sdtp_data);
3002 sc->sdtp_data = av_mallocz(entries);
3004 return AVERROR(ENOMEM);
3006 for (i = 0; i < entries && !pb->eof_reached; i++)
3007 sc->sdtp_data[i] = avio_r8(pb);
3013 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3016 if (duration == INT_MIN) {
3017 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3020 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3024 static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3027 MOVStreamContext *sc;
3028 unsigned int i, entries, ctts_count = 0;
3030 if (c->fc->nb_streams < 1)
3032 st = c->fc->streams[c->fc->nb_streams-1];
3035 avio_r8(pb); /* version */
3036 avio_rb24(pb); /* flags */
3037 entries = avio_rb32(pb);
3039 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3043 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3044 return AVERROR_INVALIDDATA;
3045 av_freep(&sc->ctts_data);
3046 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3048 return AVERROR(ENOMEM);
3050 for (i = 0; i < entries && !pb->eof_reached; i++) {
3051 int count =avio_rb32(pb);
3052 int duration =avio_rb32(pb);
3055 av_log(c->fc, AV_LOG_TRACE,
3056 "ignoring CTTS entry with count=%d duration=%d\n",
3061 add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3064 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3067 if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3068 av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3069 av_freep(&sc->ctts_data);
3075 mov_update_dts_shift(sc, duration, c->fc);
3078 sc->ctts_count = ctts_count;
3080 if (pb->eof_reached) {
3081 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3085 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3090 static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3093 MOVStreamContext *sc;
3094 unsigned int i, entries;
3096 uint32_t grouping_type;
3098 if (c->fc->nb_streams < 1)
3100 st = c->fc->streams[c->fc->nb_streams-1];
3103 version = avio_r8(pb); /* version */
3104 avio_rb24(pb); /* flags */
3105 grouping_type = avio_rl32(pb);
3106 if (grouping_type != MKTAG( 'r','a','p',' '))
3107 return 0; /* only support 'rap ' grouping */
3109 avio_rb32(pb); /* grouping_type_parameter */
3111 entries = avio_rb32(pb);
3115 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP atom\n");
3116 av_free(sc->rap_group);
3117 sc->rap_group_count = 0;
3118 sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group));
3120 return AVERROR(ENOMEM);
3122 for (i = 0; i < entries && !pb->eof_reached; i++) {
3123 sc->rap_group[i].count = avio_rb32(pb); /* sample_count */
3124 sc->rap_group[i].index = avio_rb32(pb); /* group_description_index */
3127 sc->rap_group_count = i;
3129 if (pb->eof_reached) {
3130 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3138 * Get ith edit list entry (media time, duration).
3140 static int get_edit_list_entry(MOVContext *mov,
3141 const MOVStreamContext *msc,
3142 unsigned int edit_list_index,
3143 int64_t *edit_list_media_time,
3144 int64_t *edit_list_duration,
3145 int64_t global_timescale)
3147 if (edit_list_index == msc->elst_count) {
3150 *edit_list_media_time = msc->elst_data[edit_list_index].time;
3151 *edit_list_duration = msc->elst_data[edit_list_index].duration;
3153 /* duration is in global timescale units;convert to msc timescale */
3154 if (global_timescale == 0) {
3155 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3158 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3164 * Find the closest previous frame to the timestamp_pts, in e_old index
3165 * entries. Searching for just any frame / just key frames can be controlled by
3166 * last argument 'flag'.
3167 * Note that if ctts_data is not NULL, we will always search for a key frame
3168 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3169 * return the first frame of the video.
3171 * Here the timestamp_pts is considered to be a presentation timestamp and
3172 * the timestamp of index entries are considered to be decoding timestamps.
3174 * Returns 0 if successful in finding a frame, else returns -1.
3175 * Places the found index corresponding output arg.
3177 * If ctts_old is not NULL, then refines the searched entry by searching
3178 * backwards from the found timestamp, to find the frame with correct PTS.
3180 * Places the found ctts_index and ctts_sample in corresponding output args.
3182 static int find_prev_closest_index(AVStream *st,
3183 AVIndexEntry *e_old,
3187 int64_t timestamp_pts,
3190 int64_t* ctts_index,
3191 int64_t* ctts_sample)
3193 MOVStreamContext *msc = st->priv_data;
3194 AVIndexEntry *e_keep = st->index_entries;
3195 int nb_keep = st->nb_index_entries;
3197 int64_t index_ctts_count;
3201 // If dts_shift > 0, then all the index timestamps will have to be offset by
3202 // at least dts_shift amount to obtain PTS.
3203 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3204 if (msc->dts_shift > 0) {
3205 timestamp_pts -= msc->dts_shift;
3208 st->index_entries = e_old;
3209 st->nb_index_entries = nb_old;
3210 *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3212 // Keep going backwards in the index entries until the timestamp is the same.
3214 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3216 if ((flag & AVSEEK_FLAG_ANY) ||
3217 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3223 // If we have CTTS then refine the search, by searching backwards over PTS
3224 // computed by adding corresponding CTTS durations to index timestamps.
3225 if (ctts_data && *index >= 0) {
3226 av_assert0(ctts_index);
3227 av_assert0(ctts_sample);
3228 // Find out the ctts_index for the found frame.
3231 for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3232 if (*ctts_index < ctts_count) {
3234 if (ctts_data[*ctts_index].count == *ctts_sample) {
3241 while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3242 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3243 // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3244 // compensated by dts_shift above.
3245 if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3246 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3251 if (*ctts_sample == 0) {
3253 if (*ctts_index >= 0)
3254 *ctts_sample = ctts_data[*ctts_index].count - 1;
3261 /* restore AVStream state*/
3262 st->index_entries = e_keep;
3263 st->nb_index_entries = nb_keep;
3264 return *index >= 0 ? 0 : -1;
3268 * Add index entry with the given values, to the end of st->index_entries.
3269 * Returns the new size st->index_entries if successful, else returns -1.
3271 * This function is similar to ff_add_index_entry in libavformat/utils.c
3272 * except that here we are always unconditionally adding an index entry to
3273 * the end, instead of searching the entries list and skipping the add if
3274 * there is an existing entry with the same timestamp.
3275 * This is needed because the mov_fix_index calls this func with the same
3276 * unincremented timestamp for successive discarded frames.
3278 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3279 int size, int distance, int flags)
3281 AVIndexEntry *entries, *ie;
3283 const size_t min_size_needed = (st->nb_index_entries + 1) * sizeof(AVIndexEntry);
3285 // Double the allocation each time, to lower memory fragmentation.
3286 // Another difference from ff_add_index_entry function.
3287 const size_t requested_size =
3288 min_size_needed > st->index_entries_allocated_size ?
3289 FFMAX(min_size_needed, 2 * st->index_entries_allocated_size) :
3292 if((unsigned)st->nb_index_entries + 1 >= UINT_MAX / sizeof(AVIndexEntry))
3295 entries = av_fast_realloc(st->index_entries,
3296 &st->index_entries_allocated_size,
3301 st->index_entries= entries;
3303 index= st->nb_index_entries++;
3304 ie= &entries[index];
3307 ie->timestamp = timestamp;
3308 ie->min_distance= distance;
3315 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3316 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3318 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3319 int64_t* frame_duration_buffer,
3320 int frame_duration_buffer_size) {
3322 av_assert0(end_index >= 0 && end_index <= st->nb_index_entries);
3323 for (i = 0; i < frame_duration_buffer_size; i++) {
3324 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3325 st->index_entries[end_index - 1 - i].timestamp = end_ts;
3330 * Append a new ctts entry to ctts_data.
3331 * Returns the new ctts_count if successful, else returns -1.
3333 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3334 int count, int duration)
3336 MOVStts *ctts_buf_new;
3337 const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVStts);
3338 const size_t requested_size =
3339 min_size_needed > *allocated_size ?
3340 FFMAX(min_size_needed, 2 * (*allocated_size)) :
3343 if((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
3346 ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3351 *ctts_data = ctts_buf_new;
3353 ctts_buf_new[*ctts_count].count = count;
3354 ctts_buf_new[*ctts_count].duration = duration;
3356 *ctts_count = (*ctts_count) + 1;
3360 #define MAX_REORDER_DELAY 16
3361 static void mov_estimate_video_delay(MOVContext *c, AVStream* st) {
3362 MOVStreamContext *msc = st->priv_data;
3365 int ctts_sample = 0;
3366 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3368 int j, r, num_swaps;
3370 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3371 pts_buf[j] = INT64_MIN;
3373 if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3374 st->codecpar->codec_id == AV_CODEC_ID_H264) {
3375 st->codecpar->video_delay = 0;
3376 for(ind = 0; ind < st->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3377 // Point j to the last elem of the buffer and insert the current pts there.
3379 buf_start = (buf_start + 1);
3380 if (buf_start == MAX_REORDER_DELAY + 1)
3383 pts_buf[j] = st->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3385 // The timestamps that are already in the sorted buffer, and are greater than the
3386 // current pts, are exactly the timestamps that need to be buffered to output PTS
3387 // in correct sorted order.
3388 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3389 // can be computed as the maximum no. of swaps any particular timestamp needs to
3390 // go through, to keep this buffer in sorted order.
3392 while (j != buf_start) {
3394 if (r < 0) r = MAX_REORDER_DELAY;
3395 if (pts_buf[j] < pts_buf[r]) {
3396 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3403 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3406 if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3411 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3412 st->codecpar->video_delay, st->index);
3416 static void mov_current_sample_inc(MOVStreamContext *sc)
3418 sc->current_sample++;
3419 sc->current_index++;
3420 if (sc->index_ranges &&
3421 sc->current_index >= sc->current_index_range->end &&
3422 sc->current_index_range->end) {
3423 sc->current_index_range++;
3424 sc->current_index = sc->current_index_range->start;
3428 static void mov_current_sample_dec(MOVStreamContext *sc)
3430 sc->current_sample--;
3431 sc->current_index--;
3432 if (sc->index_ranges &&
3433 sc->current_index < sc->current_index_range->start &&
3434 sc->current_index_range > sc->index_ranges) {
3435 sc->current_index_range--;
3436 sc->current_index = sc->current_index_range->end - 1;
3440 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3444 sc->current_sample = current_sample;
3445 sc->current_index = current_sample;
3446 if (!sc->index_ranges) {
3450 for (sc->current_index_range = sc->index_ranges;
3451 sc->current_index_range->end;
3452 sc->current_index_range++) {
3453 range_size = sc->current_index_range->end - sc->current_index_range->start;
3454 if (range_size > current_sample) {
3455 sc->current_index = sc->current_index_range->start + current_sample;
3458 current_sample -= range_size;
3463 * Fix st->index_entries, so that it contains only the entries (and the entries
3464 * which are needed to decode them) that fall in the edit list time ranges.
3465 * Also fixes the timestamps of the index entries to match the timeline
3466 * specified the edit lists.
3468 static void mov_fix_index(MOVContext *mov, AVStream *st)
3470 MOVStreamContext *msc = st->priv_data;
3471 AVIndexEntry *e_old = st->index_entries;
3472 int nb_old = st->nb_index_entries;
3473 const AVIndexEntry *e_old_end = e_old + nb_old;
3474 const AVIndexEntry *current = NULL;
3475 MOVStts *ctts_data_old = msc->ctts_data;
3476 int64_t ctts_index_old = 0;
3477 int64_t ctts_sample_old = 0;
3478 int64_t ctts_count_old = msc->ctts_count;
3479 int64_t edit_list_media_time = 0;
3480 int64_t edit_list_duration = 0;
3481 int64_t frame_duration = 0;
3482 int64_t edit_list_dts_counter = 0;
3483 int64_t edit_list_dts_entry_end = 0;
3484 int64_t edit_list_start_ctts_sample = 0;
3486 int64_t curr_ctts = 0;
3487 int64_t empty_edits_sum_duration = 0;
3488 int64_t edit_list_index = 0;
3491 int64_t start_dts = 0;
3492 int64_t edit_list_start_encountered = 0;
3493 int64_t search_timestamp = 0;
3494 int64_t* frame_duration_buffer = NULL;
3495 int num_discarded_begin = 0;
3496 int first_non_zero_audio_edit = -1;
3497 int packet_skip_samples = 0;
3498 MOVIndexRange *current_index_range;
3500 int found_keyframe_after_edit = 0;
3501 int found_non_empty_edit = 0;
3503 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
3507 // allocate the index ranges array
3508 msc->index_ranges = av_malloc((msc->elst_count + 1) * sizeof(msc->index_ranges[0]));
3509 if (!msc->index_ranges) {
3510 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
3513 msc->current_index_range = msc->index_ranges;
3514 current_index_range = msc->index_ranges - 1;
3516 // Clean AVStream from traces of old index
3517 st->index_entries = NULL;
3518 st->index_entries_allocated_size = 0;
3519 st->nb_index_entries = 0;
3521 // Clean ctts fields of MOVStreamContext
3522 msc->ctts_data = NULL;
3523 msc->ctts_count = 0;
3524 msc->ctts_index = 0;
3525 msc->ctts_sample = 0;
3526 msc->ctts_allocated_size = 0;
3528 // Reinitialize min_corrected_pts so that it can be computed again.
3529 msc->min_corrected_pts = -1;
3531 // If the dts_shift is positive (in case of negative ctts values in mov),
3532 // then negate the DTS by dts_shift
3533 if (msc->dts_shift > 0) {
3534 edit_list_dts_entry_end -= msc->dts_shift;
3535 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
3538 start_dts = edit_list_dts_entry_end;
3540 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
3541 &edit_list_duration, mov->time_scale)) {
3542 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
3543 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
3545 edit_list_dts_counter = edit_list_dts_entry_end;
3546 edit_list_dts_entry_end += edit_list_duration;
3547 num_discarded_begin = 0;
3548 if (!found_non_empty_edit && edit_list_media_time == -1) {
3549 empty_edits_sum_duration += edit_list_duration;
3552 found_non_empty_edit = 1;
3554 // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
3555 // according to the edit list below.
3556 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3557 if (first_non_zero_audio_edit < 0) {
3558 first_non_zero_audio_edit = 1;
3560 first_non_zero_audio_edit = 0;
3563 if (first_non_zero_audio_edit > 0)
3564 st->skip_samples = msc->start_pad = 0;
3567 // While reordering frame index according to edit list we must handle properly
3568 // the scenario when edit list entry starts from none key frame.
3569 // We find closest previous key frame and preserve it and consequent frames in index.
3570 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
3571 search_timestamp = edit_list_media_time;
3572 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3573 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
3574 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
3575 // edit_list_media_time to cover the decoder delay.
3576 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
3579 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
3580 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3581 av_log(mov->fc, AV_LOG_WARNING,
3582 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
3583 st->index, edit_list_index, search_timestamp);
3584 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
3585 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3586 av_log(mov->fc, AV_LOG_WARNING,
3587 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
3588 st->index, edit_list_index, search_timestamp);
3591 ctts_sample_old = 0;
3594 current = e_old + index;
3595 edit_list_start_ctts_sample = ctts_sample_old;
3597 // Iterate over index and arrange it according to edit list
3598 edit_list_start_encountered = 0;
3599 found_keyframe_after_edit = 0;
3600 for (; current < e_old_end; current++, index++) {
3601 // check if frame outside edit list mark it for discard
3602 frame_duration = (current + 1 < e_old_end) ?
3603 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
3605 flags = current->flags;
3607 // frames (pts) before or after edit list
3608 curr_cts = current->timestamp + msc->dts_shift;
3611 if (ctts_data_old && ctts_index_old < ctts_count_old) {
3612 curr_ctts = ctts_data_old[ctts_index_old].duration;
3613 av_log(mov->fc, AV_LOG_DEBUG, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
3614 curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
3615 curr_cts += curr_ctts;
3617 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
3618 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3619 &msc->ctts_allocated_size,
3620 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3621 ctts_data_old[ctts_index_old].duration) == -1) {
3622 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3624 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3625 ctts_data_old[ctts_index_old].duration);
3629 ctts_sample_old = 0;
3630 edit_list_start_ctts_sample = 0;
3634 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
3635 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
3636 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
3637 first_non_zero_audio_edit > 0) {
3638 packet_skip_samples = edit_list_media_time - curr_cts;
3639 st->skip_samples += packet_skip_samples;
3641 // Shift the index entry timestamp by packet_skip_samples to be correct.
3642 edit_list_dts_counter -= packet_skip_samples;
3643 if (edit_list_start_encountered == 0) {
3644 edit_list_start_encountered = 1;
3645 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
3646 // discarded packets.
3647 if (frame_duration_buffer) {
3648 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3649 frame_duration_buffer, num_discarded_begin);
3650 av_freep(&frame_duration_buffer);
3654 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
3656 flags |= AVINDEX_DISCARD_FRAME;
3657 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
3659 if (edit_list_start_encountered == 0) {
3660 num_discarded_begin++;
3661 frame_duration_buffer = av_realloc(frame_duration_buffer,
3662 num_discarded_begin * sizeof(int64_t));
3663 if (!frame_duration_buffer) {
3664 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
3667 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
3669 // Increment skip_samples for the first non-zero audio edit list
3670 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3671 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
3672 st->skip_samples += frame_duration;
3677 if (msc->min_corrected_pts < 0) {
3678 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
3680 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
3682 if (edit_list_start_encountered == 0) {
3683 edit_list_start_encountered = 1;
3684 // Make timestamps strictly monotonically increasing by rewriting timestamps for
3685 // discarded packets.
3686 if (frame_duration_buffer) {
3687 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3688 frame_duration_buffer, num_discarded_begin);
3689 av_freep(&frame_duration_buffer);
3694 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
3695 current->min_distance, flags) == -1) {
3696 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
3700 // Update the index ranges array
3701 if (current_index_range < msc->index_ranges || index != current_index_range->end) {
3702 current_index_range++;
3703 current_index_range->start = index;
3705 current_index_range->end = index + 1;
3707 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
3708 if (edit_list_start_encountered > 0) {
3709 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
3712 // Break when found first key frame after edit entry completion
3713 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
3714 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
3715 if (ctts_data_old) {
3716 // If we have CTTS and this is the first keyframe after edit elist,
3717 // wait for one more, because there might be trailing B-frames after this I-frame
3718 // that do belong to the edit.
3719 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
3720 found_keyframe_after_edit = 1;
3723 if (ctts_sample_old != 0) {
3724 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3725 &msc->ctts_allocated_size,
3726 ctts_sample_old - edit_list_start_ctts_sample,
3727 ctts_data_old[ctts_index_old].duration) == -1) {
3728 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3729 ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
3730 ctts_data_old[ctts_index_old].duration);
3739 // If there are empty edits, then msc->min_corrected_pts might be positive
3740 // intentionally. So we subtract the sum duration of emtpy edits here.
3741 msc->min_corrected_pts -= empty_edits_sum_duration;
3743 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
3744 // dts by that amount to make the first pts zero.
3745 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
3746 if (msc->min_corrected_pts > 0) {
3747 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
3748 for (i = 0; i < st->nb_index_entries; ++i) {
3749 st->index_entries[i].timestamp -= msc->min_corrected_pts;
3753 // Start time should be equal to zero or the duration of any empty edits.
3754 st->start_time = empty_edits_sum_duration;
3756 // Update av stream length, if it ends up shorter than the track's media duration
3757 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
3758 msc->start_pad = st->skip_samples;
3760 // Free the old index and the old CTTS structures
3762 av_free(ctts_data_old);
3763 av_freep(&frame_duration_buffer);
3765 // Null terminate the index ranges array
3766 current_index_range++;
3767 current_index_range->start = 0;
3768 current_index_range->end = 0;
3769 msc->current_index = msc->index_ranges[0].start;
3772 static void mov_build_index(MOVContext *mov, AVStream *st)
3774 MOVStreamContext *sc = st->priv_data;
3775 int64_t current_offset;
3776 int64_t current_dts = 0;
3777 unsigned int stts_index = 0;
3778 unsigned int stsc_index = 0;
3779 unsigned int stss_index = 0;
3780 unsigned int stps_index = 0;
3782 uint64_t stream_size = 0;
3783 MOVStts *ctts_data_old = sc->ctts_data;
3784 unsigned int ctts_count_old = sc->ctts_count;
3786 if (sc->elst_count) {
3787 int i, edit_start_index = 0, multiple_edits = 0;
3788 int64_t empty_duration = 0; // empty duration of the first edit list entry
3789 int64_t start_time = 0; // start time of the media
3791 for (i = 0; i < sc->elst_count; i++) {
3792 const MOVElst *e = &sc->elst_data[i];
3793 if (i == 0 && e->time == -1) {
3794 /* if empty, the first entry is the start time of the stream
3795 * relative to the presentation itself */
3796 empty_duration = e->duration;
3797 edit_start_index = 1;
3798 } else if (i == edit_start_index && e->time >= 0) {
3799 start_time = e->time;
3805 if (multiple_edits && !mov->advanced_editlist)
3806 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
3807 "Use -advanced_editlist to correctly decode otherwise "
3808 "a/v desync might occur\n");
3810 /* adjust first dts according to edit list */
3811 if ((empty_duration || start_time) && mov->time_scale > 0) {
3813 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
3814 sc->time_offset = start_time - empty_duration;
3815 sc->min_corrected_pts = start_time;
3816 if (!mov->advanced_editlist)
3817 current_dts = -sc->time_offset;
3820 if (!multiple_edits && !mov->advanced_editlist &&
3821 st->codecpar->codec_id == AV_CODEC_ID_AAC && start_time > 0)
3822 sc->start_pad = start_time;
3825 /* only use old uncompressed audio chunk demuxing when stts specifies it */
3826 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3827 sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
3828 unsigned int current_sample = 0;
3829 unsigned int stts_sample = 0;
3830 unsigned int sample_size;
3831 unsigned int distance = 0;
3832 unsigned int rap_group_index = 0;
3833 unsigned int rap_group_sample = 0;
3834 int64_t last_dts = 0;
3835 int64_t dts_correction = 0;
3836 int rap_group_present = sc->rap_group_count && sc->rap_group;
3837 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
3839 current_dts -= sc->dts_shift;
3840 last_dts = current_dts;
3842 if (!sc->sample_count || st->nb_index_entries)
3844 if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
3846 if (av_reallocp_array(&st->index_entries,
3847 st->nb_index_entries + sc->sample_count,
3848 sizeof(*st->index_entries)) < 0) {
3849 st->nb_index_entries = 0;
3852 st->index_entries_allocated_size = (st->nb_index_entries + sc->sample_count) * sizeof(*st->index_entries);
3854 if (ctts_data_old) {
3855 // Expand ctts entries such that we have a 1-1 mapping with samples
3856 if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
3859 sc->ctts_allocated_size = 0;
3860 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size,
3861 sc->sample_count * sizeof(*sc->ctts_data));
3862 if (!sc->ctts_data) {
3863 av_free(ctts_data_old);
3867 memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
3869 for (i = 0; i < ctts_count_old &&
3870 sc->ctts_count < sc->sample_count; i++)
3871 for (j = 0; j < ctts_data_old[i].count &&
3872 sc->ctts_count < sc->sample_count; j++)
3873 add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
3874 &sc->ctts_allocated_size, 1,
3875 ctts_data_old[i].duration);
3876 av_free(ctts_data_old);
3879 for (i = 0; i < sc->chunk_count; i++) {
3880 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
3881 current_offset = sc->chunk_offsets[i];
3882 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3883 i + 1 == sc->stsc_data[stsc_index + 1].first)
3886 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
3887 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
3888 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
3889 sc->stsz_sample_size = sc->sample_size;
3891 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
3892 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
3893 sc->stsz_sample_size = sc->sample_size;
3896 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
3898 if (current_sample >= sc->sample_count) {
3899 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
3903 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
3905 if (stss_index + 1 < sc->keyframe_count)
3907 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
3909 if (stps_index + 1 < sc->stps_count)
3912 if (rap_group_present && rap_group_index < sc->rap_group_count) {
3913 if (sc->rap_group[rap_group_index].index > 0)
3915 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
3916 rap_group_sample = 0;
3920 if (sc->keyframe_absent
3922 && !rap_group_present
3923 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
3927 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
3928 if (sc->pseudo_stream_id == -1 ||
3929 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
3931 if (sample_size > 0x3FFFFFFF) {
3932 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
3935 e = &st->index_entries[st->nb_index_entries++];
3936 e->pos = current_offset;
3937 e->timestamp = current_dts;
3938 e->size = sample_size;
3939 e->min_distance = distance;
3940 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
3941 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
3942 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
3943 current_offset, current_dts, sample_size, distance, keyframe);
3944 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries < 100)
3945 ff_rfps_add_frame(mov->fc, st, current_dts);
3948 current_offset += sample_size;
3949 stream_size += sample_size;
3951 /* A negative sample duration is invalid based on the spec,
3952 * but some samples need it to correct the DTS. */
3953 if (sc->stts_data[stts_index].duration < 0) {
3954 av_log(mov->fc, AV_LOG_WARNING,
3955 "Invalid SampleDelta %d in STTS, at %d st:%d\n",
3956 sc->stts_data[stts_index].duration, stts_index,
3958 dts_correction += sc->stts_data[stts_index].duration - 1;
3959 sc->stts_data[stts_index].duration = 1;
3961 current_dts += sc->stts_data[stts_index].duration;
3962 if (!dts_correction || current_dts + dts_correction > last_dts) {
3963 current_dts += dts_correction;
3966 /* Avoid creating non-monotonous DTS */
3967 dts_correction += current_dts - last_dts - 1;
3968 current_dts = last_dts + 1;
3970 last_dts = current_dts;
3974 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
3980 if (st->duration > 0)
3981 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
3983 unsigned chunk_samples, total = 0;
3985 if (!sc->chunk_count)
3988 // compute total chunk count
3989 for (i = 0; i < sc->stsc_count; i++) {
3990 unsigned count, chunk_count;
3992 chunk_samples = sc->stsc_data[i].count;
3993 if (i != sc->stsc_count - 1 &&
3994 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
3995 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
3999 if (sc->samples_per_frame >= 160) { // gsm
4000 count = chunk_samples / sc->samples_per_frame;
4001 } else if (sc->samples_per_frame > 1) {
4002 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4003 count = (chunk_samples+samples-1) / samples;
4005 count = (chunk_samples+1023) / 1024;
4008 if (mov_stsc_index_valid(i, sc->stsc_count))
4009 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4011 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4012 total += chunk_count * count;
4015 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4016 if (total >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
4018 if (av_reallocp_array(&st->index_entries,
4019 st->nb_index_entries + total,
4020 sizeof(*st->index_entries)) < 0) {
4021 st->nb_index_entries = 0;
4024 st->index_entries_allocated_size = (st->nb_index_entries + total) * sizeof(*st->index_entries);
4027 for (i = 0; i < sc->chunk_count; i++) {
4028 current_offset = sc->chunk_offsets[i];
4029 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4030 i + 1 == sc->stsc_data[stsc_index + 1].first)
4032 chunk_samples = sc->stsc_data[stsc_index].count;
4034 while (chunk_samples > 0) {
4036 unsigned size, samples;
4038 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4039 avpriv_request_sample(mov->fc,
4040 "Zero bytes per frame, but %d samples per frame",
4041 sc->samples_per_frame);
4045 if (sc->samples_per_frame >= 160) { // gsm
4046 samples = sc->samples_per_frame;
4047 size = sc->bytes_per_frame;
4049 if (sc->samples_per_frame > 1) {
4050 samples = FFMIN((1024 / sc->samples_per_frame)*
4051 sc->samples_per_frame, chunk_samples);
4052 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
4054 samples = FFMIN(1024, chunk_samples);
4055 size = samples * sc->sample_size;
4059 if (st->nb_index_entries >= total) {
4060 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4063 if (size > 0x3FFFFFFF) {
4064 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4067 e = &st->index_entries[st->nb_index_entries++];
4068 e->pos = current_offset;
4069 e->timestamp = current_dts;
4071 e->min_distance = 0;
4072 e->flags = AVINDEX_KEYFRAME;
4073 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4074 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4077 current_offset += size;
4078 current_dts += samples;
4079 chunk_samples -= samples;
4084 if (!mov->ignore_editlist && mov->advanced_editlist) {
4085 // Fix index according to edit lists.
4086 mov_fix_index(mov, st);
4089 // Update start time of the stream.
4090 if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries > 0) {
4091 st->start_time = st->index_entries[0].timestamp + sc->dts_shift;
4092 if (sc->ctts_data) {
4093 st->start_time += sc->ctts_data[0].duration;
4097 mov_estimate_video_delay(mov, st);
4100 static int test_same_origin(const char *src, const char *ref) {
4110 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4111 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4113 if (strlen(src) == 0) {
4115 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4116 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4117 strlen(src_host) + 1 >= sizeof(src_host) ||
4118 strlen(ref_host) + 1 >= sizeof(ref_host)) {
4120 } else if (strcmp(src_proto, ref_proto) ||
4121 strcmp(src_auth, ref_auth) ||
4122 strcmp(src_host, ref_host) ||
4123 src_port != ref_port) {
4129 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4131 /* try relative path, we do not try the absolute because it can leak information about our
4132 system to an attacker */
4133 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4134 char filename[1025];
4135 const char *src_path;
4138 /* find a source dir */
4139 src_path = strrchr(src, '/');
4145 /* find a next level down to target */
4146 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4147 if (ref->path[l] == '/') {
4148 if (i == ref->nlvl_to - 1)
4154 /* compose filename if next level down to target was found */
4155 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4156 memcpy(filename, src, src_path - src);
4157 filename[src_path - src] = 0;
4159 for (i = 1; i < ref->nlvl_from; i++)
4160 av_strlcat(filename, "../", sizeof(filename));
4162 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4163 if (!c->use_absolute_path) {
4164 int same_origin = test_same_origin(src, filename);
4167 av_log(c->fc, AV_LOG_ERROR,
4168 "Reference with mismatching origin, %s not tried for security reasons, "
4169 "set demuxer option use_absolute_path to allow it anyway\n",
4171 return AVERROR(ENOENT);
4174 if(strstr(ref->path + l + 1, "..") ||
4175 strstr(ref->path + l + 1, ":") ||
4176 (ref->nlvl_from > 1 && same_origin < 0) ||
4177 (filename[0] == '/' && src_path == src))
4178 return AVERROR(ENOENT);
4181 if (strlen(filename) + 1 == sizeof(filename))
4182 return AVERROR(ENOENT);
4183 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4186 } else if (c->use_absolute_path) {
4187 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4188 "this is a possible security issue\n");
4189 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4192 av_log(c->fc, AV_LOG_ERROR,
4193 "Absolute path %s not tried for security reasons, "
4194 "set demuxer option use_absolute_path to allow absolute paths\n",
4198 return AVERROR(ENOENT);
4201 static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
4203 if (sc->time_scale <= 0) {
4204 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4205 sc->time_scale = c->time_scale;
4206 if (sc->time_scale <= 0)
4211 static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4214 MOVStreamContext *sc;
4217 st = avformat_new_stream(c->fc, NULL);
4218 if (!st) return AVERROR(ENOMEM);
4220 sc = av_mallocz(sizeof(MOVStreamContext));
4221 if (!sc) return AVERROR(ENOMEM);
4224 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
4225 sc->ffindex = st->index;
4226 c->trak_index = st->index;
4228 if ((ret = mov_read_default(c, pb, atom)) < 0)
4233 // Here stsc refers to a chunk not described in stco. This is technically invalid,
4234 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4235 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4237 av_freep(&sc->stsc_data);
4241 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4242 (!sc->sample_size && !sc->sample_count))) ||
4243 (!sc->chunk_count && sc->sample_count)) {
4244 av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4248 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4249 av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4251 return AVERROR_INVALIDDATA;
4254 fix_timescale(c, sc);
4256 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4258 mov_build_index(c, st);
4260 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4261 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4262 if (c->enable_drefs) {
4263 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4264 av_log(c->fc, AV_LOG_ERROR,
4265 "stream %d, error opening alias: path='%s', dir='%s', "
4266 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4267 st->index, dref->path, dref->dir, dref->filename,
4268 dref->volume, dref->nlvl_from, dref->nlvl_to);
4270 av_log(c->fc, AV_LOG_WARNING,
4271 "Skipped opening external track: "
4272 "stream %d, alias: path='%s', dir='%s', "
4273 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4274 "Set enable_drefs to allow this.\n",
4275 st->index, dref->path, dref->dir, dref->filename,
4276 dref->volume, dref->nlvl_from, dref->nlvl_to);
4280 sc->pb_is_copied = 1;
4283 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4284 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4285 sc->height && sc->width &&
4286 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4287 st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4288 ((double)st->codecpar->width * sc->height), INT_MAX);
4291 #if FF_API_R_FRAME_RATE
4292 if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4293 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
4294 sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4298 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4299 if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4300 TAG_IS_AVCI(st->codecpar->codec_tag)) {
4301 ret = ff_generate_avci_extradata(st);
4306 switch (st->codecpar->codec_id) {
4307 #if CONFIG_H261_DECODER
4308 case AV_CODEC_ID_H261:
4310 #if CONFIG_H263_DECODER
4311 case AV_CODEC_ID_H263:
4313 #if CONFIG_MPEG4_DECODER
4314 case AV_CODEC_ID_MPEG4:
4316 st->codecpar->width = 0; /* let decoder init width/height */
4317 st->codecpar->height= 0;
4321 // If the duration of the mp3 packets is not constant, then they could need a parser
4322 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4323 && sc->stts_count > 3
4324 && sc->stts_count*10 > st->nb_frames
4325 && sc->time_scale == st->codecpar->sample_rate) {
4326 st->need_parsing = AVSTREAM_PARSE_FULL;
4328 /* Do not need those anymore. */
4329 av_freep(&sc->chunk_offsets);
4330 av_freep(&sc->sample_sizes);
4331 av_freep(&sc->keyframes);
4332 av_freep(&sc->stts_data);
4333 av_freep(&sc->stps_data);
4334 av_freep(&sc->elst_data);
4335 av_freep(&sc->rap_group);
4340 static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4343 c->itunes_metadata = 1;
4344 ret = mov_read_default(c, pb, atom);
4345 c->itunes_metadata = 0;
4349 static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4358 count = avio_rb32(pb);
4359 if (count > UINT_MAX / sizeof(*c->meta_keys) - 1) {
4360 av_log(c->fc, AV_LOG_ERROR,
4361 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
4362 return AVERROR_INVALIDDATA;
4365 c->meta_keys_count = count + 1;
4366 c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
4368 return AVERROR(ENOMEM);
4370 for (i = 1; i <= count; ++i) {
4371 uint32_t key_size = avio_rb32(pb);
4372 uint32_t type = avio_rl32(pb);
4374 av_log(c->fc, AV_LOG_ERROR,
4375 "The key# %"PRIu32" in meta has invalid size:"
4376 "%"PRIu32"\n", i, key_size);
4377 return AVERROR_INVALIDDATA;
4380 if (type != MKTAG('m','d','t','a')) {
4381 avio_skip(pb, key_size);
4383 c->meta_keys[i] = av_mallocz(key_size + 1);
4384 if (!c->meta_keys[i])
4385 return AVERROR(ENOMEM);
4386 avio_read(pb, c->meta_keys[i], key_size);
4392 static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4394 int64_t end = avio_tell(pb) + atom.size;
4395 uint8_t *key = NULL, *val = NULL, *mean = NULL;
4399 MOVStreamContext *sc;
4401 if (c->fc->nb_streams < 1)
4403 st = c->fc->streams[c->fc->nb_streams-1];
4406 for (i = 0; i < 3; i++) {
4410 if (end - avio_tell(pb) <= 12)
4413 len = avio_rb32(pb);
4414 tag = avio_rl32(pb);
4415 avio_skip(pb, 4); // flags
4417 if (len < 12 || len - 12 > end - avio_tell(pb))
4421 if (tag == MKTAG('m', 'e', 'a', 'n'))
4423 else if (tag == MKTAG('n', 'a', 'm', 'e'))
4425 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
4435 *p = av_malloc(len + 1);
4437 ret = AVERROR(ENOMEM);
4440 ret = ffio_read_size(pb, *p, len);
4448 if (mean && key && val) {
4449 if (strcmp(key, "iTunSMPB") == 0) {
4450 int priming, remainder, samples;
4451 if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
4452 if(priming>0 && priming<16384)
4453 sc->start_pad = priming;
4456 if (strcmp(key, "cdec") != 0) {
4457 av_dict_set(&c->fc->metadata, key, val,
4458 AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
4462 av_log(c->fc, AV_LOG_VERBOSE,
4463 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
4466 avio_seek(pb, end, SEEK_SET);
4473 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4475 while (atom.size > 8) {
4479 tag = avio_rl32(pb);
4481 if (tag == MKTAG('h','d','l','r')) {
4482 avio_seek(pb, -8, SEEK_CUR);
4484 return mov_read_default(c, pb, atom);
4490 // return 1 when matrix is identity, 0 otherwise
4491 #define IS_MATRIX_IDENT(matrix) \
4492 ( (matrix)[0][0] == (1 << 16) && \
4493 (matrix)[1][1] == (1 << 16) && \
4494 (matrix)[2][2] == (1 << 30) && \
4495 !(matrix)[0][1] && !(matrix)[0][2] && \
4496 !(matrix)[1][0] && !(matrix)[1][2] && \
4497 !(matrix)[2][0] && !(matrix)[2][1])
4499 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4504 int display_matrix[3][3];
4505 int res_display_matrix[3][3] = { { 0 } };
4507 MOVStreamContext *sc;
4511 if (c->fc->nb_streams < 1)
4513 st = c->fc->streams[c->fc->nb_streams-1];
4516 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4517 // avoids corrupting AVStreams mapped to an earlier tkhd.
4519 return AVERROR_INVALIDDATA;
4521 version = avio_r8(pb);
4522 flags = avio_rb24(pb);
4523 st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
4529 avio_rb32(pb); /* creation time */
4530 avio_rb32(pb); /* modification time */
4532 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4533 avio_rb32(pb); /* reserved */
4535 /* highlevel (considering edits) duration in movie timebase */
4536 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4537 avio_rb32(pb); /* reserved */
4538 avio_rb32(pb); /* reserved */
4540 avio_rb16(pb); /* layer */
4541 avio_rb16(pb); /* alternate group */
4542 avio_rb16(pb); /* volume */
4543 avio_rb16(pb); /* reserved */
4545 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4546 // they're kept in fixed point format through all calculations
4547 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4548 // side data, but the scale factor is not needed to calculate aspect ratio
4549 for (i = 0; i < 3; i++) {
4550 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
4551 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
4552 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
4555 width = avio_rb32(pb); // 16.16 fixed point track width
4556 height = avio_rb32(pb); // 16.16 fixed point track height
4557 sc->width = width >> 16;
4558 sc->height = height >> 16;
4560 // apply the moov display matrix (after the tkhd one)
4561 for (i = 0; i < 3; i++) {
4562 const int sh[3] = { 16, 16, 30 };
4563 for (j = 0; j < 3; j++) {
4564 for (e = 0; e < 3; e++) {
4565 res_display_matrix[i][j] +=
4566 ((int64_t) display_matrix[i][e] *
4567 c->movie_display_matrix[e][j]) >> sh[e];
4572 // save the matrix when it is not the default identity
4573 if (!IS_MATRIX_IDENT(res_display_matrix)) {
4576 av_freep(&sc->display_matrix);
4577 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4578 if (!sc->display_matrix)
4579 return AVERROR(ENOMEM);
4581 for (i = 0; i < 3; i++)
4582 for (j = 0; j < 3; j++)
4583 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4585 #if FF_API_OLD_ROTATE_API
4586 rotate = av_display_rotation_get(sc->display_matrix);
4587 if (!isnan(rotate)) {
4588 char rotate_buf[64];
4590 if (rotate < 0) // for backward compatibility
4592 snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate);
4593 av_dict_set(&st->metadata, "rotate", rotate_buf, 0);
4598 // transform the display width/height according to the matrix
4599 // to keep the same scale, use [width height 1<<16]
4600 if (width && height && sc->display_matrix) {
4601 double disp_transform[2];
4603 for (i = 0; i < 2; i++)
4604 disp_transform[i] = hypot(sc->display_matrix[0 + i],
4605 sc->display_matrix[3 + i]);
4607 if (disp_transform[0] > 0 && disp_transform[1] > 0 &&
4608 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4609 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4610 st->sample_aspect_ratio = av_d2q(
4611 disp_transform[0] / disp_transform[1],
4617 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4619 MOVFragment *frag = &c->fragment;
4620 MOVTrackExt *trex = NULL;
4621 int flags, track_id, i;
4622 MOVFragmentStreamInfo * frag_stream_info;
4624 avio_r8(pb); /* version */
4625 flags = avio_rb24(pb);
4627 track_id = avio_rb32(pb);
4629 return AVERROR_INVALIDDATA;
4630 for (i = 0; i < c->trex_count; i++)
4631 if (c->trex_data[i].track_id == track_id) {
4632 trex = &c->trex_data[i];
4636 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4639 c->fragment.found_tfhd = 1;
4640 frag->track_id = track_id;
4641 set_frag_stream(&c->frag_index, track_id);
4643 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4644 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4645 frag->moof_offset : frag->implicit_offset;
4646 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4648 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4649 avio_rb32(pb) : trex->duration;
4650 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4651 avio_rb32(pb) : trex->size;
4652 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4653 avio_rb32(pb) : trex->flags;
4654 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4656 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4657 if (frag_stream_info)
4658 frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
4663 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4668 num = atom.size / 4;
4669 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4670 return AVERROR(ENOMEM);
4672 av_free(c->chapter_tracks);
4673 c->chapter_tracks = new_tracks;
4674 c->nb_chapter_tracks = num;
4676 for (i = 0; i < num && !pb->eof_reached; i++)
4677 c->chapter_tracks[i] = avio_rb32(pb);
4682 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4687 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4688 return AVERROR_INVALIDDATA;
4689 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4690 sizeof(*c->trex_data))) < 0) {
4695 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4697 trex = &c->trex_data[c->trex_count++];
4698 avio_r8(pb); /* version */
4699 avio_rb24(pb); /* flags */
4700 trex->track_id = avio_rb32(pb);
4701 trex->stsd_id = avio_rb32(pb);
4702 trex->duration = avio_rb32(pb);
4703 trex->size = avio_rb32(pb);
4704 trex->flags = avio_rb32(pb);
4708 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4710 MOVFragment *frag = &c->fragment;
4711 AVStream *st = NULL;
4712 MOVStreamContext *sc;
4714 MOVFragmentStreamInfo * frag_stream_info;
4715 int64_t base_media_decode_time;
4717 for (i = 0; i < c->fc->nb_streams; i++) {
4718 if (c->fc->streams[i]->id == frag->track_id) {
4719 st = c->fc->streams[i];
4724 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4728 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4730 version = avio_r8(pb);
4731 avio_rb24(pb); /* flags */
4733 base_media_decode_time = avio_rb64(pb);
4735 base_media_decode_time = avio_rb32(pb);
4738 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4739 if (frag_stream_info)
4740 frag_stream_info->tfdt_dts = base_media_decode_time;
4741 sc->track_end = base_media_decode_time;
4746 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4748 MOVFragment *frag = &c->fragment;
4749 AVStream *st = NULL;
4750 MOVStreamContext *sc;
4753 int64_t dts, pts = AV_NOPTS_VALUE;
4754 int data_offset = 0;
4755 unsigned entries, first_sample_flags = frag->flags;
4756 int flags, distance, i;
4757 int64_t prev_dts = AV_NOPTS_VALUE;
4758 int next_frag_index = -1, index_entry_pos;
4759 size_t requested_size;
4760 size_t old_ctts_allocated_size;
4761 AVIndexEntry *new_entries;
4762 MOVFragmentStreamInfo * frag_stream_info;
4764 if (!frag->found_tfhd) {
4765 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4766 return AVERROR_INVALIDDATA;
4769 for (i = 0; i < c->fc->nb_streams; i++) {
4770 if (c->fc->streams[i]->id == frag->track_id) {
4771 st = c->fc->streams[i];
4776 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4780 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4783 // Find the next frag_index index that has a valid index_entry for
4784 // the current track_id.
4786 // A valid index_entry means the trun for the fragment was read
4787 // and it's samples are in index_entries at the given position.
4788 // New index entries will be inserted before the index_entry found.
4789 index_entry_pos = st->nb_index_entries;
4790 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4791 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4792 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4793 next_frag_index = i;
4794 index_entry_pos = frag_stream_info->index_entry;
4798 av_assert0(index_entry_pos <= st->nb_index_entries);
4800 avio_r8(pb); /* version */
4801 flags = avio_rb24(pb);
4802 entries = avio_rb32(pb);
4803 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4805 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4806 return AVERROR_INVALIDDATA;
4807 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4808 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4810 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4811 if (frag_stream_info)
4813 if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
4814 dts = frag_stream_info->next_trun_dts - sc->time_offset;
4815 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4816 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4817 pts = frag_stream_info->first_tfra_pts;
4818 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4819 ", using it for pts\n", pts);
4820 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4821 c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
4822 dts = frag_stream_info->first_tfra_pts;
4823 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4824 ", using it for dts\n", pts);
4825 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4826 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4827 // pts = frag_stream_info->sidx_pts;
4828 dts = frag_stream_info->sidx_pts - sc->time_offset;
4829 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4830 ", using it for pts\n", pts);
4831 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4832 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4833 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4834 ", using it for dts\n", dts);
4836 dts = sc->track_end - sc->time_offset;
4837 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4838 ", using it for dts\n", dts);
4841 dts = sc->track_end - sc->time_offset;
4842 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4843 ", using it for dts\n", dts);
4845 offset = frag->base_data_offset + data_offset;
4847 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4849 // realloc space for new index entries
4850 if((uint64_t)st->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4851 entries = UINT_MAX / sizeof(AVIndexEntry) - st->nb_index_entries;
4852 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4857 requested_size = (st->nb_index_entries + entries) * sizeof(AVIndexEntry);
4858 new_entries = av_fast_realloc(st->index_entries,
4859 &st->index_entries_allocated_size,
4862 return AVERROR(ENOMEM);
4863 st->index_entries= new_entries;
4865 requested_size = (st->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4866 old_ctts_allocated_size = sc->ctts_allocated_size;
4867 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4870 return AVERROR(ENOMEM);
4871 sc->ctts_data = ctts_data;
4873 // In case there were samples without ctts entries, ensure they get
4874 // zero valued entries. This ensures clips which mix boxes with and
4875 // without ctts entries don't pickup uninitialized data.
4876 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4877 sc->ctts_allocated_size - old_ctts_allocated_size);
4879 if (index_entry_pos < st->nb_index_entries) {
4880 // Make hole in index_entries and ctts_data for new samples
4881 memmove(st->index_entries + index_entry_pos + entries,
4882 st->index_entries + index_entry_pos,
4883 sizeof(*st->index_entries) *
4884 (st->nb_index_entries - index_entry_pos));
4885 memmove(sc->ctts_data + index_entry_pos + entries,
4886 sc->ctts_data + index_entry_pos,
4887 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4888 if (index_entry_pos < sc->current_sample) {
4889 sc->current_sample += entries;
4893 st->nb_index_entries += entries;
4894 sc->ctts_count = st->nb_index_entries;
4896 // Record the index_entry position in frag_index of this fragment
4897 if (frag_stream_info)
4898 frag_stream_info->index_entry = index_entry_pos;
4900 if (index_entry_pos > 0)
4901 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4903 for (i = 0; i < entries && !pb->eof_reached; i++) {
4904 unsigned sample_size = frag->size;
4905 int sample_flags = i ? frag->flags : first_sample_flags;
4906 unsigned sample_duration = frag->duration;
4907 unsigned ctts_duration = 0;
4909 int index_entry_flags = 0;
4911 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4912 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4913 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4914 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4916 mov_update_dts_shift(sc, ctts_duration, c->fc);
4917 if (pts != AV_NOPTS_VALUE) {
4918 dts = pts - sc->dts_shift;
4919 if (flags & MOV_TRUN_SAMPLE_CTS) {
4920 dts -= ctts_duration;
4922 dts -= sc->time_offset;
4924 av_log(c->fc, AV_LOG_DEBUG,
4925 "pts %"PRId64" calculated dts %"PRId64
4926 " sc->dts_shift %d ctts.duration %d"
4927 " sc->time_offset %"PRId64
4928 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4930 sc->dts_shift, ctts_duration,
4931 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4932 pts = AV_NOPTS_VALUE;
4935 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4939 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4940 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4943 index_entry_flags |= AVINDEX_KEYFRAME;
4945 // Fragments can overlap in time. Discard overlapping frames after
4947 if (prev_dts >= dts)
4948 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4950 st->index_entries[index_entry_pos].pos = offset;
4951 st->index_entries[index_entry_pos].timestamp = dts;
4952 st->index_entries[index_entry_pos].size= sample_size;
4953 st->index_entries[index_entry_pos].min_distance= distance;
4954 st->index_entries[index_entry_pos].flags = index_entry_flags;
4956 sc->ctts_data[index_entry_pos].count = 1;
4957 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4960 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4961 "size %u, distance %d, keyframe %d\n", st->index,
4962 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4964 dts += sample_duration;
4965 offset += sample_size;
4966 sc->data_size += sample_size;
4968 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4969 1 <= INT_MAX - sc->nb_frames_for_fps
4971 sc->duration_for_fps += sample_duration;
4972 sc->nb_frames_for_fps ++;
4975 if (frag_stream_info)
4976 frag_stream_info->next_trun_dts = dts + sc->time_offset;
4978 // EOF found before reading all entries. Fix the hole this would
4979 // leave in index_entries and ctts_data
4980 int gap = entries - i;
4981 memmove(st->index_entries + index_entry_pos,
4982 st->index_entries + index_entry_pos + gap,
4983 sizeof(*st->index_entries) *
4984 (st->nb_index_entries - (index_entry_pos + gap)));
4985 memmove(sc->ctts_data + index_entry_pos,
4986 sc->ctts_data + index_entry_pos + gap,
4987 sizeof(*sc->ctts_data) *
4988 (sc->ctts_count - (index_entry_pos + gap)));
4990 st->nb_index_entries -= gap;
4991 sc->ctts_count -= gap;
4992 if (index_entry_pos < sc->current_sample) {
4993 sc->current_sample -= gap;
4998 // The end of this new fragment may overlap in time with the start
4999 // of the next fragment in index_entries. Mark the samples in the next
5000 // fragment that overlap with AVINDEX_DISCARD_FRAME
5001 prev_dts = AV_NOPTS_VALUE;
5002 if (index_entry_pos > 0)
5003 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
5004 for (i = index_entry_pos; i < st->nb_index_entries; i++) {
5005 if (prev_dts < st->index_entries[i].timestamp)
5007 st->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
5010 // If a hole was created to insert the new index_entries into,
5011 // the index_entry recorded for all subsequent moof must
5012 // be incremented by the number of entries inserted.
5013 fix_frag_index_entries(&c->frag_index, next_frag_index,
5014 frag->track_id, entries);
5016 if (pb->eof_reached) {
5017 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
5021 frag->implicit_offset = offset;
5023 sc->track_end = dts + sc->time_offset;
5024 if (st->duration < sc->track_end)
5025 st->duration = sc->track_end;
5030 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5032 int64_t offset = avio_tell(pb) + atom.size, pts, timestamp;
5034 unsigned i, j, track_id, item_count;
5035 AVStream *st = NULL;
5036 AVStream *ref_st = NULL;
5037 MOVStreamContext *sc, *ref_sc = NULL;
5038 AVRational timescale;
5040 version = avio_r8(pb);
5042 avpriv_request_sample(c->fc, "sidx version %u", version);
5046 avio_rb24(pb); // flags
5048 track_id = avio_rb32(pb); // Reference ID
5049 for (i = 0; i < c->fc->nb_streams; i++) {
5050 if (c->fc->streams[i]->id == track_id) {
5051 st = c->fc->streams[i];
5056 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5062 timescale = av_make_q(1, avio_rb32(pb));
5064 if (timescale.den <= 0) {
5065 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5066 return AVERROR_INVALIDDATA;
5070 pts = avio_rb32(pb);
5071 offset += avio_rb32(pb);
5073 pts = avio_rb64(pb);
5074 offset += avio_rb64(pb);
5077 avio_rb16(pb); // reserved
5079 item_count = avio_rb16(pb);
5081 for (i = 0; i < item_count; i++) {
5083 MOVFragmentStreamInfo * frag_stream_info;
5084 uint32_t size = avio_rb32(pb);
5085 uint32_t duration = avio_rb32(pb);
5086 if (size & 0x80000000) {
5087 avpriv_request_sample(c->fc, "sidx reference_type 1");
5088 return AVERROR_PATCHWELCOME;
5090 avio_rb32(pb); // sap_flags
5091 timestamp = av_rescale_q(pts, timescale, st->time_base);
5093 index = update_frag_index(c, offset);
5094 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5095 if (frag_stream_info)
5096 frag_stream_info->sidx_pts = timestamp;
5102 st->duration = sc->track_end = pts;
5106 if (offset == avio_size(pb)) {
5107 // Find first entry in fragment index that came from an sidx.
5108 // This will pretty much always be the first entry.
5109 for (i = 0; i < c->frag_index.nb_items; i++) {
5110 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5111 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5112 MOVFragmentStreamInfo * si;
5113 si = &item->stream_info[j];
5114 if (si->sidx_pts != AV_NOPTS_VALUE) {
5115 ref_st = c->fc->streams[j];
5116 ref_sc = ref_st->priv_data;
5121 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5122 st = c->fc->streams[i];
5124 if (!sc->has_sidx) {
5125 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5129 c->frag_index.complete = 1;
5135 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5136 /* like the files created with Adobe Premiere 5.0, for samples see */
5137 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5138 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5143 return 0; /* continue */
5144 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5145 avio_skip(pb, atom.size - 4);
5148 atom.type = avio_rl32(pb);
5150 if (atom.type != MKTAG('m','d','a','t')) {
5151 avio_skip(pb, atom.size);
5154 err = mov_read_mdat(c, pb, atom);
5158 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5163 uint8_t *moov_data; /* uncompressed data */
5164 long cmov_len, moov_len;
5167 avio_rb32(pb); /* dcom atom */
5168 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5169 return AVERROR_INVALIDDATA;
5170 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5171 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5172 return AVERROR_INVALIDDATA;
5174 avio_rb32(pb); /* cmvd atom */
5175 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5176 return AVERROR_INVALIDDATA;
5177 moov_len = avio_rb32(pb); /* uncompressed size */
5178 cmov_len = atom.size - 6 * 4;
5180 cmov_data = av_malloc(cmov_len);
5182 return AVERROR(ENOMEM);
5183 moov_data = av_malloc(moov_len);
5186 return AVERROR(ENOMEM);
5188 ret = ffio_read_size(pb, cmov_data, cmov_len);
5190 goto free_and_return;
5192 ret = AVERROR_INVALIDDATA;
5193 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5194 goto free_and_return;
5195 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5196 goto free_and_return;
5197 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5198 atom.type = MKTAG('m','o','o','v');
5199 atom.size = moov_len;
5200 ret = mov_read_default(c, &ctx, atom);
5206 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5207 return AVERROR(ENOSYS);
5211 /* edit list atom */
5212 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5214 MOVStreamContext *sc;
5215 int i, edit_count, version;
5216 int64_t elst_entry_size;
5218 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5220 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5222 version = avio_r8(pb); /* version */
5223 avio_rb24(pb); /* flags */
5224 edit_count = avio_rb32(pb); /* entries */
5227 elst_entry_size = version == 1 ? 20 : 12;
5228 if (atom.size != edit_count * elst_entry_size) {
5229 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5230 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5231 edit_count, atom.size + 8);
5232 return AVERROR_INVALIDDATA;
5234 edit_count = atom.size / elst_entry_size;
5235 if (edit_count * elst_entry_size != atom.size) {
5236 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.", atom.size, edit_count);
5244 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5245 av_free(sc->elst_data);
5247 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5249 return AVERROR(ENOMEM);
5251 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5252 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5253 MOVElst *e = &sc->elst_data[i];
5256 e->duration = avio_rb64(pb);
5257 e->time = avio_rb64(pb);
5260 e->duration = avio_rb32(pb); /* segment duration */
5261 e->time = (int32_t)avio_rb32(pb); /* media time */
5264 e->rate = avio_rb32(pb) / 65536.0;
5266 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5267 e->duration, e->time, e->rate);
5269 if (e->time < 0 && e->time != -1 &&
5270 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5271 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5272 c->fc->nb_streams-1, i, e->time);
5273 return AVERROR_INVALIDDATA;
5281 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5283 MOVStreamContext *sc;
5285 if (c->fc->nb_streams < 1)
5286 return AVERROR_INVALIDDATA;
5287 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5288 sc->timecode_track = avio_rb32(pb);
5292 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5297 if (c->fc->nb_streams < 1)
5299 st = c->fc->streams[c->fc->nb_streams - 1];
5301 if (atom.size < 4) {
5302 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5303 return AVERROR_INVALIDDATA;
5306 /* For now, propagate only the OBUs, if any. Once libavcodec is
5307 updated to handle isobmff style extradata this can be removed. */
5313 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5320 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5323 int version, color_range, color_primaries, color_trc, color_space;
5325 if (c->fc->nb_streams < 1)
5327 st = c->fc->streams[c->fc->nb_streams - 1];
5329 if (atom.size < 5) {
5330 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5331 return AVERROR_INVALIDDATA;
5334 version = avio_r8(pb);
5336 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5339 avio_skip(pb, 3); /* flags */
5341 avio_skip(pb, 2); /* profile + level */
5342 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5343 color_primaries = avio_r8(pb);
5344 color_trc = avio_r8(pb);
5345 color_space = avio_r8(pb);
5346 if (avio_rb16(pb)) /* codecIntializationDataSize */
5347 return AVERROR_INVALIDDATA;
5349 if (!av_color_primaries_name(color_primaries))
5350 color_primaries = AVCOL_PRI_UNSPECIFIED;
5351 if (!av_color_transfer_name(color_trc))
5352 color_trc = AVCOL_TRC_UNSPECIFIED;
5353 if (!av_color_space_name(color_space))
5354 color_space = AVCOL_SPC_UNSPECIFIED;
5356 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5357 st->codecpar->color_primaries = color_primaries;
5358 st->codecpar->color_trc = color_trc;
5359 st->codecpar->color_space = color_space;
5364 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5366 MOVStreamContext *sc;
5369 if (c->fc->nb_streams < 1)
5370 return AVERROR_INVALIDDATA;
5372 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5374 if (atom.size < 5) {
5375 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5376 return AVERROR_INVALIDDATA;
5379 version = avio_r8(pb);
5381 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5384 avio_skip(pb, 3); /* flags */
5386 sc->mastering = av_mastering_display_metadata_alloc();
5388 return AVERROR(ENOMEM);
5390 for (i = 0; i < 3; i++) {
5391 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5392 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5394 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5395 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5397 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5398 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5400 sc->mastering->has_primaries = 1;
5401 sc->mastering->has_luminance = 1;
5406 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5408 MOVStreamContext *sc;
5409 const int mapping[3] = {1, 2, 0};
5410 const int chroma_den = 50000;
5411 const int luma_den = 10000;
5414 if (c->fc->nb_streams < 1)
5415 return AVERROR_INVALIDDATA;
5417 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5419 if (atom.size < 24) {
5420 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5421 return AVERROR_INVALIDDATA;
5424 sc->mastering = av_mastering_display_metadata_alloc();
5426 return AVERROR(ENOMEM);
5428 for (i = 0; i < 3; i++) {
5429 const int j = mapping[i];
5430 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5431 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5433 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5434 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5436 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5437 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5439 sc->mastering->has_luminance = 1;
5440 sc->mastering->has_primaries = 1;
5445 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5447 MOVStreamContext *sc;
5450 if (c->fc->nb_streams < 1)
5451 return AVERROR_INVALIDDATA;
5453 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5455 if (atom.size < 5) {
5456 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5457 return AVERROR_INVALIDDATA;
5460 version = avio_r8(pb);
5462 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5465 avio_skip(pb, 3); /* flags */
5467 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5469 return AVERROR(ENOMEM);
5471 sc->coll->MaxCLL = avio_rb16(pb);
5472 sc->coll->MaxFALL = avio_rb16(pb);
5477 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5479 MOVStreamContext *sc;
5481 if (c->fc->nb_streams < 1)
5482 return AVERROR_INVALIDDATA;
5484 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5486 if (atom.size < 4) {
5487 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5488 return AVERROR_INVALIDDATA;
5491 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5493 return AVERROR(ENOMEM);
5495 sc->coll->MaxCLL = avio_rb16(pb);
5496 sc->coll->MaxFALL = avio_rb16(pb);
5501 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5504 MOVStreamContext *sc;
5505 enum AVStereo3DType type;
5508 if (c->fc->nb_streams < 1)
5511 st = c->fc->streams[c->fc->nb_streams - 1];
5514 if (atom.size < 5) {
5515 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5516 return AVERROR_INVALIDDATA;
5518 avio_skip(pb, 4); /* version + flags */
5523 type = AV_STEREO3D_2D;
5526 type = AV_STEREO3D_TOPBOTTOM;
5529 type = AV_STEREO3D_SIDEBYSIDE;
5532 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5536 sc->stereo3d = av_stereo3d_alloc();
5538 return AVERROR(ENOMEM);
5540 sc->stereo3d->type = type;
5544 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5547 MOVStreamContext *sc;
5548 int size, version, layout;
5549 int32_t yaw, pitch, roll;
5550 uint32_t l = 0, t = 0, r = 0, b = 0;
5551 uint32_t tag, padding = 0;
5552 enum AVSphericalProjection projection;
5554 if (c->fc->nb_streams < 1)
5557 st = c->fc->streams[c->fc->nb_streams - 1];
5560 if (atom.size < 8) {
5561 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5562 return AVERROR_INVALIDDATA;
5565 size = avio_rb32(pb);
5566 if (size <= 12 || size > atom.size)
5567 return AVERROR_INVALIDDATA;
5569 tag = avio_rl32(pb);
5570 if (tag != MKTAG('s','v','h','d')) {
5571 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5574 version = avio_r8(pb);
5576 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5580 avio_skip(pb, 3); /* flags */
5581 avio_skip(pb, size - 12); /* metadata_source */
5583 size = avio_rb32(pb);
5584 if (size > atom.size)
5585 return AVERROR_INVALIDDATA;
5587 tag = avio_rl32(pb);
5588 if (tag != MKTAG('p','r','o','j')) {
5589 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5593 size = avio_rb32(pb);
5594 if (size > atom.size)
5595 return AVERROR_INVALIDDATA;
5597 tag = avio_rl32(pb);
5598 if (tag != MKTAG('p','r','h','d')) {
5599 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5602 version = avio_r8(pb);
5604 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5608 avio_skip(pb, 3); /* flags */
5610 /* 16.16 fixed point */
5611 yaw = avio_rb32(pb);
5612 pitch = avio_rb32(pb);
5613 roll = avio_rb32(pb);
5615 size = avio_rb32(pb);
5616 if (size > atom.size)
5617 return AVERROR_INVALIDDATA;
5619 tag = avio_rl32(pb);
5620 version = avio_r8(pb);
5622 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5626 avio_skip(pb, 3); /* flags */
5628 case MKTAG('c','b','m','p'):
5629 layout = avio_rb32(pb);
5631 av_log(c->fc, AV_LOG_WARNING,
5632 "Unsupported cubemap layout %d\n", layout);
5635 projection = AV_SPHERICAL_CUBEMAP;
5636 padding = avio_rb32(pb);
5638 case MKTAG('e','q','u','i'):
5644 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5645 av_log(c->fc, AV_LOG_ERROR,
5646 "Invalid bounding rectangle coordinates "
5647 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5648 return AVERROR_INVALIDDATA;
5651 if (l || t || r || b)
5652 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5654 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5657 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5661 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5663 return AVERROR(ENOMEM);
5665 sc->spherical->projection = projection;
5667 sc->spherical->yaw = yaw;
5668 sc->spherical->pitch = pitch;
5669 sc->spherical->roll = roll;
5671 sc->spherical->padding = padding;
5673 sc->spherical->bound_left = l;
5674 sc->spherical->bound_top = t;
5675 sc->spherical->bound_right = r;
5676 sc->spherical->bound_bottom = b;
5681 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5684 uint8_t *buffer = av_malloc(len + 1);
5688 return AVERROR(ENOMEM);
5691 ret = ffio_read_size(pb, buffer, len);
5695 /* Check for mandatory keys and values, try to support XML as best-effort */
5696 if (!sc->spherical &&
5697 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5698 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5699 av_stristr(val, "true") &&
5700 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5701 av_stristr(val, "true") &&
5702 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5703 av_stristr(val, "equirectangular")) {
5704 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5708 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5710 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5711 enum AVStereo3DType mode;
5713 if (av_stristr(buffer, "left-right"))
5714 mode = AV_STEREO3D_SIDEBYSIDE;
5715 else if (av_stristr(buffer, "top-bottom"))
5716 mode = AV_STEREO3D_TOPBOTTOM;
5718 mode = AV_STEREO3D_2D;
5720 sc->stereo3d = av_stereo3d_alloc();
5724 sc->stereo3d->type = mode;
5728 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5730 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5731 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5733 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5734 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5736 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5744 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5747 MOVStreamContext *sc;
5750 static const uint8_t uuid_isml_manifest[] = {
5751 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5752 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5754 static const uint8_t uuid_xmp[] = {
5755 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5756 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5758 static const uint8_t uuid_spherical[] = {
5759 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5760 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5763 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5764 return AVERROR_INVALIDDATA;
5766 if (c->fc->nb_streams < 1)
5768 st = c->fc->streams[c->fc->nb_streams - 1];
5771 ret = avio_read(pb, uuid, sizeof(uuid));
5774 } else if (ret != sizeof(uuid)) {
5775 return AVERROR_INVALIDDATA;
5777 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5778 uint8_t *buffer, *ptr;
5780 size_t len = atom.size - sizeof(uuid);
5783 return AVERROR_INVALIDDATA;
5785 ret = avio_skip(pb, 4); // zeroes
5788 buffer = av_mallocz(len + 1);
5790 return AVERROR(ENOMEM);
5792 ret = avio_read(pb, buffer, len);
5796 } else if (ret != len) {
5798 return AVERROR_INVALIDDATA;
5802 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5803 ptr += sizeof("systemBitrate=\"") - 1;
5804 c->bitrates_count++;
5805 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5807 c->bitrates_count = 0;
5809 return AVERROR(ENOMEM);
5812 ret = strtol(ptr, &endptr, 10);
5813 if (ret < 0 || errno || *endptr != '"') {
5814 c->bitrates[c->bitrates_count - 1] = 0;
5816 c->bitrates[c->bitrates_count - 1] = ret;
5821 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5823 size_t len = atom.size - sizeof(uuid);
5824 if (c->export_xmp) {
5825 buffer = av_mallocz(len + 1);
5827 return AVERROR(ENOMEM);
5829 ret = avio_read(pb, buffer, len);
5833 } else if (ret != len) {
5835 return AVERROR_INVALIDDATA;
5838 av_dict_set(&c->fc->metadata, "xmp",
5839 buffer, AV_DICT_DONT_STRDUP_VAL);
5841 // skip all uuid atom, which makes it fast for long uuid-xmp file
5842 ret = avio_skip(pb, len);
5846 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5847 size_t len = atom.size - sizeof(uuid);
5848 ret = mov_parse_uuid_spherical(sc, pb, len);
5852 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5858 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5861 uint8_t content[16];
5866 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5872 && !memcmp(content, "Anevia\x1A\x1A", 8)
5873 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5874 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5880 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5882 uint32_t format = avio_rl32(pb);
5883 MOVStreamContext *sc;
5887 if (c->fc->nb_streams < 1)
5889 st = c->fc->streams[c->fc->nb_streams - 1];
5894 case MKTAG('e','n','c','v'): // encrypted video
5895 case MKTAG('e','n','c','a'): // encrypted audio
5896 id = mov_codec_id(st, format);
5897 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5898 st->codecpar->codec_id != id) {
5899 av_log(c->fc, AV_LOG_WARNING,
5900 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5901 (char*)&format, st->codecpar->codec_id);
5905 st->codecpar->codec_id = id;
5906 sc->format = format;
5910 if (format != sc->format) {
5911 av_log(c->fc, AV_LOG_WARNING,
5912 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5913 (char*)&format, (char*)&sc->format);
5922 * Gets the current encryption info and associated current stream context. If
5923 * we are parsing a track fragment, this will return the specific encryption
5924 * info for this fragment; otherwise this will return the global encryption
5925 * info for the current stream.
5927 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5929 MOVFragmentStreamInfo *frag_stream_info;
5933 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5934 if (frag_stream_info) {
5935 for (i = 0; i < c->fc->nb_streams; i++) {
5936 if (c->fc->streams[i]->id == frag_stream_info->id) {
5937 st = c->fc->streams[i];
5941 if (i == c->fc->nb_streams)
5943 *sc = st->priv_data;
5945 if (!frag_stream_info->encryption_index) {
5946 // If this stream isn't encrypted, don't create the index.
5947 if (!(*sc)->cenc.default_encrypted_sample)
5949 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5950 if (!frag_stream_info->encryption_index)
5951 return AVERROR(ENOMEM);
5953 *encryption_index = frag_stream_info->encryption_index;
5956 // No current track fragment, using stream level encryption info.
5958 if (c->fc->nb_streams < 1)
5960 st = c->fc->streams[c->fc->nb_streams - 1];
5961 *sc = st->priv_data;
5963 if (!(*sc)->cenc.encryption_index) {
5964 // If this stream isn't encrypted, don't create the index.
5965 if (!(*sc)->cenc.default_encrypted_sample)
5967 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5968 if (!(*sc)->cenc.encryption_index)
5969 return AVERROR(ENOMEM);
5972 *encryption_index = (*sc)->cenc.encryption_index;
5977 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
5980 unsigned int subsample_count;
5981 AVSubsampleEncryptionInfo *subsamples;
5983 if (!sc->cenc.default_encrypted_sample) {
5984 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
5985 return AVERROR_INVALIDDATA;
5988 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
5990 return AVERROR(ENOMEM);
5992 if (sc->cenc.per_sample_iv_size != 0) {
5993 if (avio_read(pb, (*sample)->iv, sc->cenc.per_sample_iv_size) != sc->cenc.per_sample_iv_size) {
5994 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
5995 av_encryption_info_free(*sample);
5997 return AVERROR_INVALIDDATA;
6001 if (use_subsamples) {
6002 subsample_count = avio_rb16(pb);
6003 av_free((*sample)->subsamples);
6004 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
6005 if (!(*sample)->subsamples) {
6006 av_encryption_info_free(*sample);
6008 return AVERROR(ENOMEM);
6011 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
6012 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
6013 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
6016 if (pb->eof_reached) {
6017 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
6018 av_encryption_info_free(*sample);
6020 return AVERROR_INVALIDDATA;
6022 (*sample)->subsample_count = subsample_count;
6028 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6030 AVEncryptionInfo **encrypted_samples;
6031 MOVEncryptionIndex *encryption_index;
6032 MOVStreamContext *sc;
6033 int use_subsamples, ret;
6034 unsigned int sample_count, i, alloc_size = 0;
6036 ret = get_current_encryption_info(c, &encryption_index, &sc);
6040 if (encryption_index->nb_encrypted_samples) {
6041 // This can happen if we have both saio/saiz and senc atoms.
6042 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6046 avio_r8(pb); /* version */
6047 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6049 sample_count = avio_rb32(pb);
6050 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6051 return AVERROR(ENOMEM);
6053 for (i = 0; i < sample_count; i++) {
6054 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6055 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6056 min_samples * sizeof(*encrypted_samples));
6057 if (encrypted_samples) {
6058 encryption_index->encrypted_samples = encrypted_samples;
6060 ret = mov_read_sample_encryption_info(
6061 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6063 ret = AVERROR(ENOMEM);
6065 if (pb->eof_reached) {
6066 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6067 ret = AVERROR_INVALIDDATA;
6072 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6073 av_freep(&encryption_index->encrypted_samples);
6077 encryption_index->nb_encrypted_samples = sample_count;
6082 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6084 AVEncryptionInfo **sample, **encrypted_samples;
6086 size_t sample_count, sample_info_size, i;
6088 unsigned int alloc_size = 0;
6090 if (encryption_index->nb_encrypted_samples)
6092 sample_count = encryption_index->auxiliary_info_sample_count;
6093 if (encryption_index->auxiliary_offsets_count != 1) {
6094 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6095 return AVERROR_PATCHWELCOME;
6097 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6098 return AVERROR(ENOMEM);
6100 prev_pos = avio_tell(pb);
6101 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6102 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6103 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6107 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6108 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6109 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6110 min_samples * sizeof(*encrypted_samples));
6111 if (!encrypted_samples) {
6112 ret = AVERROR(ENOMEM);
6115 encryption_index->encrypted_samples = encrypted_samples;
6117 sample = &encryption_index->encrypted_samples[i];
6118 sample_info_size = encryption_index->auxiliary_info_default_size
6119 ? encryption_index->auxiliary_info_default_size
6120 : encryption_index->auxiliary_info_sizes[i];
6122 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6126 if (pb->eof_reached) {
6127 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6128 ret = AVERROR_INVALIDDATA;
6130 encryption_index->nb_encrypted_samples = sample_count;
6134 avio_seek(pb, prev_pos, SEEK_SET);
6136 for (; i > 0; i--) {
6137 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6139 av_freep(&encryption_index->encrypted_samples);
6145 * Tries to read the given number of bytes from the stream and puts it in a
6146 * newly allocated buffer. This reads in small chunks to avoid allocating large
6147 * memory if the file contains an invalid/malicious size value.
6149 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6151 const unsigned int block_size = 1024 * 1024;
6152 uint8_t *buffer = NULL;
6153 unsigned int alloc_size = 0, offset = 0;
6154 while (offset < size) {
6155 unsigned int new_size =
6156 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6157 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6158 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6161 return AVERROR(ENOMEM);
6163 buffer = new_buffer;
6165 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6167 return AVERROR_INVALIDDATA;
6176 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6178 MOVEncryptionIndex *encryption_index;
6179 MOVStreamContext *sc;
6181 unsigned int sample_count, aux_info_type, aux_info_param;
6183 ret = get_current_encryption_info(c, &encryption_index, &sc);
6187 if (encryption_index->nb_encrypted_samples) {
6188 // This can happen if we have both saio/saiz and senc atoms.
6189 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6193 if (encryption_index->auxiliary_info_sample_count) {
6194 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6195 return AVERROR_INVALIDDATA;
6198 avio_r8(pb); /* version */
6199 if (avio_rb24(pb) & 0x01) { /* flags */
6200 aux_info_type = avio_rb32(pb);
6201 aux_info_param = avio_rb32(pb);
6202 if (sc->cenc.default_encrypted_sample) {
6203 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6204 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6207 if (aux_info_param != 0) {
6208 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6212 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6213 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6214 aux_info_type == MKBETAG('c','e','n','s') ||
6215 aux_info_type == MKBETAG('c','b','c','1') ||
6216 aux_info_type == MKBETAG('c','b','c','s')) &&
6217 aux_info_param == 0) {
6218 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6219 return AVERROR_INVALIDDATA;
6224 } else if (!sc->cenc.default_encrypted_sample) {
6225 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6229 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6230 sample_count = avio_rb32(pb);
6231 encryption_index->auxiliary_info_sample_count = sample_count;
6233 if (encryption_index->auxiliary_info_default_size == 0) {
6234 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6236 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6241 if (encryption_index->auxiliary_offsets_count) {
6242 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6248 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6250 uint64_t *auxiliary_offsets;
6251 MOVEncryptionIndex *encryption_index;
6252 MOVStreamContext *sc;
6254 unsigned int version, entry_count, aux_info_type, aux_info_param;
6255 unsigned int alloc_size = 0;
6257 ret = get_current_encryption_info(c, &encryption_index, &sc);
6261 if (encryption_index->nb_encrypted_samples) {
6262 // This can happen if we have both saio/saiz and senc atoms.
6263 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6267 if (encryption_index->auxiliary_offsets_count) {
6268 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6269 return AVERROR_INVALIDDATA;
6272 version = avio_r8(pb); /* version */
6273 if (avio_rb24(pb) & 0x01) { /* flags */
6274 aux_info_type = avio_rb32(pb);
6275 aux_info_param = avio_rb32(pb);
6276 if (sc->cenc.default_encrypted_sample) {
6277 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6278 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6281 if (aux_info_param != 0) {
6282 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6286 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6287 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6288 aux_info_type == MKBETAG('c','e','n','s') ||
6289 aux_info_type == MKBETAG('c','b','c','1') ||
6290 aux_info_type == MKBETAG('c','b','c','s')) &&
6291 aux_info_param == 0) {
6292 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6293 return AVERROR_INVALIDDATA;
6298 } else if (!sc->cenc.default_encrypted_sample) {
6299 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6303 entry_count = avio_rb32(pb);
6304 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6305 return AVERROR(ENOMEM);
6307 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6308 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6309 auxiliary_offsets = av_fast_realloc(
6310 encryption_index->auxiliary_offsets, &alloc_size,
6311 min_offsets * sizeof(*auxiliary_offsets));
6312 if (!auxiliary_offsets) {
6313 av_freep(&encryption_index->auxiliary_offsets);
6314 return AVERROR(ENOMEM);
6316 encryption_index->auxiliary_offsets = auxiliary_offsets;
6319 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6321 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6323 if (c->frag_index.current >= 0) {
6324 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6328 if (pb->eof_reached) {
6329 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6330 av_freep(&encryption_index->auxiliary_offsets);
6331 return AVERROR_INVALIDDATA;
6334 encryption_index->auxiliary_offsets_count = entry_count;
6336 if (encryption_index->auxiliary_info_sample_count) {
6337 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6343 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6345 AVEncryptionInitInfo *info, *old_init_info;
6348 uint8_t *side_data, *extra_data, *old_side_data;
6349 size_t side_data_size;
6350 int ret = 0, old_side_data_size;
6351 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6353 if (c->fc->nb_streams < 1)
6355 st = c->fc->streams[c->fc->nb_streams-1];
6357 version = avio_r8(pb); /* version */
6358 avio_rb24(pb); /* flags */
6360 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6361 /* key_id_size */ 16, /* data_size */ 0);
6363 return AVERROR(ENOMEM);
6365 if (avio_read(pb, info->system_id, 16) != 16) {
6366 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6367 ret = AVERROR_INVALIDDATA;
6372 kid_count = avio_rb32(pb);
6373 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
6374 ret = AVERROR(ENOMEM);
6378 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6379 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6380 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6381 min_kid_count * sizeof(*key_ids));
6383 ret = AVERROR(ENOMEM);
6386 info->key_ids = key_ids;
6388 info->key_ids[i] = av_mallocz(16);
6389 if (!info->key_ids[i]) {
6390 ret = AVERROR(ENOMEM);
6393 info->num_key_ids = i + 1;
6395 if (avio_read(pb, info->key_ids[i], 16) != 16) {
6396 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6397 ret = AVERROR_INVALIDDATA;
6402 if (pb->eof_reached) {
6403 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6404 ret = AVERROR_INVALIDDATA;
6409 extra_data_size = avio_rb32(pb);
6410 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6414 av_freep(&info->data); // malloc(0) may still allocate something.
6415 info->data = extra_data;
6416 info->data_size = extra_data_size;
6418 // If there is existing initialization data, append to the list.
6419 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6420 if (old_side_data) {
6421 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6422 if (old_init_info) {
6423 // Append to the end of the list.
6424 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6430 info = old_init_info;
6432 // Assume existing side-data will be valid, so the only error we could get is OOM.
6433 ret = AVERROR(ENOMEM);
6438 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6440 ret = AVERROR(ENOMEM);
6443 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6444 side_data, side_data_size);
6449 av_encryption_init_info_free(info);
6453 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6456 MOVStreamContext *sc;
6458 if (c->fc->nb_streams < 1)
6460 st = c->fc->streams[c->fc->nb_streams-1];
6463 if (sc->pseudo_stream_id != 0) {
6464 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6465 return AVERROR_PATCHWELCOME;
6469 return AVERROR_INVALIDDATA;
6471 avio_rb32(pb); /* version and flags */
6473 if (!sc->cenc.default_encrypted_sample) {
6474 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6475 if (!sc->cenc.default_encrypted_sample) {
6476 return AVERROR(ENOMEM);
6480 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6484 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6487 MOVStreamContext *sc;
6488 unsigned int version, pattern, is_protected, iv_size;
6490 if (c->fc->nb_streams < 1)
6492 st = c->fc->streams[c->fc->nb_streams-1];
6495 if (sc->pseudo_stream_id != 0) {
6496 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6497 return AVERROR_PATCHWELCOME;
6500 if (!sc->cenc.default_encrypted_sample) {
6501 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6502 if (!sc->cenc.default_encrypted_sample) {
6503 return AVERROR(ENOMEM);
6508 return AVERROR_INVALIDDATA;
6510 version = avio_r8(pb); /* version */
6511 avio_rb24(pb); /* flags */
6513 avio_r8(pb); /* reserved */
6514 pattern = avio_r8(pb);
6517 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6518 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6521 is_protected = avio_r8(pb);
6522 if (is_protected && !sc->cenc.encryption_index) {
6523 // The whole stream should be by-default encrypted.
6524 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6525 if (!sc->cenc.encryption_index)
6526 return AVERROR(ENOMEM);
6528 sc->cenc.per_sample_iv_size = avio_r8(pb);
6529 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6530 sc->cenc.per_sample_iv_size != 16) {
6531 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6532 return AVERROR_INVALIDDATA;
6534 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6535 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6536 return AVERROR_INVALIDDATA;
6539 if (is_protected && !sc->cenc.per_sample_iv_size) {
6540 iv_size = avio_r8(pb);
6541 if (iv_size != 8 && iv_size != 16) {
6542 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6543 return AVERROR_INVALIDDATA;
6546 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6547 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6548 return AVERROR_INVALIDDATA;
6555 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6558 int last, type, size, ret;
6561 if (c->fc->nb_streams < 1)
6563 st = c->fc->streams[c->fc->nb_streams-1];
6565 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6566 return AVERROR_INVALIDDATA;
6568 /* Check FlacSpecificBox version. */
6569 if (avio_r8(pb) != 0)
6570 return AVERROR_INVALIDDATA;
6572 avio_rb24(pb); /* Flags */
6574 avio_read(pb, buf, sizeof(buf));
6575 flac_parse_block_header(buf, &last, &type, &size);
6577 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6578 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6579 return AVERROR_INVALIDDATA;
6582 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6587 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6592 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6596 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6597 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6598 return AVERROR_PATCHWELCOME;
6601 if (!sc->cenc.aes_ctr) {
6602 /* initialize the cipher */
6603 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6604 if (!sc->cenc.aes_ctr) {
6605 return AVERROR(ENOMEM);
6608 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6614 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6616 if (!sample->subsample_count)
6618 /* decrypt the whole packet */
6619 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6623 for (i = 0; i < sample->subsample_count; i++)
6625 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6626 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6627 return AVERROR_INVALIDDATA;
6630 /* skip the clear bytes */
6631 input += sample->subsamples[i].bytes_of_clear_data;
6632 size -= sample->subsamples[i].bytes_of_clear_data;
6634 /* decrypt the encrypted bytes */
6635 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6636 input += sample->subsamples[i].bytes_of_protected_data;
6637 size -= sample->subsamples[i].bytes_of_protected_data;
6641 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6642 return AVERROR_INVALIDDATA;
6648 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6650 MOVFragmentStreamInfo *frag_stream_info;
6651 MOVEncryptionIndex *encryption_index;
6652 AVEncryptionInfo *encrypted_sample;
6653 int encrypted_index, ret;
6655 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6656 encrypted_index = current_index;
6657 encryption_index = NULL;
6658 if (frag_stream_info) {
6659 // Note this only supports encryption info in the first sample descriptor.
6660 if (mov->fragment.stsd_id == 1) {
6661 if (frag_stream_info->encryption_index) {
6662 encrypted_index = current_index - frag_stream_info->index_entry;
6663 encryption_index = frag_stream_info->encryption_index;
6665 encryption_index = sc->cenc.encryption_index;
6669 encryption_index = sc->cenc.encryption_index;
6672 if (encryption_index) {
6673 if (encryption_index->auxiliary_info_sample_count &&
6674 !encryption_index->nb_encrypted_samples) {
6675 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6676 return AVERROR_INVALIDDATA;
6678 if (encryption_index->auxiliary_offsets_count &&
6679 !encryption_index->nb_encrypted_samples) {
6680 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6681 return AVERROR_INVALIDDATA;
6684 if (!encryption_index->nb_encrypted_samples) {
6685 // Full-sample encryption with default settings.
6686 encrypted_sample = sc->cenc.default_encrypted_sample;
6687 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6688 // Per-sample setting override.
6689 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6691 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6692 return AVERROR_INVALIDDATA;
6695 if (mov->decryption_key) {
6696 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6699 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6701 return AVERROR(ENOMEM);
6702 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6712 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6714 const int OPUS_SEEK_PREROLL_MS = 80;
6720 if (c->fc->nb_streams < 1)
6722 st = c->fc->streams[c->fc->nb_streams-1];
6724 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6725 return AVERROR_INVALIDDATA;
6727 /* Check OpusSpecificBox version. */
6728 if (avio_r8(pb) != 0) {
6729 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6730 return AVERROR_INVALIDDATA;
6733 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6734 size = atom.size + 8;
6736 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
6739 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6740 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6741 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6742 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6744 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6745 little-endian; aside from the preceeding magic and version they're
6746 otherwise currently identical. Data after output gain at offset 16
6747 doesn't need to be bytewapped. */
6748 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6749 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6750 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6751 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6753 st->codecpar->initial_padding = pre_skip;
6754 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6755 (AVRational){1, 1000},
6756 (AVRational){1, 48000});
6761 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6764 unsigned format_info;
6765 int channel_assignment, channel_assignment1, channel_assignment2;
6768 if (c->fc->nb_streams < 1)
6770 st = c->fc->streams[c->fc->nb_streams-1];
6773 return AVERROR_INVALIDDATA;
6775 format_info = avio_rb32(pb);
6777 ratebits = (format_info >> 28) & 0xF;
6778 channel_assignment1 = (format_info >> 15) & 0x1F;
6779 channel_assignment2 = format_info & 0x1FFF;
6780 if (channel_assignment2)
6781 channel_assignment = channel_assignment2;
6783 channel_assignment = channel_assignment1;
6785 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6786 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6787 st->codecpar->channels = truehd_channels(channel_assignment);
6788 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6793 static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6797 AVDOVIDecoderConfigurationRecord *dovi;
6801 if (c->fc->nb_streams < 1)
6803 st = c->fc->streams[c->fc->nb_streams-1];
6805 if ((uint64_t)atom.size > (1<<30) || atom.size < 4)
6806 return AVERROR_INVALIDDATA;
6808 dovi = av_dovi_alloc(&dovi_size);
6810 return AVERROR(ENOMEM);
6812 dovi->dv_version_major = avio_r8(pb);
6813 dovi->dv_version_minor = avio_r8(pb);
6815 buf = avio_rb16(pb);
6816 dovi->dv_profile = (buf >> 9) & 0x7f; // 7 bits
6817 dovi->dv_level = (buf >> 3) & 0x3f; // 6 bits
6818 dovi->rpu_present_flag = (buf >> 2) & 0x01; // 1 bit
6819 dovi->el_present_flag = (buf >> 1) & 0x01; // 1 bit
6820 dovi->bl_present_flag = buf & 0x01; // 1 bit
6821 if (atom.size >= 24) { // 4 + 4 + 4 * 4
6823 dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits
6825 // 0 stands for None
6826 // Dolby Vision V1.2.93 profiles and levels
6827 dovi->dv_bl_signal_compatibility_id = 0;
6830 ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF,
6831 (uint8_t *)dovi, dovi_size);
6837 av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC box, version: %d.%d, profile: %d, level: %d, "
6838 "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n",
6839 dovi->dv_version_major, dovi->dv_version_minor,
6840 dovi->dv_profile, dovi->dv_level,
6841 dovi->rpu_present_flag,
6842 dovi->el_present_flag,
6843 dovi->bl_present_flag,
6844 dovi->dv_bl_signal_compatibility_id
6850 static const MOVParseTableEntry mov_default_parse_table[] = {
6851 { MKTAG('A','C','L','R'), mov_read_aclr },
6852 { MKTAG('A','P','R','G'), mov_read_avid },
6853 { MKTAG('A','A','L','P'), mov_read_avid },
6854 { MKTAG('A','R','E','S'), mov_read_ares },
6855 { MKTAG('a','v','s','s'), mov_read_avss },
6856 { MKTAG('a','v','1','C'), mov_read_av1c },
6857 { MKTAG('c','h','p','l'), mov_read_chpl },
6858 { MKTAG('c','o','6','4'), mov_read_stco },
6859 { MKTAG('c','o','l','r'), mov_read_colr },
6860 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6861 { MKTAG('d','i','n','f'), mov_read_default },
6862 { MKTAG('D','p','x','E'), mov_read_dpxe },
6863 { MKTAG('d','r','e','f'), mov_read_dref },
6864 { MKTAG('e','d','t','s'), mov_read_default },
6865 { MKTAG('e','l','s','t'), mov_read_elst },
6866 { MKTAG('e','n','d','a'), mov_read_enda },
6867 { MKTAG('f','i','e','l'), mov_read_fiel },
6868 { MKTAG('a','d','r','m'), mov_read_adrm },
6869 { MKTAG('f','t','y','p'), mov_read_ftyp },
6870 { MKTAG('g','l','b','l'), mov_read_glbl },
6871 { MKTAG('h','d','l','r'), mov_read_hdlr },
6872 { MKTAG('i','l','s','t'), mov_read_ilst },
6873 { MKTAG('j','p','2','h'), mov_read_jp2h },
6874 { MKTAG('m','d','a','t'), mov_read_mdat },
6875 { MKTAG('m','d','h','d'), mov_read_mdhd },
6876 { MKTAG('m','d','i','a'), mov_read_default },
6877 { MKTAG('m','e','t','a'), mov_read_meta },
6878 { MKTAG('m','i','n','f'), mov_read_default },
6879 { MKTAG('m','o','o','f'), mov_read_moof },
6880 { MKTAG('m','o','o','v'), mov_read_moov },
6881 { MKTAG('m','v','e','x'), mov_read_default },
6882 { MKTAG('m','v','h','d'), mov_read_mvhd },
6883 { MKTAG('S','M','I',' '), mov_read_svq3 },
6884 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6885 { MKTAG('a','v','c','C'), mov_read_glbl },
6886 { MKTAG('p','a','s','p'), mov_read_pasp },
6887 { MKTAG('s','i','d','x'), mov_read_sidx },
6888 { MKTAG('s','t','b','l'), mov_read_default },
6889 { MKTAG('s','t','c','o'), mov_read_stco },
6890 { MKTAG('s','t','p','s'), mov_read_stps },
6891 { MKTAG('s','t','r','f'), mov_read_strf },
6892 { MKTAG('s','t','s','c'), mov_read_stsc },
6893 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6894 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6895 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6896 { MKTAG('s','t','t','s'), mov_read_stts },
6897 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6898 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
6899 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6900 { MKTAG('t','f','d','t'), mov_read_tfdt },
6901 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6902 { MKTAG('t','r','a','k'), mov_read_trak },
6903 { MKTAG('t','r','a','f'), mov_read_default },
6904 { MKTAG('t','r','e','f'), mov_read_default },
6905 { MKTAG('t','m','c','d'), mov_read_tmcd },
6906 { MKTAG('c','h','a','p'), mov_read_chap },
6907 { MKTAG('t','r','e','x'), mov_read_trex },
6908 { MKTAG('t','r','u','n'), mov_read_trun },
6909 { MKTAG('u','d','t','a'), mov_read_default },
6910 { MKTAG('w','a','v','e'), mov_read_wave },
6911 { MKTAG('e','s','d','s'), mov_read_esds },
6912 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6913 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6914 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6915 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6916 { MKTAG('w','f','e','x'), mov_read_wfex },
6917 { MKTAG('c','m','o','v'), mov_read_cmov },
6918 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6919 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6920 { MKTAG('s','b','g','p'), mov_read_sbgp },
6921 { MKTAG('h','v','c','C'), mov_read_glbl },
6922 { MKTAG('u','u','i','d'), mov_read_uuid },
6923 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6924 { MKTAG('f','r','e','e'), mov_read_free },
6925 { MKTAG('-','-','-','-'), mov_read_custom },
6926 { MKTAG('s','i','n','f'), mov_read_default },
6927 { MKTAG('f','r','m','a'), mov_read_frma },
6928 { MKTAG('s','e','n','c'), mov_read_senc },
6929 { MKTAG('s','a','i','z'), mov_read_saiz },
6930 { MKTAG('s','a','i','o'), mov_read_saio },
6931 { MKTAG('p','s','s','h'), mov_read_pssh },
6932 { MKTAG('s','c','h','m'), mov_read_schm },
6933 { MKTAG('s','c','h','i'), mov_read_default },
6934 { MKTAG('t','e','n','c'), mov_read_tenc },
6935 { MKTAG('d','f','L','a'), mov_read_dfla },
6936 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6937 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6938 { MKTAG('d','O','p','s'), mov_read_dops },
6939 { MKTAG('d','m','l','p'), mov_read_dmlp },
6940 { MKTAG('S','m','D','m'), mov_read_smdm },
6941 { MKTAG('C','o','L','L'), mov_read_coll },
6942 { MKTAG('v','p','c','C'), mov_read_vpcc },
6943 { MKTAG('m','d','c','v'), mov_read_mdcv },
6944 { MKTAG('c','l','l','i'), mov_read_clli },
6945 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
6946 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
6950 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6952 int64_t total_size = 0;
6956 if (c->atom_depth > 10) {
6957 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6958 return AVERROR_INVALIDDATA;
6963 atom.size = INT64_MAX;
6964 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6965 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
6968 if (atom.size >= 8) {
6969 a.size = avio_rb32(pb);
6970 a.type = avio_rl32(pb);
6971 if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
6972 a.type == MKTAG('h','o','o','v')) &&
6974 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
6976 uint32_t *type = (uint32_t *)buf + 1;
6977 if (avio_read(pb, buf, 8) != 8)
6978 return AVERROR_INVALIDDATA;
6979 avio_seek(pb, -8, SEEK_CUR);
6980 if (*type == MKTAG('m','v','h','d') ||
6981 *type == MKTAG('c','m','o','v')) {
6982 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
6983 a.type = MKTAG('m','o','o','v');
6986 if (atom.type != MKTAG('r','o','o','t') &&
6987 atom.type != MKTAG('m','o','o','v'))
6989 if (a.type == MKTAG('t','r','a','k') || a.type == MKTAG('m','d','a','t'))
6991 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
6998 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
6999 a.size = avio_rb64(pb) - 8;
7003 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
7004 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
7006 a.size = atom.size - total_size + 8;
7011 a.size = FFMIN(a.size, atom.size - total_size);
7013 for (i = 0; mov_default_parse_table[i].type; i++)
7014 if (mov_default_parse_table[i].type == a.type) {
7015 parse = mov_default_parse_table[i].parse;
7019 // container is user data
7020 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
7021 atom.type == MKTAG('i','l','s','t')))
7022 parse = mov_read_udta_string;
7024 // Supports parsing the QuickTime Metadata Keys.
7025 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
7026 if (!parse && c->found_hdlr_mdta &&
7027 atom.type == MKTAG('m','e','t','a') &&
7028 a.type == MKTAG('k','e','y','s') &&
7029 c->meta_keys_count == 0) {
7030 parse = mov_read_keys;
7033 if (!parse) { /* skip leaf atoms data */
7034 avio_skip(pb, a.size);
7036 int64_t start_pos = avio_tell(pb);
7038 int err = parse(c, pb, a);
7043 if (c->found_moov && c->found_mdat &&
7044 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
7045 start_pos + a.size == avio_size(pb))) {
7046 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
7047 c->next_root_atom = start_pos + a.size;
7051 left = a.size - avio_tell(pb) + start_pos;
7052 if (left > 0) /* skip garbage at atom end */
7053 avio_skip(pb, left);
7054 else if (left < 0) {
7055 av_log(c->fc, AV_LOG_WARNING,
7056 "overread end of atom '%.4s' by %"PRId64" bytes\n",
7057 (char*)&a.type, -left);
7058 avio_seek(pb, left, SEEK_CUR);
7062 total_size += a.size;
7065 if (total_size < atom.size && atom.size < 0x7ffff)
7066 avio_skip(pb, atom.size - total_size);
7072 static int mov_probe(const AVProbeData *p)
7077 int moov_offset = -1;
7079 /* check file header */
7082 /* ignore invalid offset */
7083 if ((offset + 8) > (unsigned int)p->buf_size)
7085 tag = AV_RL32(p->buf + offset + 4);
7087 /* check for obvious tags */
7088 case MKTAG('m','o','o','v'):
7089 moov_offset = offset + 4;
7090 case MKTAG('m','d','a','t'):
7091 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
7092 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
7093 case MKTAG('f','t','y','p'):
7094 if (AV_RB32(p->buf+offset) < 8 &&
7095 (AV_RB32(p->buf+offset) != 1 ||
7096 offset + 12 > (unsigned int)p->buf_size ||
7097 AV_RB64(p->buf+offset + 8) == 0)) {
7098 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7099 } else if (tag == MKTAG('f','t','y','p') &&
7100 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
7101 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
7103 score = FFMAX(score, 5);
7105 score = AVPROBE_SCORE_MAX;
7107 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7109 /* those are more common words, so rate then a bit less */
7110 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
7111 case MKTAG('w','i','d','e'):
7112 case MKTAG('f','r','e','e'):
7113 case MKTAG('j','u','n','k'):
7114 case MKTAG('p','i','c','t'):
7115 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
7116 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7118 case MKTAG(0x82,0x82,0x7f,0x7d):
7119 case MKTAG('s','k','i','p'):
7120 case MKTAG('u','u','i','d'):
7121 case MKTAG('p','r','f','l'):
7122 /* if we only find those cause probedata is too small at least rate them */
7123 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7124 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7127 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7130 if(score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
7131 /* moov atom in the header - we should make sure that this is not a
7132 * MOV-packed MPEG-PS */
7133 offset = moov_offset;
7135 while(offset < (p->buf_size - 16)){ /* Sufficient space */
7136 /* We found an actual hdlr atom */
7137 if(AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7138 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7139 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')){
7140 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7141 /* We found a media handler reference atom describing an
7142 * MPEG-PS-in-MOV, return a
7143 * low score to force expanding the probe window until
7144 * mpegps_probe finds what it needs */
7155 // must be done after parsing all trak because there's no order requirement
7156 static void mov_read_chapters(AVFormatContext *s)
7158 MOVContext *mov = s->priv_data;
7160 MOVStreamContext *sc;
7165 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7166 chapter_track = mov->chapter_tracks[j];
7168 for (i = 0; i < s->nb_streams; i++)
7169 if (s->streams[i]->id == chapter_track) {
7174 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7179 cur_pos = avio_tell(sc->pb);
7181 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7182 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7183 if (st->nb_index_entries) {
7184 // Retrieve the first frame, if possible
7185 AVIndexEntry *sample = &st->index_entries[0];
7186 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7187 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7191 if (av_get_packet(sc->pb, &st->attached_pic, sample->size) < 0)
7194 st->attached_pic.stream_index = st->index;
7195 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
7198 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7199 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7200 st->discard = AVDISCARD_ALL;
7201 for (i = 0; i < st->nb_index_entries; i++) {
7202 AVIndexEntry *sample = &st->index_entries[i];
7203 int64_t end = i+1 < st->nb_index_entries ? st->index_entries[i+1].timestamp : st->duration;
7208 if (end < sample->timestamp) {
7209 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7210 end = AV_NOPTS_VALUE;
7213 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7214 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7218 // the first two bytes are the length of the title
7219 len = avio_rb16(sc->pb);
7220 if (len > sample->size-2)
7222 title_len = 2*len + 1;
7223 if (!(title = av_mallocz(title_len)))
7226 // The samples could theoretically be in any encoding if there's an encd
7227 // atom following, but in practice are only utf-8 or utf-16, distinguished
7228 // instead by the presence of a BOM
7232 ch = avio_rb16(sc->pb);
7234 avio_get_str16be(sc->pb, len, title, title_len);
7235 else if (ch == 0xfffe)
7236 avio_get_str16le(sc->pb, len, title, title_len);
7239 if (len == 1 || len == 2)
7242 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7246 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7251 avio_seek(sc->pb, cur_pos, SEEK_SET);
7255 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7256 uint32_t value, int flags)
7259 char buf[AV_TIMECODE_STR_SIZE];
7260 AVRational rate = st->avg_frame_rate;
7261 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7264 av_dict_set(&st->metadata, "timecode",
7265 av_timecode_make_string(&tc, buf, value), 0);
7269 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7271 MOVStreamContext *sc = st->priv_data;
7272 char buf[AV_TIMECODE_STR_SIZE];
7273 int64_t cur_pos = avio_tell(sc->pb);
7274 int hh, mm, ss, ff, drop;
7276 if (!st->nb_index_entries)
7279 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7280 avio_skip(s->pb, 13);
7281 hh = avio_r8(s->pb);
7282 mm = avio_r8(s->pb);
7283 ss = avio_r8(s->pb);
7284 drop = avio_r8(s->pb);
7285 ff = avio_r8(s->pb);
7286 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7287 hh, mm, ss, drop ? ';' : ':', ff);
7288 av_dict_set(&st->metadata, "timecode", buf, 0);
7290 avio_seek(sc->pb, cur_pos, SEEK_SET);
7294 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7296 MOVStreamContext *sc = st->priv_data;
7298 int64_t cur_pos = avio_tell(sc->pb);
7301 if (!st->nb_index_entries)
7304 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7305 value = avio_rb32(s->pb);
7307 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7308 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7309 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7311 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7312 * not the case) and thus assume "frame number format" instead of QT one.
7313 * No sample with tmcd track can be found with a QT timecode at the moment,
7314 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7316 parse_timecode_in_framenum_format(s, st, value, flags);
7318 avio_seek(sc->pb, cur_pos, SEEK_SET);
7322 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7324 if (!index || !*index) return;
7325 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7326 av_encryption_info_free((*index)->encrypted_samples[i]);
7328 av_freep(&(*index)->encrypted_samples);
7329 av_freep(&(*index)->auxiliary_info_sizes);
7330 av_freep(&(*index)->auxiliary_offsets);
7334 static int mov_read_close(AVFormatContext *s)
7336 MOVContext *mov = s->priv_data;
7339 for (i = 0; i < s->nb_streams; i++) {
7340 AVStream *st = s->streams[i];
7341 MOVStreamContext *sc = st->priv_data;
7346 av_freep(&sc->ctts_data);
7347 for (j = 0; j < sc->drefs_count; j++) {
7348 av_freep(&sc->drefs[j].path);
7349 av_freep(&sc->drefs[j].dir);
7351 av_freep(&sc->drefs);
7353 sc->drefs_count = 0;
7355 if (!sc->pb_is_copied)
7356 ff_format_io_close(s, &sc->pb);
7359 av_freep(&sc->chunk_offsets);
7360 av_freep(&sc->stsc_data);
7361 av_freep(&sc->sample_sizes);
7362 av_freep(&sc->keyframes);
7363 av_freep(&sc->stts_data);
7364 av_freep(&sc->sdtp_data);
7365 av_freep(&sc->stps_data);
7366 av_freep(&sc->elst_data);
7367 av_freep(&sc->rap_group);
7368 av_freep(&sc->display_matrix);
7369 av_freep(&sc->index_ranges);
7372 for (j = 0; j < sc->stsd_count; j++)
7373 av_free(sc->extradata[j]);
7374 av_freep(&sc->extradata);
7375 av_freep(&sc->extradata_size);
7377 mov_free_encryption_index(&sc->cenc.encryption_index);
7378 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7379 av_aes_ctr_free(sc->cenc.aes_ctr);
7381 av_freep(&sc->stereo3d);
7382 av_freep(&sc->spherical);
7383 av_freep(&sc->mastering);
7384 av_freep(&sc->coll);
7387 if (mov->dv_demux) {
7388 avformat_free_context(mov->dv_fctx);
7389 mov->dv_fctx = NULL;
7392 if (mov->meta_keys) {
7393 for (i = 1; i < mov->meta_keys_count; i++) {
7394 av_freep(&mov->meta_keys[i]);
7396 av_freep(&mov->meta_keys);
7399 av_freep(&mov->trex_data);
7400 av_freep(&mov->bitrates);
7402 for (i = 0; i < mov->frag_index.nb_items; i++) {
7403 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7404 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7405 mov_free_encryption_index(&frag[j].encryption_index);
7407 av_freep(&mov->frag_index.item[i].stream_info);
7409 av_freep(&mov->frag_index.item);
7411 av_freep(&mov->aes_decrypt);
7412 av_freep(&mov->chapter_tracks);
7417 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7421 for (i = 0; i < s->nb_streams; i++) {
7422 AVStream *st = s->streams[i];
7423 MOVStreamContext *sc = st->priv_data;
7425 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7426 sc->timecode_track == tmcd_id)
7432 /* look for a tmcd track not referenced by any video track, and export it globally */
7433 static void export_orphan_timecode(AVFormatContext *s)
7437 for (i = 0; i < s->nb_streams; i++) {
7438 AVStream *st = s->streams[i];
7440 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7441 !tmcd_is_referenced(s, i + 1)) {
7442 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7444 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7451 static int read_tfra(MOVContext *mov, AVIOContext *f)
7453 int version, fieldlength, i, j;
7454 int64_t pos = avio_tell(f);
7455 uint32_t size = avio_rb32(f);
7456 unsigned track_id, item_count;
7458 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7461 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7463 version = avio_r8(f);
7465 track_id = avio_rb32(f);
7466 fieldlength = avio_rb32(f);
7467 item_count = avio_rb32(f);
7468 for (i = 0; i < item_count; i++) {
7469 int64_t time, offset;
7471 MOVFragmentStreamInfo * frag_stream_info;
7474 return AVERROR_INVALIDDATA;
7478 time = avio_rb64(f);
7479 offset = avio_rb64(f);
7481 time = avio_rb32(f);
7482 offset = avio_rb32(f);
7485 // The first sample of each stream in a fragment is always a random
7486 // access sample. So it's entry in the tfra can be used as the
7487 // initial PTS of the fragment.
7488 index = update_frag_index(mov, offset);
7489 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7490 if (frag_stream_info &&
7491 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7492 frag_stream_info->first_tfra_pts = time;
7494 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7496 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7498 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7502 avio_seek(f, pos + size, SEEK_SET);
7506 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7508 int64_t stream_size = avio_size(f);
7509 int64_t original_pos = avio_tell(f);
7513 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7517 mfra_size = avio_rb32(f);
7518 if (mfra_size < 0 || mfra_size > stream_size) {
7519 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7522 if ((seek_ret = avio_seek(f, -mfra_size, SEEK_CUR)) < 0) {
7526 if (avio_rb32(f) != mfra_size) {
7527 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7530 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7531 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7534 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7536 ret = read_tfra(c, f);
7542 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7544 av_log(c->fc, AV_LOG_ERROR,
7545 "failed to seek back after looking for mfra\n");
7551 static int mov_read_header(AVFormatContext *s)
7553 MOVContext *mov = s->priv_data;
7554 AVIOContext *pb = s->pb;
7556 MOVAtom atom = { AV_RL32("root") };
7559 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7560 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7561 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7562 return AVERROR(EINVAL);
7566 mov->trak_index = -1;
7567 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7568 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7569 atom.size = avio_size(pb);
7571 atom.size = INT64_MAX;
7573 /* check MOV header */
7575 if (mov->moov_retry)
7576 avio_seek(pb, 0, SEEK_SET);
7577 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7578 av_log(s, AV_LOG_ERROR, "error reading header\n");
7581 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7582 if (!mov->found_moov) {
7583 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7584 err = AVERROR_INVALIDDATA;
7587 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7589 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7590 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7591 mov_read_chapters(s);
7592 for (i = 0; i < s->nb_streams; i++)
7593 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7594 mov_read_timecode_track(s, s->streams[i]);
7595 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7596 mov_read_rtmd_track(s, s->streams[i]);
7600 /* copy timecode metadata from tmcd tracks to the related video streams */
7601 for (i = 0; i < s->nb_streams; i++) {
7602 AVStream *st = s->streams[i];
7603 MOVStreamContext *sc = st->priv_data;
7604 if (sc->timecode_track > 0) {
7605 AVDictionaryEntry *tcr;
7606 int tmcd_st_id = -1;
7608 for (j = 0; j < s->nb_streams; j++)
7609 if (s->streams[j]->id == sc->timecode_track)
7612 if (tmcd_st_id < 0 || tmcd_st_id == i)
7614 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7616 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7619 export_orphan_timecode(s);
7621 for (i = 0; i < s->nb_streams; i++) {
7622 AVStream *st = s->streams[i];
7623 MOVStreamContext *sc = st->priv_data;
7624 fix_timescale(mov, sc);
7625 if(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7626 st->skip_samples = sc->start_pad;
7628 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7629 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7630 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7631 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7632 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7633 st->codecpar->width = sc->width;
7634 st->codecpar->height = sc->height;
7636 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7637 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7641 if (mov->handbrake_version &&
7642 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7643 st->codecpar->codec_id == AV_CODEC_ID_MP3
7645 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7646 st->need_parsing = AVSTREAM_PARSE_FULL;
7650 if (mov->trex_data) {
7651 for (i = 0; i < s->nb_streams; i++) {
7652 AVStream *st = s->streams[i];
7653 MOVStreamContext *sc = st->priv_data;
7654 if (st->duration > 0) {
7655 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7656 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7657 sc->data_size, sc->time_scale);
7658 err = AVERROR_INVALIDDATA;
7661 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7666 if (mov->use_mfra_for > 0) {
7667 for (i = 0; i < s->nb_streams; i++) {
7668 AVStream *st = s->streams[i];
7669 MOVStreamContext *sc = st->priv_data;
7670 if (sc->duration_for_fps > 0) {
7671 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7672 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7673 sc->data_size, sc->time_scale);
7674 err = AVERROR_INVALIDDATA;
7677 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7678 sc->duration_for_fps;
7683 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7684 if (mov->bitrates[i]) {
7685 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7689 ff_rfps_calculate(s);
7691 for (i = 0; i < s->nb_streams; i++) {
7692 AVStream *st = s->streams[i];
7693 MOVStreamContext *sc = st->priv_data;
7695 switch (st->codecpar->codec_type) {
7696 case AVMEDIA_TYPE_AUDIO:
7697 err = ff_replaygain_export(st, s->metadata);
7702 case AVMEDIA_TYPE_VIDEO:
7703 if (sc->display_matrix) {
7704 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7705 sizeof(int32_t) * 9);
7709 sc->display_matrix = NULL;
7712 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7713 (uint8_t *)sc->stereo3d,
7714 sizeof(*sc->stereo3d));
7718 sc->stereo3d = NULL;
7720 if (sc->spherical) {
7721 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7722 (uint8_t *)sc->spherical,
7723 sc->spherical_size);
7727 sc->spherical = NULL;
7729 if (sc->mastering) {
7730 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7731 (uint8_t *)sc->mastering,
7732 sizeof(*sc->mastering));
7736 sc->mastering = NULL;
7739 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7740 (uint8_t *)sc->coll,
7750 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7752 for (i = 0; i < mov->frag_index.nb_items; i++)
7753 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7754 mov->frag_index.item[i].headers_read = 1;
7762 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7764 AVIndexEntry *sample = NULL;
7765 int64_t best_dts = INT64_MAX;
7767 for (i = 0; i < s->nb_streams; i++) {
7768 AVStream *avst = s->streams[i];
7769 MOVStreamContext *msc = avst->priv_data;
7770 if (msc->pb && msc->current_sample < avst->nb_index_entries) {
7771 AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample];
7772 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7773 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7774 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7775 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7776 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
7777 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7778 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7779 sample = current_sample;
7788 static int should_retry(AVIOContext *pb, int error_code) {
7789 if (error_code == AVERROR_EOF || avio_feof(pb))
7795 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7798 MOVContext *mov = s->priv_data;
7800 if (index >= 0 && index < mov->frag_index.nb_items)
7801 target = mov->frag_index.item[index].moof_offset;
7802 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7803 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7804 return AVERROR_INVALIDDATA;
7807 mov->next_root_atom = 0;
7808 if (index < 0 || index >= mov->frag_index.nb_items)
7809 index = search_frag_moof_offset(&mov->frag_index, target);
7810 if (index < mov->frag_index.nb_items &&
7811 mov->frag_index.item[index].moof_offset == target) {
7812 if (index + 1 < mov->frag_index.nb_items)
7813 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7814 if (mov->frag_index.item[index].headers_read)
7816 mov->frag_index.item[index].headers_read = 1;
7819 mov->found_mdat = 0;
7821 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7824 if (avio_feof(s->pb))
7826 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7831 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7833 uint8_t *side, *extradata;
7836 /* Save the current index. */
7837 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7839 /* Notify the decoder that extradata changed. */
7840 extradata_size = sc->extradata_size[sc->last_stsd_index];
7841 extradata = sc->extradata[sc->last_stsd_index];
7842 if (extradata_size > 0 && extradata) {
7843 side = av_packet_new_side_data(pkt,
7844 AV_PKT_DATA_NEW_EXTRADATA,
7847 return AVERROR(ENOMEM);
7848 memcpy(side, extradata, extradata_size);
7854 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int size)
7859 return AVERROR_INVALIDDATA;
7860 new_size = ((size - 8) / 2) * 3;
7861 ret = av_new_packet(pkt, new_size);
7866 for (int j = 0; j < new_size; j += 3) {
7867 pkt->data[j] = 0xFC;
7868 pkt->data[j+1] = avio_r8(pb);
7869 pkt->data[j+2] = avio_r8(pb);
7875 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7877 MOVContext *mov = s->priv_data;
7878 MOVStreamContext *sc;
7879 AVIndexEntry *sample;
7880 AVStream *st = NULL;
7881 int64_t current_index;
7885 sample = mov_find_next_sample(s, &st);
7886 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7887 if (!mov->next_root_atom)
7889 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7894 /* must be done just before reading, to avoid infinite loop on sample */
7895 current_index = sc->current_index;
7896 mov_current_sample_inc(sc);
7898 if (mov->next_root_atom) {
7899 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7900 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7903 if (st->discard != AVDISCARD_ALL) {
7904 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7905 if (ret64 != sample->pos) {
7906 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7907 sc->ffindex, sample->pos);
7908 if (should_retry(sc->pb, ret64)) {
7909 mov_current_sample_dec(sc);
7911 return AVERROR_INVALIDDATA;
7914 if( st->discard == AVDISCARD_NONKEY && 0==(sample->flags & AVINDEX_KEYFRAME) ) {
7915 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7919 if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
7920 ret = get_eia608_packet(sc->pb, pkt, sample->size);
7922 ret = av_get_packet(sc->pb, pkt, sample->size);
7924 if (should_retry(sc->pb, ret)) {
7925 mov_current_sample_dec(sc);
7929 if (sc->has_palette) {
7932 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7934 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7936 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7937 sc->has_palette = 0;
7940 #if CONFIG_DV_DEMUXER
7941 if (mov->dv_demux && sc->dv_audio_container) {
7942 avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7943 av_freep(&pkt->data);
7945 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7950 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7951 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7952 st->need_parsing = AVSTREAM_PARSE_FULL;
7956 pkt->stream_index = sc->ffindex;
7957 pkt->dts = sample->timestamp;
7958 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7959 pkt->flags |= AV_PKT_FLAG_DISCARD;
7961 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7962 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
7963 /* update ctts context */
7965 if (sc->ctts_index < sc->ctts_count &&
7966 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
7968 sc->ctts_sample = 0;
7971 int64_t next_dts = (sc->current_sample < st->nb_index_entries) ?
7972 st->index_entries[sc->current_sample].timestamp : st->duration;
7974 if (next_dts >= pkt->dts)
7975 pkt->duration = next_dts - pkt->dts;
7976 pkt->pts = pkt->dts;
7978 if (st->discard == AVDISCARD_ALL)
7980 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
7981 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
7982 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
7983 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
7985 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
7986 pkt->pos = sample->pos;
7988 /* Multiple stsd handling. */
7989 if (sc->stsc_data) {
7990 /* Keep track of the stsc index for the given sample, then check
7991 * if the stsd index is different from the last used one. */
7993 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
7994 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
7996 sc->stsc_sample = 0;
7997 /* Do not check indexes after a switch. */
7998 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
7999 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
8000 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
8001 ret = mov_change_extradata(sc, pkt);
8008 aax_filter(pkt->data, pkt->size, mov);
8010 ret = cenc_filter(mov, st, sc, pkt, current_index);
8018 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
8020 MOVContext *mov = s->priv_data;
8023 if (!mov->frag_index.complete)
8026 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
8029 if (!mov->frag_index.item[index].headers_read)
8030 return mov_switch_root(s, -1, index);
8031 if (index + 1 < mov->frag_index.nb_items)
8032 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
8037 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
8039 MOVStreamContext *sc = st->priv_data;
8040 int sample, time_sample, ret;
8043 // Here we consider timestamp to be PTS, hence try to offset it so that we
8044 // can search over the DTS timeline.
8045 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
8047 ret = mov_seek_fragment(s, st, timestamp);
8051 sample = av_index_search_timestamp(st, timestamp, flags);
8052 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
8053 if (sample < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp)
8055 if (sample < 0) /* not sure what to do */
8056 return AVERROR_INVALIDDATA;
8057 mov_current_sample_set(sc, sample);
8058 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
8059 /* adjust ctts index */
8060 if (sc->ctts_data) {
8062 for (i = 0; i < sc->ctts_count; i++) {
8063 int next = time_sample + sc->ctts_data[i].count;
8064 if (next > sc->current_sample) {
8066 sc->ctts_sample = sc->current_sample - time_sample;
8073 /* adjust stsd index */
8074 if (sc->chunk_count) {
8076 for (i = 0; i < sc->stsc_count; i++) {
8077 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
8078 if (next > sc->current_sample) {
8080 sc->stsc_sample = sc->current_sample - time_sample;
8083 av_assert0(next == (int)next);
8091 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
8093 MOVContext *mc = s->priv_data;
8098 if (stream_index >= s->nb_streams)
8099 return AVERROR_INVALIDDATA;
8101 st = s->streams[stream_index];
8102 sample = mov_seek_stream(s, st, sample_time, flags);
8106 if (mc->seek_individually) {
8107 /* adjust seek timestamp to found sample timestamp */
8108 int64_t seek_timestamp = st->index_entries[sample].timestamp;
8110 for (i = 0; i < s->nb_streams; i++) {
8112 MOVStreamContext *sc = s->streams[i]->priv_data;
8114 st->skip_samples = (sample_time <= 0) ? sc->start_pad : 0;
8116 if (stream_index == i)
8119 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
8120 mov_seek_stream(s, st, timestamp, flags);
8123 for (i = 0; i < s->nb_streams; i++) {
8124 MOVStreamContext *sc;
8127 mov_current_sample_set(sc, 0);
8130 MOVStreamContext *sc;
8131 AVIndexEntry *entry = mov_find_next_sample(s, &st);
8133 return AVERROR_INVALIDDATA;
8135 if (sc->ffindex == stream_index && sc->current_sample == sample)
8137 mov_current_sample_inc(sc);
8143 #define OFFSET(x) offsetof(MOVContext, x)
8144 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
8145 static const AVOption mov_options[] = {
8146 {"use_absolute_path",
8147 "allow using absolute path when opening alias, this is a possible security issue",
8148 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
8150 {"seek_streams_individually",
8151 "Seek each stream individually to the closest point",
8152 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
8154 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
8156 {"advanced_editlist",
8157 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
8158 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
8160 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8163 "use mfra for fragment timestamps",
8164 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8165 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8167 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8168 FLAGS, "use_mfra_for" },
8169 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8170 FLAGS, "use_mfra_for" },
8171 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8172 FLAGS, "use_mfra_for" },
8173 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8174 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8175 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8176 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8177 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8178 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8179 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8180 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8181 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8182 .flags = AV_OPT_FLAG_DECODING_PARAM },
8183 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8184 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8185 {.i64 = 0}, 0, 1, FLAGS },
8190 static const AVClass mov_class = {
8191 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8192 .item_name = av_default_item_name,
8193 .option = mov_options,
8194 .version = LIBAVUTIL_VERSION_INT,
8197 AVInputFormat ff_mov_demuxer = {
8198 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8199 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8200 .priv_class = &mov_class,
8201 .priv_data_size = sizeof(MOVContext),
8202 .extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
8203 .read_probe = mov_probe,
8204 .read_header = mov_read_header,
8205 .read_packet = mov_read_packet,
8206 .read_close = mov_read_close,
8207 .read_seek = mov_read_seek,
8208 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,