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)
861 uint8_t buf[DDTS_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
863 uint32_t frame_duration_code = 0;
864 uint32_t channel_layout_code = 0;
868 if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
871 init_get_bits(&gb, buf, 8 * DDTS_SIZE);
873 if (c->fc->nb_streams < 1) {
876 st = c->fc->streams[c->fc->nb_streams-1];
878 st->codecpar->sample_rate = get_bits_long(&gb, 32);
879 if (st->codecpar->sample_rate <= 0) {
880 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
881 return AVERROR_INVALIDDATA;
883 skip_bits_long(&gb, 32); /* max bitrate */
884 st->codecpar->bit_rate = get_bits_long(&gb, 32);
885 st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
886 frame_duration_code = get_bits(&gb, 2);
887 skip_bits(&gb, 30); /* various fields */
888 channel_layout_code = get_bits(&gb, 16);
890 st->codecpar->frame_size =
891 (frame_duration_code == 0) ? 512 :
892 (frame_duration_code == 1) ? 1024 :
893 (frame_duration_code == 2) ? 2048 :
894 (frame_duration_code == 3) ? 4096 : 0;
896 if (channel_layout_code > 0xff) {
897 av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout");
899 st->codecpar->channel_layout =
900 ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
901 ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
902 ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
903 ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
904 ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
905 ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0);
907 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
912 static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
916 if (c->fc->nb_streams < 1)
918 st = c->fc->streams[c->fc->nb_streams-1];
923 /* skip version and flags */
926 ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
931 static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
936 if (c->fc->nb_streams < 1)
938 st = c->fc->streams[c->fc->nb_streams-1];
940 if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
941 av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
946 static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
948 const int num = avio_rb32(pb);
949 const int den = avio_rb32(pb);
952 if (c->fc->nb_streams < 1)
954 st = c->fc->streams[c->fc->nb_streams-1];
956 if ((st->sample_aspect_ratio.den != 1 || st->sample_aspect_ratio.num) && // default
957 (den != st->sample_aspect_ratio.den || num != st->sample_aspect_ratio.num)) {
958 av_log(c->fc, AV_LOG_WARNING,
959 "sample aspect ratio already set to %d:%d, ignoring 'pasp' atom (%d:%d)\n",
960 st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
962 } else if (den != 0) {
963 av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den,
969 /* this atom contains actual media data */
970 static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
972 if (atom.size == 0) /* wrong one (MP4) */
975 return 0; /* now go for moov */
978 #define DRM_BLOB_SIZE 56
980 static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
982 uint8_t intermediate_key[20];
983 uint8_t intermediate_iv[20];
986 uint8_t file_checksum[20];
987 uint8_t calculated_checksum[20];
991 uint8_t *activation_bytes = c->activation_bytes;
992 uint8_t *fixed_key = c->audible_fixed_key;
996 sha = av_sha_alloc();
998 return AVERROR(ENOMEM);
999 av_free(c->aes_decrypt);
1000 c->aes_decrypt = av_aes_alloc();
1001 if (!c->aes_decrypt) {
1002 ret = AVERROR(ENOMEM);
1006 /* drm blob processing */
1007 avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1008 avio_read(pb, input, DRM_BLOB_SIZE);
1009 avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1010 avio_read(pb, file_checksum, 20);
1012 av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == "); // required by external tools
1013 for (i = 0; i < 20; i++)
1014 av_log(c->fc, AV_LOG_INFO, "%02x", file_checksum[i]);
1015 av_log(c->fc, AV_LOG_INFO, "\n");
1017 /* verify activation data */
1018 if (!activation_bytes) {
1019 av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1020 ret = 0; /* allow ffprobe to continue working on .aax files */
1023 if (c->activation_bytes_size != 4) {
1024 av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1025 ret = AVERROR(EINVAL);
1029 /* verify fixed key */
1030 if (c->audible_fixed_key_size != 16) {
1031 av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1032 ret = AVERROR(EINVAL);
1036 /* AAX (and AAX+) key derivation */
1037 av_sha_init(sha, 160);
1038 av_sha_update(sha, fixed_key, 16);
1039 av_sha_update(sha, activation_bytes, 4);
1040 av_sha_final(sha, intermediate_key);
1041 av_sha_init(sha, 160);
1042 av_sha_update(sha, fixed_key, 16);
1043 av_sha_update(sha, intermediate_key, 20);
1044 av_sha_update(sha, activation_bytes, 4);
1045 av_sha_final(sha, intermediate_iv);
1046 av_sha_init(sha, 160);
1047 av_sha_update(sha, intermediate_key, 16);
1048 av_sha_update(sha, intermediate_iv, 16);
1049 av_sha_final(sha, calculated_checksum);
1050 if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1051 av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1052 ret = AVERROR_INVALIDDATA;
1055 av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1056 av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1057 for (i = 0; i < 4; i++) {
1058 // file data (in output) is stored in big-endian mode
1059 if (activation_bytes[i] != output[3 - i]) { // critical error
1060 av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1061 ret = AVERROR_INVALIDDATA;
1065 memcpy(c->file_key, output + 8, 16);
1066 memcpy(input, output + 26, 16);
1067 av_sha_init(sha, 160);
1068 av_sha_update(sha, input, 16);
1069 av_sha_update(sha, c->file_key, 16);
1070 av_sha_update(sha, fixed_key, 16);
1071 av_sha_final(sha, c->file_iv);
1079 // Audible AAX (and AAX+) bytestream decryption
1080 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1083 unsigned char iv[16];
1085 memcpy(iv, c->file_iv, 16); // iv is overwritten
1086 blocks = size >> 4; // trailing bytes are not encrypted!
1087 av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1088 av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1093 /* read major brand, minor version and compatible brands and store them as metadata */
1094 static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1097 int comp_brand_size;
1098 char* comp_brands_str;
1099 uint8_t type[5] = {0};
1100 int ret = ffio_read_size(pb, type, 4);
1104 if (strcmp(type, "qt "))
1106 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1107 av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1108 minor_ver = avio_rb32(pb); /* minor version */
1109 av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1111 comp_brand_size = atom.size - 8;
1112 if (comp_brand_size < 0)
1113 return AVERROR_INVALIDDATA;
1114 comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1115 if (!comp_brands_str)
1116 return AVERROR(ENOMEM);
1118 ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1120 av_freep(&comp_brands_str);
1123 comp_brands_str[comp_brand_size] = 0;
1124 av_dict_set(&c->fc->metadata, "compatible_brands",
1125 comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1130 /* this atom should contain all header atoms */
1131 static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1135 if (c->found_moov) {
1136 av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1137 avio_skip(pb, atom.size);
1141 if ((ret = mov_read_default(c, pb, atom)) < 0)
1143 /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1144 /* so we don't parse the whole file if over a network */
1146 return 0; /* now go for mdat */
1149 static MOVFragmentStreamInfo * get_frag_stream_info(
1150 MOVFragmentIndex *frag_index,
1155 MOVFragmentIndexItem * item;
1157 if (index < 0 || index >= frag_index->nb_items)
1159 item = &frag_index->item[index];
1160 for (i = 0; i < item->nb_stream_info; i++)
1161 if (item->stream_info[i].id == id)
1162 return &item->stream_info[i];
1164 // This shouldn't happen
1168 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1171 MOVFragmentIndexItem * item;
1173 if (frag_index->current < 0 ||
1174 frag_index->current >= frag_index->nb_items)
1177 item = &frag_index->item[frag_index->current];
1178 for (i = 0; i < item->nb_stream_info; i++)
1179 if (item->stream_info[i].id == id) {
1184 // id not found. This shouldn't happen.
1188 static MOVFragmentStreamInfo * get_current_frag_stream_info(
1189 MOVFragmentIndex *frag_index)
1191 MOVFragmentIndexItem *item;
1192 if (frag_index->current < 0 ||
1193 frag_index->current >= frag_index->nb_items)
1196 item = &frag_index->item[frag_index->current];
1197 if (item->current >= 0 && item->current < item->nb_stream_info)
1198 return &item->stream_info[item->current];
1200 // This shouldn't happen
1204 static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
1207 int64_t moof_offset;
1209 // Optimize for appending new entries
1210 if (!frag_index->nb_items ||
1211 frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1212 return frag_index->nb_items;
1215 b = frag_index->nb_items;
1219 moof_offset = frag_index->item[m].moof_offset;
1220 if (moof_offset >= offset)
1222 if (moof_offset <= offset)
1228 static int64_t get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
1230 av_assert0(frag_stream_info);
1231 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1232 return frag_stream_info->sidx_pts;
1233 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1234 return frag_stream_info->first_tfra_pts;
1235 return frag_stream_info->tfdt_dts;
1238 static int64_t get_frag_time(MOVFragmentIndex *frag_index,
1239 int index, int track_id)
1241 MOVFragmentStreamInfo * frag_stream_info;
1245 if (track_id >= 0) {
1246 frag_stream_info = get_frag_stream_info(frag_index, index, track_id);
1247 return frag_stream_info->sidx_pts;
1250 for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1251 frag_stream_info = &frag_index->item[index].stream_info[i];
1252 timestamp = get_stream_info_time(frag_stream_info);
1253 if (timestamp != AV_NOPTS_VALUE)
1256 return AV_NOPTS_VALUE;
1259 static int search_frag_timestamp(MOVFragmentIndex *frag_index,
1260 AVStream *st, int64_t timestamp)
1267 // If the stream is referenced by any sidx, limit the search
1268 // to fragments that referenced this stream in the sidx
1269 MOVStreamContext *sc = st->priv_data;
1275 b = frag_index->nb_items;
1278 m0 = m = (a + b) >> 1;
1281 (frag_time = get_frag_time(frag_index, m, id)) == AV_NOPTS_VALUE)
1284 if (m < b && frag_time <= timestamp)
1293 static int update_frag_index(MOVContext *c, int64_t offset)
1296 MOVFragmentIndexItem * item;
1297 MOVFragmentStreamInfo * frag_stream_info;
1299 // If moof_offset already exists in frag_index, return index to it
1300 index = search_frag_moof_offset(&c->frag_index, offset);
1301 if (index < c->frag_index.nb_items &&
1302 c->frag_index.item[index].moof_offset == offset)
1305 // offset is not yet in frag index.
1306 // Insert new item at index (sorted by moof offset)
1307 item = av_fast_realloc(c->frag_index.item,
1308 &c->frag_index.allocated_size,
1309 (c->frag_index.nb_items + 1) *
1310 sizeof(*c->frag_index.item));
1313 c->frag_index.item = item;
1315 frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1316 sizeof(*item->stream_info));
1317 if (!frag_stream_info)
1320 for (i = 0; i < c->fc->nb_streams; i++) {
1321 // Avoid building frag index if streams lack track id.
1322 if (c->fc->streams[i]->id < 0) {
1323 av_free(frag_stream_info);
1324 return AVERROR_INVALIDDATA;
1327 frag_stream_info[i].id = c->fc->streams[i]->id;
1328 frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1329 frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1330 frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1331 frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1332 frag_stream_info[i].index_entry = -1;
1333 frag_stream_info[i].encryption_index = NULL;
1336 if (index < c->frag_index.nb_items)
1337 memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1338 (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1340 item = &c->frag_index.item[index];
1341 item->headers_read = 0;
1343 item->nb_stream_info = c->fc->nb_streams;
1344 item->moof_offset = offset;
1345 item->stream_info = frag_stream_info;
1346 c->frag_index.nb_items++;
1351 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1352 int id, int entries)
1355 MOVFragmentStreamInfo * frag_stream_info;
1359 for (i = index; i < frag_index->nb_items; i++) {
1360 frag_stream_info = get_frag_stream_info(frag_index, i, id);
1361 if (frag_stream_info && frag_stream_info->index_entry >= 0)
1362 frag_stream_info->index_entry += entries;
1366 static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1368 // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1369 c->fragment.found_tfhd = 0;
1371 if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1372 c->has_looked_for_mfra = 1;
1373 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1375 av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1377 if ((ret = mov_read_mfra(c, pb)) < 0) {
1378 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1379 "read the mfra (may be a live ismv)\n");
1382 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1383 "seekable, can not look for mfra\n");
1386 c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1387 av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1388 c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1389 return mov_read_default(c, pb, atom);
1392 static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time, void *logctx)
1395 if (time >= 2082844800)
1396 time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1398 if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1399 av_log(logctx, AV_LOG_DEBUG, "creation_time is not representable\n");
1403 avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1407 static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1410 MOVStreamContext *sc;
1412 char language[4] = {0};
1414 int64_t creation_time;
1416 if (c->fc->nb_streams < 1)
1418 st = c->fc->streams[c->fc->nb_streams-1];
1421 if (sc->time_scale) {
1422 av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1423 return AVERROR_INVALIDDATA;
1426 version = avio_r8(pb);
1428 avpriv_request_sample(c->fc, "Version %d", version);
1429 return AVERROR_PATCHWELCOME;
1431 avio_rb24(pb); /* flags */
1433 creation_time = avio_rb64(pb);
1436 creation_time = avio_rb32(pb);
1437 avio_rb32(pb); /* modification time */
1439 mov_metadata_creation_time(&st->metadata, creation_time, c->fc);
1441 sc->time_scale = avio_rb32(pb);
1442 if (sc->time_scale <= 0) {
1443 av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1446 st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1448 lang = avio_rb16(pb); /* language */
1449 if (ff_mov_lang_to_iso639(lang, language))
1450 av_dict_set(&st->metadata, "language", language, 0);
1451 avio_rb16(pb); /* quality */
1456 static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1459 int64_t creation_time;
1460 int version = avio_r8(pb); /* version */
1461 avio_rb24(pb); /* flags */
1464 creation_time = avio_rb64(pb);
1467 creation_time = avio_rb32(pb);
1468 avio_rb32(pb); /* modification time */
1470 mov_metadata_creation_time(&c->fc->metadata, creation_time, c->fc);
1471 c->time_scale = avio_rb32(pb); /* time scale */
1472 if (c->time_scale <= 0) {
1473 av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1476 av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1478 c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1479 // set the AVCodecContext duration because the duration of individual tracks
1480 // may be inaccurate
1481 if (c->time_scale > 0 && !c->trex_data)
1482 c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale);
1483 avio_rb32(pb); /* preferred scale */
1485 avio_rb16(pb); /* preferred volume */
1487 avio_skip(pb, 10); /* reserved */
1489 /* movie display matrix, store it in main context and use it later on */
1490 for (i = 0; i < 3; i++) {
1491 c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1492 c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1493 c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1496 avio_rb32(pb); /* preview time */
1497 avio_rb32(pb); /* preview duration */
1498 avio_rb32(pb); /* poster time */
1499 avio_rb32(pb); /* selection time */
1500 avio_rb32(pb); /* selection duration */
1501 avio_rb32(pb); /* current time */
1502 avio_rb32(pb); /* next track ID */
1507 static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1512 if (c->fc->nb_streams < 1)
1514 st = c->fc->streams[c->fc->nb_streams-1];
1516 little_endian = avio_rb16(pb) & 0xFF;
1517 av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1518 if (little_endian == 1) {
1519 switch (st->codecpar->codec_id) {
1520 case AV_CODEC_ID_PCM_S24BE:
1521 st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE;
1523 case AV_CODEC_ID_PCM_S32BE:
1524 st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE;
1526 case AV_CODEC_ID_PCM_F32BE:
1527 st->codecpar->codec_id = AV_CODEC_ID_PCM_F32LE;
1529 case AV_CODEC_ID_PCM_F64BE:
1530 st->codecpar->codec_id = AV_CODEC_ID_PCM_F64LE;
1539 static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1542 uint8_t *icc_profile;
1543 char color_parameter_type[5] = { 0 };
1544 uint16_t color_primaries, color_trc, color_matrix;
1547 if (c->fc->nb_streams < 1)
1549 st = c->fc->streams[c->fc->nb_streams - 1];
1551 ret = ffio_read_size(pb, color_parameter_type, 4);
1554 if (strncmp(color_parameter_type, "nclx", 4) &&
1555 strncmp(color_parameter_type, "nclc", 4) &&
1556 strncmp(color_parameter_type, "prof", 4)) {
1557 av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
1558 color_parameter_type);
1562 if (!strncmp(color_parameter_type, "prof", 4)) {
1563 icc_profile = av_stream_new_side_data(st, AV_PKT_DATA_ICC_PROFILE, atom.size - 4);
1565 return AVERROR(ENOMEM);
1566 ret = ffio_read_size(pb, icc_profile, atom.size - 4);
1570 color_primaries = avio_rb16(pb);
1571 color_trc = avio_rb16(pb);
1572 color_matrix = avio_rb16(pb);
1574 av_log(c->fc, AV_LOG_TRACE,
1575 "%s: pri %d trc %d matrix %d",
1576 color_parameter_type, color_primaries, color_trc, color_matrix);
1578 if (!strncmp(color_parameter_type, "nclx", 4)) {
1579 uint8_t color_range = avio_r8(pb) >> 7;
1580 av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
1582 st->codecpar->color_range = AVCOL_RANGE_JPEG;
1584 st->codecpar->color_range = AVCOL_RANGE_MPEG;
1587 if (!av_color_primaries_name(color_primaries))
1588 color_primaries = AVCOL_PRI_UNSPECIFIED;
1589 if (!av_color_transfer_name(color_trc))
1590 color_trc = AVCOL_TRC_UNSPECIFIED;
1591 if (!av_color_space_name(color_matrix))
1592 color_matrix = AVCOL_SPC_UNSPECIFIED;
1594 st->codecpar->color_primaries = color_primaries;
1595 st->codecpar->color_trc = color_trc;
1596 st->codecpar->color_space = color_matrix;
1597 av_log(c->fc, AV_LOG_TRACE, "\n");
1602 static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1605 unsigned mov_field_order;
1606 enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
1608 if (c->fc->nb_streams < 1) // will happen with jp2 files
1610 st = c->fc->streams[c->fc->nb_streams-1];
1612 return AVERROR_INVALIDDATA;
1613 mov_field_order = avio_rb16(pb);
1614 if ((mov_field_order & 0xFF00) == 0x0100)
1615 decoded_field_order = AV_FIELD_PROGRESSIVE;
1616 else if ((mov_field_order & 0xFF00) == 0x0200) {
1617 switch (mov_field_order & 0xFF) {
1618 case 0x01: decoded_field_order = AV_FIELD_TT;
1620 case 0x06: decoded_field_order = AV_FIELD_BB;
1622 case 0x09: decoded_field_order = AV_FIELD_TB;
1624 case 0x0E: decoded_field_order = AV_FIELD_BT;
1628 if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
1629 av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
1631 st->codecpar->field_order = decoded_field_order;
1636 static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
1639 uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
1640 if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
1641 return AVERROR_INVALIDDATA;
1642 if ((err = av_reallocp(&par->extradata, size)) < 0) {
1643 par->extradata_size = 0;
1646 par->extradata_size = size - AV_INPUT_BUFFER_PADDING_SIZE;
1650 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
1651 static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1652 AVCodecParameters *par, uint8_t *buf)
1654 int64_t result = atom.size;
1657 AV_WB32(buf , atom.size + 8);
1658 AV_WL32(buf + 4, atom.type);
1659 err = ffio_read_size(pb, buf + 8, atom.size);
1661 par->extradata_size -= atom.size;
1663 } else if (err < atom.size) {
1664 av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
1665 par->extradata_size -= atom.size - err;
1668 memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1672 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
1673 static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1674 enum AVCodecID codec_id)
1677 uint64_t original_size;
1680 if (c->fc->nb_streams < 1) // will happen with jp2 files
1682 st = c->fc->streams[c->fc->nb_streams-1];
1684 if (st->codecpar->codec_id != codec_id)
1685 return 0; /* unexpected codec_id - don't mess with extradata */
1687 original_size = st->codecpar->extradata_size;
1688 err = mov_realloc_extradata(st->codecpar, atom);
1692 err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
1695 return 0; // Note: this is the original behavior to ignore truncation.
1698 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
1699 static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1701 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
1704 static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1706 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS);
1709 static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1711 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
1714 static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1716 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
1719 static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1721 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
1723 ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
1727 static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1729 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
1731 if (!ret && c->fc->nb_streams >= 1) {
1732 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1733 if (par->extradata_size >= 40) {
1734 par->height = AV_RB16(&par->extradata[36]);
1735 par->width = AV_RB16(&par->extradata[38]);
1741 static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1743 if (c->fc->nb_streams >= 1) {
1744 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1745 if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
1746 par->codec_id == AV_CODEC_ID_H264 &&
1750 cid = avio_rb16(pb);
1751 /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
1752 if (cid == 0xd4d || cid == 0xd4e)
1755 } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
1756 par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
1757 par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
1761 num = avio_rb32(pb);
1762 den = avio_rb32(pb);
1763 if (num <= 0 || den <= 0)
1765 switch (avio_rb32(pb)) {
1767 if (den >= INT_MAX / 2)
1771 c->fc->streams[c->fc->nb_streams-1]->display_aspect_ratio.num = num;
1772 c->fc->streams[c->fc->nb_streams-1]->display_aspect_ratio.den = den;
1779 return mov_read_avid(c, pb, atom);
1782 static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1786 uint64_t original_size;
1787 if (c->fc->nb_streams >= 1) {
1788 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1789 if (par->codec_id == AV_CODEC_ID_H264)
1791 if (atom.size == 16) {
1792 original_size = par->extradata_size;
1793 ret = mov_realloc_extradata(par, atom);
1795 length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
1796 if (length == atom.size) {
1797 const uint8_t range_value = par->extradata[original_size + 19];
1798 switch (range_value) {
1800 par->color_range = AVCOL_RANGE_MPEG;
1803 par->color_range = AVCOL_RANGE_JPEG;
1806 av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
1809 ff_dlog(c->fc, "color_range: %d\n", par->color_range);
1811 /* For some reason the whole atom was not added to the extradata */
1812 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
1815 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
1818 av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
1825 static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1827 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
1830 static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1835 if (c->fc->nb_streams < 1)
1837 st = c->fc->streams[c->fc->nb_streams-1];
1839 if ((uint64_t)atom.size > (1<<30))
1840 return AVERROR_INVALIDDATA;
1842 if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
1843 st->codecpar->codec_id == AV_CODEC_ID_QDMC ||
1844 st->codecpar->codec_id == AV_CODEC_ID_SPEEX) {
1845 // pass all frma atom to codec, needed at least for QDMC and QDM2
1846 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1849 } else if (atom.size > 8) { /* to read frma, esds atoms */
1850 if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
1852 ret = ffio_ensure_seekback(pb, 8);
1855 buffer = avio_rb64(pb);
1857 if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
1858 && buffer >> 32 <= atom.size
1859 && buffer >> 32 >= 8) {
1862 } else if (!st->codecpar->extradata_size) {
1863 #define ALAC_EXTRADATA_SIZE 36
1864 st->codecpar->extradata = av_mallocz(ALAC_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
1865 if (!st->codecpar->extradata)
1866 return AVERROR(ENOMEM);
1867 st->codecpar->extradata_size = ALAC_EXTRADATA_SIZE;
1868 AV_WB32(st->codecpar->extradata , ALAC_EXTRADATA_SIZE);
1869 AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
1870 AV_WB64(st->codecpar->extradata + 12, buffer);
1871 avio_read(pb, st->codecpar->extradata + 20, 16);
1872 avio_skip(pb, atom.size - 24);
1876 if ((ret = mov_read_default(c, pb, atom)) < 0)
1879 avio_skip(pb, atom.size);
1884 * This function reads atom content and puts data in extradata without tag
1885 * nor size unlike mov_read_extradata.
1887 static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1892 if (c->fc->nb_streams < 1)
1894 st = c->fc->streams[c->fc->nb_streams-1];
1896 if ((uint64_t)atom.size > (1<<30))
1897 return AVERROR_INVALIDDATA;
1899 if (atom.size >= 10) {
1900 // Broken files created by legacy versions of libavformat will
1901 // wrap a whole fiel atom inside of a glbl atom.
1902 unsigned size = avio_rb32(pb);
1903 unsigned type = avio_rl32(pb);
1904 avio_seek(pb, -8, SEEK_CUR);
1905 if (type == MKTAG('f','i','e','l') && size == atom.size)
1906 return mov_read_default(c, pb, atom);
1908 if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
1909 av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
1912 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1915 if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
1916 /* HEVC-based Dolby Vision derived from hvc1.
1917 Happens to match with an identifier
1918 previously utilized for DV. Thus, if we have
1919 the hvcC extradata box available as specified,
1920 set codec to HEVC */
1921 st->codecpar->codec_id = AV_CODEC_ID_HEVC;
1926 static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1929 uint8_t profile_level;
1932 if (c->fc->nb_streams < 1)
1934 st = c->fc->streams[c->fc->nb_streams-1];
1936 if (atom.size >= (1<<28) || atom.size < 7)
1937 return AVERROR_INVALIDDATA;
1939 profile_level = avio_r8(pb);
1940 if ((profile_level & 0xf0) != 0xc0)
1943 avio_seek(pb, 6, SEEK_CUR);
1944 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
1952 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
1953 * but can have extradata appended at the end after the 40 bytes belonging
1956 static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1961 if (c->fc->nb_streams < 1)
1963 if (atom.size <= 40)
1965 st = c->fc->streams[c->fc->nb_streams-1];
1967 if ((uint64_t)atom.size > (1<<30))
1968 return AVERROR_INVALIDDATA;
1971 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
1978 static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1981 MOVStreamContext *sc;
1982 unsigned int i, entries;
1984 if (c->trak_index < 0) {
1985 av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
1988 if (c->fc->nb_streams < 1)
1990 st = c->fc->streams[c->fc->nb_streams-1];
1993 avio_r8(pb); /* version */
1994 avio_rb24(pb); /* flags */
1996 entries = avio_rb32(pb);
2001 if (sc->chunk_offsets)
2002 av_log(c->fc, AV_LOG_WARNING, "Duplicated STCO atom\n");
2003 av_free(sc->chunk_offsets);
2004 sc->chunk_count = 0;
2005 sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2006 if (!sc->chunk_offsets)
2007 return AVERROR(ENOMEM);
2008 sc->chunk_count = entries;
2010 if (atom.type == MKTAG('s','t','c','o'))
2011 for (i = 0; i < entries && !pb->eof_reached; i++)
2012 sc->chunk_offsets[i] = avio_rb32(pb);
2013 else if (atom.type == MKTAG('c','o','6','4'))
2014 for (i = 0; i < entries && !pb->eof_reached; i++)
2015 sc->chunk_offsets[i] = avio_rb64(pb);
2017 return AVERROR_INVALIDDATA;
2019 sc->chunk_count = i;
2021 if (pb->eof_reached) {
2022 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2029 static int mov_codec_id(AVStream *st, uint32_t format)
2031 int id = ff_codec_get_id(ff_codec_movaudio_tags, format);
2034 ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2035 (format & 0xFFFF) == 'T' + ('S' << 8)))
2036 id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format) & 0xFFFF);
2038 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2039 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2040 } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2041 /* skip old ASF MPEG-4 tag */
2042 format && format != MKTAG('m','p','4','s')) {
2043 id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2045 id = ff_codec_get_id(ff_codec_bmp_tags, format);
2047 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
2048 else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2049 (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE &&
2050 st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2051 id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
2053 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
2055 id = ff_codec_get_id(ff_codec_movdata_tags, format);
2059 st->codecpar->codec_tag = format;
2064 static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
2065 AVStream *st, MOVStreamContext *sc)
2067 uint8_t codec_name[32] = { 0 };
2071 /* The first 16 bytes of the video sample description are already
2072 * read in ff_mov_read_stsd_entries() */
2073 stsd_start = avio_tell(pb) - 16;
2075 avio_rb16(pb); /* version */
2076 avio_rb16(pb); /* revision level */
2077 avio_rb32(pb); /* vendor */
2078 avio_rb32(pb); /* temporal quality */
2079 avio_rb32(pb); /* spatial quality */
2081 st->codecpar->width = avio_rb16(pb); /* width */
2082 st->codecpar->height = avio_rb16(pb); /* height */
2084 avio_rb32(pb); /* horiz resolution */
2085 avio_rb32(pb); /* vert resolution */
2086 avio_rb32(pb); /* data size, always 0 */
2087 avio_rb16(pb); /* frames per samples */
2089 len = avio_r8(pb); /* codec name, pascal string */
2092 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2094 avio_skip(pb, 31 - len);
2097 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2099 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2100 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2101 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2102 st->codecpar->width &= ~1;
2103 st->codecpar->height &= ~1;
2105 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2106 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2107 !strncmp(codec_name, "Sorenson H263", 13))
2108 st->codecpar->codec_id = AV_CODEC_ID_FLV1;
2110 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2112 avio_seek(pb, stsd_start, SEEK_SET);
2114 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2115 st->codecpar->bits_per_coded_sample &= 0x1F;
2116 sc->has_palette = 1;
2120 static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
2121 AVStream *st, MOVStreamContext *sc)
2123 int bits_per_sample, flags;
2124 uint16_t version = avio_rb16(pb);
2125 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2127 avio_rb16(pb); /* revision level */
2128 avio_rb32(pb); /* vendor */
2130 st->codecpar->channels = avio_rb16(pb); /* channel count */
2131 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2132 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", st->codecpar->channels);
2134 sc->audio_cid = avio_rb16(pb);
2135 avio_rb16(pb); /* packet size = 0 */
2137 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2139 // Read QT version 1 fields. In version 0 these do not exist.
2140 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2142 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2143 (sc->stsd_version == 0 && version > 0)) {
2145 sc->samples_per_frame = avio_rb32(pb);
2146 avio_rb32(pb); /* bytes per packet */
2147 sc->bytes_per_frame = avio_rb32(pb);
2148 avio_rb32(pb); /* bytes per sample */
2149 } else if (version == 2) {
2150 avio_rb32(pb); /* sizeof struct only */
2151 st->codecpar->sample_rate = av_int2double(avio_rb64(pb));
2152 st->codecpar->channels = avio_rb32(pb);
2153 avio_rb32(pb); /* always 0x7F000000 */
2154 st->codecpar->bits_per_coded_sample = avio_rb32(pb);
2156 flags = avio_rb32(pb); /* lpcm format specific flag */
2157 sc->bytes_per_frame = avio_rb32(pb);
2158 sc->samples_per_frame = avio_rb32(pb);
2159 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2160 st->codecpar->codec_id =
2161 ff_mov_get_lpcm_codec_id(st->codecpar->bits_per_coded_sample,
2164 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2165 /* can't correctly handle variable sized packet as audio unit */
2166 switch (st->codecpar->codec_id) {
2167 case AV_CODEC_ID_MP2:
2168 case AV_CODEC_ID_MP3:
2169 st->need_parsing = AVSTREAM_PARSE_FULL;
2175 if (sc->format == 0) {
2176 if (st->codecpar->bits_per_coded_sample == 8)
2177 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2178 else if (st->codecpar->bits_per_coded_sample == 16)
2179 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2182 switch (st->codecpar->codec_id) {
2183 case AV_CODEC_ID_PCM_S8:
2184 case AV_CODEC_ID_PCM_U8:
2185 if (st->codecpar->bits_per_coded_sample == 16)
2186 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16BE;
2188 case AV_CODEC_ID_PCM_S16LE:
2189 case AV_CODEC_ID_PCM_S16BE:
2190 if (st->codecpar->bits_per_coded_sample == 8)
2191 st->codecpar->codec_id = AV_CODEC_ID_PCM_S8;
2192 else if (st->codecpar->bits_per_coded_sample == 24)
2193 st->codecpar->codec_id =
2194 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2195 AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
2196 else if (st->codecpar->bits_per_coded_sample == 32)
2197 st->codecpar->codec_id =
2198 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2199 AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
2201 /* set values for old format before stsd version 1 appeared */
2202 case AV_CODEC_ID_MACE3:
2203 sc->samples_per_frame = 6;
2204 sc->bytes_per_frame = 2 * st->codecpar->channels;
2206 case AV_CODEC_ID_MACE6:
2207 sc->samples_per_frame = 6;
2208 sc->bytes_per_frame = 1 * st->codecpar->channels;
2210 case AV_CODEC_ID_ADPCM_IMA_QT:
2211 sc->samples_per_frame = 64;
2212 sc->bytes_per_frame = 34 * st->codecpar->channels;
2214 case AV_CODEC_ID_GSM:
2215 sc->samples_per_frame = 160;
2216 sc->bytes_per_frame = 33;
2222 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2223 if (bits_per_sample) {
2224 st->codecpar->bits_per_coded_sample = bits_per_sample;
2225 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->channels;
2229 static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
2230 AVStream *st, MOVStreamContext *sc,
2233 // ttxt stsd contains display flags, justification, background
2234 // color, fonts, and default styles, so fake an atom to read it
2235 MOVAtom fake_atom = { .size = size };
2236 // mp4s contains a regular esds atom
2237 if (st->codecpar->codec_tag != AV_RL32("mp4s"))
2238 mov_read_glbl(c, pb, fake_atom);
2239 st->codecpar->width = sc->width;
2240 st->codecpar->height = sc->height;
2243 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2248 y = (ycbcr >> 16) & 0xFF;
2249 cr = (ycbcr >> 8) & 0xFF;
2252 b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
2253 g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
2254 r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
2256 return (r << 16) | (g << 8) | b;
2259 static int mov_rewrite_dvd_sub_extradata(AVStream *st)
2261 char buf[256] = {0};
2262 uint8_t *src = st->codecpar->extradata;
2265 if (st->codecpar->extradata_size != 64)
2268 if (st->codecpar->width > 0 && st->codecpar->height > 0)
2269 snprintf(buf, sizeof(buf), "size: %dx%d\n",
2270 st->codecpar->width, st->codecpar->height);
2271 av_strlcat(buf, "palette: ", sizeof(buf));
2273 for (i = 0; i < 16; i++) {
2274 uint32_t yuv = AV_RB32(src + i * 4);
2275 uint32_t rgba = yuv_to_rgba(yuv);
2277 av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2280 if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2283 ret = ff_alloc_extradata(st->codecpar, strlen(buf));
2286 memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2291 static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
2292 AVStream *st, MOVStreamContext *sc,
2297 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2298 if ((int)size != size)
2299 return AVERROR(ENOMEM);
2301 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2305 MOVStreamContext *tmcd_ctx = st->priv_data;
2307 val = AV_RB32(st->codecpar->extradata + 4);
2308 tmcd_ctx->tmcd_flags = val;
2309 st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2310 st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2311 #if FF_API_LAVF_AVCTX
2312 FF_DISABLE_DEPRECATION_WARNINGS
2313 st->codec->time_base = av_inv_q(st->avg_frame_rate);
2314 FF_ENABLE_DEPRECATION_WARNINGS
2316 /* adjust for per frame dur in counter mode */
2317 if (tmcd_ctx->tmcd_flags & 0x0008) {
2318 int timescale = AV_RB32(st->codecpar->extradata + 8);
2319 int framedur = AV_RB32(st->codecpar->extradata + 12);
2320 st->avg_frame_rate.num *= timescale;
2321 st->avg_frame_rate.den *= framedur;
2322 #if FF_API_LAVF_AVCTX
2323 FF_DISABLE_DEPRECATION_WARNINGS
2324 st->codec->time_base.den *= timescale;
2325 st->codec->time_base.num *= framedur;
2326 FF_ENABLE_DEPRECATION_WARNINGS
2330 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2331 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2332 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2333 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2334 if (str_size > 0 && size >= (int)str_size + 30 &&
2335 st->codecpar->extradata[30] /* Don't add empty string */) {
2336 char *reel_name = av_malloc(str_size + 1);
2338 return AVERROR(ENOMEM);
2339 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2340 reel_name[str_size] = 0; /* Add null terminator */
2341 av_dict_set(&st->metadata, "reel_name", reel_name,
2342 AV_DICT_DONT_STRDUP_VAL);
2348 /* other codec type, just skip (rtp, mp4s ...) */
2349 avio_skip(pb, size);
2354 static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
2355 AVStream *st, MOVStreamContext *sc)
2357 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2358 !st->codecpar->sample_rate && sc->time_scale > 1)
2359 st->codecpar->sample_rate = sc->time_scale;
2361 /* special codec parameters handling */
2362 switch (st->codecpar->codec_id) {
2363 #if CONFIG_DV_DEMUXER
2364 case AV_CODEC_ID_DVAUDIO:
2365 c->dv_fctx = avformat_alloc_context();
2367 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2368 return AVERROR(ENOMEM);
2370 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2372 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2373 return AVERROR(ENOMEM);
2375 sc->dv_audio_container = 1;
2376 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
2379 /* no ifdef since parameters are always those */
2380 case AV_CODEC_ID_QCELP:
2381 st->codecpar->channels = 1;
2382 // force sample rate for qcelp when not stored in mov
2383 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2384 st->codecpar->sample_rate = 8000;
2385 // FIXME: Why is the following needed for some files?
2386 sc->samples_per_frame = 160;
2387 if (!sc->bytes_per_frame)
2388 sc->bytes_per_frame = 35;
2390 case AV_CODEC_ID_AMR_NB:
2391 st->codecpar->channels = 1;
2392 /* force sample rate for amr, stsd in 3gp does not store sample rate */
2393 st->codecpar->sample_rate = 8000;
2395 case AV_CODEC_ID_AMR_WB:
2396 st->codecpar->channels = 1;
2397 st->codecpar->sample_rate = 16000;
2399 case AV_CODEC_ID_MP2:
2400 case AV_CODEC_ID_MP3:
2401 /* force type after stsd for m1a hdlr */
2402 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2404 case AV_CODEC_ID_GSM:
2405 case AV_CODEC_ID_ADPCM_MS:
2406 case AV_CODEC_ID_ADPCM_IMA_WAV:
2407 case AV_CODEC_ID_ILBC:
2408 case AV_CODEC_ID_MACE3:
2409 case AV_CODEC_ID_MACE6:
2410 case AV_CODEC_ID_QDM2:
2411 st->codecpar->block_align = sc->bytes_per_frame;
2413 case AV_CODEC_ID_ALAC:
2414 if (st->codecpar->extradata_size == 36) {
2415 st->codecpar->channels = AV_RB8 (st->codecpar->extradata + 21);
2416 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2419 case AV_CODEC_ID_AC3:
2420 case AV_CODEC_ID_EAC3:
2421 case AV_CODEC_ID_MPEG1VIDEO:
2422 case AV_CODEC_ID_VC1:
2423 case AV_CODEC_ID_VP8:
2424 case AV_CODEC_ID_VP9:
2425 st->need_parsing = AVSTREAM_PARSE_FULL;
2433 static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
2434 int codec_tag, int format,
2437 int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2440 (codec_tag != format &&
2441 // AVID 1:1 samples with differing data format and codec tag exist
2442 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
2443 // prores is allowed to have differing data format and codec tag
2444 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
2446 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
2447 (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id
2448 : codec_tag != MKTAG('j','p','e','g')))) {
2449 /* Multiple fourcc, we skip JPEG. This is not correct, we should
2450 * export it as a separate AVStream but this needs a few changes
2451 * in the MOV demuxer, patch welcome. */
2453 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
2454 avio_skip(pb, size);
2461 int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
2464 MOVStreamContext *sc;
2465 int pseudo_stream_id;
2467 av_assert0 (c->fc->nb_streams >= 1);
2468 st = c->fc->streams[c->fc->nb_streams-1];
2471 for (pseudo_stream_id = 0;
2472 pseudo_stream_id < entries && !pb->eof_reached;
2473 pseudo_stream_id++) {
2474 //Parsing Sample description table
2476 int ret, dref_id = 1;
2477 MOVAtom a = { AV_RL32("stsd") };
2478 int64_t start_pos = avio_tell(pb);
2479 int64_t size = avio_rb32(pb); /* size */
2480 uint32_t format = avio_rl32(pb); /* data format */
2483 avio_rb32(pb); /* reserved */
2484 avio_rb16(pb); /* reserved */
2485 dref_id = avio_rb16(pb);
2486 } else if (size <= 7) {
2487 av_log(c->fc, AV_LOG_ERROR,
2488 "invalid size %"PRId64" in stsd\n", size);
2489 return AVERROR_INVALIDDATA;
2492 if (mov_skip_multiple_stsd(c, pb, st->codecpar->codec_tag, format,
2493 size - (avio_tell(pb) - start_pos))) {
2498 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
2499 sc->dref_id= dref_id;
2500 sc->format = format;
2502 id = mov_codec_id(st, format);
2504 av_log(c->fc, AV_LOG_TRACE,
2505 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
2506 av_fourcc2str(format), st->codecpar->codec_type);
2508 st->codecpar->codec_id = id;
2509 if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) {
2510 mov_parse_stsd_video(c, pb, st, sc);
2511 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
2512 mov_parse_stsd_audio(c, pb, st, sc);
2513 if (st->codecpar->sample_rate < 0) {
2514 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
2515 return AVERROR_INVALIDDATA;
2517 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
2518 mov_parse_stsd_subtitle(c, pb, st, sc,
2519 size - (avio_tell(pb) - start_pos));
2521 ret = mov_parse_stsd_data(c, pb, st, sc,
2522 size - (avio_tell(pb) - start_pos));
2526 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
2527 a.size = size - (avio_tell(pb) - start_pos);
2529 if ((ret = mov_read_default(c, pb, a)) < 0)
2531 } else if (a.size > 0)
2532 avio_skip(pb, a.size);
2534 if (sc->extradata && st->codecpar->extradata) {
2535 int extra_size = st->codecpar->extradata_size;
2537 /* Move the current stream extradata to the stream context one. */
2538 sc->extradata_size[pseudo_stream_id] = extra_size;
2539 sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
2540 st->codecpar->extradata = NULL;
2541 st->codecpar->extradata_size = 0;
2546 if (pb->eof_reached) {
2547 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
2554 static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2557 MOVStreamContext *sc;
2560 if (c->fc->nb_streams < 1)
2562 st = c->fc->streams[c->fc->nb_streams - 1];
2565 sc->stsd_version = avio_r8(pb);
2566 avio_rb24(pb); /* flags */
2567 entries = avio_rb32(pb);
2569 /* Each entry contains a size (4 bytes) and format (4 bytes). */
2570 if (entries <= 0 || entries > atom.size / 8) {
2571 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
2572 return AVERROR_INVALIDDATA;
2575 if (sc->extradata) {
2576 av_log(c->fc, AV_LOG_ERROR,
2577 "Duplicate stsd found in this track.\n");
2578 return AVERROR_INVALIDDATA;
2581 /* Prepare space for hosting multiple extradata. */
2582 sc->extradata = av_mallocz_array(entries, sizeof(*sc->extradata));
2584 return AVERROR(ENOMEM);
2586 sc->extradata_size = av_mallocz_array(entries, sizeof(*sc->extradata_size));
2587 if (!sc->extradata_size) {
2588 ret = AVERROR(ENOMEM);
2592 ret = ff_mov_read_stsd_entries(c, pb, entries);
2596 /* Restore back the primary extradata. */
2597 av_freep(&st->codecpar->extradata);
2598 st->codecpar->extradata_size = sc->extradata_size[0];
2599 if (sc->extradata_size[0]) {
2600 st->codecpar->extradata = av_mallocz(sc->extradata_size[0] + AV_INPUT_BUFFER_PADDING_SIZE);
2601 if (!st->codecpar->extradata)
2602 return AVERROR(ENOMEM);
2603 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
2606 return mov_finalize_stsd_codec(c, pb, st, sc);
2608 if (sc->extradata) {
2610 for (j = 0; j < sc->stsd_count; j++)
2611 av_freep(&sc->extradata[j]);
2614 av_freep(&sc->extradata);
2615 av_freep(&sc->extradata_size);
2619 static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2622 MOVStreamContext *sc;
2623 unsigned int i, entries;
2625 if (c->fc->nb_streams < 1)
2627 st = c->fc->streams[c->fc->nb_streams-1];
2630 avio_r8(pb); /* version */
2631 avio_rb24(pb); /* flags */
2633 entries = avio_rb32(pb);
2634 if ((uint64_t)entries * 12 + 4 > atom.size)
2635 return AVERROR_INVALIDDATA;
2637 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
2642 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSC atom\n");
2643 av_free(sc->stsc_data);
2645 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
2647 return AVERROR(ENOMEM);
2649 for (i = 0; i < entries && !pb->eof_reached; i++) {
2650 sc->stsc_data[i].first = avio_rb32(pb);
2651 sc->stsc_data[i].count = avio_rb32(pb);
2652 sc->stsc_data[i].id = avio_rb32(pb);
2656 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
2657 int64_t first_min = i + 1;
2658 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
2659 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
2660 sc->stsc_data[i].first < first_min ||
2661 sc->stsc_data[i].count < 1 ||
2662 sc->stsc_data[i].id < 1) {
2663 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);
2664 if (i+1 >= sc->stsc_count) {
2665 if (sc->stsc_data[i].count == 0 && i > 0) {
2669 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
2670 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
2671 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
2672 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
2673 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
2676 av_assert0(sc->stsc_data[i+1].first >= 2);
2677 // We replace this entry by the next valid
2678 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
2679 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
2680 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
2684 if (pb->eof_reached) {
2685 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
2692 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
2694 return index < count - 1;
2697 /* Compute the samples value for the stsc entry at the given index. */
2698 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
2702 if (mov_stsc_index_valid(index, sc->stsc_count))
2703 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
2705 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
2706 av_assert0(sc->stsc_data[index].first <= sc->chunk_count);
2707 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
2710 return sc->stsc_data[index].count * (int64_t)chunk_count;
2713 static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2716 MOVStreamContext *sc;
2717 unsigned i, entries;
2719 if (c->fc->nb_streams < 1)
2721 st = c->fc->streams[c->fc->nb_streams-1];
2724 avio_rb32(pb); // version + flags
2726 entries = avio_rb32(pb);
2728 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
2729 av_free(sc->stps_data);
2731 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
2733 return AVERROR(ENOMEM);
2735 for (i = 0; i < entries && !pb->eof_reached; i++) {
2736 sc->stps_data[i] = avio_rb32(pb);
2741 if (pb->eof_reached) {
2742 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
2749 static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2752 MOVStreamContext *sc;
2753 unsigned int i, entries;
2755 if (c->fc->nb_streams < 1)
2757 st = c->fc->streams[c->fc->nb_streams-1];
2760 avio_r8(pb); /* version */
2761 avio_rb24(pb); /* flags */
2763 entries = avio_rb32(pb);
2765 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
2768 sc->keyframe_absent = 1;
2769 if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
2770 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2774 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
2775 if (entries >= UINT_MAX / sizeof(int))
2776 return AVERROR_INVALIDDATA;
2777 av_freep(&sc->keyframes);
2778 sc->keyframe_count = 0;
2779 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
2781 return AVERROR(ENOMEM);
2783 for (i = 0; i < entries && !pb->eof_reached; i++) {
2784 sc->keyframes[i] = avio_rb32(pb);
2787 sc->keyframe_count = i;
2789 if (pb->eof_reached) {
2790 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
2797 static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2800 MOVStreamContext *sc;
2801 unsigned int i, entries, sample_size, field_size, num_bytes;
2806 if (c->fc->nb_streams < 1)
2808 st = c->fc->streams[c->fc->nb_streams-1];
2811 avio_r8(pb); /* version */
2812 avio_rb24(pb); /* flags */
2814 if (atom.type == MKTAG('s','t','s','z')) {
2815 sample_size = avio_rb32(pb);
2816 if (!sc->sample_size) /* do not overwrite value computed in stsd */
2817 sc->sample_size = sample_size;
2818 sc->stsz_sample_size = sample_size;
2822 avio_rb24(pb); /* reserved */
2823 field_size = avio_r8(pb);
2825 entries = avio_rb32(pb);
2827 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
2829 sc->sample_count = entries;
2833 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
2834 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
2835 return AVERROR_INVALIDDATA;
2840 if (entries >= (UINT_MAX - 4) / field_size)
2841 return AVERROR_INVALIDDATA;
2842 if (sc->sample_sizes)
2843 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
2844 av_free(sc->sample_sizes);
2845 sc->sample_count = 0;
2846 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
2847 if (!sc->sample_sizes)
2848 return AVERROR(ENOMEM);
2850 num_bytes = (entries*field_size+4)>>3;
2852 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
2854 av_freep(&sc->sample_sizes);
2855 return AVERROR(ENOMEM);
2858 ret = ffio_read_size(pb, buf, num_bytes);
2860 av_freep(&sc->sample_sizes);
2862 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
2866 init_get_bits(&gb, buf, 8*num_bytes);
2868 for (i = 0; i < entries && !pb->eof_reached; i++) {
2869 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
2870 if (sc->sample_sizes[i] < 0) {
2872 av_log(c->fc, AV_LOG_ERROR, "Invalid sample size %d\n", sc->sample_sizes[i]);
2873 return AVERROR_INVALIDDATA;
2875 sc->data_size += sc->sample_sizes[i];
2878 sc->sample_count = i;
2882 if (pb->eof_reached) {
2883 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSZ atom\n");
2890 static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2893 MOVStreamContext *sc;
2894 unsigned int i, entries, alloc_size = 0;
2895 int64_t duration = 0;
2896 int64_t total_sample_count = 0;
2898 if (c->fc->nb_streams < 1)
2900 st = c->fc->streams[c->fc->nb_streams-1];
2903 avio_r8(pb); /* version */
2904 avio_rb24(pb); /* flags */
2905 entries = avio_rb32(pb);
2907 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
2908 c->fc->nb_streams-1, entries);
2911 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
2912 av_freep(&sc->stts_data);
2914 if (entries >= INT_MAX / sizeof(*sc->stts_data))
2915 return AVERROR(ENOMEM);
2917 for (i = 0; i < entries && !pb->eof_reached; i++) {
2918 int sample_duration;
2919 unsigned int sample_count;
2920 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
2921 MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
2922 min_entries * sizeof(*sc->stts_data));
2924 av_freep(&sc->stts_data);
2926 return AVERROR(ENOMEM);
2928 sc->stts_count = min_entries;
2929 sc->stts_data = stts_data;
2931 sample_count = avio_rb32(pb);
2932 sample_duration = avio_rb32(pb);
2934 sc->stts_data[i].count= sample_count;
2935 sc->stts_data[i].duration= sample_duration;
2937 av_log(c->fc, AV_LOG_TRACE, "sample_count=%d, sample_duration=%d\n",
2938 sample_count, sample_duration);
2940 duration+=(int64_t)sample_duration*(uint64_t)sample_count;
2941 total_sample_count+=sample_count;
2947 duration <= INT64_MAX - sc->duration_for_fps &&
2948 total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
2949 sc->duration_for_fps += duration;
2950 sc->nb_frames_for_fps += total_sample_count;
2953 if (pb->eof_reached) {
2954 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
2958 st->nb_frames= total_sample_count;
2960 st->duration= FFMIN(st->duration, duration);
2961 sc->track_end = duration;
2965 static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2968 MOVStreamContext *sc;
2971 if (c->fc->nb_streams < 1)
2973 st = c->fc->streams[c->fc->nb_streams - 1];
2976 avio_r8(pb); /* version */
2977 avio_rb24(pb); /* flags */
2978 entries = atom.size - 4;
2980 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
2981 c->fc->nb_streams - 1, entries);
2984 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
2985 av_freep(&sc->sdtp_data);
2988 sc->sdtp_data = av_mallocz(entries);
2990 return AVERROR(ENOMEM);
2992 for (i = 0; i < entries && !pb->eof_reached; i++)
2993 sc->sdtp_data[i] = avio_r8(pb);
2999 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3002 if (duration == INT_MIN) {
3003 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3006 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3010 static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3013 MOVStreamContext *sc;
3014 unsigned int i, entries, ctts_count = 0;
3016 if (c->fc->nb_streams < 1)
3018 st = c->fc->streams[c->fc->nb_streams-1];
3021 avio_r8(pb); /* version */
3022 avio_rb24(pb); /* flags */
3023 entries = avio_rb32(pb);
3025 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3029 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3030 return AVERROR_INVALIDDATA;
3031 av_freep(&sc->ctts_data);
3032 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3034 return AVERROR(ENOMEM);
3036 for (i = 0; i < entries && !pb->eof_reached; i++) {
3037 int count = avio_rb32(pb);
3038 int duration = avio_rb32(pb);
3041 av_log(c->fc, AV_LOG_TRACE,
3042 "ignoring CTTS entry with count=%d duration=%d\n",
3047 add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3050 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3053 if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3054 av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3055 av_freep(&sc->ctts_data);
3061 mov_update_dts_shift(sc, duration, c->fc);
3064 sc->ctts_count = ctts_count;
3066 if (pb->eof_reached) {
3067 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3071 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3076 static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3079 MOVStreamContext *sc;
3080 unsigned int i, entries;
3082 uint32_t grouping_type;
3084 if (c->fc->nb_streams < 1)
3086 st = c->fc->streams[c->fc->nb_streams-1];
3089 version = avio_r8(pb); /* version */
3090 avio_rb24(pb); /* flags */
3091 grouping_type = avio_rl32(pb);
3092 if (grouping_type != MKTAG( 'r','a','p',' '))
3093 return 0; /* only support 'rap ' grouping */
3095 avio_rb32(pb); /* grouping_type_parameter */
3097 entries = avio_rb32(pb);
3101 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP atom\n");
3102 av_free(sc->rap_group);
3103 sc->rap_group_count = 0;
3104 sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group));
3106 return AVERROR(ENOMEM);
3108 for (i = 0; i < entries && !pb->eof_reached; i++) {
3109 sc->rap_group[i].count = avio_rb32(pb); /* sample_count */
3110 sc->rap_group[i].index = avio_rb32(pb); /* group_description_index */
3113 sc->rap_group_count = i;
3115 if (pb->eof_reached) {
3116 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3124 * Get ith edit list entry (media time, duration).
3126 static int get_edit_list_entry(MOVContext *mov,
3127 const MOVStreamContext *msc,
3128 unsigned int edit_list_index,
3129 int64_t *edit_list_media_time,
3130 int64_t *edit_list_duration,
3131 int64_t global_timescale)
3133 if (edit_list_index == msc->elst_count) {
3136 *edit_list_media_time = msc->elst_data[edit_list_index].time;
3137 *edit_list_duration = msc->elst_data[edit_list_index].duration;
3139 /* duration is in global timescale units;convert to msc timescale */
3140 if (global_timescale == 0) {
3141 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3144 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3150 * Find the closest previous frame to the timestamp_pts, in e_old index
3151 * entries. Searching for just any frame / just key frames can be controlled by
3152 * last argument 'flag'.
3153 * Note that if ctts_data is not NULL, we will always search for a key frame
3154 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3155 * return the first frame of the video.
3157 * Here the timestamp_pts is considered to be a presentation timestamp and
3158 * the timestamp of index entries are considered to be decoding timestamps.
3160 * Returns 0 if successful in finding a frame, else returns -1.
3161 * Places the found index corresponding output arg.
3163 * If ctts_old is not NULL, then refines the searched entry by searching
3164 * backwards from the found timestamp, to find the frame with correct PTS.
3166 * Places the found ctts_index and ctts_sample in corresponding output args.
3168 static int find_prev_closest_index(AVStream *st,
3169 AVIndexEntry *e_old,
3173 int64_t timestamp_pts,
3176 int64_t* ctts_index,
3177 int64_t* ctts_sample)
3179 MOVStreamContext *msc = st->priv_data;
3180 AVIndexEntry *e_keep = st->index_entries;
3181 int nb_keep = st->nb_index_entries;
3183 int64_t index_ctts_count;
3187 // If dts_shift > 0, then all the index timestamps will have to be offset by
3188 // at least dts_shift amount to obtain PTS.
3189 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3190 if (msc->dts_shift > 0) {
3191 timestamp_pts -= msc->dts_shift;
3194 st->index_entries = e_old;
3195 st->nb_index_entries = nb_old;
3196 *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3198 // Keep going backwards in the index entries until the timestamp is the same.
3200 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3202 if ((flag & AVSEEK_FLAG_ANY) ||
3203 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3209 // If we have CTTS then refine the search, by searching backwards over PTS
3210 // computed by adding corresponding CTTS durations to index timestamps.
3211 if (ctts_data && *index >= 0) {
3212 av_assert0(ctts_index);
3213 av_assert0(ctts_sample);
3214 // Find out the ctts_index for the found frame.
3217 for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3218 if (*ctts_index < ctts_count) {
3220 if (ctts_data[*ctts_index].count == *ctts_sample) {
3227 while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3228 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3229 // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3230 // compensated by dts_shift above.
3231 if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3232 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3237 if (*ctts_sample == 0) {
3239 if (*ctts_index >= 0)
3240 *ctts_sample = ctts_data[*ctts_index].count - 1;
3247 /* restore AVStream state*/
3248 st->index_entries = e_keep;
3249 st->nb_index_entries = nb_keep;
3250 return *index >= 0 ? 0 : -1;
3254 * Add index entry with the given values, to the end of st->index_entries.
3255 * Returns the new size st->index_entries if successful, else returns -1.
3257 * This function is similar to ff_add_index_entry in libavformat/utils.c
3258 * except that here we are always unconditionally adding an index entry to
3259 * the end, instead of searching the entries list and skipping the add if
3260 * there is an existing entry with the same timestamp.
3261 * This is needed because the mov_fix_index calls this func with the same
3262 * unincremented timestamp for successive discarded frames.
3264 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3265 int size, int distance, int flags)
3267 AVIndexEntry *entries, *ie;
3269 const size_t min_size_needed = (st->nb_index_entries + 1) * sizeof(AVIndexEntry);
3271 // Double the allocation each time, to lower memory fragmentation.
3272 // Another difference from ff_add_index_entry function.
3273 const size_t requested_size =
3274 min_size_needed > st->index_entries_allocated_size ?
3275 FFMAX(min_size_needed, 2 * st->index_entries_allocated_size) :
3278 if (st->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
3281 entries = av_fast_realloc(st->index_entries,
3282 &st->index_entries_allocated_size,
3287 st->index_entries= entries;
3289 index= st->nb_index_entries++;
3290 ie= &entries[index];
3293 ie->timestamp = timestamp;
3294 ie->min_distance= distance;
3301 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3302 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3304 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3305 int64_t* frame_duration_buffer,
3306 int frame_duration_buffer_size) {
3308 av_assert0(end_index >= 0 && end_index <= st->nb_index_entries);
3309 for (i = 0; i < frame_duration_buffer_size; i++) {
3310 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3311 st->index_entries[end_index - 1 - i].timestamp = end_ts;
3316 * Append a new ctts entry to ctts_data.
3317 * Returns the new ctts_count if successful, else returns -1.
3319 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3320 int count, int duration)
3322 MOVStts *ctts_buf_new;
3323 const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVStts);
3324 const size_t requested_size =
3325 min_size_needed > *allocated_size ?
3326 FFMAX(min_size_needed, 2 * (*allocated_size)) :
3329 if ((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
3332 ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3337 *ctts_data = ctts_buf_new;
3339 ctts_buf_new[*ctts_count].count = count;
3340 ctts_buf_new[*ctts_count].duration = duration;
3342 *ctts_count = (*ctts_count) + 1;
3346 #define MAX_REORDER_DELAY 16
3347 static void mov_estimate_video_delay(MOVContext *c, AVStream* st)
3349 MOVStreamContext *msc = st->priv_data;
3352 int ctts_sample = 0;
3353 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3355 int j, r, num_swaps;
3357 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3358 pts_buf[j] = INT64_MIN;
3360 if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3361 st->codecpar->codec_id == AV_CODEC_ID_H264) {
3362 st->codecpar->video_delay = 0;
3363 for (ind = 0; ind < st->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3364 // Point j to the last elem of the buffer and insert the current pts there.
3366 buf_start = (buf_start + 1);
3367 if (buf_start == MAX_REORDER_DELAY + 1)
3370 pts_buf[j] = st->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3372 // The timestamps that are already in the sorted buffer, and are greater than the
3373 // current pts, are exactly the timestamps that need to be buffered to output PTS
3374 // in correct sorted order.
3375 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3376 // can be computed as the maximum no. of swaps any particular timestamp needs to
3377 // go through, to keep this buffer in sorted order.
3379 while (j != buf_start) {
3381 if (r < 0) r = MAX_REORDER_DELAY;
3382 if (pts_buf[j] < pts_buf[r]) {
3383 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3390 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3393 if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3398 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3399 st->codecpar->video_delay, st->index);
3403 static void mov_current_sample_inc(MOVStreamContext *sc)
3405 sc->current_sample++;
3406 sc->current_index++;
3407 if (sc->index_ranges &&
3408 sc->current_index >= sc->current_index_range->end &&
3409 sc->current_index_range->end) {
3410 sc->current_index_range++;
3411 sc->current_index = sc->current_index_range->start;
3415 static void mov_current_sample_dec(MOVStreamContext *sc)
3417 sc->current_sample--;
3418 sc->current_index--;
3419 if (sc->index_ranges &&
3420 sc->current_index < sc->current_index_range->start &&
3421 sc->current_index_range > sc->index_ranges) {
3422 sc->current_index_range--;
3423 sc->current_index = sc->current_index_range->end - 1;
3427 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3431 sc->current_sample = current_sample;
3432 sc->current_index = current_sample;
3433 if (!sc->index_ranges) {
3437 for (sc->current_index_range = sc->index_ranges;
3438 sc->current_index_range->end;
3439 sc->current_index_range++) {
3440 range_size = sc->current_index_range->end - sc->current_index_range->start;
3441 if (range_size > current_sample) {
3442 sc->current_index = sc->current_index_range->start + current_sample;
3445 current_sample -= range_size;
3450 * Fix st->index_entries, so that it contains only the entries (and the entries
3451 * which are needed to decode them) that fall in the edit list time ranges.
3452 * Also fixes the timestamps of the index entries to match the timeline
3453 * specified the edit lists.
3455 static void mov_fix_index(MOVContext *mov, AVStream *st)
3457 MOVStreamContext *msc = st->priv_data;
3458 AVIndexEntry *e_old = st->index_entries;
3459 int nb_old = st->nb_index_entries;
3460 const AVIndexEntry *e_old_end = e_old + nb_old;
3461 const AVIndexEntry *current = NULL;
3462 MOVStts *ctts_data_old = msc->ctts_data;
3463 int64_t ctts_index_old = 0;
3464 int64_t ctts_sample_old = 0;
3465 int64_t ctts_count_old = msc->ctts_count;
3466 int64_t edit_list_media_time = 0;
3467 int64_t edit_list_duration = 0;
3468 int64_t frame_duration = 0;
3469 int64_t edit_list_dts_counter = 0;
3470 int64_t edit_list_dts_entry_end = 0;
3471 int64_t edit_list_start_ctts_sample = 0;
3473 int64_t curr_ctts = 0;
3474 int64_t empty_edits_sum_duration = 0;
3475 int64_t edit_list_index = 0;
3478 int64_t start_dts = 0;
3479 int64_t edit_list_start_encountered = 0;
3480 int64_t search_timestamp = 0;
3481 int64_t* frame_duration_buffer = NULL;
3482 int num_discarded_begin = 0;
3483 int first_non_zero_audio_edit = -1;
3484 int packet_skip_samples = 0;
3485 MOVIndexRange *current_index_range;
3487 int found_keyframe_after_edit = 0;
3488 int found_non_empty_edit = 0;
3490 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
3494 // allocate the index ranges array
3495 msc->index_ranges = av_malloc((msc->elst_count + 1) * sizeof(msc->index_ranges[0]));
3496 if (!msc->index_ranges) {
3497 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
3500 msc->current_index_range = msc->index_ranges;
3501 current_index_range = msc->index_ranges - 1;
3503 // Clean AVStream from traces of old index
3504 st->index_entries = NULL;
3505 st->index_entries_allocated_size = 0;
3506 st->nb_index_entries = 0;
3508 // Clean ctts fields of MOVStreamContext
3509 msc->ctts_data = NULL;
3510 msc->ctts_count = 0;
3511 msc->ctts_index = 0;
3512 msc->ctts_sample = 0;
3513 msc->ctts_allocated_size = 0;
3515 // Reinitialize min_corrected_pts so that it can be computed again.
3516 msc->min_corrected_pts = -1;
3518 // If the dts_shift is positive (in case of negative ctts values in mov),
3519 // then negate the DTS by dts_shift
3520 if (msc->dts_shift > 0) {
3521 edit_list_dts_entry_end -= msc->dts_shift;
3522 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
3525 start_dts = edit_list_dts_entry_end;
3527 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
3528 &edit_list_duration, mov->time_scale)) {
3529 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
3530 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
3532 edit_list_dts_counter = edit_list_dts_entry_end;
3533 edit_list_dts_entry_end += edit_list_duration;
3534 num_discarded_begin = 0;
3535 if (!found_non_empty_edit && edit_list_media_time == -1) {
3536 empty_edits_sum_duration += edit_list_duration;
3539 found_non_empty_edit = 1;
3541 // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
3542 // according to the edit list below.
3543 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3544 if (first_non_zero_audio_edit < 0) {
3545 first_non_zero_audio_edit = 1;
3547 first_non_zero_audio_edit = 0;
3550 if (first_non_zero_audio_edit > 0)
3551 st->skip_samples = msc->start_pad = 0;
3554 // While reordering frame index according to edit list we must handle properly
3555 // the scenario when edit list entry starts from none key frame.
3556 // We find closest previous key frame and preserve it and consequent frames in index.
3557 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
3558 search_timestamp = edit_list_media_time;
3559 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3560 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
3561 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
3562 // edit_list_media_time to cover the decoder delay.
3563 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
3566 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
3567 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3568 av_log(mov->fc, AV_LOG_WARNING,
3569 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
3570 st->index, edit_list_index, search_timestamp);
3571 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
3572 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3573 av_log(mov->fc, AV_LOG_WARNING,
3574 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
3575 st->index, edit_list_index, search_timestamp);
3578 ctts_sample_old = 0;
3581 current = e_old + index;
3582 edit_list_start_ctts_sample = ctts_sample_old;
3584 // Iterate over index and arrange it according to edit list
3585 edit_list_start_encountered = 0;
3586 found_keyframe_after_edit = 0;
3587 for (; current < e_old_end; current++, index++) {
3588 // check if frame outside edit list mark it for discard
3589 frame_duration = (current + 1 < e_old_end) ?
3590 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
3592 flags = current->flags;
3594 // frames (pts) before or after edit list
3595 curr_cts = current->timestamp + msc->dts_shift;
3598 if (ctts_data_old && ctts_index_old < ctts_count_old) {
3599 curr_ctts = ctts_data_old[ctts_index_old].duration;
3600 av_log(mov->fc, AV_LOG_DEBUG, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
3601 curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
3602 curr_cts += curr_ctts;
3604 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
3605 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3606 &msc->ctts_allocated_size,
3607 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3608 ctts_data_old[ctts_index_old].duration) == -1) {
3609 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3611 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3612 ctts_data_old[ctts_index_old].duration);
3616 ctts_sample_old = 0;
3617 edit_list_start_ctts_sample = 0;
3621 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
3622 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
3623 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
3624 first_non_zero_audio_edit > 0) {
3625 packet_skip_samples = edit_list_media_time - curr_cts;
3626 st->skip_samples += packet_skip_samples;
3628 // Shift the index entry timestamp by packet_skip_samples to be correct.
3629 edit_list_dts_counter -= packet_skip_samples;
3630 if (edit_list_start_encountered == 0) {
3631 edit_list_start_encountered = 1;
3632 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
3633 // discarded packets.
3634 if (frame_duration_buffer) {
3635 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3636 frame_duration_buffer, num_discarded_begin);
3637 av_freep(&frame_duration_buffer);
3641 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
3643 flags |= AVINDEX_DISCARD_FRAME;
3644 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
3646 if (edit_list_start_encountered == 0) {
3647 num_discarded_begin++;
3648 frame_duration_buffer = av_realloc(frame_duration_buffer,
3649 num_discarded_begin * sizeof(int64_t));
3650 if (!frame_duration_buffer) {
3651 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
3654 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
3656 // Increment skip_samples for the first non-zero audio edit list
3657 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3658 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
3659 st->skip_samples += frame_duration;
3664 if (msc->min_corrected_pts < 0) {
3665 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
3667 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
3669 if (edit_list_start_encountered == 0) {
3670 edit_list_start_encountered = 1;
3671 // Make timestamps strictly monotonically increasing by rewriting timestamps for
3672 // discarded packets.
3673 if (frame_duration_buffer) {
3674 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3675 frame_duration_buffer, num_discarded_begin);
3676 av_freep(&frame_duration_buffer);
3681 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
3682 current->min_distance, flags) == -1) {
3683 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
3687 // Update the index ranges array
3688 if (current_index_range < msc->index_ranges || index != current_index_range->end) {
3689 current_index_range++;
3690 current_index_range->start = index;
3692 current_index_range->end = index + 1;
3694 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
3695 if (edit_list_start_encountered > 0) {
3696 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
3699 // Break when found first key frame after edit entry completion
3700 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
3701 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
3702 if (ctts_data_old) {
3703 // If we have CTTS and this is the first keyframe after edit elist,
3704 // wait for one more, because there might be trailing B-frames after this I-frame
3705 // that do belong to the edit.
3706 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
3707 found_keyframe_after_edit = 1;
3710 if (ctts_sample_old != 0) {
3711 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3712 &msc->ctts_allocated_size,
3713 ctts_sample_old - edit_list_start_ctts_sample,
3714 ctts_data_old[ctts_index_old].duration) == -1) {
3715 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3716 ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
3717 ctts_data_old[ctts_index_old].duration);
3726 // If there are empty edits, then msc->min_corrected_pts might be positive
3727 // intentionally. So we subtract the sum duration of emtpy edits here.
3728 msc->min_corrected_pts -= empty_edits_sum_duration;
3730 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
3731 // dts by that amount to make the first pts zero.
3732 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
3733 if (msc->min_corrected_pts > 0) {
3734 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
3735 for (i = 0; i < st->nb_index_entries; ++i) {
3736 st->index_entries[i].timestamp -= msc->min_corrected_pts;
3740 // Start time should be equal to zero or the duration of any empty edits.
3741 st->start_time = empty_edits_sum_duration;
3743 // Update av stream length, if it ends up shorter than the track's media duration
3744 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
3745 msc->start_pad = st->skip_samples;
3747 // Free the old index and the old CTTS structures
3749 av_free(ctts_data_old);
3750 av_freep(&frame_duration_buffer);
3752 // Null terminate the index ranges array
3753 current_index_range++;
3754 current_index_range->start = 0;
3755 current_index_range->end = 0;
3756 msc->current_index = msc->index_ranges[0].start;
3759 static void mov_build_index(MOVContext *mov, AVStream *st)
3761 MOVStreamContext *sc = st->priv_data;
3762 int64_t current_offset;
3763 int64_t current_dts = 0;
3764 unsigned int stts_index = 0;
3765 unsigned int stsc_index = 0;
3766 unsigned int stss_index = 0;
3767 unsigned int stps_index = 0;
3769 uint64_t stream_size = 0;
3770 MOVStts *ctts_data_old = sc->ctts_data;
3771 unsigned int ctts_count_old = sc->ctts_count;
3773 if (sc->elst_count) {
3774 int i, edit_start_index = 0, multiple_edits = 0;
3775 int64_t empty_duration = 0; // empty duration of the first edit list entry
3776 int64_t start_time = 0; // start time of the media
3778 for (i = 0; i < sc->elst_count; i++) {
3779 const MOVElst *e = &sc->elst_data[i];
3780 if (i == 0 && e->time == -1) {
3781 /* if empty, the first entry is the start time of the stream
3782 * relative to the presentation itself */
3783 empty_duration = e->duration;
3784 edit_start_index = 1;
3785 } else if (i == edit_start_index && e->time >= 0) {
3786 start_time = e->time;
3792 if (multiple_edits && !mov->advanced_editlist)
3793 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
3794 "Use -advanced_editlist to correctly decode otherwise "
3795 "a/v desync might occur\n");
3797 /* adjust first dts according to edit list */
3798 if ((empty_duration || start_time) && mov->time_scale > 0) {
3800 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
3801 sc->time_offset = start_time - empty_duration;
3802 sc->min_corrected_pts = start_time;
3803 if (!mov->advanced_editlist)
3804 current_dts = -sc->time_offset;
3807 if (!multiple_edits && !mov->advanced_editlist &&
3808 st->codecpar->codec_id == AV_CODEC_ID_AAC && start_time > 0)
3809 sc->start_pad = start_time;
3812 /* only use old uncompressed audio chunk demuxing when stts specifies it */
3813 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3814 sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
3815 unsigned int current_sample = 0;
3816 unsigned int stts_sample = 0;
3817 unsigned int sample_size;
3818 unsigned int distance = 0;
3819 unsigned int rap_group_index = 0;
3820 unsigned int rap_group_sample = 0;
3821 int64_t last_dts = 0;
3822 int64_t dts_correction = 0;
3823 int rap_group_present = sc->rap_group_count && sc->rap_group;
3824 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
3826 current_dts -= sc->dts_shift;
3827 last_dts = current_dts;
3829 if (!sc->sample_count || st->nb_index_entries)
3831 if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
3833 if (av_reallocp_array(&st->index_entries,
3834 st->nb_index_entries + sc->sample_count,
3835 sizeof(*st->index_entries)) < 0) {
3836 st->nb_index_entries = 0;
3839 st->index_entries_allocated_size = (st->nb_index_entries + sc->sample_count) * sizeof(*st->index_entries);
3841 if (ctts_data_old) {
3842 // Expand ctts entries such that we have a 1-1 mapping with samples
3843 if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
3846 sc->ctts_allocated_size = 0;
3847 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size,
3848 sc->sample_count * sizeof(*sc->ctts_data));
3849 if (!sc->ctts_data) {
3850 av_free(ctts_data_old);
3854 memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
3856 for (i = 0; i < ctts_count_old &&
3857 sc->ctts_count < sc->sample_count; i++)
3858 for (j = 0; j < ctts_data_old[i].count &&
3859 sc->ctts_count < sc->sample_count; j++)
3860 add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
3861 &sc->ctts_allocated_size, 1,
3862 ctts_data_old[i].duration);
3863 av_free(ctts_data_old);
3866 for (i = 0; i < sc->chunk_count; i++) {
3867 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
3868 current_offset = sc->chunk_offsets[i];
3869 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3870 i + 1 == sc->stsc_data[stsc_index + 1].first)
3873 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
3874 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
3875 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
3876 sc->stsz_sample_size = sc->sample_size;
3878 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
3879 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
3880 sc->stsz_sample_size = sc->sample_size;
3883 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
3885 if (current_sample >= sc->sample_count) {
3886 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
3890 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
3892 if (stss_index + 1 < sc->keyframe_count)
3894 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
3896 if (stps_index + 1 < sc->stps_count)
3899 if (rap_group_present && rap_group_index < sc->rap_group_count) {
3900 if (sc->rap_group[rap_group_index].index > 0)
3902 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
3903 rap_group_sample = 0;
3907 if (sc->keyframe_absent
3909 && !rap_group_present
3910 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
3914 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
3915 if (sc->pseudo_stream_id == -1 ||
3916 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
3918 if (sample_size > 0x3FFFFFFF) {
3919 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
3922 e = &st->index_entries[st->nb_index_entries++];
3923 e->pos = current_offset;
3924 e->timestamp = current_dts;
3925 e->size = sample_size;
3926 e->min_distance = distance;
3927 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
3928 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
3929 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
3930 current_offset, current_dts, sample_size, distance, keyframe);
3931 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries < 100)
3932 ff_rfps_add_frame(mov->fc, st, current_dts);
3935 current_offset += sample_size;
3936 stream_size += sample_size;
3938 /* A negative sample duration is invalid based on the spec,
3939 * but some samples need it to correct the DTS. */
3940 if (sc->stts_data[stts_index].duration < 0) {
3941 av_log(mov->fc, AV_LOG_WARNING,
3942 "Invalid SampleDelta %d in STTS, at %d st:%d\n",
3943 sc->stts_data[stts_index].duration, stts_index,
3945 dts_correction += sc->stts_data[stts_index].duration - 1;
3946 sc->stts_data[stts_index].duration = 1;
3948 current_dts += sc->stts_data[stts_index].duration;
3949 if (!dts_correction || current_dts + dts_correction > last_dts) {
3950 current_dts += dts_correction;
3953 /* Avoid creating non-monotonous DTS */
3954 dts_correction += current_dts - last_dts - 1;
3955 current_dts = last_dts + 1;
3957 last_dts = current_dts;
3961 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
3967 if (st->duration > 0)
3968 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
3970 unsigned chunk_samples, total = 0;
3972 if (!sc->chunk_count)
3975 // compute total chunk count
3976 for (i = 0; i < sc->stsc_count; i++) {
3977 unsigned count, chunk_count;
3979 chunk_samples = sc->stsc_data[i].count;
3980 if (i != sc->stsc_count - 1 &&
3981 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
3982 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
3986 if (sc->samples_per_frame >= 160) { // gsm
3987 count = chunk_samples / sc->samples_per_frame;
3988 } else if (sc->samples_per_frame > 1) {
3989 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
3990 count = (chunk_samples+samples-1) / samples;
3992 count = (chunk_samples+1023) / 1024;
3995 if (mov_stsc_index_valid(i, sc->stsc_count))
3996 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
3998 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
3999 total += chunk_count * count;
4002 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4003 if (total >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
4005 if (av_reallocp_array(&st->index_entries,
4006 st->nb_index_entries + total,
4007 sizeof(*st->index_entries)) < 0) {
4008 st->nb_index_entries = 0;
4011 st->index_entries_allocated_size = (st->nb_index_entries + total) * sizeof(*st->index_entries);
4014 for (i = 0; i < sc->chunk_count; i++) {
4015 current_offset = sc->chunk_offsets[i];
4016 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4017 i + 1 == sc->stsc_data[stsc_index + 1].first)
4019 chunk_samples = sc->stsc_data[stsc_index].count;
4021 while (chunk_samples > 0) {
4023 unsigned size, samples;
4025 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4026 avpriv_request_sample(mov->fc,
4027 "Zero bytes per frame, but %d samples per frame",
4028 sc->samples_per_frame);
4032 if (sc->samples_per_frame >= 160) { // gsm
4033 samples = sc->samples_per_frame;
4034 size = sc->bytes_per_frame;
4036 if (sc->samples_per_frame > 1) {
4037 samples = FFMIN((1024 / sc->samples_per_frame)*
4038 sc->samples_per_frame, chunk_samples);
4039 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
4041 samples = FFMIN(1024, chunk_samples);
4042 size = samples * sc->sample_size;
4046 if (st->nb_index_entries >= total) {
4047 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4050 if (size > 0x3FFFFFFF) {
4051 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4054 e = &st->index_entries[st->nb_index_entries++];
4055 e->pos = current_offset;
4056 e->timestamp = current_dts;
4058 e->min_distance = 0;
4059 e->flags = AVINDEX_KEYFRAME;
4060 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4061 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4064 current_offset += size;
4065 current_dts += samples;
4066 chunk_samples -= samples;
4071 if (!mov->ignore_editlist && mov->advanced_editlist) {
4072 // Fix index according to edit lists.
4073 mov_fix_index(mov, st);
4076 // Update start time of the stream.
4077 if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries > 0) {
4078 st->start_time = st->index_entries[0].timestamp + sc->dts_shift;
4079 if (sc->ctts_data) {
4080 st->start_time += sc->ctts_data[0].duration;
4084 mov_estimate_video_delay(mov, st);
4087 static int test_same_origin(const char *src, const char *ref) {
4097 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4098 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4100 if (strlen(src) == 0) {
4102 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4103 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4104 strlen(src_host) + 1 >= sizeof(src_host) ||
4105 strlen(ref_host) + 1 >= sizeof(ref_host)) {
4107 } else if (strcmp(src_proto, ref_proto) ||
4108 strcmp(src_auth, ref_auth) ||
4109 strcmp(src_host, ref_host) ||
4110 src_port != ref_port) {
4116 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4118 /* try relative path, we do not try the absolute because it can leak information about our
4119 system to an attacker */
4120 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4121 char filename[1025];
4122 const char *src_path;
4125 /* find a source dir */
4126 src_path = strrchr(src, '/');
4132 /* find a next level down to target */
4133 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4134 if (ref->path[l] == '/') {
4135 if (i == ref->nlvl_to - 1)
4141 /* compose filename if next level down to target was found */
4142 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4143 memcpy(filename, src, src_path - src);
4144 filename[src_path - src] = 0;
4146 for (i = 1; i < ref->nlvl_from; i++)
4147 av_strlcat(filename, "../", sizeof(filename));
4149 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4150 if (!c->use_absolute_path) {
4151 int same_origin = test_same_origin(src, filename);
4154 av_log(c->fc, AV_LOG_ERROR,
4155 "Reference with mismatching origin, %s not tried for security reasons, "
4156 "set demuxer option use_absolute_path to allow it anyway\n",
4158 return AVERROR(ENOENT);
4161 if (strstr(ref->path + l + 1, "..") ||
4162 strstr(ref->path + l + 1, ":") ||
4163 (ref->nlvl_from > 1 && same_origin < 0) ||
4164 (filename[0] == '/' && src_path == src))
4165 return AVERROR(ENOENT);
4168 if (strlen(filename) + 1 == sizeof(filename))
4169 return AVERROR(ENOENT);
4170 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4173 } else if (c->use_absolute_path) {
4174 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4175 "this is a possible security issue\n");
4176 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4179 av_log(c->fc, AV_LOG_ERROR,
4180 "Absolute path %s not tried for security reasons, "
4181 "set demuxer option use_absolute_path to allow absolute paths\n",
4185 return AVERROR(ENOENT);
4188 static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
4190 if (sc->time_scale <= 0) {
4191 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4192 sc->time_scale = c->time_scale;
4193 if (sc->time_scale <= 0)
4198 static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4201 MOVStreamContext *sc;
4204 st = avformat_new_stream(c->fc, NULL);
4205 if (!st) return AVERROR(ENOMEM);
4207 sc = av_mallocz(sizeof(MOVStreamContext));
4208 if (!sc) return AVERROR(ENOMEM);
4211 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
4212 sc->ffindex = st->index;
4213 c->trak_index = st->index;
4215 if ((ret = mov_read_default(c, pb, atom)) < 0)
4220 // Here stsc refers to a chunk not described in stco. This is technically invalid,
4221 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4222 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4224 av_freep(&sc->stsc_data);
4228 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4229 (!sc->sample_size && !sc->sample_count))) ||
4230 (!sc->chunk_count && sc->sample_count)) {
4231 av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4235 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4236 av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4238 return AVERROR_INVALIDDATA;
4241 fix_timescale(c, sc);
4243 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4245 mov_build_index(c, st);
4247 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4248 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4249 if (c->enable_drefs) {
4250 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4251 av_log(c->fc, AV_LOG_ERROR,
4252 "stream %d, error opening alias: path='%s', dir='%s', "
4253 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4254 st->index, dref->path, dref->dir, dref->filename,
4255 dref->volume, dref->nlvl_from, dref->nlvl_to);
4257 av_log(c->fc, AV_LOG_WARNING,
4258 "Skipped opening external track: "
4259 "stream %d, alias: path='%s', dir='%s', "
4260 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4261 "Set enable_drefs to allow this.\n",
4262 st->index, dref->path, dref->dir, dref->filename,
4263 dref->volume, dref->nlvl_from, dref->nlvl_to);
4267 sc->pb_is_copied = 1;
4270 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4271 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4272 sc->height && sc->width &&
4273 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4274 st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4275 ((double)st->codecpar->width * sc->height), INT_MAX);
4278 #if FF_API_R_FRAME_RATE
4279 if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4280 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
4281 sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4285 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4286 if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4287 TAG_IS_AVCI(st->codecpar->codec_tag)) {
4288 ret = ff_generate_avci_extradata(st);
4293 switch (st->codecpar->codec_id) {
4294 #if CONFIG_H261_DECODER
4295 case AV_CODEC_ID_H261:
4297 #if CONFIG_H263_DECODER
4298 case AV_CODEC_ID_H263:
4300 #if CONFIG_MPEG4_DECODER
4301 case AV_CODEC_ID_MPEG4:
4303 st->codecpar->width = 0; /* let decoder init width/height */
4304 st->codecpar->height= 0;
4308 // If the duration of the mp3 packets is not constant, then they could need a parser
4309 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4310 && sc->stts_count > 3
4311 && sc->stts_count*10 > st->nb_frames
4312 && sc->time_scale == st->codecpar->sample_rate) {
4313 st->need_parsing = AVSTREAM_PARSE_FULL;
4315 /* Do not need those anymore. */
4316 av_freep(&sc->chunk_offsets);
4317 av_freep(&sc->sample_sizes);
4318 av_freep(&sc->keyframes);
4319 av_freep(&sc->stts_data);
4320 av_freep(&sc->stps_data);
4321 av_freep(&sc->elst_data);
4322 av_freep(&sc->rap_group);
4327 static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4330 c->itunes_metadata = 1;
4331 ret = mov_read_default(c, pb, atom);
4332 c->itunes_metadata = 0;
4336 static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4345 count = avio_rb32(pb);
4346 if (count > UINT_MAX / sizeof(*c->meta_keys) - 1) {
4347 av_log(c->fc, AV_LOG_ERROR,
4348 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
4349 return AVERROR_INVALIDDATA;
4352 c->meta_keys_count = count + 1;
4353 c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
4355 return AVERROR(ENOMEM);
4357 for (i = 1; i <= count; ++i) {
4358 uint32_t key_size = avio_rb32(pb);
4359 uint32_t type = avio_rl32(pb);
4361 av_log(c->fc, AV_LOG_ERROR,
4362 "The key# %"PRIu32" in meta has invalid size:"
4363 "%"PRIu32"\n", i, key_size);
4364 return AVERROR_INVALIDDATA;
4367 if (type != MKTAG('m','d','t','a')) {
4368 avio_skip(pb, key_size);
4370 c->meta_keys[i] = av_mallocz(key_size + 1);
4371 if (!c->meta_keys[i])
4372 return AVERROR(ENOMEM);
4373 avio_read(pb, c->meta_keys[i], key_size);
4379 static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4381 int64_t end = avio_tell(pb) + atom.size;
4382 uint8_t *key = NULL, *val = NULL, *mean = NULL;
4386 MOVStreamContext *sc;
4388 if (c->fc->nb_streams < 1)
4390 st = c->fc->streams[c->fc->nb_streams-1];
4393 for (i = 0; i < 3; i++) {
4397 if (end - avio_tell(pb) <= 12)
4400 len = avio_rb32(pb);
4401 tag = avio_rl32(pb);
4402 avio_skip(pb, 4); // flags
4404 if (len < 12 || len - 12 > end - avio_tell(pb))
4408 if (tag == MKTAG('m', 'e', 'a', 'n'))
4410 else if (tag == MKTAG('n', 'a', 'm', 'e'))
4412 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
4422 *p = av_malloc(len + 1);
4424 ret = AVERROR(ENOMEM);
4427 ret = ffio_read_size(pb, *p, len);
4435 if (mean && key && val) {
4436 if (strcmp(key, "iTunSMPB") == 0) {
4437 int priming, remainder, samples;
4438 if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
4439 if(priming>0 && priming<16384)
4440 sc->start_pad = priming;
4443 if (strcmp(key, "cdec") != 0) {
4444 av_dict_set(&c->fc->metadata, key, val,
4445 AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
4449 av_log(c->fc, AV_LOG_VERBOSE,
4450 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
4453 avio_seek(pb, end, SEEK_SET);
4460 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4462 while (atom.size > 8) {
4466 tag = avio_rl32(pb);
4468 if (tag == MKTAG('h','d','l','r')) {
4469 avio_seek(pb, -8, SEEK_CUR);
4471 return mov_read_default(c, pb, atom);
4477 // return 1 when matrix is identity, 0 otherwise
4478 #define IS_MATRIX_IDENT(matrix) \
4479 ( (matrix)[0][0] == (1 << 16) && \
4480 (matrix)[1][1] == (1 << 16) && \
4481 (matrix)[2][2] == (1 << 30) && \
4482 !(matrix)[0][1] && !(matrix)[0][2] && \
4483 !(matrix)[1][0] && !(matrix)[1][2] && \
4484 !(matrix)[2][0] && !(matrix)[2][1])
4486 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4491 int display_matrix[3][3];
4492 int res_display_matrix[3][3] = { { 0 } };
4494 MOVStreamContext *sc;
4498 if (c->fc->nb_streams < 1)
4500 st = c->fc->streams[c->fc->nb_streams-1];
4503 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4504 // avoids corrupting AVStreams mapped to an earlier tkhd.
4506 return AVERROR_INVALIDDATA;
4508 version = avio_r8(pb);
4509 flags = avio_rb24(pb);
4510 st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
4516 avio_rb32(pb); /* creation time */
4517 avio_rb32(pb); /* modification time */
4519 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4520 avio_rb32(pb); /* reserved */
4522 /* highlevel (considering edits) duration in movie timebase */
4523 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4524 avio_rb32(pb); /* reserved */
4525 avio_rb32(pb); /* reserved */
4527 avio_rb16(pb); /* layer */
4528 avio_rb16(pb); /* alternate group */
4529 avio_rb16(pb); /* volume */
4530 avio_rb16(pb); /* reserved */
4532 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4533 // they're kept in fixed point format through all calculations
4534 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4535 // side data, but the scale factor is not needed to calculate aspect ratio
4536 for (i = 0; i < 3; i++) {
4537 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
4538 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
4539 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
4542 width = avio_rb32(pb); // 16.16 fixed point track width
4543 height = avio_rb32(pb); // 16.16 fixed point track height
4544 sc->width = width >> 16;
4545 sc->height = height >> 16;
4547 // apply the moov display matrix (after the tkhd one)
4548 for (i = 0; i < 3; i++) {
4549 const int sh[3] = { 16, 16, 30 };
4550 for (j = 0; j < 3; j++) {
4551 for (e = 0; e < 3; e++) {
4552 res_display_matrix[i][j] +=
4553 ((int64_t) display_matrix[i][e] *
4554 c->movie_display_matrix[e][j]) >> sh[e];
4559 // save the matrix when it is not the default identity
4560 if (!IS_MATRIX_IDENT(res_display_matrix)) {
4563 av_freep(&sc->display_matrix);
4564 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4565 if (!sc->display_matrix)
4566 return AVERROR(ENOMEM);
4568 for (i = 0; i < 3; i++)
4569 for (j = 0; j < 3; j++)
4570 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4572 #if FF_API_OLD_ROTATE_API
4573 rotate = av_display_rotation_get(sc->display_matrix);
4574 if (!isnan(rotate)) {
4575 char rotate_buf[64];
4577 if (rotate < 0) // for backward compatibility
4579 snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate);
4580 av_dict_set(&st->metadata, "rotate", rotate_buf, 0);
4585 // transform the display width/height according to the matrix
4586 // to keep the same scale, use [width height 1<<16]
4587 if (width && height && sc->display_matrix) {
4588 double disp_transform[2];
4590 for (i = 0; i < 2; i++)
4591 disp_transform[i] = hypot(sc->display_matrix[0 + i],
4592 sc->display_matrix[3 + i]);
4594 if (disp_transform[0] > 0 && disp_transform[1] > 0 &&
4595 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4596 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4597 st->sample_aspect_ratio = av_d2q(
4598 disp_transform[0] / disp_transform[1],
4604 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4606 MOVFragment *frag = &c->fragment;
4607 MOVTrackExt *trex = NULL;
4608 int flags, track_id, i;
4609 MOVFragmentStreamInfo * frag_stream_info;
4611 avio_r8(pb); /* version */
4612 flags = avio_rb24(pb);
4614 track_id = avio_rb32(pb);
4616 return AVERROR_INVALIDDATA;
4617 for (i = 0; i < c->trex_count; i++)
4618 if (c->trex_data[i].track_id == track_id) {
4619 trex = &c->trex_data[i];
4623 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4626 c->fragment.found_tfhd = 1;
4627 frag->track_id = track_id;
4628 set_frag_stream(&c->frag_index, track_id);
4630 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4631 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4632 frag->moof_offset : frag->implicit_offset;
4633 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4635 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4636 avio_rb32(pb) : trex->duration;
4637 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4638 avio_rb32(pb) : trex->size;
4639 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4640 avio_rb32(pb) : trex->flags;
4641 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4643 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4644 if (frag_stream_info)
4645 frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
4650 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4655 num = atom.size / 4;
4656 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4657 return AVERROR(ENOMEM);
4659 av_free(c->chapter_tracks);
4660 c->chapter_tracks = new_tracks;
4661 c->nb_chapter_tracks = num;
4663 for (i = 0; i < num && !pb->eof_reached; i++)
4664 c->chapter_tracks[i] = avio_rb32(pb);
4669 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4674 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4675 return AVERROR_INVALIDDATA;
4676 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4677 sizeof(*c->trex_data))) < 0) {
4682 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4684 trex = &c->trex_data[c->trex_count++];
4685 avio_r8(pb); /* version */
4686 avio_rb24(pb); /* flags */
4687 trex->track_id = avio_rb32(pb);
4688 trex->stsd_id = avio_rb32(pb);
4689 trex->duration = avio_rb32(pb);
4690 trex->size = avio_rb32(pb);
4691 trex->flags = avio_rb32(pb);
4695 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4697 MOVFragment *frag = &c->fragment;
4698 AVStream *st = NULL;
4699 MOVStreamContext *sc;
4701 MOVFragmentStreamInfo * frag_stream_info;
4702 int64_t base_media_decode_time;
4704 for (i = 0; i < c->fc->nb_streams; i++) {
4705 if (c->fc->streams[i]->id == frag->track_id) {
4706 st = c->fc->streams[i];
4711 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4715 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4717 version = avio_r8(pb);
4718 avio_rb24(pb); /* flags */
4720 base_media_decode_time = avio_rb64(pb);
4722 base_media_decode_time = avio_rb32(pb);
4725 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4726 if (frag_stream_info)
4727 frag_stream_info->tfdt_dts = base_media_decode_time;
4728 sc->track_end = base_media_decode_time;
4733 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4735 MOVFragment *frag = &c->fragment;
4736 AVStream *st = NULL;
4737 MOVStreamContext *sc;
4740 int64_t dts, pts = AV_NOPTS_VALUE;
4741 int data_offset = 0;
4742 unsigned entries, first_sample_flags = frag->flags;
4743 int flags, distance, i;
4744 int64_t prev_dts = AV_NOPTS_VALUE;
4745 int next_frag_index = -1, index_entry_pos;
4746 size_t requested_size;
4747 size_t old_ctts_allocated_size;
4748 AVIndexEntry *new_entries;
4749 MOVFragmentStreamInfo * frag_stream_info;
4751 if (!frag->found_tfhd) {
4752 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4753 return AVERROR_INVALIDDATA;
4756 for (i = 0; i < c->fc->nb_streams; i++) {
4757 if (c->fc->streams[i]->id == frag->track_id) {
4758 st = c->fc->streams[i];
4763 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4767 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4770 // Find the next frag_index index that has a valid index_entry for
4771 // the current track_id.
4773 // A valid index_entry means the trun for the fragment was read
4774 // and it's samples are in index_entries at the given position.
4775 // New index entries will be inserted before the index_entry found.
4776 index_entry_pos = st->nb_index_entries;
4777 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4778 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4779 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4780 next_frag_index = i;
4781 index_entry_pos = frag_stream_info->index_entry;
4785 av_assert0(index_entry_pos <= st->nb_index_entries);
4787 avio_r8(pb); /* version */
4788 flags = avio_rb24(pb);
4789 entries = avio_rb32(pb);
4790 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4792 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4793 return AVERROR_INVALIDDATA;
4794 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4795 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4797 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4798 if (frag_stream_info) {
4799 if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
4800 dts = frag_stream_info->next_trun_dts - sc->time_offset;
4801 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4802 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4803 pts = frag_stream_info->first_tfra_pts;
4804 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4805 ", using it for pts\n", pts);
4806 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4807 c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
4808 dts = frag_stream_info->first_tfra_pts;
4809 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4810 ", using it for dts\n", pts);
4811 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4812 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4813 // pts = frag_stream_info->sidx_pts;
4814 dts = frag_stream_info->sidx_pts - sc->time_offset;
4815 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4816 ", using it for pts\n", pts);
4817 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4818 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4819 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4820 ", using it for dts\n", dts);
4822 dts = sc->track_end - sc->time_offset;
4823 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4824 ", using it for dts\n", dts);
4827 dts = sc->track_end - sc->time_offset;
4828 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4829 ", using it for dts\n", dts);
4831 offset = frag->base_data_offset + data_offset;
4833 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4835 // realloc space for new index entries
4836 if((uint64_t)st->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4837 entries = UINT_MAX / sizeof(AVIndexEntry) - st->nb_index_entries;
4838 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4843 requested_size = (st->nb_index_entries + entries) * sizeof(AVIndexEntry);
4844 new_entries = av_fast_realloc(st->index_entries,
4845 &st->index_entries_allocated_size,
4848 return AVERROR(ENOMEM);
4849 st->index_entries= new_entries;
4851 requested_size = (st->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4852 old_ctts_allocated_size = sc->ctts_allocated_size;
4853 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4856 return AVERROR(ENOMEM);
4857 sc->ctts_data = ctts_data;
4859 // In case there were samples without ctts entries, ensure they get
4860 // zero valued entries. This ensures clips which mix boxes with and
4861 // without ctts entries don't pickup uninitialized data.
4862 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4863 sc->ctts_allocated_size - old_ctts_allocated_size);
4865 if (index_entry_pos < st->nb_index_entries) {
4866 // Make hole in index_entries and ctts_data for new samples
4867 memmove(st->index_entries + index_entry_pos + entries,
4868 st->index_entries + index_entry_pos,
4869 sizeof(*st->index_entries) *
4870 (st->nb_index_entries - index_entry_pos));
4871 memmove(sc->ctts_data + index_entry_pos + entries,
4872 sc->ctts_data + index_entry_pos,
4873 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4874 if (index_entry_pos < sc->current_sample) {
4875 sc->current_sample += entries;
4879 st->nb_index_entries += entries;
4880 sc->ctts_count = st->nb_index_entries;
4882 // Record the index_entry position in frag_index of this fragment
4883 if (frag_stream_info)
4884 frag_stream_info->index_entry = index_entry_pos;
4886 if (index_entry_pos > 0)
4887 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4889 for (i = 0; i < entries && !pb->eof_reached; i++) {
4890 unsigned sample_size = frag->size;
4891 int sample_flags = i ? frag->flags : first_sample_flags;
4892 unsigned sample_duration = frag->duration;
4893 unsigned ctts_duration = 0;
4895 int index_entry_flags = 0;
4897 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4898 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4899 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4900 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4902 mov_update_dts_shift(sc, ctts_duration, c->fc);
4903 if (pts != AV_NOPTS_VALUE) {
4904 dts = pts - sc->dts_shift;
4905 if (flags & MOV_TRUN_SAMPLE_CTS) {
4906 dts -= ctts_duration;
4908 dts -= sc->time_offset;
4910 av_log(c->fc, AV_LOG_DEBUG,
4911 "pts %"PRId64" calculated dts %"PRId64
4912 " sc->dts_shift %d ctts.duration %d"
4913 " sc->time_offset %"PRId64
4914 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4916 sc->dts_shift, ctts_duration,
4917 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4918 pts = AV_NOPTS_VALUE;
4921 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4925 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4926 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4929 index_entry_flags |= AVINDEX_KEYFRAME;
4931 // Fragments can overlap in time. Discard overlapping frames after
4933 if (prev_dts >= dts)
4934 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4936 st->index_entries[index_entry_pos].pos = offset;
4937 st->index_entries[index_entry_pos].timestamp = dts;
4938 st->index_entries[index_entry_pos].size= sample_size;
4939 st->index_entries[index_entry_pos].min_distance= distance;
4940 st->index_entries[index_entry_pos].flags = index_entry_flags;
4942 sc->ctts_data[index_entry_pos].count = 1;
4943 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4946 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4947 "size %u, distance %d, keyframe %d\n", st->index,
4948 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4950 dts += sample_duration;
4951 offset += sample_size;
4952 sc->data_size += sample_size;
4954 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4955 1 <= INT_MAX - sc->nb_frames_for_fps
4957 sc->duration_for_fps += sample_duration;
4958 sc->nb_frames_for_fps ++;
4961 if (frag_stream_info)
4962 frag_stream_info->next_trun_dts = dts + sc->time_offset;
4964 // EOF found before reading all entries. Fix the hole this would
4965 // leave in index_entries and ctts_data
4966 int gap = entries - i;
4967 memmove(st->index_entries + index_entry_pos,
4968 st->index_entries + index_entry_pos + gap,
4969 sizeof(*st->index_entries) *
4970 (st->nb_index_entries - (index_entry_pos + gap)));
4971 memmove(sc->ctts_data + index_entry_pos,
4972 sc->ctts_data + index_entry_pos + gap,
4973 sizeof(*sc->ctts_data) *
4974 (sc->ctts_count - (index_entry_pos + gap)));
4976 st->nb_index_entries -= gap;
4977 sc->ctts_count -= gap;
4978 if (index_entry_pos < sc->current_sample) {
4979 sc->current_sample -= gap;
4984 // The end of this new fragment may overlap in time with the start
4985 // of the next fragment in index_entries. Mark the samples in the next
4986 // fragment that overlap with AVINDEX_DISCARD_FRAME
4987 prev_dts = AV_NOPTS_VALUE;
4988 if (index_entry_pos > 0)
4989 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4990 for (i = index_entry_pos; i < st->nb_index_entries; i++) {
4991 if (prev_dts < st->index_entries[i].timestamp)
4993 st->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
4996 // If a hole was created to insert the new index_entries into,
4997 // the index_entry recorded for all subsequent moof must
4998 // be incremented by the number of entries inserted.
4999 fix_frag_index_entries(&c->frag_index, next_frag_index,
5000 frag->track_id, entries);
5002 if (pb->eof_reached) {
5003 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
5007 frag->implicit_offset = offset;
5009 sc->track_end = dts + sc->time_offset;
5010 if (st->duration < sc->track_end)
5011 st->duration = sc->track_end;
5016 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5018 int64_t offset = avio_tell(pb) + atom.size, pts, timestamp;
5020 unsigned i, j, track_id, item_count;
5021 AVStream *st = NULL;
5022 AVStream *ref_st = NULL;
5023 MOVStreamContext *sc, *ref_sc = NULL;
5024 AVRational timescale;
5026 version = avio_r8(pb);
5028 avpriv_request_sample(c->fc, "sidx version %u", version);
5032 avio_rb24(pb); // flags
5034 track_id = avio_rb32(pb); // Reference ID
5035 for (i = 0; i < c->fc->nb_streams; i++) {
5036 if (c->fc->streams[i]->id == track_id) {
5037 st = c->fc->streams[i];
5042 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5048 timescale = av_make_q(1, avio_rb32(pb));
5050 if (timescale.den <= 0) {
5051 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5052 return AVERROR_INVALIDDATA;
5056 pts = avio_rb32(pb);
5057 offset += avio_rb32(pb);
5059 pts = avio_rb64(pb);
5060 offset += avio_rb64(pb);
5063 avio_rb16(pb); // reserved
5065 item_count = avio_rb16(pb);
5067 for (i = 0; i < item_count; i++) {
5069 MOVFragmentStreamInfo * frag_stream_info;
5070 uint32_t size = avio_rb32(pb);
5071 uint32_t duration = avio_rb32(pb);
5072 if (size & 0x80000000) {
5073 avpriv_request_sample(c->fc, "sidx reference_type 1");
5074 return AVERROR_PATCHWELCOME;
5076 avio_rb32(pb); // sap_flags
5077 timestamp = av_rescale_q(pts, timescale, st->time_base);
5079 index = update_frag_index(c, offset);
5080 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5081 if (frag_stream_info)
5082 frag_stream_info->sidx_pts = timestamp;
5088 st->duration = sc->track_end = pts;
5092 if (offset == avio_size(pb)) {
5093 // Find first entry in fragment index that came from an sidx.
5094 // This will pretty much always be the first entry.
5095 for (i = 0; i < c->frag_index.nb_items; i++) {
5096 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5097 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5098 MOVFragmentStreamInfo * si;
5099 si = &item->stream_info[j];
5100 if (si->sidx_pts != AV_NOPTS_VALUE) {
5101 ref_st = c->fc->streams[j];
5102 ref_sc = ref_st->priv_data;
5107 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5108 st = c->fc->streams[i];
5110 if (!sc->has_sidx) {
5111 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5115 c->frag_index.complete = 1;
5121 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5122 /* like the files created with Adobe Premiere 5.0, for samples see */
5123 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5124 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5129 return 0; /* continue */
5130 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5131 avio_skip(pb, atom.size - 4);
5134 atom.type = avio_rl32(pb);
5136 if (atom.type != MKTAG('m','d','a','t')) {
5137 avio_skip(pb, atom.size);
5140 err = mov_read_mdat(c, pb, atom);
5144 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5149 uint8_t *moov_data; /* uncompressed data */
5150 long cmov_len, moov_len;
5153 avio_rb32(pb); /* dcom atom */
5154 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5155 return AVERROR_INVALIDDATA;
5156 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5157 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5158 return AVERROR_INVALIDDATA;
5160 avio_rb32(pb); /* cmvd atom */
5161 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5162 return AVERROR_INVALIDDATA;
5163 moov_len = avio_rb32(pb); /* uncompressed size */
5164 cmov_len = atom.size - 6 * 4;
5166 cmov_data = av_malloc(cmov_len);
5168 return AVERROR(ENOMEM);
5169 moov_data = av_malloc(moov_len);
5172 return AVERROR(ENOMEM);
5174 ret = ffio_read_size(pb, cmov_data, cmov_len);
5176 goto free_and_return;
5178 ret = AVERROR_INVALIDDATA;
5179 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5180 goto free_and_return;
5181 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5182 goto free_and_return;
5183 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5184 atom.type = MKTAG('m','o','o','v');
5185 atom.size = moov_len;
5186 ret = mov_read_default(c, &ctx, atom);
5192 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5193 return AVERROR(ENOSYS);
5197 /* edit list atom */
5198 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5200 MOVStreamContext *sc;
5201 int i, edit_count, version;
5202 int64_t elst_entry_size;
5204 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5206 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5208 version = avio_r8(pb); /* version */
5209 avio_rb24(pb); /* flags */
5210 edit_count = avio_rb32(pb); /* entries */
5213 elst_entry_size = version == 1 ? 20 : 12;
5214 if (atom.size != edit_count * elst_entry_size) {
5215 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5216 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5217 edit_count, atom.size + 8);
5218 return AVERROR_INVALIDDATA;
5220 edit_count = atom.size / elst_entry_size;
5221 if (edit_count * elst_entry_size != atom.size) {
5222 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.", atom.size, edit_count);
5230 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5231 av_free(sc->elst_data);
5233 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5235 return AVERROR(ENOMEM);
5237 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5238 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5239 MOVElst *e = &sc->elst_data[i];
5242 e->duration = avio_rb64(pb);
5243 e->time = avio_rb64(pb);
5246 e->duration = avio_rb32(pb); /* segment duration */
5247 e->time = (int32_t)avio_rb32(pb); /* media time */
5250 e->rate = avio_rb32(pb) / 65536.0;
5252 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5253 e->duration, e->time, e->rate);
5255 if (e->time < 0 && e->time != -1 &&
5256 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5257 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5258 c->fc->nb_streams-1, i, e->time);
5259 return AVERROR_INVALIDDATA;
5267 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5269 MOVStreamContext *sc;
5271 if (c->fc->nb_streams < 1)
5272 return AVERROR_INVALIDDATA;
5273 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5274 sc->timecode_track = avio_rb32(pb);
5278 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5283 if (c->fc->nb_streams < 1)
5285 st = c->fc->streams[c->fc->nb_streams - 1];
5287 if (atom.size < 4) {
5288 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5289 return AVERROR_INVALIDDATA;
5292 /* For now, propagate only the OBUs, if any. Once libavcodec is
5293 updated to handle isobmff style extradata this can be removed. */
5299 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5306 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5309 int version, color_range, color_primaries, color_trc, color_space;
5311 if (c->fc->nb_streams < 1)
5313 st = c->fc->streams[c->fc->nb_streams - 1];
5315 if (atom.size < 5) {
5316 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5317 return AVERROR_INVALIDDATA;
5320 version = avio_r8(pb);
5322 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5325 avio_skip(pb, 3); /* flags */
5327 avio_skip(pb, 2); /* profile + level */
5328 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5329 color_primaries = avio_r8(pb);
5330 color_trc = avio_r8(pb);
5331 color_space = avio_r8(pb);
5332 if (avio_rb16(pb)) /* codecIntializationDataSize */
5333 return AVERROR_INVALIDDATA;
5335 if (!av_color_primaries_name(color_primaries))
5336 color_primaries = AVCOL_PRI_UNSPECIFIED;
5337 if (!av_color_transfer_name(color_trc))
5338 color_trc = AVCOL_TRC_UNSPECIFIED;
5339 if (!av_color_space_name(color_space))
5340 color_space = AVCOL_SPC_UNSPECIFIED;
5342 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5343 st->codecpar->color_primaries = color_primaries;
5344 st->codecpar->color_trc = color_trc;
5345 st->codecpar->color_space = color_space;
5350 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5352 MOVStreamContext *sc;
5355 if (c->fc->nb_streams < 1)
5356 return AVERROR_INVALIDDATA;
5358 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5360 if (atom.size < 5) {
5361 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5362 return AVERROR_INVALIDDATA;
5365 version = avio_r8(pb);
5367 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5370 avio_skip(pb, 3); /* flags */
5372 sc->mastering = av_mastering_display_metadata_alloc();
5374 return AVERROR(ENOMEM);
5376 for (i = 0; i < 3; i++) {
5377 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5378 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5380 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5381 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5383 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5384 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5386 sc->mastering->has_primaries = 1;
5387 sc->mastering->has_luminance = 1;
5392 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5394 MOVStreamContext *sc;
5395 const int mapping[3] = {1, 2, 0};
5396 const int chroma_den = 50000;
5397 const int luma_den = 10000;
5400 if (c->fc->nb_streams < 1)
5401 return AVERROR_INVALIDDATA;
5403 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5405 if (atom.size < 24) {
5406 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5407 return AVERROR_INVALIDDATA;
5410 sc->mastering = av_mastering_display_metadata_alloc();
5412 return AVERROR(ENOMEM);
5414 for (i = 0; i < 3; i++) {
5415 const int j = mapping[i];
5416 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5417 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5419 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5420 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5422 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5423 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5425 sc->mastering->has_luminance = 1;
5426 sc->mastering->has_primaries = 1;
5431 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5433 MOVStreamContext *sc;
5436 if (c->fc->nb_streams < 1)
5437 return AVERROR_INVALIDDATA;
5439 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5441 if (atom.size < 5) {
5442 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5443 return AVERROR_INVALIDDATA;
5446 version = avio_r8(pb);
5448 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5451 avio_skip(pb, 3); /* flags */
5453 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5455 return AVERROR(ENOMEM);
5457 sc->coll->MaxCLL = avio_rb16(pb);
5458 sc->coll->MaxFALL = avio_rb16(pb);
5463 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5465 MOVStreamContext *sc;
5467 if (c->fc->nb_streams < 1)
5468 return AVERROR_INVALIDDATA;
5470 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5472 if (atom.size < 4) {
5473 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5474 return AVERROR_INVALIDDATA;
5477 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5479 return AVERROR(ENOMEM);
5481 sc->coll->MaxCLL = avio_rb16(pb);
5482 sc->coll->MaxFALL = avio_rb16(pb);
5487 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5490 MOVStreamContext *sc;
5491 enum AVStereo3DType type;
5494 if (c->fc->nb_streams < 1)
5497 st = c->fc->streams[c->fc->nb_streams - 1];
5500 if (atom.size < 5) {
5501 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5502 return AVERROR_INVALIDDATA;
5504 avio_skip(pb, 4); /* version + flags */
5509 type = AV_STEREO3D_2D;
5512 type = AV_STEREO3D_TOPBOTTOM;
5515 type = AV_STEREO3D_SIDEBYSIDE;
5518 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5522 sc->stereo3d = av_stereo3d_alloc();
5524 return AVERROR(ENOMEM);
5526 sc->stereo3d->type = type;
5530 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5533 MOVStreamContext *sc;
5534 int size, version, layout;
5535 int32_t yaw, pitch, roll;
5536 uint32_t l = 0, t = 0, r = 0, b = 0;
5537 uint32_t tag, padding = 0;
5538 enum AVSphericalProjection projection;
5540 if (c->fc->nb_streams < 1)
5543 st = c->fc->streams[c->fc->nb_streams - 1];
5546 if (atom.size < 8) {
5547 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5548 return AVERROR_INVALIDDATA;
5551 size = avio_rb32(pb);
5552 if (size <= 12 || size > atom.size)
5553 return AVERROR_INVALIDDATA;
5555 tag = avio_rl32(pb);
5556 if (tag != MKTAG('s','v','h','d')) {
5557 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5560 version = avio_r8(pb);
5562 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5566 avio_skip(pb, 3); /* flags */
5567 avio_skip(pb, size - 12); /* metadata_source */
5569 size = avio_rb32(pb);
5570 if (size > atom.size)
5571 return AVERROR_INVALIDDATA;
5573 tag = avio_rl32(pb);
5574 if (tag != MKTAG('p','r','o','j')) {
5575 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5579 size = avio_rb32(pb);
5580 if (size > atom.size)
5581 return AVERROR_INVALIDDATA;
5583 tag = avio_rl32(pb);
5584 if (tag != MKTAG('p','r','h','d')) {
5585 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5588 version = avio_r8(pb);
5590 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5594 avio_skip(pb, 3); /* flags */
5596 /* 16.16 fixed point */
5597 yaw = avio_rb32(pb);
5598 pitch = avio_rb32(pb);
5599 roll = avio_rb32(pb);
5601 size = avio_rb32(pb);
5602 if (size > atom.size)
5603 return AVERROR_INVALIDDATA;
5605 tag = avio_rl32(pb);
5606 version = avio_r8(pb);
5608 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5612 avio_skip(pb, 3); /* flags */
5614 case MKTAG('c','b','m','p'):
5615 layout = avio_rb32(pb);
5617 av_log(c->fc, AV_LOG_WARNING,
5618 "Unsupported cubemap layout %d\n", layout);
5621 projection = AV_SPHERICAL_CUBEMAP;
5622 padding = avio_rb32(pb);
5624 case MKTAG('e','q','u','i'):
5630 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5631 av_log(c->fc, AV_LOG_ERROR,
5632 "Invalid bounding rectangle coordinates "
5633 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5634 return AVERROR_INVALIDDATA;
5637 if (l || t || r || b)
5638 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5640 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5643 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5647 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5649 return AVERROR(ENOMEM);
5651 sc->spherical->projection = projection;
5653 sc->spherical->yaw = yaw;
5654 sc->spherical->pitch = pitch;
5655 sc->spherical->roll = roll;
5657 sc->spherical->padding = padding;
5659 sc->spherical->bound_left = l;
5660 sc->spherical->bound_top = t;
5661 sc->spherical->bound_right = r;
5662 sc->spherical->bound_bottom = b;
5667 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5670 uint8_t *buffer = av_malloc(len + 1);
5674 return AVERROR(ENOMEM);
5677 ret = ffio_read_size(pb, buffer, len);
5681 /* Check for mandatory keys and values, try to support XML as best-effort */
5682 if (!sc->spherical &&
5683 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5684 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5685 av_stristr(val, "true") &&
5686 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5687 av_stristr(val, "true") &&
5688 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5689 av_stristr(val, "equirectangular")) {
5690 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5694 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5696 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5697 enum AVStereo3DType mode;
5699 if (av_stristr(buffer, "left-right"))
5700 mode = AV_STEREO3D_SIDEBYSIDE;
5701 else if (av_stristr(buffer, "top-bottom"))
5702 mode = AV_STEREO3D_TOPBOTTOM;
5704 mode = AV_STEREO3D_2D;
5706 sc->stereo3d = av_stereo3d_alloc();
5710 sc->stereo3d->type = mode;
5714 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5716 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5717 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5719 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5720 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5722 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5730 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5733 MOVStreamContext *sc;
5736 static const uint8_t uuid_isml_manifest[] = {
5737 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5738 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5740 static const uint8_t uuid_xmp[] = {
5741 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5742 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5744 static const uint8_t uuid_spherical[] = {
5745 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5746 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5749 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5750 return AVERROR_INVALIDDATA;
5752 if (c->fc->nb_streams < 1)
5754 st = c->fc->streams[c->fc->nb_streams - 1];
5757 ret = ffio_read_size(pb, uuid, sizeof(uuid));
5760 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5761 uint8_t *buffer, *ptr;
5763 size_t len = atom.size - sizeof(uuid);
5766 return AVERROR_INVALIDDATA;
5768 ret = avio_skip(pb, 4); // zeroes
5771 buffer = av_mallocz(len + 1);
5773 return AVERROR(ENOMEM);
5775 ret = ffio_read_size(pb, buffer, len);
5782 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5783 ptr += sizeof("systemBitrate=\"") - 1;
5784 c->bitrates_count++;
5785 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5787 c->bitrates_count = 0;
5789 return AVERROR(ENOMEM);
5792 ret = strtol(ptr, &endptr, 10);
5793 if (ret < 0 || errno || *endptr != '"') {
5794 c->bitrates[c->bitrates_count - 1] = 0;
5796 c->bitrates[c->bitrates_count - 1] = ret;
5801 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5803 size_t len = atom.size - sizeof(uuid);
5804 if (c->export_xmp) {
5805 buffer = av_mallocz(len + 1);
5807 return AVERROR(ENOMEM);
5809 ret = ffio_read_size(pb, buffer, len);
5815 av_dict_set(&c->fc->metadata, "xmp",
5816 buffer, AV_DICT_DONT_STRDUP_VAL);
5818 // skip all uuid atom, which makes it fast for long uuid-xmp file
5819 ret = avio_skip(pb, len);
5823 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5824 size_t len = atom.size - sizeof(uuid);
5825 ret = mov_parse_uuid_spherical(sc, pb, len);
5829 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5835 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5838 uint8_t content[16];
5843 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5849 && !memcmp(content, "Anevia\x1A\x1A", 8)
5850 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5851 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5857 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5859 uint32_t format = avio_rl32(pb);
5860 MOVStreamContext *sc;
5864 if (c->fc->nb_streams < 1)
5866 st = c->fc->streams[c->fc->nb_streams - 1];
5871 case MKTAG('e','n','c','v'): // encrypted video
5872 case MKTAG('e','n','c','a'): // encrypted audio
5873 id = mov_codec_id(st, format);
5874 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5875 st->codecpar->codec_id != id) {
5876 av_log(c->fc, AV_LOG_WARNING,
5877 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5878 (char*)&format, st->codecpar->codec_id);
5882 st->codecpar->codec_id = id;
5883 sc->format = format;
5887 if (format != sc->format) {
5888 av_log(c->fc, AV_LOG_WARNING,
5889 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5890 (char*)&format, (char*)&sc->format);
5899 * Gets the current encryption info and associated current stream context. If
5900 * we are parsing a track fragment, this will return the specific encryption
5901 * info for this fragment; otherwise this will return the global encryption
5902 * info for the current stream.
5904 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5906 MOVFragmentStreamInfo *frag_stream_info;
5910 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5911 if (frag_stream_info) {
5912 for (i = 0; i < c->fc->nb_streams; i++) {
5913 if (c->fc->streams[i]->id == frag_stream_info->id) {
5914 st = c->fc->streams[i];
5918 if (i == c->fc->nb_streams)
5920 *sc = st->priv_data;
5922 if (!frag_stream_info->encryption_index) {
5923 // If this stream isn't encrypted, don't create the index.
5924 if (!(*sc)->cenc.default_encrypted_sample)
5926 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5927 if (!frag_stream_info->encryption_index)
5928 return AVERROR(ENOMEM);
5930 *encryption_index = frag_stream_info->encryption_index;
5933 // No current track fragment, using stream level encryption info.
5935 if (c->fc->nb_streams < 1)
5937 st = c->fc->streams[c->fc->nb_streams - 1];
5938 *sc = st->priv_data;
5940 if (!(*sc)->cenc.encryption_index) {
5941 // If this stream isn't encrypted, don't create the index.
5942 if (!(*sc)->cenc.default_encrypted_sample)
5944 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5945 if (!(*sc)->cenc.encryption_index)
5946 return AVERROR(ENOMEM);
5949 *encryption_index = (*sc)->cenc.encryption_index;
5954 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
5957 unsigned int subsample_count;
5958 AVSubsampleEncryptionInfo *subsamples;
5960 if (!sc->cenc.default_encrypted_sample) {
5961 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
5962 return AVERROR_INVALIDDATA;
5965 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
5967 return AVERROR(ENOMEM);
5969 if (sc->cenc.per_sample_iv_size != 0) {
5970 if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
5971 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
5972 av_encryption_info_free(*sample);
5978 if (use_subsamples) {
5979 subsample_count = avio_rb16(pb);
5980 av_free((*sample)->subsamples);
5981 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
5982 if (!(*sample)->subsamples) {
5983 av_encryption_info_free(*sample);
5985 return AVERROR(ENOMEM);
5988 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
5989 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
5990 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
5993 if (pb->eof_reached) {
5994 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
5995 av_encryption_info_free(*sample);
5997 return AVERROR_INVALIDDATA;
5999 (*sample)->subsample_count = subsample_count;
6005 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6007 AVEncryptionInfo **encrypted_samples;
6008 MOVEncryptionIndex *encryption_index;
6009 MOVStreamContext *sc;
6010 int use_subsamples, ret;
6011 unsigned int sample_count, i, alloc_size = 0;
6013 ret = get_current_encryption_info(c, &encryption_index, &sc);
6017 if (encryption_index->nb_encrypted_samples) {
6018 // This can happen if we have both saio/saiz and senc atoms.
6019 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6023 avio_r8(pb); /* version */
6024 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6026 sample_count = avio_rb32(pb);
6027 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6028 return AVERROR(ENOMEM);
6030 for (i = 0; i < sample_count; i++) {
6031 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6032 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6033 min_samples * sizeof(*encrypted_samples));
6034 if (encrypted_samples) {
6035 encryption_index->encrypted_samples = encrypted_samples;
6037 ret = mov_read_sample_encryption_info(
6038 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6040 ret = AVERROR(ENOMEM);
6042 if (pb->eof_reached) {
6043 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6044 ret = AVERROR_INVALIDDATA;
6049 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6050 av_freep(&encryption_index->encrypted_samples);
6054 encryption_index->nb_encrypted_samples = sample_count;
6059 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6061 AVEncryptionInfo **sample, **encrypted_samples;
6063 size_t sample_count, sample_info_size, i;
6065 unsigned int alloc_size = 0;
6067 if (encryption_index->nb_encrypted_samples)
6069 sample_count = encryption_index->auxiliary_info_sample_count;
6070 if (encryption_index->auxiliary_offsets_count != 1) {
6071 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6072 return AVERROR_PATCHWELCOME;
6074 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6075 return AVERROR(ENOMEM);
6077 prev_pos = avio_tell(pb);
6078 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6079 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6080 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6084 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6085 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6086 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6087 min_samples * sizeof(*encrypted_samples));
6088 if (!encrypted_samples) {
6089 ret = AVERROR(ENOMEM);
6092 encryption_index->encrypted_samples = encrypted_samples;
6094 sample = &encryption_index->encrypted_samples[i];
6095 sample_info_size = encryption_index->auxiliary_info_default_size
6096 ? encryption_index->auxiliary_info_default_size
6097 : encryption_index->auxiliary_info_sizes[i];
6099 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6103 if (pb->eof_reached) {
6104 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6105 ret = AVERROR_INVALIDDATA;
6107 encryption_index->nb_encrypted_samples = sample_count;
6111 avio_seek(pb, prev_pos, SEEK_SET);
6113 for (; i > 0; i--) {
6114 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6116 av_freep(&encryption_index->encrypted_samples);
6122 * Tries to read the given number of bytes from the stream and puts it in a
6123 * newly allocated buffer. This reads in small chunks to avoid allocating large
6124 * memory if the file contains an invalid/malicious size value.
6126 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6128 const unsigned int block_size = 1024 * 1024;
6129 uint8_t *buffer = NULL;
6130 unsigned int alloc_size = 0, offset = 0;
6131 while (offset < size) {
6132 unsigned int new_size =
6133 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6134 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6135 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6138 return AVERROR(ENOMEM);
6140 buffer = new_buffer;
6142 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6144 return AVERROR_INVALIDDATA;
6153 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6155 MOVEncryptionIndex *encryption_index;
6156 MOVStreamContext *sc;
6158 unsigned int sample_count, aux_info_type, aux_info_param;
6160 ret = get_current_encryption_info(c, &encryption_index, &sc);
6164 if (encryption_index->nb_encrypted_samples) {
6165 // This can happen if we have both saio/saiz and senc atoms.
6166 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6170 if (encryption_index->auxiliary_info_sample_count) {
6171 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6172 return AVERROR_INVALIDDATA;
6175 avio_r8(pb); /* version */
6176 if (avio_rb24(pb) & 0x01) { /* flags */
6177 aux_info_type = avio_rb32(pb);
6178 aux_info_param = avio_rb32(pb);
6179 if (sc->cenc.default_encrypted_sample) {
6180 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6181 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6184 if (aux_info_param != 0) {
6185 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6189 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6190 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6191 aux_info_type == MKBETAG('c','e','n','s') ||
6192 aux_info_type == MKBETAG('c','b','c','1') ||
6193 aux_info_type == MKBETAG('c','b','c','s')) &&
6194 aux_info_param == 0) {
6195 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6196 return AVERROR_INVALIDDATA;
6201 } else if (!sc->cenc.default_encrypted_sample) {
6202 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6206 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6207 sample_count = avio_rb32(pb);
6208 encryption_index->auxiliary_info_sample_count = sample_count;
6210 if (encryption_index->auxiliary_info_default_size == 0) {
6211 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6213 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6218 if (encryption_index->auxiliary_offsets_count) {
6219 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6225 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6227 uint64_t *auxiliary_offsets;
6228 MOVEncryptionIndex *encryption_index;
6229 MOVStreamContext *sc;
6231 unsigned int version, entry_count, aux_info_type, aux_info_param;
6232 unsigned int alloc_size = 0;
6234 ret = get_current_encryption_info(c, &encryption_index, &sc);
6238 if (encryption_index->nb_encrypted_samples) {
6239 // This can happen if we have both saio/saiz and senc atoms.
6240 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6244 if (encryption_index->auxiliary_offsets_count) {
6245 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6246 return AVERROR_INVALIDDATA;
6249 version = avio_r8(pb); /* version */
6250 if (avio_rb24(pb) & 0x01) { /* flags */
6251 aux_info_type = avio_rb32(pb);
6252 aux_info_param = avio_rb32(pb);
6253 if (sc->cenc.default_encrypted_sample) {
6254 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6255 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6258 if (aux_info_param != 0) {
6259 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6263 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6264 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6265 aux_info_type == MKBETAG('c','e','n','s') ||
6266 aux_info_type == MKBETAG('c','b','c','1') ||
6267 aux_info_type == MKBETAG('c','b','c','s')) &&
6268 aux_info_param == 0) {
6269 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6270 return AVERROR_INVALIDDATA;
6275 } else if (!sc->cenc.default_encrypted_sample) {
6276 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6280 entry_count = avio_rb32(pb);
6281 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6282 return AVERROR(ENOMEM);
6284 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6285 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6286 auxiliary_offsets = av_fast_realloc(
6287 encryption_index->auxiliary_offsets, &alloc_size,
6288 min_offsets * sizeof(*auxiliary_offsets));
6289 if (!auxiliary_offsets) {
6290 av_freep(&encryption_index->auxiliary_offsets);
6291 return AVERROR(ENOMEM);
6293 encryption_index->auxiliary_offsets = auxiliary_offsets;
6296 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6298 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6300 if (c->frag_index.current >= 0) {
6301 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6305 if (pb->eof_reached) {
6306 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6307 av_freep(&encryption_index->auxiliary_offsets);
6308 return AVERROR_INVALIDDATA;
6311 encryption_index->auxiliary_offsets_count = entry_count;
6313 if (encryption_index->auxiliary_info_sample_count) {
6314 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6320 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6322 AVEncryptionInitInfo *info, *old_init_info;
6325 uint8_t *side_data, *extra_data, *old_side_data;
6326 size_t side_data_size;
6327 int ret = 0, old_side_data_size;
6328 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6330 if (c->fc->nb_streams < 1)
6332 st = c->fc->streams[c->fc->nb_streams-1];
6334 version = avio_r8(pb); /* version */
6335 avio_rb24(pb); /* flags */
6337 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6338 /* key_id_size */ 16, /* data_size */ 0);
6340 return AVERROR(ENOMEM);
6342 if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
6343 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6348 kid_count = avio_rb32(pb);
6349 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
6350 ret = AVERROR(ENOMEM);
6354 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6355 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6356 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6357 min_kid_count * sizeof(*key_ids));
6359 ret = AVERROR(ENOMEM);
6362 info->key_ids = key_ids;
6364 info->key_ids[i] = av_mallocz(16);
6365 if (!info->key_ids[i]) {
6366 ret = AVERROR(ENOMEM);
6369 info->num_key_ids = i + 1;
6371 if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
6372 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6377 if (pb->eof_reached) {
6378 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6379 ret = AVERROR_INVALIDDATA;
6384 extra_data_size = avio_rb32(pb);
6385 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6389 av_freep(&info->data); // malloc(0) may still allocate something.
6390 info->data = extra_data;
6391 info->data_size = extra_data_size;
6393 // If there is existing initialization data, append to the list.
6394 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6395 if (old_side_data) {
6396 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6397 if (old_init_info) {
6398 // Append to the end of the list.
6399 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6405 info = old_init_info;
6407 // Assume existing side-data will be valid, so the only error we could get is OOM.
6408 ret = AVERROR(ENOMEM);
6413 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6415 ret = AVERROR(ENOMEM);
6418 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6419 side_data, side_data_size);
6424 av_encryption_init_info_free(info);
6428 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6431 MOVStreamContext *sc;
6433 if (c->fc->nb_streams < 1)
6435 st = c->fc->streams[c->fc->nb_streams-1];
6438 if (sc->pseudo_stream_id != 0) {
6439 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6440 return AVERROR_PATCHWELCOME;
6444 return AVERROR_INVALIDDATA;
6446 avio_rb32(pb); /* version and flags */
6448 if (!sc->cenc.default_encrypted_sample) {
6449 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6450 if (!sc->cenc.default_encrypted_sample) {
6451 return AVERROR(ENOMEM);
6455 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6459 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6462 MOVStreamContext *sc;
6463 unsigned int version, pattern, is_protected, iv_size;
6465 if (c->fc->nb_streams < 1)
6467 st = c->fc->streams[c->fc->nb_streams-1];
6470 if (sc->pseudo_stream_id != 0) {
6471 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6472 return AVERROR_PATCHWELCOME;
6475 if (!sc->cenc.default_encrypted_sample) {
6476 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6477 if (!sc->cenc.default_encrypted_sample) {
6478 return AVERROR(ENOMEM);
6483 return AVERROR_INVALIDDATA;
6485 version = avio_r8(pb); /* version */
6486 avio_rb24(pb); /* flags */
6488 avio_r8(pb); /* reserved */
6489 pattern = avio_r8(pb);
6492 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6493 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6496 is_protected = avio_r8(pb);
6497 if (is_protected && !sc->cenc.encryption_index) {
6498 // The whole stream should be by-default encrypted.
6499 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6500 if (!sc->cenc.encryption_index)
6501 return AVERROR(ENOMEM);
6503 sc->cenc.per_sample_iv_size = avio_r8(pb);
6504 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6505 sc->cenc.per_sample_iv_size != 16) {
6506 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6507 return AVERROR_INVALIDDATA;
6509 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6510 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6511 return AVERROR_INVALIDDATA;
6514 if (is_protected && !sc->cenc.per_sample_iv_size) {
6515 iv_size = avio_r8(pb);
6516 if (iv_size != 8 && iv_size != 16) {
6517 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6518 return AVERROR_INVALIDDATA;
6521 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6522 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6523 return AVERROR_INVALIDDATA;
6530 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6533 int last, type, size, ret;
6536 if (c->fc->nb_streams < 1)
6538 st = c->fc->streams[c->fc->nb_streams-1];
6540 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6541 return AVERROR_INVALIDDATA;
6543 /* Check FlacSpecificBox version. */
6544 if (avio_r8(pb) != 0)
6545 return AVERROR_INVALIDDATA;
6547 avio_rb24(pb); /* Flags */
6549 avio_read(pb, buf, sizeof(buf));
6550 flac_parse_block_header(buf, &last, &type, &size);
6552 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6553 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6554 return AVERROR_INVALIDDATA;
6557 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6562 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6567 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6571 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6572 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6573 return AVERROR_PATCHWELCOME;
6576 if (!sc->cenc.aes_ctr) {
6577 /* initialize the cipher */
6578 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6579 if (!sc->cenc.aes_ctr) {
6580 return AVERROR(ENOMEM);
6583 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6589 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6591 if (!sample->subsample_count) {
6592 /* decrypt the whole packet */
6593 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6597 for (i = 0; i < sample->subsample_count; i++) {
6598 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6599 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6600 return AVERROR_INVALIDDATA;
6603 /* skip the clear bytes */
6604 input += sample->subsamples[i].bytes_of_clear_data;
6605 size -= sample->subsamples[i].bytes_of_clear_data;
6607 /* decrypt the encrypted bytes */
6608 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6609 input += sample->subsamples[i].bytes_of_protected_data;
6610 size -= sample->subsamples[i].bytes_of_protected_data;
6614 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6615 return AVERROR_INVALIDDATA;
6621 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6623 MOVFragmentStreamInfo *frag_stream_info;
6624 MOVEncryptionIndex *encryption_index;
6625 AVEncryptionInfo *encrypted_sample;
6626 int encrypted_index, ret;
6628 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6629 encrypted_index = current_index;
6630 encryption_index = NULL;
6631 if (frag_stream_info) {
6632 // Note this only supports encryption info in the first sample descriptor.
6633 if (mov->fragment.stsd_id == 1) {
6634 if (frag_stream_info->encryption_index) {
6635 encrypted_index = current_index - frag_stream_info->index_entry;
6636 encryption_index = frag_stream_info->encryption_index;
6638 encryption_index = sc->cenc.encryption_index;
6642 encryption_index = sc->cenc.encryption_index;
6645 if (encryption_index) {
6646 if (encryption_index->auxiliary_info_sample_count &&
6647 !encryption_index->nb_encrypted_samples) {
6648 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6649 return AVERROR_INVALIDDATA;
6651 if (encryption_index->auxiliary_offsets_count &&
6652 !encryption_index->nb_encrypted_samples) {
6653 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6654 return AVERROR_INVALIDDATA;
6657 if (!encryption_index->nb_encrypted_samples) {
6658 // Full-sample encryption with default settings.
6659 encrypted_sample = sc->cenc.default_encrypted_sample;
6660 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6661 // Per-sample setting override.
6662 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6664 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6665 return AVERROR_INVALIDDATA;
6668 if (mov->decryption_key) {
6669 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6672 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6674 return AVERROR(ENOMEM);
6675 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6685 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6687 const int OPUS_SEEK_PREROLL_MS = 80;
6693 if (c->fc->nb_streams < 1)
6695 st = c->fc->streams[c->fc->nb_streams-1];
6697 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6698 return AVERROR_INVALIDDATA;
6700 /* Check OpusSpecificBox version. */
6701 if (avio_r8(pb) != 0) {
6702 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6703 return AVERROR_INVALIDDATA;
6706 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6707 size = atom.size + 8;
6709 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
6712 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6713 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6714 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6715 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6717 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6718 little-endian; aside from the preceeding magic and version they're
6719 otherwise currently identical. Data after output gain at offset 16
6720 doesn't need to be bytewapped. */
6721 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6722 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6723 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6724 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6726 st->codecpar->initial_padding = pre_skip;
6727 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6728 (AVRational){1, 1000},
6729 (AVRational){1, 48000});
6734 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6737 unsigned format_info;
6738 int channel_assignment, channel_assignment1, channel_assignment2;
6741 if (c->fc->nb_streams < 1)
6743 st = c->fc->streams[c->fc->nb_streams-1];
6746 return AVERROR_INVALIDDATA;
6748 format_info = avio_rb32(pb);
6750 ratebits = (format_info >> 28) & 0xF;
6751 channel_assignment1 = (format_info >> 15) & 0x1F;
6752 channel_assignment2 = format_info & 0x1FFF;
6753 if (channel_assignment2)
6754 channel_assignment = channel_assignment2;
6756 channel_assignment = channel_assignment1;
6758 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6759 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6760 st->codecpar->channels = truehd_channels(channel_assignment);
6761 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6766 static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6770 AVDOVIDecoderConfigurationRecord *dovi;
6774 if (c->fc->nb_streams < 1)
6776 st = c->fc->streams[c->fc->nb_streams-1];
6778 if ((uint64_t)atom.size > (1<<30) || atom.size < 4)
6779 return AVERROR_INVALIDDATA;
6781 dovi = av_dovi_alloc(&dovi_size);
6783 return AVERROR(ENOMEM);
6785 dovi->dv_version_major = avio_r8(pb);
6786 dovi->dv_version_minor = avio_r8(pb);
6788 buf = avio_rb16(pb);
6789 dovi->dv_profile = (buf >> 9) & 0x7f; // 7 bits
6790 dovi->dv_level = (buf >> 3) & 0x3f; // 6 bits
6791 dovi->rpu_present_flag = (buf >> 2) & 0x01; // 1 bit
6792 dovi->el_present_flag = (buf >> 1) & 0x01; // 1 bit
6793 dovi->bl_present_flag = buf & 0x01; // 1 bit
6794 if (atom.size >= 24) { // 4 + 4 + 4 * 4
6796 dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits
6798 // 0 stands for None
6799 // Dolby Vision V1.2.93 profiles and levels
6800 dovi->dv_bl_signal_compatibility_id = 0;
6803 ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF,
6804 (uint8_t *)dovi, dovi_size);
6810 av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC box, version: %d.%d, profile: %d, level: %d, "
6811 "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n",
6812 dovi->dv_version_major, dovi->dv_version_minor,
6813 dovi->dv_profile, dovi->dv_level,
6814 dovi->rpu_present_flag,
6815 dovi->el_present_flag,
6816 dovi->bl_present_flag,
6817 dovi->dv_bl_signal_compatibility_id
6823 static const MOVParseTableEntry mov_default_parse_table[] = {
6824 { MKTAG('A','C','L','R'), mov_read_aclr },
6825 { MKTAG('A','P','R','G'), mov_read_avid },
6826 { MKTAG('A','A','L','P'), mov_read_avid },
6827 { MKTAG('A','R','E','S'), mov_read_ares },
6828 { MKTAG('a','v','s','s'), mov_read_avss },
6829 { MKTAG('a','v','1','C'), mov_read_av1c },
6830 { MKTAG('c','h','p','l'), mov_read_chpl },
6831 { MKTAG('c','o','6','4'), mov_read_stco },
6832 { MKTAG('c','o','l','r'), mov_read_colr },
6833 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6834 { MKTAG('d','i','n','f'), mov_read_default },
6835 { MKTAG('D','p','x','E'), mov_read_dpxe },
6836 { MKTAG('d','r','e','f'), mov_read_dref },
6837 { MKTAG('e','d','t','s'), mov_read_default },
6838 { MKTAG('e','l','s','t'), mov_read_elst },
6839 { MKTAG('e','n','d','a'), mov_read_enda },
6840 { MKTAG('f','i','e','l'), mov_read_fiel },
6841 { MKTAG('a','d','r','m'), mov_read_adrm },
6842 { MKTAG('f','t','y','p'), mov_read_ftyp },
6843 { MKTAG('g','l','b','l'), mov_read_glbl },
6844 { MKTAG('h','d','l','r'), mov_read_hdlr },
6845 { MKTAG('i','l','s','t'), mov_read_ilst },
6846 { MKTAG('j','p','2','h'), mov_read_jp2h },
6847 { MKTAG('m','d','a','t'), mov_read_mdat },
6848 { MKTAG('m','d','h','d'), mov_read_mdhd },
6849 { MKTAG('m','d','i','a'), mov_read_default },
6850 { MKTAG('m','e','t','a'), mov_read_meta },
6851 { MKTAG('m','i','n','f'), mov_read_default },
6852 { MKTAG('m','o','o','f'), mov_read_moof },
6853 { MKTAG('m','o','o','v'), mov_read_moov },
6854 { MKTAG('m','v','e','x'), mov_read_default },
6855 { MKTAG('m','v','h','d'), mov_read_mvhd },
6856 { MKTAG('S','M','I',' '), mov_read_svq3 },
6857 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6858 { MKTAG('a','v','c','C'), mov_read_glbl },
6859 { MKTAG('p','a','s','p'), mov_read_pasp },
6860 { MKTAG('s','i','d','x'), mov_read_sidx },
6861 { MKTAG('s','t','b','l'), mov_read_default },
6862 { MKTAG('s','t','c','o'), mov_read_stco },
6863 { MKTAG('s','t','p','s'), mov_read_stps },
6864 { MKTAG('s','t','r','f'), mov_read_strf },
6865 { MKTAG('s','t','s','c'), mov_read_stsc },
6866 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6867 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6868 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6869 { MKTAG('s','t','t','s'), mov_read_stts },
6870 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6871 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
6872 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6873 { MKTAG('t','f','d','t'), mov_read_tfdt },
6874 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6875 { MKTAG('t','r','a','k'), mov_read_trak },
6876 { MKTAG('t','r','a','f'), mov_read_default },
6877 { MKTAG('t','r','e','f'), mov_read_default },
6878 { MKTAG('t','m','c','d'), mov_read_tmcd },
6879 { MKTAG('c','h','a','p'), mov_read_chap },
6880 { MKTAG('t','r','e','x'), mov_read_trex },
6881 { MKTAG('t','r','u','n'), mov_read_trun },
6882 { MKTAG('u','d','t','a'), mov_read_default },
6883 { MKTAG('w','a','v','e'), mov_read_wave },
6884 { MKTAG('e','s','d','s'), mov_read_esds },
6885 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6886 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6887 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6888 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6889 { MKTAG('w','f','e','x'), mov_read_wfex },
6890 { MKTAG('c','m','o','v'), mov_read_cmov },
6891 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6892 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6893 { MKTAG('s','b','g','p'), mov_read_sbgp },
6894 { MKTAG('h','v','c','C'), mov_read_glbl },
6895 { MKTAG('u','u','i','d'), mov_read_uuid },
6896 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6897 { MKTAG('f','r','e','e'), mov_read_free },
6898 { MKTAG('-','-','-','-'), mov_read_custom },
6899 { MKTAG('s','i','n','f'), mov_read_default },
6900 { MKTAG('f','r','m','a'), mov_read_frma },
6901 { MKTAG('s','e','n','c'), mov_read_senc },
6902 { MKTAG('s','a','i','z'), mov_read_saiz },
6903 { MKTAG('s','a','i','o'), mov_read_saio },
6904 { MKTAG('p','s','s','h'), mov_read_pssh },
6905 { MKTAG('s','c','h','m'), mov_read_schm },
6906 { MKTAG('s','c','h','i'), mov_read_default },
6907 { MKTAG('t','e','n','c'), mov_read_tenc },
6908 { MKTAG('d','f','L','a'), mov_read_dfla },
6909 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6910 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6911 { MKTAG('d','O','p','s'), mov_read_dops },
6912 { MKTAG('d','m','l','p'), mov_read_dmlp },
6913 { MKTAG('S','m','D','m'), mov_read_smdm },
6914 { MKTAG('C','o','L','L'), mov_read_coll },
6915 { MKTAG('v','p','c','C'), mov_read_vpcc },
6916 { MKTAG('m','d','c','v'), mov_read_mdcv },
6917 { MKTAG('c','l','l','i'), mov_read_clli },
6918 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
6919 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
6923 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6925 int64_t total_size = 0;
6929 if (c->atom_depth > 10) {
6930 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6931 return AVERROR_INVALIDDATA;
6936 atom.size = INT64_MAX;
6937 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6938 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
6941 if (atom.size >= 8) {
6942 a.size = avio_rb32(pb);
6943 a.type = avio_rl32(pb);
6944 if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
6945 a.type == MKTAG('h','o','o','v')) &&
6947 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
6949 uint32_t *type = (uint32_t *)buf + 1;
6950 if (avio_read(pb, buf, 8) != 8)
6951 return AVERROR_INVALIDDATA;
6952 avio_seek(pb, -8, SEEK_CUR);
6953 if (*type == MKTAG('m','v','h','d') ||
6954 *type == MKTAG('c','m','o','v')) {
6955 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
6956 a.type = MKTAG('m','o','o','v');
6959 if (atom.type != MKTAG('r','o','o','t') &&
6960 atom.type != MKTAG('m','o','o','v')) {
6961 if (a.type == MKTAG('t','r','a','k') ||
6962 a.type == MKTAG('m','d','a','t')) {
6963 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
6970 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
6971 a.size = avio_rb64(pb) - 8;
6975 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
6976 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
6978 a.size = atom.size - total_size + 8;
6983 a.size = FFMIN(a.size, atom.size - total_size);
6985 for (i = 0; mov_default_parse_table[i].type; i++)
6986 if (mov_default_parse_table[i].type == a.type) {
6987 parse = mov_default_parse_table[i].parse;
6991 // container is user data
6992 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
6993 atom.type == MKTAG('i','l','s','t')))
6994 parse = mov_read_udta_string;
6996 // Supports parsing the QuickTime Metadata Keys.
6997 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
6998 if (!parse && c->found_hdlr_mdta &&
6999 atom.type == MKTAG('m','e','t','a') &&
7000 a.type == MKTAG('k','e','y','s') &&
7001 c->meta_keys_count == 0) {
7002 parse = mov_read_keys;
7005 if (!parse) { /* skip leaf atoms data */
7006 avio_skip(pb, a.size);
7008 int64_t start_pos = avio_tell(pb);
7010 int err = parse(c, pb, a);
7015 if (c->found_moov && c->found_mdat &&
7016 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
7017 start_pos + a.size == avio_size(pb))) {
7018 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
7019 c->next_root_atom = start_pos + a.size;
7023 left = a.size - avio_tell(pb) + start_pos;
7024 if (left > 0) /* skip garbage at atom end */
7025 avio_skip(pb, left);
7026 else if (left < 0) {
7027 av_log(c->fc, AV_LOG_WARNING,
7028 "overread end of atom '%.4s' by %"PRId64" bytes\n",
7029 (char*)&a.type, -left);
7030 avio_seek(pb, left, SEEK_CUR);
7034 total_size += a.size;
7037 if (total_size < atom.size && atom.size < 0x7ffff)
7038 avio_skip(pb, atom.size - total_size);
7044 static int mov_probe(const AVProbeData *p)
7049 int moov_offset = -1;
7051 /* check file header */
7054 /* ignore invalid offset */
7055 if ((offset + 8) > (unsigned int)p->buf_size)
7057 tag = AV_RL32(p->buf + offset + 4);
7059 /* check for obvious tags */
7060 case MKTAG('m','o','o','v'):
7061 moov_offset = offset + 4;
7062 case MKTAG('m','d','a','t'):
7063 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
7064 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
7065 case MKTAG('f','t','y','p'):
7066 if (AV_RB32(p->buf+offset) < 8 &&
7067 (AV_RB32(p->buf+offset) != 1 ||
7068 offset + 12 > (unsigned int)p->buf_size ||
7069 AV_RB64(p->buf+offset + 8) == 0)) {
7070 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7071 } else if (tag == MKTAG('f','t','y','p') &&
7072 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
7073 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
7075 score = FFMAX(score, 5);
7077 score = AVPROBE_SCORE_MAX;
7079 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7081 /* those are more common words, so rate then a bit less */
7082 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
7083 case MKTAG('w','i','d','e'):
7084 case MKTAG('f','r','e','e'):
7085 case MKTAG('j','u','n','k'):
7086 case MKTAG('p','i','c','t'):
7087 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
7088 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7090 case MKTAG(0x82,0x82,0x7f,0x7d):
7091 case MKTAG('s','k','i','p'):
7092 case MKTAG('u','u','i','d'):
7093 case MKTAG('p','r','f','l'):
7094 /* if we only find those cause probedata is too small at least rate them */
7095 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7096 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7099 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7102 if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
7103 /* moov atom in the header - we should make sure that this is not a
7104 * MOV-packed MPEG-PS */
7105 offset = moov_offset;
7107 while (offset < (p->buf_size - 16)) { /* Sufficient space */
7108 /* We found an actual hdlr atom */
7109 if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7110 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7111 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
7112 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7113 /* We found a media handler reference atom describing an
7114 * MPEG-PS-in-MOV, return a
7115 * low score to force expanding the probe window until
7116 * mpegps_probe finds what it needs */
7128 // must be done after parsing all trak because there's no order requirement
7129 static void mov_read_chapters(AVFormatContext *s)
7131 MOVContext *mov = s->priv_data;
7133 MOVStreamContext *sc;
7138 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7139 chapter_track = mov->chapter_tracks[j];
7141 for (i = 0; i < s->nb_streams; i++)
7142 if (s->streams[i]->id == chapter_track) {
7147 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7152 cur_pos = avio_tell(sc->pb);
7154 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7155 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7156 if (st->nb_index_entries) {
7157 // Retrieve the first frame, if possible
7158 AVIndexEntry *sample = &st->index_entries[0];
7159 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7160 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7164 if (av_get_packet(sc->pb, &st->attached_pic, sample->size) < 0)
7167 st->attached_pic.stream_index = st->index;
7168 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
7171 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7172 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7173 st->discard = AVDISCARD_ALL;
7174 for (i = 0; i < st->nb_index_entries; i++) {
7175 AVIndexEntry *sample = &st->index_entries[i];
7176 int64_t end = i+1 < st->nb_index_entries ? st->index_entries[i+1].timestamp : st->duration;
7181 if (end < sample->timestamp) {
7182 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7183 end = AV_NOPTS_VALUE;
7186 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7187 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7191 // the first two bytes are the length of the title
7192 len = avio_rb16(sc->pb);
7193 if (len > sample->size-2)
7195 title_len = 2*len + 1;
7196 if (!(title = av_mallocz(title_len)))
7199 // The samples could theoretically be in any encoding if there's an encd
7200 // atom following, but in practice are only utf-8 or utf-16, distinguished
7201 // instead by the presence of a BOM
7205 ch = avio_rb16(sc->pb);
7207 avio_get_str16be(sc->pb, len, title, title_len);
7208 else if (ch == 0xfffe)
7209 avio_get_str16le(sc->pb, len, title, title_len);
7212 if (len == 1 || len == 2)
7215 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7219 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7224 avio_seek(sc->pb, cur_pos, SEEK_SET);
7228 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7229 uint32_t value, int flags)
7232 char buf[AV_TIMECODE_STR_SIZE];
7233 AVRational rate = st->avg_frame_rate;
7234 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7237 av_dict_set(&st->metadata, "timecode",
7238 av_timecode_make_string(&tc, buf, value), 0);
7242 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7244 MOVStreamContext *sc = st->priv_data;
7245 char buf[AV_TIMECODE_STR_SIZE];
7246 int64_t cur_pos = avio_tell(sc->pb);
7247 int hh, mm, ss, ff, drop;
7249 if (!st->nb_index_entries)
7252 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7253 avio_skip(s->pb, 13);
7254 hh = avio_r8(s->pb);
7255 mm = avio_r8(s->pb);
7256 ss = avio_r8(s->pb);
7257 drop = avio_r8(s->pb);
7258 ff = avio_r8(s->pb);
7259 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7260 hh, mm, ss, drop ? ';' : ':', ff);
7261 av_dict_set(&st->metadata, "timecode", buf, 0);
7263 avio_seek(sc->pb, cur_pos, SEEK_SET);
7267 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7269 MOVStreamContext *sc = st->priv_data;
7271 int64_t cur_pos = avio_tell(sc->pb);
7274 if (!st->nb_index_entries)
7277 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7278 value = avio_rb32(s->pb);
7280 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7281 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7282 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7284 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7285 * not the case) and thus assume "frame number format" instead of QT one.
7286 * No sample with tmcd track can be found with a QT timecode at the moment,
7287 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7289 parse_timecode_in_framenum_format(s, st, value, flags);
7291 avio_seek(sc->pb, cur_pos, SEEK_SET);
7295 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7297 if (!index || !*index) return;
7298 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7299 av_encryption_info_free((*index)->encrypted_samples[i]);
7301 av_freep(&(*index)->encrypted_samples);
7302 av_freep(&(*index)->auxiliary_info_sizes);
7303 av_freep(&(*index)->auxiliary_offsets);
7307 static int mov_read_close(AVFormatContext *s)
7309 MOVContext *mov = s->priv_data;
7312 for (i = 0; i < s->nb_streams; i++) {
7313 AVStream *st = s->streams[i];
7314 MOVStreamContext *sc = st->priv_data;
7319 av_freep(&sc->ctts_data);
7320 for (j = 0; j < sc->drefs_count; j++) {
7321 av_freep(&sc->drefs[j].path);
7322 av_freep(&sc->drefs[j].dir);
7324 av_freep(&sc->drefs);
7326 sc->drefs_count = 0;
7328 if (!sc->pb_is_copied)
7329 ff_format_io_close(s, &sc->pb);
7332 av_freep(&sc->chunk_offsets);
7333 av_freep(&sc->stsc_data);
7334 av_freep(&sc->sample_sizes);
7335 av_freep(&sc->keyframes);
7336 av_freep(&sc->stts_data);
7337 av_freep(&sc->sdtp_data);
7338 av_freep(&sc->stps_data);
7339 av_freep(&sc->elst_data);
7340 av_freep(&sc->rap_group);
7341 av_freep(&sc->display_matrix);
7342 av_freep(&sc->index_ranges);
7345 for (j = 0; j < sc->stsd_count; j++)
7346 av_free(sc->extradata[j]);
7347 av_freep(&sc->extradata);
7348 av_freep(&sc->extradata_size);
7350 mov_free_encryption_index(&sc->cenc.encryption_index);
7351 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7352 av_aes_ctr_free(sc->cenc.aes_ctr);
7354 av_freep(&sc->stereo3d);
7355 av_freep(&sc->spherical);
7356 av_freep(&sc->mastering);
7357 av_freep(&sc->coll);
7360 if (mov->dv_demux) {
7361 avformat_free_context(mov->dv_fctx);
7362 mov->dv_fctx = NULL;
7365 if (mov->meta_keys) {
7366 for (i = 1; i < mov->meta_keys_count; i++) {
7367 av_freep(&mov->meta_keys[i]);
7369 av_freep(&mov->meta_keys);
7372 av_freep(&mov->trex_data);
7373 av_freep(&mov->bitrates);
7375 for (i = 0; i < mov->frag_index.nb_items; i++) {
7376 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7377 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7378 mov_free_encryption_index(&frag[j].encryption_index);
7380 av_freep(&mov->frag_index.item[i].stream_info);
7382 av_freep(&mov->frag_index.item);
7384 av_freep(&mov->aes_decrypt);
7385 av_freep(&mov->chapter_tracks);
7390 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7394 for (i = 0; i < s->nb_streams; i++) {
7395 AVStream *st = s->streams[i];
7396 MOVStreamContext *sc = st->priv_data;
7398 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7399 sc->timecode_track == tmcd_id)
7405 /* look for a tmcd track not referenced by any video track, and export it globally */
7406 static void export_orphan_timecode(AVFormatContext *s)
7410 for (i = 0; i < s->nb_streams; i++) {
7411 AVStream *st = s->streams[i];
7413 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7414 !tmcd_is_referenced(s, i + 1)) {
7415 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7417 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7424 static int read_tfra(MOVContext *mov, AVIOContext *f)
7426 int version, fieldlength, i, j;
7427 int64_t pos = avio_tell(f);
7428 uint32_t size = avio_rb32(f);
7429 unsigned track_id, item_count;
7431 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7434 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7436 version = avio_r8(f);
7438 track_id = avio_rb32(f);
7439 fieldlength = avio_rb32(f);
7440 item_count = avio_rb32(f);
7441 for (i = 0; i < item_count; i++) {
7442 int64_t time, offset;
7444 MOVFragmentStreamInfo * frag_stream_info;
7447 return AVERROR_INVALIDDATA;
7451 time = avio_rb64(f);
7452 offset = avio_rb64(f);
7454 time = avio_rb32(f);
7455 offset = avio_rb32(f);
7458 // The first sample of each stream in a fragment is always a random
7459 // access sample. So it's entry in the tfra can be used as the
7460 // initial PTS of the fragment.
7461 index = update_frag_index(mov, offset);
7462 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7463 if (frag_stream_info &&
7464 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7465 frag_stream_info->first_tfra_pts = time;
7467 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7469 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7471 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7475 avio_seek(f, pos + size, SEEK_SET);
7479 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7481 int64_t stream_size = avio_size(f);
7482 int64_t original_pos = avio_tell(f);
7486 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7490 mfra_size = avio_rb32(f);
7491 if (mfra_size < 0 || mfra_size > stream_size) {
7492 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7495 if ((seek_ret = avio_seek(f, -mfra_size, SEEK_CUR)) < 0) {
7499 if (avio_rb32(f) != mfra_size) {
7500 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7503 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7504 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7507 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7509 ret = read_tfra(c, f);
7515 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7517 av_log(c->fc, AV_LOG_ERROR,
7518 "failed to seek back after looking for mfra\n");
7524 static int mov_read_header(AVFormatContext *s)
7526 MOVContext *mov = s->priv_data;
7527 AVIOContext *pb = s->pb;
7529 MOVAtom atom = { AV_RL32("root") };
7532 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7533 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7534 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7535 return AVERROR(EINVAL);
7539 mov->trak_index = -1;
7540 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7541 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7542 atom.size = avio_size(pb);
7544 atom.size = INT64_MAX;
7546 /* check MOV header */
7548 if (mov->moov_retry)
7549 avio_seek(pb, 0, SEEK_SET);
7550 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7551 av_log(s, AV_LOG_ERROR, "error reading header\n");
7554 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7555 if (!mov->found_moov) {
7556 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7557 err = AVERROR_INVALIDDATA;
7560 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7562 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7563 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7564 mov_read_chapters(s);
7565 for (i = 0; i < s->nb_streams; i++)
7566 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7567 mov_read_timecode_track(s, s->streams[i]);
7568 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7569 mov_read_rtmd_track(s, s->streams[i]);
7573 /* copy timecode metadata from tmcd tracks to the related video streams */
7574 for (i = 0; i < s->nb_streams; i++) {
7575 AVStream *st = s->streams[i];
7576 MOVStreamContext *sc = st->priv_data;
7577 if (sc->timecode_track > 0) {
7578 AVDictionaryEntry *tcr;
7579 int tmcd_st_id = -1;
7581 for (j = 0; j < s->nb_streams; j++)
7582 if (s->streams[j]->id == sc->timecode_track)
7585 if (tmcd_st_id < 0 || tmcd_st_id == i)
7587 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7589 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7592 export_orphan_timecode(s);
7594 for (i = 0; i < s->nb_streams; i++) {
7595 AVStream *st = s->streams[i];
7596 MOVStreamContext *sc = st->priv_data;
7597 fix_timescale(mov, sc);
7598 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
7599 st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7600 st->skip_samples = sc->start_pad;
7602 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7603 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7604 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7605 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7606 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7607 st->codecpar->width = sc->width;
7608 st->codecpar->height = sc->height;
7610 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7611 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7615 if (mov->handbrake_version &&
7616 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7617 st->codecpar->codec_id == AV_CODEC_ID_MP3) {
7618 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7619 st->need_parsing = AVSTREAM_PARSE_FULL;
7623 if (mov->trex_data) {
7624 for (i = 0; i < s->nb_streams; i++) {
7625 AVStream *st = s->streams[i];
7626 MOVStreamContext *sc = st->priv_data;
7627 if (st->duration > 0) {
7628 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7629 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7630 sc->data_size, sc->time_scale);
7631 err = AVERROR_INVALIDDATA;
7634 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7639 if (mov->use_mfra_for > 0) {
7640 for (i = 0; i < s->nb_streams; i++) {
7641 AVStream *st = s->streams[i];
7642 MOVStreamContext *sc = st->priv_data;
7643 if (sc->duration_for_fps > 0) {
7644 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7645 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7646 sc->data_size, sc->time_scale);
7647 err = AVERROR_INVALIDDATA;
7650 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7651 sc->duration_for_fps;
7656 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7657 if (mov->bitrates[i]) {
7658 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7662 ff_rfps_calculate(s);
7664 for (i = 0; i < s->nb_streams; i++) {
7665 AVStream *st = s->streams[i];
7666 MOVStreamContext *sc = st->priv_data;
7668 switch (st->codecpar->codec_type) {
7669 case AVMEDIA_TYPE_AUDIO:
7670 err = ff_replaygain_export(st, s->metadata);
7674 case AVMEDIA_TYPE_VIDEO:
7675 if (sc->display_matrix) {
7676 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7677 sizeof(int32_t) * 9);
7681 sc->display_matrix = NULL;
7684 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7685 (uint8_t *)sc->stereo3d,
7686 sizeof(*sc->stereo3d));
7690 sc->stereo3d = NULL;
7692 if (sc->spherical) {
7693 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7694 (uint8_t *)sc->spherical,
7695 sc->spherical_size);
7699 sc->spherical = NULL;
7701 if (sc->mastering) {
7702 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7703 (uint8_t *)sc->mastering,
7704 sizeof(*sc->mastering));
7708 sc->mastering = NULL;
7711 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7712 (uint8_t *)sc->coll,
7722 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7724 for (i = 0; i < mov->frag_index.nb_items; i++)
7725 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7726 mov->frag_index.item[i].headers_read = 1;
7734 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7736 AVIndexEntry *sample = NULL;
7737 int64_t best_dts = INT64_MAX;
7739 for (i = 0; i < s->nb_streams; i++) {
7740 AVStream *avst = s->streams[i];
7741 MOVStreamContext *msc = avst->priv_data;
7742 if (msc->pb && msc->current_sample < avst->nb_index_entries) {
7743 AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample];
7744 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7745 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7746 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7747 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7748 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
7749 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7750 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7751 sample = current_sample;
7760 static int should_retry(AVIOContext *pb, int error_code) {
7761 if (error_code == AVERROR_EOF || avio_feof(pb))
7767 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7770 MOVContext *mov = s->priv_data;
7772 if (index >= 0 && index < mov->frag_index.nb_items)
7773 target = mov->frag_index.item[index].moof_offset;
7774 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7775 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7776 return AVERROR_INVALIDDATA;
7779 mov->next_root_atom = 0;
7780 if (index < 0 || index >= mov->frag_index.nb_items)
7781 index = search_frag_moof_offset(&mov->frag_index, target);
7782 if (index < mov->frag_index.nb_items &&
7783 mov->frag_index.item[index].moof_offset == target) {
7784 if (index + 1 < mov->frag_index.nb_items)
7785 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7786 if (mov->frag_index.item[index].headers_read)
7788 mov->frag_index.item[index].headers_read = 1;
7791 mov->found_mdat = 0;
7793 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7796 if (avio_feof(s->pb))
7798 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7803 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7805 uint8_t *side, *extradata;
7808 /* Save the current index. */
7809 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7811 /* Notify the decoder that extradata changed. */
7812 extradata_size = sc->extradata_size[sc->last_stsd_index];
7813 extradata = sc->extradata[sc->last_stsd_index];
7814 if (extradata_size > 0 && extradata) {
7815 side = av_packet_new_side_data(pkt,
7816 AV_PKT_DATA_NEW_EXTRADATA,
7819 return AVERROR(ENOMEM);
7820 memcpy(side, extradata, extradata_size);
7826 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int size)
7831 return AVERROR_INVALIDDATA;
7832 new_size = ((size - 8) / 2) * 3;
7833 ret = av_new_packet(pkt, new_size);
7838 for (int j = 0; j < new_size; j += 3) {
7839 pkt->data[j] = 0xFC;
7840 pkt->data[j+1] = avio_r8(pb);
7841 pkt->data[j+2] = avio_r8(pb);
7847 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7849 MOVContext *mov = s->priv_data;
7850 MOVStreamContext *sc;
7851 AVIndexEntry *sample;
7852 AVStream *st = NULL;
7853 int64_t current_index;
7857 sample = mov_find_next_sample(s, &st);
7858 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7859 if (!mov->next_root_atom)
7861 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7866 /* must be done just before reading, to avoid infinite loop on sample */
7867 current_index = sc->current_index;
7868 mov_current_sample_inc(sc);
7870 if (mov->next_root_atom) {
7871 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7872 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7875 if (st->discard != AVDISCARD_ALL) {
7876 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7877 if (ret64 != sample->pos) {
7878 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7879 sc->ffindex, sample->pos);
7880 if (should_retry(sc->pb, ret64)) {
7881 mov_current_sample_dec(sc);
7883 return AVERROR_INVALIDDATA;
7886 if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
7887 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7891 if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
7892 ret = get_eia608_packet(sc->pb, pkt, sample->size);
7894 ret = av_get_packet(sc->pb, pkt, sample->size);
7896 if (should_retry(sc->pb, ret)) {
7897 mov_current_sample_dec(sc);
7901 #if CONFIG_DV_DEMUXER
7902 if (mov->dv_demux && sc->dv_audio_container) {
7903 AVBufferRef *buf = pkt->buf;
7904 ret = avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7906 av_packet_unref(pkt);
7909 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7914 if (sc->has_palette) {
7917 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7919 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7921 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7922 sc->has_palette = 0;
7925 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7926 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7927 st->need_parsing = AVSTREAM_PARSE_FULL;
7931 pkt->stream_index = sc->ffindex;
7932 pkt->dts = sample->timestamp;
7933 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7934 pkt->flags |= AV_PKT_FLAG_DISCARD;
7936 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7937 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
7938 /* update ctts context */
7940 if (sc->ctts_index < sc->ctts_count &&
7941 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
7943 sc->ctts_sample = 0;
7946 int64_t next_dts = (sc->current_sample < st->nb_index_entries) ?
7947 st->index_entries[sc->current_sample].timestamp : st->duration;
7949 if (next_dts >= pkt->dts)
7950 pkt->duration = next_dts - pkt->dts;
7951 pkt->pts = pkt->dts;
7953 if (st->discard == AVDISCARD_ALL)
7955 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
7956 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
7957 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
7958 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
7960 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
7961 pkt->pos = sample->pos;
7963 /* Multiple stsd handling. */
7964 if (sc->stsc_data) {
7965 /* Keep track of the stsc index for the given sample, then check
7966 * if the stsd index is different from the last used one. */
7968 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
7969 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
7971 sc->stsc_sample = 0;
7972 /* Do not check indexes after a switch. */
7973 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
7974 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
7975 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
7976 ret = mov_change_extradata(sc, pkt);
7983 aax_filter(pkt->data, pkt->size, mov);
7985 ret = cenc_filter(mov, st, sc, pkt, current_index);
7993 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
7995 MOVContext *mov = s->priv_data;
7998 if (!mov->frag_index.complete)
8001 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
8004 if (!mov->frag_index.item[index].headers_read)
8005 return mov_switch_root(s, -1, index);
8006 if (index + 1 < mov->frag_index.nb_items)
8007 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
8012 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
8014 MOVStreamContext *sc = st->priv_data;
8015 int sample, time_sample, ret;
8018 // Here we consider timestamp to be PTS, hence try to offset it so that we
8019 // can search over the DTS timeline.
8020 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
8022 ret = mov_seek_fragment(s, st, timestamp);
8026 sample = av_index_search_timestamp(st, timestamp, flags);
8027 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
8028 if (sample < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp)
8030 if (sample < 0) /* not sure what to do */
8031 return AVERROR_INVALIDDATA;
8032 mov_current_sample_set(sc, sample);
8033 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
8034 /* adjust ctts index */
8035 if (sc->ctts_data) {
8037 for (i = 0; i < sc->ctts_count; i++) {
8038 int next = time_sample + sc->ctts_data[i].count;
8039 if (next > sc->current_sample) {
8041 sc->ctts_sample = sc->current_sample - time_sample;
8048 /* adjust stsd index */
8049 if (sc->chunk_count) {
8051 for (i = 0; i < sc->stsc_count; i++) {
8052 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
8053 if (next > sc->current_sample) {
8055 sc->stsc_sample = sc->current_sample - time_sample;
8058 av_assert0(next == (int)next);
8066 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
8068 MOVContext *mc = s->priv_data;
8073 if (stream_index >= s->nb_streams)
8074 return AVERROR_INVALIDDATA;
8076 st = s->streams[stream_index];
8077 sample = mov_seek_stream(s, st, sample_time, flags);
8081 if (mc->seek_individually) {
8082 /* adjust seek timestamp to found sample timestamp */
8083 int64_t seek_timestamp = st->index_entries[sample].timestamp;
8085 for (i = 0; i < s->nb_streams; i++) {
8087 MOVStreamContext *sc = s->streams[i]->priv_data;
8089 st->skip_samples = (sample_time <= 0) ? sc->start_pad : 0;
8091 if (stream_index == i)
8094 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
8095 mov_seek_stream(s, st, timestamp, flags);
8098 for (i = 0; i < s->nb_streams; i++) {
8099 MOVStreamContext *sc;
8102 mov_current_sample_set(sc, 0);
8105 MOVStreamContext *sc;
8106 AVIndexEntry *entry = mov_find_next_sample(s, &st);
8108 return AVERROR_INVALIDDATA;
8110 if (sc->ffindex == stream_index && sc->current_sample == sample)
8112 mov_current_sample_inc(sc);
8118 #define OFFSET(x) offsetof(MOVContext, x)
8119 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
8120 static const AVOption mov_options[] = {
8121 {"use_absolute_path",
8122 "allow using absolute path when opening alias, this is a possible security issue",
8123 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
8125 {"seek_streams_individually",
8126 "Seek each stream individually to the closest point",
8127 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
8129 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
8131 {"advanced_editlist",
8132 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
8133 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
8135 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8138 "use mfra for fragment timestamps",
8139 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8140 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8142 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8143 FLAGS, "use_mfra_for" },
8144 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8145 FLAGS, "use_mfra_for" },
8146 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8147 FLAGS, "use_mfra_for" },
8148 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8149 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8150 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8151 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8152 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8153 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8154 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8155 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8156 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8157 .flags = AV_OPT_FLAG_DECODING_PARAM },
8158 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8159 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8160 {.i64 = 0}, 0, 1, FLAGS },
8165 static const AVClass mov_class = {
8166 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8167 .item_name = av_default_item_name,
8168 .option = mov_options,
8169 .version = LIBAVUTIL_VERSION_INT,
8172 AVInputFormat ff_mov_demuxer = {
8173 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8174 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8175 .priv_class = &mov_class,
8176 .priv_data_size = sizeof(MOVContext),
8177 .extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
8178 .read_probe = mov_probe,
8179 .read_header = mov_read_header,
8180 .read_packet = mov_read_packet,
8181 .read_close = mov_read_close,
8182 .read_seek = mov_read_seek,
8183 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,