3 * Copyright (c) 2001 Fabrice Bellard
4 * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
6 * first version by Francois Revol <revol@free.fr>
7 * seek function by Gael Chardon <gael.dev@4now.net>
9 * This file is part of FFmpeg.
11 * FFmpeg is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * FFmpeg is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with FFmpeg; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30 #include "libavutil/attributes.h"
31 #include "libavutil/channel_layout.h"
32 #include "libavutil/internal.h"
33 #include "libavutil/intreadwrite.h"
34 #include "libavutil/intfloat.h"
35 #include "libavutil/mathematics.h"
36 #include "libavutil/time_internal.h"
37 #include "libavutil/avassert.h"
38 #include "libavutil/avstring.h"
39 #include "libavutil/dict.h"
40 #include "libavutil/display.h"
41 #include "libavutil/opt.h"
42 #include "libavutil/aes.h"
43 #include "libavutil/aes_ctr.h"
44 #include "libavutil/pixdesc.h"
45 #include "libavutil/sha.h"
46 #include "libavutil/spherical.h"
47 #include "libavutil/stereo3d.h"
48 #include "libavutil/timecode.h"
49 #include "libavutil/dovi_meta.h"
50 #include "libavcodec/ac3tab.h"
51 #include "libavcodec/flac.h"
52 #include "libavcodec/mpegaudiodecheader.h"
53 #include "libavcodec/mlp_parse.h"
56 #include "avio_internal.h"
59 #include "libavcodec/get_bits.h"
62 #include "replaygain.h"
68 #include "qtpalette.h"
70 /* those functions parse an atom */
71 /* links atom IDs to parse functions */
72 typedef struct MOVParseTableEntry {
74 int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
77 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
78 static int mov_read_mfra(MOVContext *c, AVIOContext *f);
79 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
80 int count, int duration);
82 static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb,
83 unsigned len, const char *key)
87 short current, total = 0;
88 avio_rb16(pb); // unknown
89 current = avio_rb16(pb);
91 total = avio_rb16(pb);
93 snprintf(buf, sizeof(buf), "%d", current);
95 snprintf(buf, sizeof(buf), "%d/%d", current, total);
96 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
97 av_dict_set(&c->fc->metadata, key, buf, 0);
102 static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb,
103 unsigned len, const char *key)
105 /* bypass padding bytes */
110 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
111 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
116 static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb,
117 unsigned len, const char *key)
119 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
120 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
125 static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb,
126 unsigned len, const char *key)
130 avio_r8(pb); // unknown
133 if (genre < 1 || genre > ID3v1_GENRE_MAX)
135 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
136 av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
141 static const uint32_t mac_to_unicode[128] = {
142 0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
143 0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
144 0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
145 0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
146 0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
147 0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
148 0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
149 0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
150 0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
151 0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
152 0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
153 0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
154 0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
155 0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
156 0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
157 0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
160 static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len,
161 char *dst, int dstlen)
164 char *end = dst+dstlen-1;
167 for (i = 0; i < len; i++) {
168 uint8_t t, c = avio_r8(pb);
176 PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
182 static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
185 MOVStreamContext *sc;
190 case 0xd: id = AV_CODEC_ID_MJPEG; break;
191 case 0xe: id = AV_CODEC_ID_PNG; break;
192 case 0x1b: id = AV_CODEC_ID_BMP; break;
194 av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
199 st = avformat_new_stream(c->fc, NULL);
201 return AVERROR(ENOMEM);
202 sc = av_mallocz(sizeof(*sc));
204 return AVERROR(ENOMEM);
207 ret = av_get_packet(pb, &st->attached_pic, len);
211 if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) {
212 if (AV_RB64(st->attached_pic.data) == 0x89504e470d0a1a0a) {
213 id = AV_CODEC_ID_PNG;
215 id = AV_CODEC_ID_MJPEG;
219 st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
221 st->attached_pic.stream_index = st->index;
222 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
224 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
225 st->codecpar->codec_id = id;
231 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
233 char language[4] = { 0 };
234 char buf[200], place[100];
235 uint16_t langcode = 0;
236 double longitude, latitude, altitude;
237 const char *key = "location";
239 if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
240 av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
241 return AVERROR_INVALIDDATA;
244 avio_skip(pb, 4); // version+flags
245 langcode = avio_rb16(pb);
246 ff_mov_lang_to_iso639(langcode, language);
249 len -= avio_get_str(pb, len, place, sizeof(place));
251 av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
252 return AVERROR_INVALIDDATA;
254 avio_skip(pb, 1); // role
258 av_log(c->fc, AV_LOG_ERROR,
259 "loci too short (%u bytes left, need at least %d)\n", len, 12);
260 return AVERROR_INVALIDDATA;
262 longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
263 latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
264 altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
266 // Try to output in the same format as the ?xyz field
267 snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
269 av_strlcatf(buf, sizeof(buf), "%+f", altitude);
270 av_strlcatf(buf, sizeof(buf), "/%s", place);
272 if (*language && strcmp(language, "und")) {
274 snprintf(key2, sizeof(key2), "%s-%s", key, language);
275 av_dict_set(&c->fc->metadata, key2, buf, 0);
277 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
278 return av_dict_set(&c->fc->metadata, key, buf, 0);
281 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
287 if (c->ignore_chapters)
290 n_hmmt = avio_rb32(pb);
291 for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
292 int moment_time = avio_rb32(pb);
293 avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
298 static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
301 char key2[32], language[4] = {0};
303 const char *key = NULL;
304 uint16_t langcode = 0;
305 uint32_t data_type = 0, str_size, str_size_alloc;
306 int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
311 case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
312 case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
313 case MKTAG( 'X','M','P','_'):
314 if (c->export_xmp) { key = "xmp"; raw = 1; } break;
315 case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
316 case MKTAG( 'a','k','I','D'): key = "account_type";
317 parse = mov_metadata_int8_no_padding; break;
318 case MKTAG( 'a','p','I','D'): key = "account_id"; break;
319 case MKTAG( 'c','a','t','g'): key = "category"; break;
320 case MKTAG( 'c','p','i','l'): key = "compilation";
321 parse = mov_metadata_int8_no_padding; break;
322 case MKTAG( 'c','p','r','t'): key = "copyright"; break;
323 case MKTAG( 'd','e','s','c'): key = "description"; break;
324 case MKTAG( 'd','i','s','k'): key = "disc";
325 parse = mov_metadata_track_or_disc_number; break;
326 case MKTAG( 'e','g','i','d'): key = "episode_uid";
327 parse = mov_metadata_int8_no_padding; break;
328 case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
329 case MKTAG( 'g','n','r','e'): key = "genre";
330 parse = mov_metadata_gnre; break;
331 case MKTAG( 'h','d','v','d'): key = "hd_video";
332 parse = mov_metadata_int8_no_padding; break;
333 case MKTAG( 'H','M','M','T'):
334 return mov_metadata_hmmt(c, pb, atom.size);
335 case MKTAG( 'k','e','y','w'): key = "keywords"; break;
336 case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
337 case MKTAG( 'l','o','c','i'):
338 return mov_metadata_loci(c, pb, atom.size);
339 case MKTAG( 'm','a','n','u'): key = "make"; break;
340 case MKTAG( 'm','o','d','l'): key = "model"; break;
341 case MKTAG( 'p','c','s','t'): key = "podcast";
342 parse = mov_metadata_int8_no_padding; break;
343 case MKTAG( 'p','g','a','p'): key = "gapless_playback";
344 parse = mov_metadata_int8_no_padding; break;
345 case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
346 case MKTAG( 'r','t','n','g'): key = "rating";
347 parse = mov_metadata_int8_no_padding; break;
348 case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
349 case MKTAG( 's','o','a','l'): key = "sort_album"; break;
350 case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
351 case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
352 case MKTAG( 's','o','n','m'): key = "sort_name"; break;
353 case MKTAG( 's','o','s','n'): key = "sort_show"; break;
354 case MKTAG( 's','t','i','k'): key = "media_type";
355 parse = mov_metadata_int8_no_padding; break;
356 case MKTAG( 't','r','k','n'): key = "track";
357 parse = mov_metadata_track_or_disc_number; break;
358 case MKTAG( 't','v','e','n'): key = "episode_id"; break;
359 case MKTAG( 't','v','e','s'): key = "episode_sort";
360 parse = mov_metadata_int8_bypass_padding; break;
361 case MKTAG( 't','v','n','n'): key = "network"; break;
362 case MKTAG( 't','v','s','h'): key = "show"; break;
363 case MKTAG( 't','v','s','n'): key = "season_number";
364 parse = mov_metadata_int8_bypass_padding; break;
365 case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
366 case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
367 case MKTAG(0xa9,'a','l','b'): key = "album"; break;
368 case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
369 case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
370 case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
371 case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
372 case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
373 case MKTAG(0xa9,'d','a','y'): key = "date"; break;
374 case MKTAG(0xa9,'d','i','r'): key = "director"; break;
375 case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
376 case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
377 case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
378 case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
379 case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
380 case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
381 case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
382 case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
383 case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
384 case MKTAG(0xa9,'m','a','k'): key = "make"; break;
385 case MKTAG(0xa9,'m','o','d'): key = "model"; break;
386 case MKTAG(0xa9,'n','a','m'): key = "title"; break;
387 case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
388 case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
389 case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
390 case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
391 case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
392 case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
393 case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
394 case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
395 case MKTAG(0xa9,'t','r','k'): key = "track"; break;
396 case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
397 case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
398 case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
399 case MKTAG(0xa9,'x','y','z'): key = "location"; break;
402 if (c->itunes_metadata && atom.size > 8) {
403 int data_size = avio_rb32(pb);
404 int tag = avio_rl32(pb);
405 if (tag == MKTAG('d','a','t','a') && data_size <= atom.size) {
406 data_type = avio_rb32(pb); // type
407 avio_rb32(pb); // unknown
408 str_size = data_size - 16;
411 if (atom.type == MKTAG('c', 'o', 'v', 'r')) {
412 int ret = mov_read_covr(c, pb, data_type, str_size);
414 av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
417 atom.size -= str_size;
421 } else if (!key && c->found_hdlr_mdta && c->meta_keys) {
422 uint32_t index = AV_RB32(&atom.type);
423 if (index < c->meta_keys_count && index > 0) {
424 key = c->meta_keys[index];
426 av_log(c->fc, AV_LOG_WARNING,
427 "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
428 index, c->meta_keys_count);
432 } else if (atom.size > 4 && key && !c->itunes_metadata && !raw) {
433 str_size = avio_rb16(pb); // string length
434 if (str_size > atom.size) {
436 avio_seek(pb, -2, SEEK_CUR);
437 av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
440 langcode = avio_rb16(pb);
441 ff_mov_lang_to_iso639(langcode, language);
444 str_size = atom.size;
446 if (c->export_all && !key) {
447 snprintf(tmp_key, 5, "%.4s", (char*)&atom.type);
453 if (atom.size < 0 || str_size >= INT_MAX/2)
454 return AVERROR_INVALIDDATA;
456 // Allocates enough space if data_type is a int32 or float32 number, otherwise
457 // worst-case requirement for output string in case of utf8 coded input
458 num = (data_type >= 21 && data_type <= 23);
459 str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
460 str = av_mallocz(str_size_alloc);
462 return AVERROR(ENOMEM);
465 parse(c, pb, str_size, key);
467 if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
468 mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
469 } else if (data_type == 21) { // BE signed integer, variable size
472 val = (int8_t)avio_r8(pb);
473 else if (str_size == 2)
474 val = (int16_t)avio_rb16(pb);
475 else if (str_size == 3)
476 val = ((int32_t)(avio_rb24(pb)<<8))>>8;
477 else if (str_size == 4)
478 val = (int32_t)avio_rb32(pb);
479 if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
480 av_log(c->fc, AV_LOG_ERROR,
481 "Failed to store the number (%d) in string.\n", val);
483 return AVERROR_INVALIDDATA;
485 } else if (data_type == 22) { // BE unsigned integer, variable size
486 unsigned int val = 0;
489 else if (str_size == 2)
491 else if (str_size == 3)
493 else if (str_size == 4)
495 if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
496 av_log(c->fc, AV_LOG_ERROR,
497 "Failed to store the number (%u) in string.\n", val);
499 return AVERROR_INVALIDDATA;
501 } else if (data_type == 23 && str_size >= 4) { // BE float32
502 float val = av_int2float(avio_rb32(pb));
503 if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
504 av_log(c->fc, AV_LOG_ERROR,
505 "Failed to store the float32 number (%f) in string.\n", val);
507 return AVERROR_INVALIDDATA;
510 int ret = ffio_read_size(pb, str, str_size);
517 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
518 av_dict_set(&c->fc->metadata, key, str, 0);
519 if (*language && strcmp(language, "und")) {
520 snprintf(key2, sizeof(key2), "%s-%s", key, language);
521 av_dict_set(&c->fc->metadata, key2, str, 0);
523 if (!strcmp(key, "encoder")) {
524 int major, minor, micro;
525 if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, µ) == 3) {
526 c->handbrake_version = 1000000*major + 1000*minor + micro;
535 static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
538 int i, nb_chapters, str_len, version;
542 if (c->ignore_chapters)
545 if ((atom.size -= 5) < 0)
548 version = avio_r8(pb);
551 avio_rb32(pb); // ???
552 nb_chapters = avio_r8(pb);
554 for (i = 0; i < nb_chapters; i++) {
558 start = avio_rb64(pb);
559 str_len = avio_r8(pb);
561 if ((atom.size -= 9+str_len) < 0)
564 ret = ffio_read_size(pb, str, str_len);
568 avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
573 #define MIN_DATA_ENTRY_BOX_SIZE 12
574 static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
577 MOVStreamContext *sc;
580 if (c->fc->nb_streams < 1)
582 st = c->fc->streams[c->fc->nb_streams-1];
585 avio_rb32(pb); // version + flags
586 entries = avio_rb32(pb);
588 entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
589 entries >= UINT_MAX / sizeof(*sc->drefs))
590 return AVERROR_INVALIDDATA;
594 sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
596 return AVERROR(ENOMEM);
597 sc->drefs_count = entries;
599 for (i = 0; i < entries; i++) {
600 MOVDref *dref = &sc->drefs[i];
601 uint32_t size = avio_rb32(pb);
602 int64_t next = avio_tell(pb) + size - 4;
605 return AVERROR_INVALIDDATA;
607 dref->type = avio_rl32(pb);
608 avio_rb32(pb); // version + flags
610 if (dref->type == MKTAG('a','l','i','s') && size > 150) {
611 /* macintosh alias record */
612 uint16_t volume_len, len;
618 volume_len = avio_r8(pb);
619 volume_len = FFMIN(volume_len, 27);
620 ret = ffio_read_size(pb, dref->volume, 27);
623 dref->volume[volume_len] = 0;
624 av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
629 len = FFMIN(len, 63);
630 ret = ffio_read_size(pb, dref->filename, 63);
633 dref->filename[len] = 0;
634 av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
638 /* read next level up_from_alias/down_to_target */
639 dref->nlvl_from = avio_rb16(pb);
640 dref->nlvl_to = avio_rb16(pb);
641 av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
642 dref->nlvl_from, dref->nlvl_to);
646 for (type = 0; type != -1 && avio_tell(pb) < next; ) {
649 type = avio_rb16(pb);
651 av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
654 if (type == 2) { // absolute path
656 dref->path = av_mallocz(len+1);
658 return AVERROR(ENOMEM);
660 ret = ffio_read_size(pb, dref->path, len);
662 av_freep(&dref->path);
665 if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
667 memmove(dref->path, dref->path+volume_len, len);
670 // trim string of any ending zeros
671 for (j = len - 1; j >= 0; j--) {
672 if (dref->path[j] == 0)
677 for (j = 0; j < len; j++)
678 if (dref->path[j] == ':' || dref->path[j] == 0)
680 av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
681 } else if (type == 0) { // directory name
683 dref->dir = av_malloc(len+1);
685 return AVERROR(ENOMEM);
687 ret = ffio_read_size(pb, dref->dir, len);
689 av_freep(&dref->dir);
693 for (j = 0; j < len; j++)
694 if (dref->dir[j] == ':')
696 av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
701 av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
706 avio_seek(pb, next, SEEK_SET);
711 static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
720 avio_r8(pb); /* version */
721 avio_rb24(pb); /* flags */
724 ctype = avio_rl32(pb);
725 type = avio_rl32(pb); /* component subtype */
727 av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
728 av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
730 if (c->trak_index < 0) { // meta not inside a trak
731 if (type == MKTAG('m','d','t','a')) {
732 c->found_hdlr_mdta = 1;
737 st = c->fc->streams[c->fc->nb_streams-1];
739 if (type == MKTAG('v','i','d','e'))
740 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
741 else if (type == MKTAG('s','o','u','n'))
742 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
743 else if (type == MKTAG('m','1','a',' '))
744 st->codecpar->codec_id = AV_CODEC_ID_MP2;
745 else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
746 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
748 avio_rb32(pb); /* component manufacture */
749 avio_rb32(pb); /* component flags */
750 avio_rb32(pb); /* component flags mask */
752 title_size = atom.size - 24;
753 if (title_size > 0) {
754 if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
755 return AVERROR_INVALIDDATA;
756 title_str = av_malloc(title_size + 1); /* Add null terminator */
758 return AVERROR(ENOMEM);
760 ret = ffio_read_size(pb, title_str, title_size);
762 av_freep(&title_str);
765 title_str[title_size] = 0;
767 int off = (!c->isom && title_str[0] == title_size - 1);
768 // flag added so as to not set stream handler name if already set from mdia->hdlr
769 av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
771 av_freep(&title_str);
777 static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
779 return ff_mov_read_esds(c->fc, pb);
782 static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
785 enum AVAudioServiceType *ast;
786 int ac3info, acmod, lfeon, bsmod;
788 if (c->fc->nb_streams < 1)
790 st = c->fc->streams[c->fc->nb_streams-1];
792 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
795 return AVERROR(ENOMEM);
797 ac3info = avio_rb24(pb);
798 bsmod = (ac3info >> 14) & 0x7;
799 acmod = (ac3info >> 11) & 0x7;
800 lfeon = (ac3info >> 10) & 0x1;
801 st->codecpar->channels = ((int[]){2,1,2,3,3,4,4,5})[acmod] + lfeon;
802 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
804 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
806 if (st->codecpar->channels > 1 && bsmod == 0x7)
807 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
809 #if FF_API_LAVF_AVCTX
810 FF_DISABLE_DEPRECATION_WARNINGS
811 st->codec->audio_service_type = *ast;
812 FF_ENABLE_DEPRECATION_WARNINGS
818 static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
821 enum AVAudioServiceType *ast;
822 int eac3info, acmod, lfeon, bsmod;
824 if (c->fc->nb_streams < 1)
826 st = c->fc->streams[c->fc->nb_streams-1];
828 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
831 return AVERROR(ENOMEM);
833 /* No need to parse fields for additional independent substreams and its
834 * associated dependent substreams since libavcodec's E-AC-3 decoder
835 * does not support them yet. */
836 avio_rb16(pb); /* data_rate and num_ind_sub */
837 eac3info = avio_rb24(pb);
838 bsmod = (eac3info >> 12) & 0x1f;
839 acmod = (eac3info >> 9) & 0x7;
840 lfeon = (eac3info >> 8) & 0x1;
841 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
843 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
844 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
846 if (st->codecpar->channels > 1 && bsmod == 0x7)
847 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
849 #if FF_API_LAVF_AVCTX
850 FF_DISABLE_DEPRECATION_WARNINGS
851 st->codec->audio_service_type = *ast;
852 FF_ENABLE_DEPRECATION_WARNINGS
858 static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
860 const uint32_t ddts_size = 20;
863 uint32_t frame_duration_code = 0;
864 uint32_t channel_layout_code = 0;
867 buf = av_malloc(ddts_size + AV_INPUT_BUFFER_PADDING_SIZE);
869 return AVERROR(ENOMEM);
871 if (avio_read(pb, buf, ddts_size) < ddts_size) {
873 return AVERROR_INVALIDDATA;
876 init_get_bits(&gb, buf, 8*ddts_size);
878 if (c->fc->nb_streams < 1) {
882 st = c->fc->streams[c->fc->nb_streams-1];
884 st->codecpar->sample_rate = get_bits_long(&gb, 32);
885 if (st->codecpar->sample_rate <= 0) {
886 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
888 return AVERROR_INVALIDDATA;
890 skip_bits_long(&gb, 32); /* max bitrate */
891 st->codecpar->bit_rate = get_bits_long(&gb, 32);
892 st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
893 frame_duration_code = get_bits(&gb, 2);
894 skip_bits(&gb, 30); /* various fields */
895 channel_layout_code = get_bits(&gb, 16);
897 st->codecpar->frame_size =
898 (frame_duration_code == 0) ? 512 :
899 (frame_duration_code == 1) ? 1024 :
900 (frame_duration_code == 2) ? 2048 :
901 (frame_duration_code == 3) ? 4096 : 0;
903 if (channel_layout_code > 0xff) {
904 av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout");
906 st->codecpar->channel_layout =
907 ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
908 ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
909 ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
910 ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
911 ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
912 ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0);
914 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
920 static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
924 if (c->fc->nb_streams < 1)
926 st = c->fc->streams[c->fc->nb_streams-1];
931 /* skip version and flags */
934 ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
939 static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
944 if (c->fc->nb_streams < 1)
946 st = c->fc->streams[c->fc->nb_streams-1];
948 if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
949 av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
954 static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
956 const int num = avio_rb32(pb);
957 const int den = avio_rb32(pb);
960 if (c->fc->nb_streams < 1)
962 st = c->fc->streams[c->fc->nb_streams-1];
964 if ((st->sample_aspect_ratio.den != 1 || st->sample_aspect_ratio.num) && // default
965 (den != st->sample_aspect_ratio.den || num != st->sample_aspect_ratio.num)) {
966 av_log(c->fc, AV_LOG_WARNING,
967 "sample aspect ratio already set to %d:%d, ignoring 'pasp' atom (%d:%d)\n",
968 st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
970 } else if (den != 0) {
971 av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den,
977 /* this atom contains actual media data */
978 static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
980 if (atom.size == 0) /* wrong one (MP4) */
983 return 0; /* now go for moov */
986 #define DRM_BLOB_SIZE 56
988 static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
990 uint8_t intermediate_key[20];
991 uint8_t intermediate_iv[20];
994 uint8_t file_checksum[20];
995 uint8_t calculated_checksum[20];
999 uint8_t *activation_bytes = c->activation_bytes;
1000 uint8_t *fixed_key = c->audible_fixed_key;
1004 sha = av_sha_alloc();
1006 return AVERROR(ENOMEM);
1007 av_free(c->aes_decrypt);
1008 c->aes_decrypt = av_aes_alloc();
1009 if (!c->aes_decrypt) {
1010 ret = AVERROR(ENOMEM);
1014 /* drm blob processing */
1015 avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1016 avio_read(pb, input, DRM_BLOB_SIZE);
1017 avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1018 avio_read(pb, file_checksum, 20);
1020 av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == "); // required by external tools
1021 for (i = 0; i < 20; i++)
1022 av_log(c->fc, AV_LOG_INFO, "%02x", file_checksum[i]);
1023 av_log(c->fc, AV_LOG_INFO, "\n");
1025 /* verify activation data */
1026 if (!activation_bytes) {
1027 av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1028 ret = 0; /* allow ffprobe to continue working on .aax files */
1031 if (c->activation_bytes_size != 4) {
1032 av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1033 ret = AVERROR(EINVAL);
1037 /* verify fixed key */
1038 if (c->audible_fixed_key_size != 16) {
1039 av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1040 ret = AVERROR(EINVAL);
1044 /* AAX (and AAX+) key derivation */
1045 av_sha_init(sha, 160);
1046 av_sha_update(sha, fixed_key, 16);
1047 av_sha_update(sha, activation_bytes, 4);
1048 av_sha_final(sha, intermediate_key);
1049 av_sha_init(sha, 160);
1050 av_sha_update(sha, fixed_key, 16);
1051 av_sha_update(sha, intermediate_key, 20);
1052 av_sha_update(sha, activation_bytes, 4);
1053 av_sha_final(sha, intermediate_iv);
1054 av_sha_init(sha, 160);
1055 av_sha_update(sha, intermediate_key, 16);
1056 av_sha_update(sha, intermediate_iv, 16);
1057 av_sha_final(sha, calculated_checksum);
1058 if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1059 av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1060 ret = AVERROR_INVALIDDATA;
1063 av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1064 av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1065 for (i = 0; i < 4; i++) {
1066 // file data (in output) is stored in big-endian mode
1067 if (activation_bytes[i] != output[3 - i]) { // critical error
1068 av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1069 ret = AVERROR_INVALIDDATA;
1073 memcpy(c->file_key, output + 8, 16);
1074 memcpy(input, output + 26, 16);
1075 av_sha_init(sha, 160);
1076 av_sha_update(sha, input, 16);
1077 av_sha_update(sha, c->file_key, 16);
1078 av_sha_update(sha, fixed_key, 16);
1079 av_sha_final(sha, c->file_iv);
1087 // Audible AAX (and AAX+) bytestream decryption
1088 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1091 unsigned char iv[16];
1093 memcpy(iv, c->file_iv, 16); // iv is overwritten
1094 blocks = size >> 4; // trailing bytes are not encrypted!
1095 av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1096 av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1101 /* read major brand, minor version and compatible brands and store them as metadata */
1102 static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1105 int comp_brand_size;
1106 char* comp_brands_str;
1107 uint8_t type[5] = {0};
1108 int ret = ffio_read_size(pb, type, 4);
1112 if (strcmp(type, "qt "))
1114 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1115 av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1116 minor_ver = avio_rb32(pb); /* minor version */
1117 av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1119 comp_brand_size = atom.size - 8;
1120 if (comp_brand_size < 0)
1121 return AVERROR_INVALIDDATA;
1122 comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1123 if (!comp_brands_str)
1124 return AVERROR(ENOMEM);
1126 ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1128 av_freep(&comp_brands_str);
1131 comp_brands_str[comp_brand_size] = 0;
1132 av_dict_set(&c->fc->metadata, "compatible_brands",
1133 comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1138 /* this atom should contain all header atoms */
1139 static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1143 if (c->found_moov) {
1144 av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1145 avio_skip(pb, atom.size);
1149 if ((ret = mov_read_default(c, pb, atom)) < 0)
1151 /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1152 /* so we don't parse the whole file if over a network */
1154 return 0; /* now go for mdat */
1157 static MOVFragmentStreamInfo * get_frag_stream_info(
1158 MOVFragmentIndex *frag_index,
1163 MOVFragmentIndexItem * item;
1165 if (index < 0 || index >= frag_index->nb_items)
1167 item = &frag_index->item[index];
1168 for (i = 0; i < item->nb_stream_info; i++)
1169 if (item->stream_info[i].id == id)
1170 return &item->stream_info[i];
1172 // This shouldn't happen
1176 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1179 MOVFragmentIndexItem * item;
1181 if (frag_index->current < 0 ||
1182 frag_index->current >= frag_index->nb_items)
1185 item = &frag_index->item[frag_index->current];
1186 for (i = 0; i < item->nb_stream_info; i++)
1187 if (item->stream_info[i].id == id) {
1192 // id not found. This shouldn't happen.
1196 static MOVFragmentStreamInfo * get_current_frag_stream_info(
1197 MOVFragmentIndex *frag_index)
1199 MOVFragmentIndexItem *item;
1200 if (frag_index->current < 0 ||
1201 frag_index->current >= frag_index->nb_items)
1204 item = &frag_index->item[frag_index->current];
1205 if (item->current >= 0 && item->current < item->nb_stream_info)
1206 return &item->stream_info[item->current];
1208 // This shouldn't happen
1212 static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
1215 int64_t moof_offset;
1217 // Optimize for appending new entries
1218 if (!frag_index->nb_items ||
1219 frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1220 return frag_index->nb_items;
1223 b = frag_index->nb_items;
1227 moof_offset = frag_index->item[m].moof_offset;
1228 if (moof_offset >= offset)
1230 if (moof_offset <= offset)
1236 static int64_t get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
1238 av_assert0(frag_stream_info);
1239 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1240 return frag_stream_info->sidx_pts;
1241 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1242 return frag_stream_info->first_tfra_pts;
1243 return frag_stream_info->tfdt_dts;
1246 static int64_t get_frag_time(MOVFragmentIndex *frag_index,
1247 int index, int track_id)
1249 MOVFragmentStreamInfo * frag_stream_info;
1253 if (track_id >= 0) {
1254 frag_stream_info = get_frag_stream_info(frag_index, index, track_id);
1255 return frag_stream_info->sidx_pts;
1258 for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1259 frag_stream_info = &frag_index->item[index].stream_info[i];
1260 timestamp = get_stream_info_time(frag_stream_info);
1261 if (timestamp != AV_NOPTS_VALUE)
1264 return AV_NOPTS_VALUE;
1267 static int search_frag_timestamp(MOVFragmentIndex *frag_index,
1268 AVStream *st, int64_t timestamp)
1275 // If the stream is referenced by any sidx, limit the search
1276 // to fragments that referenced this stream in the sidx
1277 MOVStreamContext *sc = st->priv_data;
1283 b = frag_index->nb_items;
1286 m0 = m = (a + b) >> 1;
1289 (frag_time = get_frag_time(frag_index, m, id)) == AV_NOPTS_VALUE)
1292 if (m < b && frag_time <= timestamp)
1301 static int update_frag_index(MOVContext *c, int64_t offset)
1304 MOVFragmentIndexItem * item;
1305 MOVFragmentStreamInfo * frag_stream_info;
1307 // If moof_offset already exists in frag_index, return index to it
1308 index = search_frag_moof_offset(&c->frag_index, offset);
1309 if (index < c->frag_index.nb_items &&
1310 c->frag_index.item[index].moof_offset == offset)
1313 // offset is not yet in frag index.
1314 // Insert new item at index (sorted by moof offset)
1315 item = av_fast_realloc(c->frag_index.item,
1316 &c->frag_index.allocated_size,
1317 (c->frag_index.nb_items + 1) *
1318 sizeof(*c->frag_index.item));
1321 c->frag_index.item = item;
1323 frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1324 sizeof(*item->stream_info));
1325 if (!frag_stream_info)
1328 for (i = 0; i < c->fc->nb_streams; i++) {
1329 // Avoid building frag index if streams lack track id.
1330 if (c->fc->streams[i]->id < 0) {
1331 av_free(frag_stream_info);
1332 return AVERROR_INVALIDDATA;
1335 frag_stream_info[i].id = c->fc->streams[i]->id;
1336 frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1337 frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1338 frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1339 frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1340 frag_stream_info[i].index_entry = -1;
1341 frag_stream_info[i].encryption_index = NULL;
1344 if (index < c->frag_index.nb_items)
1345 memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1346 (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1348 item = &c->frag_index.item[index];
1349 item->headers_read = 0;
1351 item->nb_stream_info = c->fc->nb_streams;
1352 item->moof_offset = offset;
1353 item->stream_info = frag_stream_info;
1354 c->frag_index.nb_items++;
1359 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1360 int id, int entries)
1363 MOVFragmentStreamInfo * frag_stream_info;
1367 for (i = index; i < frag_index->nb_items; i++) {
1368 frag_stream_info = get_frag_stream_info(frag_index, i, id);
1369 if (frag_stream_info && frag_stream_info->index_entry >= 0)
1370 frag_stream_info->index_entry += entries;
1374 static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1376 // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1377 c->fragment.found_tfhd = 0;
1379 if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1380 c->has_looked_for_mfra = 1;
1381 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1383 av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1385 if ((ret = mov_read_mfra(c, pb)) < 0) {
1386 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1387 "read the mfra (may be a live ismv)\n");
1390 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1391 "seekable, can not look for mfra\n");
1394 c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1395 av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1396 c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1397 return mov_read_default(c, pb, atom);
1400 static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time, void *logctx)
1403 if(time >= 2082844800)
1404 time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1406 if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1407 av_log(logctx, AV_LOG_DEBUG, "creation_time is not representable\n");
1411 avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1415 static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1418 MOVStreamContext *sc;
1420 char language[4] = {0};
1422 int64_t creation_time;
1424 if (c->fc->nb_streams < 1)
1426 st = c->fc->streams[c->fc->nb_streams-1];
1429 if (sc->time_scale) {
1430 av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1431 return AVERROR_INVALIDDATA;
1434 version = avio_r8(pb);
1436 avpriv_request_sample(c->fc, "Version %d", version);
1437 return AVERROR_PATCHWELCOME;
1439 avio_rb24(pb); /* flags */
1441 creation_time = avio_rb64(pb);
1444 creation_time = avio_rb32(pb);
1445 avio_rb32(pb); /* modification time */
1447 mov_metadata_creation_time(&st->metadata, creation_time, c->fc);
1449 sc->time_scale = avio_rb32(pb);
1450 if (sc->time_scale <= 0) {
1451 av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1454 st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1456 lang = avio_rb16(pb); /* language */
1457 if (ff_mov_lang_to_iso639(lang, language))
1458 av_dict_set(&st->metadata, "language", language, 0);
1459 avio_rb16(pb); /* quality */
1464 static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1467 int64_t creation_time;
1468 int version = avio_r8(pb); /* version */
1469 avio_rb24(pb); /* flags */
1472 creation_time = avio_rb64(pb);
1475 creation_time = avio_rb32(pb);
1476 avio_rb32(pb); /* modification time */
1478 mov_metadata_creation_time(&c->fc->metadata, creation_time, c->fc);
1479 c->time_scale = avio_rb32(pb); /* time scale */
1480 if (c->time_scale <= 0) {
1481 av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1484 av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1486 c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1487 // set the AVCodecContext duration because the duration of individual tracks
1488 // may be inaccurate
1489 if (c->time_scale > 0 && !c->trex_data)
1490 c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale);
1491 avio_rb32(pb); /* preferred scale */
1493 avio_rb16(pb); /* preferred volume */
1495 avio_skip(pb, 10); /* reserved */
1497 /* movie display matrix, store it in main context and use it later on */
1498 for (i = 0; i < 3; i++) {
1499 c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1500 c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1501 c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1504 avio_rb32(pb); /* preview time */
1505 avio_rb32(pb); /* preview duration */
1506 avio_rb32(pb); /* poster time */
1507 avio_rb32(pb); /* selection time */
1508 avio_rb32(pb); /* selection duration */
1509 avio_rb32(pb); /* current time */
1510 avio_rb32(pb); /* next track ID */
1515 static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1520 if (c->fc->nb_streams < 1)
1522 st = c->fc->streams[c->fc->nb_streams-1];
1524 little_endian = avio_rb16(pb) & 0xFF;
1525 av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1526 if (little_endian == 1) {
1527 switch (st->codecpar->codec_id) {
1528 case AV_CODEC_ID_PCM_S24BE:
1529 st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE;
1531 case AV_CODEC_ID_PCM_S32BE:
1532 st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE;
1534 case AV_CODEC_ID_PCM_F32BE:
1535 st->codecpar->codec_id = AV_CODEC_ID_PCM_F32LE;
1537 case AV_CODEC_ID_PCM_F64BE:
1538 st->codecpar->codec_id = AV_CODEC_ID_PCM_F64LE;
1547 static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1550 uint8_t *icc_profile;
1551 char color_parameter_type[5] = { 0 };
1552 uint16_t color_primaries, color_trc, color_matrix;
1555 if (c->fc->nb_streams < 1)
1557 st = c->fc->streams[c->fc->nb_streams - 1];
1559 ret = ffio_read_size(pb, color_parameter_type, 4);
1562 if (strncmp(color_parameter_type, "nclx", 4) &&
1563 strncmp(color_parameter_type, "nclc", 4) &&
1564 strncmp(color_parameter_type, "prof", 4)) {
1565 av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
1566 color_parameter_type);
1570 if (!strncmp(color_parameter_type, "prof", 4)) {
1571 icc_profile = av_stream_new_side_data(st, AV_PKT_DATA_ICC_PROFILE, atom.size - 4);
1573 return AVERROR(ENOMEM);
1574 ret = ffio_read_size(pb, icc_profile, atom.size - 4);
1579 color_primaries = avio_rb16(pb);
1580 color_trc = avio_rb16(pb);
1581 color_matrix = avio_rb16(pb);
1583 av_log(c->fc, AV_LOG_TRACE,
1584 "%s: pri %d trc %d matrix %d",
1585 color_parameter_type, color_primaries, color_trc, color_matrix);
1587 if (!strncmp(color_parameter_type, "nclx", 4)) {
1588 uint8_t color_range = avio_r8(pb) >> 7;
1589 av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
1591 st->codecpar->color_range = AVCOL_RANGE_JPEG;
1593 st->codecpar->color_range = AVCOL_RANGE_MPEG;
1596 if (!av_color_primaries_name(color_primaries))
1597 color_primaries = AVCOL_PRI_UNSPECIFIED;
1598 if (!av_color_transfer_name(color_trc))
1599 color_trc = AVCOL_TRC_UNSPECIFIED;
1600 if (!av_color_space_name(color_matrix))
1601 color_matrix = AVCOL_SPC_UNSPECIFIED;
1603 st->codecpar->color_primaries = color_primaries;
1604 st->codecpar->color_trc = color_trc;
1605 st->codecpar->color_space = color_matrix;
1606 av_log(c->fc, AV_LOG_TRACE, "\n");
1611 static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1614 unsigned mov_field_order;
1615 enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
1617 if (c->fc->nb_streams < 1) // will happen with jp2 files
1619 st = c->fc->streams[c->fc->nb_streams-1];
1621 return AVERROR_INVALIDDATA;
1622 mov_field_order = avio_rb16(pb);
1623 if ((mov_field_order & 0xFF00) == 0x0100)
1624 decoded_field_order = AV_FIELD_PROGRESSIVE;
1625 else if ((mov_field_order & 0xFF00) == 0x0200) {
1626 switch (mov_field_order & 0xFF) {
1627 case 0x01: decoded_field_order = AV_FIELD_TT;
1629 case 0x06: decoded_field_order = AV_FIELD_BB;
1631 case 0x09: decoded_field_order = AV_FIELD_TB;
1633 case 0x0E: decoded_field_order = AV_FIELD_BT;
1637 if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
1638 av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
1640 st->codecpar->field_order = decoded_field_order;
1645 static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
1648 uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
1649 if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
1650 return AVERROR_INVALIDDATA;
1651 if ((err = av_reallocp(&par->extradata, size)) < 0) {
1652 par->extradata_size = 0;
1655 par->extradata_size = size - AV_INPUT_BUFFER_PADDING_SIZE;
1659 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
1660 static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1661 AVCodecParameters *par, uint8_t *buf)
1663 int64_t result = atom.size;
1666 AV_WB32(buf , atom.size + 8);
1667 AV_WL32(buf + 4, atom.type);
1668 err = ffio_read_size(pb, buf + 8, atom.size);
1670 par->extradata_size -= atom.size;
1672 } else if (err < atom.size) {
1673 av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
1674 par->extradata_size -= atom.size - err;
1677 memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1681 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
1682 static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1683 enum AVCodecID codec_id)
1686 uint64_t original_size;
1689 if (c->fc->nb_streams < 1) // will happen with jp2 files
1691 st = c->fc->streams[c->fc->nb_streams-1];
1693 if (st->codecpar->codec_id != codec_id)
1694 return 0; /* unexpected codec_id - don't mess with extradata */
1696 original_size = st->codecpar->extradata_size;
1697 err = mov_realloc_extradata(st->codecpar, atom);
1701 err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
1704 return 0; // Note: this is the original behavior to ignore truncation.
1707 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
1708 static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1710 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
1713 static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1715 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS);
1718 static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1720 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
1723 static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1725 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
1728 static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1730 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
1732 ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
1736 static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1738 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
1740 if (!ret && c->fc->nb_streams >= 1) {
1741 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1742 if (par->extradata_size >= 40) {
1743 par->height = AV_RB16(&par->extradata[36]);
1744 par->width = AV_RB16(&par->extradata[38]);
1750 static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1752 if (c->fc->nb_streams >= 1) {
1753 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1754 if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
1755 par->codec_id == AV_CODEC_ID_H264 &&
1759 cid = avio_rb16(pb);
1760 /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
1761 if (cid == 0xd4d || cid == 0xd4e)
1764 } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
1765 par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
1766 par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
1770 num = avio_rb32(pb);
1771 den = avio_rb32(pb);
1772 if (num <= 0 || den <= 0)
1774 switch (avio_rb32(pb)) {
1776 if (den >= INT_MAX / 2)
1780 c->fc->streams[c->fc->nb_streams-1]->display_aspect_ratio.num = num;
1781 c->fc->streams[c->fc->nb_streams-1]->display_aspect_ratio.den = den;
1788 return mov_read_avid(c, pb, atom);
1791 static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1795 uint64_t original_size;
1796 if (c->fc->nb_streams >= 1) {
1797 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1798 if (par->codec_id == AV_CODEC_ID_H264)
1800 if (atom.size == 16) {
1801 original_size = par->extradata_size;
1802 ret = mov_realloc_extradata(par, atom);
1804 length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
1805 if (length == atom.size) {
1806 const uint8_t range_value = par->extradata[original_size + 19];
1807 switch (range_value) {
1809 par->color_range = AVCOL_RANGE_MPEG;
1812 par->color_range = AVCOL_RANGE_JPEG;
1815 av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
1818 ff_dlog(c->fc, "color_range: %d\n", par->color_range);
1820 /* For some reason the whole atom was not added to the extradata */
1821 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
1824 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
1827 av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
1834 static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1836 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
1839 static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1844 if (c->fc->nb_streams < 1)
1846 st = c->fc->streams[c->fc->nb_streams-1];
1848 if ((uint64_t)atom.size > (1<<30))
1849 return AVERROR_INVALIDDATA;
1851 if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
1852 st->codecpar->codec_id == AV_CODEC_ID_QDMC ||
1853 st->codecpar->codec_id == AV_CODEC_ID_SPEEX) {
1854 // pass all frma atom to codec, needed at least for QDMC and QDM2
1855 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1858 } else if (atom.size > 8) { /* to read frma, esds atoms */
1859 if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
1861 ret = ffio_ensure_seekback(pb, 8);
1864 buffer = avio_rb64(pb);
1866 if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
1867 && buffer >> 32 <= atom.size
1868 && buffer >> 32 >= 8) {
1871 } else if (!st->codecpar->extradata_size) {
1872 #define ALAC_EXTRADATA_SIZE 36
1873 st->codecpar->extradata = av_mallocz(ALAC_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
1874 if (!st->codecpar->extradata)
1875 return AVERROR(ENOMEM);
1876 st->codecpar->extradata_size = ALAC_EXTRADATA_SIZE;
1877 AV_WB32(st->codecpar->extradata , ALAC_EXTRADATA_SIZE);
1878 AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
1879 AV_WB64(st->codecpar->extradata + 12, buffer);
1880 avio_read(pb, st->codecpar->extradata + 20, 16);
1881 avio_skip(pb, atom.size - 24);
1885 if ((ret = mov_read_default(c, pb, atom)) < 0)
1888 avio_skip(pb, atom.size);
1893 * This function reads atom content and puts data in extradata without tag
1894 * nor size unlike mov_read_extradata.
1896 static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1901 if (c->fc->nb_streams < 1)
1903 st = c->fc->streams[c->fc->nb_streams-1];
1905 if ((uint64_t)atom.size > (1<<30))
1906 return AVERROR_INVALIDDATA;
1908 if (atom.size >= 10) {
1909 // Broken files created by legacy versions of libavformat will
1910 // wrap a whole fiel atom inside of a glbl atom.
1911 unsigned size = avio_rb32(pb);
1912 unsigned type = avio_rl32(pb);
1913 avio_seek(pb, -8, SEEK_CUR);
1914 if (type == MKTAG('f','i','e','l') && size == atom.size)
1915 return mov_read_default(c, pb, atom);
1917 if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
1918 av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
1921 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1924 if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
1925 /* HEVC-based Dolby Vision derived from hvc1.
1926 Happens to match with an identifier
1927 previously utilized for DV. Thus, if we have
1928 the hvcC extradata box available as specified,
1929 set codec to HEVC */
1930 st->codecpar->codec_id = AV_CODEC_ID_HEVC;
1935 static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1938 uint8_t profile_level;
1941 if (c->fc->nb_streams < 1)
1943 st = c->fc->streams[c->fc->nb_streams-1];
1945 if (atom.size >= (1<<28) || atom.size < 7)
1946 return AVERROR_INVALIDDATA;
1948 profile_level = avio_r8(pb);
1949 if ((profile_level & 0xf0) != 0xc0)
1952 avio_seek(pb, 6, SEEK_CUR);
1953 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
1961 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
1962 * but can have extradata appended at the end after the 40 bytes belonging
1965 static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1970 if (c->fc->nb_streams < 1)
1972 if (atom.size <= 40)
1974 st = c->fc->streams[c->fc->nb_streams-1];
1976 if ((uint64_t)atom.size > (1<<30))
1977 return AVERROR_INVALIDDATA;
1980 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
1987 static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1990 MOVStreamContext *sc;
1991 unsigned int i, entries;
1993 if (c->trak_index < 0) {
1994 av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
1997 if (c->fc->nb_streams < 1)
1999 st = c->fc->streams[c->fc->nb_streams-1];
2002 avio_r8(pb); /* version */
2003 avio_rb24(pb); /* flags */
2005 entries = avio_rb32(pb);
2010 if (sc->chunk_offsets)
2011 av_log(c->fc, AV_LOG_WARNING, "Duplicated STCO atom\n");
2012 av_free(sc->chunk_offsets);
2013 sc->chunk_count = 0;
2014 sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2015 if (!sc->chunk_offsets)
2016 return AVERROR(ENOMEM);
2017 sc->chunk_count = entries;
2019 if (atom.type == MKTAG('s','t','c','o'))
2020 for (i = 0; i < entries && !pb->eof_reached; i++)
2021 sc->chunk_offsets[i] = avio_rb32(pb);
2022 else if (atom.type == MKTAG('c','o','6','4'))
2023 for (i = 0; i < entries && !pb->eof_reached; i++)
2024 sc->chunk_offsets[i] = avio_rb64(pb);
2026 return AVERROR_INVALIDDATA;
2028 sc->chunk_count = i;
2030 if (pb->eof_reached) {
2031 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2038 static int mov_codec_id(AVStream *st, uint32_t format)
2040 int id = ff_codec_get_id(ff_codec_movaudio_tags, format);
2043 ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2044 (format & 0xFFFF) == 'T' + ('S' << 8)))
2045 id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format) & 0xFFFF);
2047 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2048 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2049 } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2050 /* skip old ASF MPEG-4 tag */
2051 format && format != MKTAG('m','p','4','s')) {
2052 id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2054 id = ff_codec_get_id(ff_codec_bmp_tags, format);
2056 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
2057 else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2058 (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE &&
2059 st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2060 id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
2062 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
2064 id = ff_codec_get_id(ff_codec_movdata_tags, format);
2068 st->codecpar->codec_tag = format;
2073 static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
2074 AVStream *st, MOVStreamContext *sc)
2076 uint8_t codec_name[32] = { 0 };
2080 /* The first 16 bytes of the video sample description are already
2081 * read in ff_mov_read_stsd_entries() */
2082 stsd_start = avio_tell(pb) - 16;
2084 avio_rb16(pb); /* version */
2085 avio_rb16(pb); /* revision level */
2086 avio_rb32(pb); /* vendor */
2087 avio_rb32(pb); /* temporal quality */
2088 avio_rb32(pb); /* spatial quality */
2090 st->codecpar->width = avio_rb16(pb); /* width */
2091 st->codecpar->height = avio_rb16(pb); /* height */
2093 avio_rb32(pb); /* horiz resolution */
2094 avio_rb32(pb); /* vert resolution */
2095 avio_rb32(pb); /* data size, always 0 */
2096 avio_rb16(pb); /* frames per samples */
2098 len = avio_r8(pb); /* codec name, pascal string */
2101 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2103 avio_skip(pb, 31 - len);
2106 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2108 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2109 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2110 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2111 st->codecpar->width &= ~1;
2112 st->codecpar->height &= ~1;
2114 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2115 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2116 !strncmp(codec_name, "Sorenson H263", 13))
2117 st->codecpar->codec_id = AV_CODEC_ID_FLV1;
2119 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2121 avio_seek(pb, stsd_start, SEEK_SET);
2123 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2124 st->codecpar->bits_per_coded_sample &= 0x1F;
2125 sc->has_palette = 1;
2129 static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
2130 AVStream *st, MOVStreamContext *sc)
2132 int bits_per_sample, flags;
2133 uint16_t version = avio_rb16(pb);
2134 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2136 avio_rb16(pb); /* revision level */
2137 avio_rb32(pb); /* vendor */
2139 st->codecpar->channels = avio_rb16(pb); /* channel count */
2140 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2141 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", st->codecpar->channels);
2143 sc->audio_cid = avio_rb16(pb);
2144 avio_rb16(pb); /* packet size = 0 */
2146 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2148 // Read QT version 1 fields. In version 0 these do not exist.
2149 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2151 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2152 (sc->stsd_version == 0 && version > 0)) {
2154 sc->samples_per_frame = avio_rb32(pb);
2155 avio_rb32(pb); /* bytes per packet */
2156 sc->bytes_per_frame = avio_rb32(pb);
2157 avio_rb32(pb); /* bytes per sample */
2158 } else if (version == 2) {
2159 avio_rb32(pb); /* sizeof struct only */
2160 st->codecpar->sample_rate = av_int2double(avio_rb64(pb));
2161 st->codecpar->channels = avio_rb32(pb);
2162 avio_rb32(pb); /* always 0x7F000000 */
2163 st->codecpar->bits_per_coded_sample = avio_rb32(pb);
2165 flags = avio_rb32(pb); /* lpcm format specific flag */
2166 sc->bytes_per_frame = avio_rb32(pb);
2167 sc->samples_per_frame = avio_rb32(pb);
2168 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2169 st->codecpar->codec_id =
2170 ff_mov_get_lpcm_codec_id(st->codecpar->bits_per_coded_sample,
2173 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2174 /* can't correctly handle variable sized packet as audio unit */
2175 switch (st->codecpar->codec_id) {
2176 case AV_CODEC_ID_MP2:
2177 case AV_CODEC_ID_MP3:
2178 st->need_parsing = AVSTREAM_PARSE_FULL;
2184 if (sc->format == 0) {
2185 if (st->codecpar->bits_per_coded_sample == 8)
2186 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2187 else if (st->codecpar->bits_per_coded_sample == 16)
2188 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2191 switch (st->codecpar->codec_id) {
2192 case AV_CODEC_ID_PCM_S8:
2193 case AV_CODEC_ID_PCM_U8:
2194 if (st->codecpar->bits_per_coded_sample == 16)
2195 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16BE;
2197 case AV_CODEC_ID_PCM_S16LE:
2198 case AV_CODEC_ID_PCM_S16BE:
2199 if (st->codecpar->bits_per_coded_sample == 8)
2200 st->codecpar->codec_id = AV_CODEC_ID_PCM_S8;
2201 else if (st->codecpar->bits_per_coded_sample == 24)
2202 st->codecpar->codec_id =
2203 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2204 AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
2205 else if (st->codecpar->bits_per_coded_sample == 32)
2206 st->codecpar->codec_id =
2207 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2208 AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
2210 /* set values for old format before stsd version 1 appeared */
2211 case AV_CODEC_ID_MACE3:
2212 sc->samples_per_frame = 6;
2213 sc->bytes_per_frame = 2 * st->codecpar->channels;
2215 case AV_CODEC_ID_MACE6:
2216 sc->samples_per_frame = 6;
2217 sc->bytes_per_frame = 1 * st->codecpar->channels;
2219 case AV_CODEC_ID_ADPCM_IMA_QT:
2220 sc->samples_per_frame = 64;
2221 sc->bytes_per_frame = 34 * st->codecpar->channels;
2223 case AV_CODEC_ID_GSM:
2224 sc->samples_per_frame = 160;
2225 sc->bytes_per_frame = 33;
2231 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2232 if (bits_per_sample) {
2233 st->codecpar->bits_per_coded_sample = bits_per_sample;
2234 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->channels;
2238 static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
2239 AVStream *st, MOVStreamContext *sc,
2242 // ttxt stsd contains display flags, justification, background
2243 // color, fonts, and default styles, so fake an atom to read it
2244 MOVAtom fake_atom = { .size = size };
2245 // mp4s contains a regular esds atom
2246 if (st->codecpar->codec_tag != AV_RL32("mp4s"))
2247 mov_read_glbl(c, pb, fake_atom);
2248 st->codecpar->width = sc->width;
2249 st->codecpar->height = sc->height;
2252 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2257 y = (ycbcr >> 16) & 0xFF;
2258 cr = (ycbcr >> 8) & 0xFF;
2261 b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
2262 g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
2263 r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
2265 return (r << 16) | (g << 8) | b;
2268 static int mov_rewrite_dvd_sub_extradata(AVStream *st)
2270 char buf[256] = {0};
2271 uint8_t *src = st->codecpar->extradata;
2274 if (st->codecpar->extradata_size != 64)
2277 if (st->codecpar->width > 0 && st->codecpar->height > 0)
2278 snprintf(buf, sizeof(buf), "size: %dx%d\n",
2279 st->codecpar->width, st->codecpar->height);
2280 av_strlcat(buf, "palette: ", sizeof(buf));
2282 for (i = 0; i < 16; i++) {
2283 uint32_t yuv = AV_RB32(src + i * 4);
2284 uint32_t rgba = yuv_to_rgba(yuv);
2286 av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2289 if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2292 ret = ff_alloc_extradata(st->codecpar, strlen(buf));
2295 memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2300 static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
2301 AVStream *st, MOVStreamContext *sc,
2306 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2307 if ((int)size != size)
2308 return AVERROR(ENOMEM);
2310 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2314 MOVStreamContext *tmcd_ctx = st->priv_data;
2316 val = AV_RB32(st->codecpar->extradata + 4);
2317 tmcd_ctx->tmcd_flags = val;
2318 st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2319 st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2320 #if FF_API_LAVF_AVCTX
2321 FF_DISABLE_DEPRECATION_WARNINGS
2322 st->codec->time_base = av_inv_q(st->avg_frame_rate);
2323 FF_ENABLE_DEPRECATION_WARNINGS
2325 /* adjust for per frame dur in counter mode */
2326 if (tmcd_ctx->tmcd_flags & 0x0008) {
2327 int timescale = AV_RB32(st->codecpar->extradata + 8);
2328 int framedur = AV_RB32(st->codecpar->extradata + 12);
2329 st->avg_frame_rate.num *= timescale;
2330 st->avg_frame_rate.den *= framedur;
2331 #if FF_API_LAVF_AVCTX
2332 FF_DISABLE_DEPRECATION_WARNINGS
2333 st->codec->time_base.den *= timescale;
2334 st->codec->time_base.num *= framedur;
2335 FF_ENABLE_DEPRECATION_WARNINGS
2339 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2340 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2341 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2342 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2343 if (str_size > 0 && size >= (int)str_size + 30 &&
2344 st->codecpar->extradata[30] /* Don't add empty string */) {
2345 char *reel_name = av_malloc(str_size + 1);
2347 return AVERROR(ENOMEM);
2348 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2349 reel_name[str_size] = 0; /* Add null terminator */
2350 av_dict_set(&st->metadata, "reel_name", reel_name,
2351 AV_DICT_DONT_STRDUP_VAL);
2357 /* other codec type, just skip (rtp, mp4s ...) */
2358 avio_skip(pb, size);
2363 static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
2364 AVStream *st, MOVStreamContext *sc)
2366 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2367 !st->codecpar->sample_rate && sc->time_scale > 1)
2368 st->codecpar->sample_rate = sc->time_scale;
2370 /* special codec parameters handling */
2371 switch (st->codecpar->codec_id) {
2372 #if CONFIG_DV_DEMUXER
2373 case AV_CODEC_ID_DVAUDIO:
2374 c->dv_fctx = avformat_alloc_context();
2376 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2377 return AVERROR(ENOMEM);
2379 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2381 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2382 return AVERROR(ENOMEM);
2384 sc->dv_audio_container = 1;
2385 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
2388 /* no ifdef since parameters are always those */
2389 case AV_CODEC_ID_QCELP:
2390 st->codecpar->channels = 1;
2391 // force sample rate for qcelp when not stored in mov
2392 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2393 st->codecpar->sample_rate = 8000;
2394 // FIXME: Why is the following needed for some files?
2395 sc->samples_per_frame = 160;
2396 if (!sc->bytes_per_frame)
2397 sc->bytes_per_frame = 35;
2399 case AV_CODEC_ID_AMR_NB:
2400 st->codecpar->channels = 1;
2401 /* force sample rate for amr, stsd in 3gp does not store sample rate */
2402 st->codecpar->sample_rate = 8000;
2404 case AV_CODEC_ID_AMR_WB:
2405 st->codecpar->channels = 1;
2406 st->codecpar->sample_rate = 16000;
2408 case AV_CODEC_ID_MP2:
2409 case AV_CODEC_ID_MP3:
2410 /* force type after stsd for m1a hdlr */
2411 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2413 case AV_CODEC_ID_GSM:
2414 case AV_CODEC_ID_ADPCM_MS:
2415 case AV_CODEC_ID_ADPCM_IMA_WAV:
2416 case AV_CODEC_ID_ILBC:
2417 case AV_CODEC_ID_MACE3:
2418 case AV_CODEC_ID_MACE6:
2419 case AV_CODEC_ID_QDM2:
2420 st->codecpar->block_align = sc->bytes_per_frame;
2422 case AV_CODEC_ID_ALAC:
2423 if (st->codecpar->extradata_size == 36) {
2424 st->codecpar->channels = AV_RB8 (st->codecpar->extradata + 21);
2425 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2428 case AV_CODEC_ID_AC3:
2429 case AV_CODEC_ID_EAC3:
2430 case AV_CODEC_ID_MPEG1VIDEO:
2431 case AV_CODEC_ID_VC1:
2432 case AV_CODEC_ID_VP8:
2433 case AV_CODEC_ID_VP9:
2434 st->need_parsing = AVSTREAM_PARSE_FULL;
2442 static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
2443 int codec_tag, int format,
2446 int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2449 (codec_tag != format &&
2450 // AVID 1:1 samples with differing data format and codec tag exist
2451 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
2452 // prores is allowed to have differing data format and codec tag
2453 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
2455 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
2456 (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id
2457 : codec_tag != MKTAG('j','p','e','g')))) {
2458 /* Multiple fourcc, we skip JPEG. This is not correct, we should
2459 * export it as a separate AVStream but this needs a few changes
2460 * in the MOV demuxer, patch welcome. */
2462 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
2463 avio_skip(pb, size);
2470 int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
2473 MOVStreamContext *sc;
2474 int pseudo_stream_id;
2476 av_assert0 (c->fc->nb_streams >= 1);
2477 st = c->fc->streams[c->fc->nb_streams-1];
2480 for (pseudo_stream_id = 0;
2481 pseudo_stream_id < entries && !pb->eof_reached;
2482 pseudo_stream_id++) {
2483 //Parsing Sample description table
2485 int ret, dref_id = 1;
2486 MOVAtom a = { AV_RL32("stsd") };
2487 int64_t start_pos = avio_tell(pb);
2488 int64_t size = avio_rb32(pb); /* size */
2489 uint32_t format = avio_rl32(pb); /* data format */
2492 avio_rb32(pb); /* reserved */
2493 avio_rb16(pb); /* reserved */
2494 dref_id = avio_rb16(pb);
2495 } else if (size <= 7) {
2496 av_log(c->fc, AV_LOG_ERROR,
2497 "invalid size %"PRId64" in stsd\n", size);
2498 return AVERROR_INVALIDDATA;
2501 if (mov_skip_multiple_stsd(c, pb, st->codecpar->codec_tag, format,
2502 size - (avio_tell(pb) - start_pos))) {
2507 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
2508 sc->dref_id= dref_id;
2509 sc->format = format;
2511 id = mov_codec_id(st, format);
2513 av_log(c->fc, AV_LOG_TRACE,
2514 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
2515 av_fourcc2str(format), st->codecpar->codec_type);
2517 st->codecpar->codec_id = id;
2518 if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) {
2519 mov_parse_stsd_video(c, pb, st, sc);
2520 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
2521 mov_parse_stsd_audio(c, pb, st, sc);
2522 if (st->codecpar->sample_rate < 0) {
2523 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
2524 return AVERROR_INVALIDDATA;
2526 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
2527 mov_parse_stsd_subtitle(c, pb, st, sc,
2528 size - (avio_tell(pb) - start_pos));
2530 ret = mov_parse_stsd_data(c, pb, st, sc,
2531 size - (avio_tell(pb) - start_pos));
2535 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
2536 a.size = size - (avio_tell(pb) - start_pos);
2538 if ((ret = mov_read_default(c, pb, a)) < 0)
2540 } else if (a.size > 0)
2541 avio_skip(pb, a.size);
2543 if (sc->extradata && st->codecpar->extradata) {
2544 int extra_size = st->codecpar->extradata_size;
2546 /* Move the current stream extradata to the stream context one. */
2547 sc->extradata_size[pseudo_stream_id] = extra_size;
2548 sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
2549 st->codecpar->extradata = NULL;
2550 st->codecpar->extradata_size = 0;
2555 if (pb->eof_reached) {
2556 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
2563 static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2566 MOVStreamContext *sc;
2569 if (c->fc->nb_streams < 1)
2571 st = c->fc->streams[c->fc->nb_streams - 1];
2574 sc->stsd_version = avio_r8(pb);
2575 avio_rb24(pb); /* flags */
2576 entries = avio_rb32(pb);
2578 /* Each entry contains a size (4 bytes) and format (4 bytes). */
2579 if (entries <= 0 || entries > atom.size / 8) {
2580 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
2581 return AVERROR_INVALIDDATA;
2584 if (sc->extradata) {
2585 av_log(c->fc, AV_LOG_ERROR,
2586 "Duplicate stsd found in this track.\n");
2587 return AVERROR_INVALIDDATA;
2590 /* Prepare space for hosting multiple extradata. */
2591 sc->extradata = av_mallocz_array(entries, sizeof(*sc->extradata));
2593 return AVERROR(ENOMEM);
2595 sc->extradata_size = av_mallocz_array(entries, sizeof(*sc->extradata_size));
2596 if (!sc->extradata_size) {
2597 ret = AVERROR(ENOMEM);
2601 ret = ff_mov_read_stsd_entries(c, pb, entries);
2605 /* Restore back the primary extradata. */
2606 av_freep(&st->codecpar->extradata);
2607 st->codecpar->extradata_size = sc->extradata_size[0];
2608 if (sc->extradata_size[0]) {
2609 st->codecpar->extradata = av_mallocz(sc->extradata_size[0] + AV_INPUT_BUFFER_PADDING_SIZE);
2610 if (!st->codecpar->extradata)
2611 return AVERROR(ENOMEM);
2612 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
2615 return mov_finalize_stsd_codec(c, pb, st, sc);
2617 if (sc->extradata) {
2619 for (j = 0; j < sc->stsd_count; j++)
2620 av_freep(&sc->extradata[j]);
2623 av_freep(&sc->extradata);
2624 av_freep(&sc->extradata_size);
2628 static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2631 MOVStreamContext *sc;
2632 unsigned int i, entries;
2634 if (c->fc->nb_streams < 1)
2636 st = c->fc->streams[c->fc->nb_streams-1];
2639 avio_r8(pb); /* version */
2640 avio_rb24(pb); /* flags */
2642 entries = avio_rb32(pb);
2643 if ((uint64_t)entries * 12 + 4 > atom.size)
2644 return AVERROR_INVALIDDATA;
2646 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
2651 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSC atom\n");
2652 av_free(sc->stsc_data);
2654 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
2656 return AVERROR(ENOMEM);
2658 for (i = 0; i < entries && !pb->eof_reached; i++) {
2659 sc->stsc_data[i].first = avio_rb32(pb);
2660 sc->stsc_data[i].count = avio_rb32(pb);
2661 sc->stsc_data[i].id = avio_rb32(pb);
2665 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
2666 int64_t first_min = i + 1;
2667 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
2668 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
2669 sc->stsc_data[i].first < first_min ||
2670 sc->stsc_data[i].count < 1 ||
2671 sc->stsc_data[i].id < 1) {
2672 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);
2673 if (i+1 >= sc->stsc_count) {
2674 if (sc->stsc_data[i].count == 0 && i > 0) {
2678 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
2679 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
2680 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
2681 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
2682 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
2685 av_assert0(sc->stsc_data[i+1].first >= 2);
2686 // We replace this entry by the next valid
2687 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
2688 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
2689 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
2693 if (pb->eof_reached) {
2694 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
2701 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
2703 return index < count - 1;
2706 /* Compute the samples value for the stsc entry at the given index. */
2707 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
2711 if (mov_stsc_index_valid(index, sc->stsc_count))
2712 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
2714 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
2715 av_assert0(sc->stsc_data[index].first <= sc->chunk_count);
2716 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
2719 return sc->stsc_data[index].count * (int64_t)chunk_count;
2722 static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2725 MOVStreamContext *sc;
2726 unsigned i, entries;
2728 if (c->fc->nb_streams < 1)
2730 st = c->fc->streams[c->fc->nb_streams-1];
2733 avio_rb32(pb); // version + flags
2735 entries = avio_rb32(pb);
2737 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
2738 av_free(sc->stps_data);
2740 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
2742 return AVERROR(ENOMEM);
2744 for (i = 0; i < entries && !pb->eof_reached; i++) {
2745 sc->stps_data[i] = avio_rb32(pb);
2750 if (pb->eof_reached) {
2751 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
2758 static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2761 MOVStreamContext *sc;
2762 unsigned int i, entries;
2764 if (c->fc->nb_streams < 1)
2766 st = c->fc->streams[c->fc->nb_streams-1];
2769 avio_r8(pb); /* version */
2770 avio_rb24(pb); /* flags */
2772 entries = avio_rb32(pb);
2774 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
2778 sc->keyframe_absent = 1;
2779 if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
2780 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2784 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
2785 if (entries >= UINT_MAX / sizeof(int))
2786 return AVERROR_INVALIDDATA;
2787 av_freep(&sc->keyframes);
2788 sc->keyframe_count = 0;
2789 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
2791 return AVERROR(ENOMEM);
2793 for (i = 0; i < entries && !pb->eof_reached; i++) {
2794 sc->keyframes[i] = avio_rb32(pb);
2797 sc->keyframe_count = i;
2799 if (pb->eof_reached) {
2800 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
2807 static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2810 MOVStreamContext *sc;
2811 unsigned int i, entries, sample_size, field_size, num_bytes;
2816 if (c->fc->nb_streams < 1)
2818 st = c->fc->streams[c->fc->nb_streams-1];
2821 avio_r8(pb); /* version */
2822 avio_rb24(pb); /* flags */
2824 if (atom.type == MKTAG('s','t','s','z')) {
2825 sample_size = avio_rb32(pb);
2826 if (!sc->sample_size) /* do not overwrite value computed in stsd */
2827 sc->sample_size = sample_size;
2828 sc->stsz_sample_size = sample_size;
2832 avio_rb24(pb); /* reserved */
2833 field_size = avio_r8(pb);
2835 entries = avio_rb32(pb);
2837 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
2839 sc->sample_count = entries;
2843 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
2844 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
2845 return AVERROR_INVALIDDATA;
2850 if (entries >= (UINT_MAX - 4) / field_size)
2851 return AVERROR_INVALIDDATA;
2852 if (sc->sample_sizes)
2853 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
2854 av_free(sc->sample_sizes);
2855 sc->sample_count = 0;
2856 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
2857 if (!sc->sample_sizes)
2858 return AVERROR(ENOMEM);
2860 num_bytes = (entries*field_size+4)>>3;
2862 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
2864 av_freep(&sc->sample_sizes);
2865 return AVERROR(ENOMEM);
2868 ret = ffio_read_size(pb, buf, num_bytes);
2870 av_freep(&sc->sample_sizes);
2872 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
2876 init_get_bits(&gb, buf, 8*num_bytes);
2878 for (i = 0; i < entries && !pb->eof_reached; i++) {
2879 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
2880 if (sc->sample_sizes[i] < 0) {
2882 av_log(c->fc, AV_LOG_ERROR, "Invalid sample size %d\n", sc->sample_sizes[i]);
2883 return AVERROR_INVALIDDATA;
2885 sc->data_size += sc->sample_sizes[i];
2888 sc->sample_count = i;
2892 if (pb->eof_reached) {
2893 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSZ atom\n");
2900 static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2903 MOVStreamContext *sc;
2904 unsigned int i, entries, alloc_size = 0;
2906 int64_t total_sample_count=0;
2908 if (c->fc->nb_streams < 1)
2910 st = c->fc->streams[c->fc->nb_streams-1];
2913 avio_r8(pb); /* version */
2914 avio_rb24(pb); /* flags */
2915 entries = avio_rb32(pb);
2917 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
2918 c->fc->nb_streams-1, entries);
2921 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
2922 av_freep(&sc->stts_data);
2924 if (entries >= INT_MAX / sizeof(*sc->stts_data))
2925 return AVERROR(ENOMEM);
2927 for (i = 0; i < entries && !pb->eof_reached; i++) {
2928 int sample_duration;
2929 unsigned int sample_count;
2930 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
2931 MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
2932 min_entries * sizeof(*sc->stts_data));
2934 av_freep(&sc->stts_data);
2936 return AVERROR(ENOMEM);
2938 sc->stts_count = min_entries;
2939 sc->stts_data = stts_data;
2941 sample_count=avio_rb32(pb);
2942 sample_duration = avio_rb32(pb);
2944 sc->stts_data[i].count= sample_count;
2945 sc->stts_data[i].duration= sample_duration;
2947 av_log(c->fc, AV_LOG_TRACE, "sample_count=%d, sample_duration=%d\n",
2948 sample_count, sample_duration);
2950 duration+=(int64_t)sample_duration*(uint64_t)sample_count;
2951 total_sample_count+=sample_count;
2957 duration <= INT64_MAX - sc->duration_for_fps &&
2958 total_sample_count <= INT_MAX - sc->nb_frames_for_fps
2960 sc->duration_for_fps += duration;
2961 sc->nb_frames_for_fps += total_sample_count;
2964 if (pb->eof_reached) {
2965 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
2969 st->nb_frames= total_sample_count;
2971 st->duration= FFMIN(st->duration, duration);
2972 sc->track_end = duration;
2976 static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2979 MOVStreamContext *sc;
2982 if (c->fc->nb_streams < 1)
2984 st = c->fc->streams[c->fc->nb_streams - 1];
2987 avio_r8(pb); /* version */
2988 avio_rb24(pb); /* flags */
2989 entries = atom.size - 4;
2991 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
2992 c->fc->nb_streams - 1, entries);
2995 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
2996 av_freep(&sc->sdtp_data);
2999 sc->sdtp_data = av_mallocz(entries);
3001 return AVERROR(ENOMEM);
3003 for (i = 0; i < entries && !pb->eof_reached; i++)
3004 sc->sdtp_data[i] = avio_r8(pb);
3010 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3013 if (duration == INT_MIN) {
3014 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3017 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3021 static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3024 MOVStreamContext *sc;
3025 unsigned int i, entries, ctts_count = 0;
3027 if (c->fc->nb_streams < 1)
3029 st = c->fc->streams[c->fc->nb_streams-1];
3032 avio_r8(pb); /* version */
3033 avio_rb24(pb); /* flags */
3034 entries = avio_rb32(pb);
3036 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3040 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3041 return AVERROR_INVALIDDATA;
3042 av_freep(&sc->ctts_data);
3043 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3045 return AVERROR(ENOMEM);
3047 for (i = 0; i < entries && !pb->eof_reached; i++) {
3048 int count =avio_rb32(pb);
3049 int duration =avio_rb32(pb);
3052 av_log(c->fc, AV_LOG_TRACE,
3053 "ignoring CTTS entry with count=%d duration=%d\n",
3058 add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3061 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3064 if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3065 av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3066 av_freep(&sc->ctts_data);
3072 mov_update_dts_shift(sc, duration, c->fc);
3075 sc->ctts_count = ctts_count;
3077 if (pb->eof_reached) {
3078 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3082 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3087 static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3090 MOVStreamContext *sc;
3091 unsigned int i, entries;
3093 uint32_t grouping_type;
3095 if (c->fc->nb_streams < 1)
3097 st = c->fc->streams[c->fc->nb_streams-1];
3100 version = avio_r8(pb); /* version */
3101 avio_rb24(pb); /* flags */
3102 grouping_type = avio_rl32(pb);
3103 if (grouping_type != MKTAG( 'r','a','p',' '))
3104 return 0; /* only support 'rap ' grouping */
3106 avio_rb32(pb); /* grouping_type_parameter */
3108 entries = avio_rb32(pb);
3112 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP atom\n");
3113 av_free(sc->rap_group);
3114 sc->rap_group_count = 0;
3115 sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group));
3117 return AVERROR(ENOMEM);
3119 for (i = 0; i < entries && !pb->eof_reached; i++) {
3120 sc->rap_group[i].count = avio_rb32(pb); /* sample_count */
3121 sc->rap_group[i].index = avio_rb32(pb); /* group_description_index */
3124 sc->rap_group_count = i;
3126 if (pb->eof_reached) {
3127 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3135 * Get ith edit list entry (media time, duration).
3137 static int get_edit_list_entry(MOVContext *mov,
3138 const MOVStreamContext *msc,
3139 unsigned int edit_list_index,
3140 int64_t *edit_list_media_time,
3141 int64_t *edit_list_duration,
3142 int64_t global_timescale)
3144 if (edit_list_index == msc->elst_count) {
3147 *edit_list_media_time = msc->elst_data[edit_list_index].time;
3148 *edit_list_duration = msc->elst_data[edit_list_index].duration;
3150 /* duration is in global timescale units;convert to msc timescale */
3151 if (global_timescale == 0) {
3152 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3155 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3161 * Find the closest previous frame to the timestamp_pts, in e_old index
3162 * entries. Searching for just any frame / just key frames can be controlled by
3163 * last argument 'flag'.
3164 * Note that if ctts_data is not NULL, we will always search for a key frame
3165 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3166 * return the first frame of the video.
3168 * Here the timestamp_pts is considered to be a presentation timestamp and
3169 * the timestamp of index entries are considered to be decoding timestamps.
3171 * Returns 0 if successful in finding a frame, else returns -1.
3172 * Places the found index corresponding output arg.
3174 * If ctts_old is not NULL, then refines the searched entry by searching
3175 * backwards from the found timestamp, to find the frame with correct PTS.
3177 * Places the found ctts_index and ctts_sample in corresponding output args.
3179 static int find_prev_closest_index(AVStream *st,
3180 AVIndexEntry *e_old,
3184 int64_t timestamp_pts,
3187 int64_t* ctts_index,
3188 int64_t* ctts_sample)
3190 MOVStreamContext *msc = st->priv_data;
3191 AVIndexEntry *e_keep = st->index_entries;
3192 int nb_keep = st->nb_index_entries;
3194 int64_t index_ctts_count;
3198 // If dts_shift > 0, then all the index timestamps will have to be offset by
3199 // at least dts_shift amount to obtain PTS.
3200 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3201 if (msc->dts_shift > 0) {
3202 timestamp_pts -= msc->dts_shift;
3205 st->index_entries = e_old;
3206 st->nb_index_entries = nb_old;
3207 *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3209 // Keep going backwards in the index entries until the timestamp is the same.
3211 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3213 if ((flag & AVSEEK_FLAG_ANY) ||
3214 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3220 // If we have CTTS then refine the search, by searching backwards over PTS
3221 // computed by adding corresponding CTTS durations to index timestamps.
3222 if (ctts_data && *index >= 0) {
3223 av_assert0(ctts_index);
3224 av_assert0(ctts_sample);
3225 // Find out the ctts_index for the found frame.
3228 for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3229 if (*ctts_index < ctts_count) {
3231 if (ctts_data[*ctts_index].count == *ctts_sample) {
3238 while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3239 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3240 // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3241 // compensated by dts_shift above.
3242 if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3243 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3248 if (*ctts_sample == 0) {
3250 if (*ctts_index >= 0)
3251 *ctts_sample = ctts_data[*ctts_index].count - 1;
3258 /* restore AVStream state*/
3259 st->index_entries = e_keep;
3260 st->nb_index_entries = nb_keep;
3261 return *index >= 0 ? 0 : -1;
3265 * Add index entry with the given values, to the end of st->index_entries.
3266 * Returns the new size st->index_entries if successful, else returns -1.
3268 * This function is similar to ff_add_index_entry in libavformat/utils.c
3269 * except that here we are always unconditionally adding an index entry to
3270 * the end, instead of searching the entries list and skipping the add if
3271 * there is an existing entry with the same timestamp.
3272 * This is needed because the mov_fix_index calls this func with the same
3273 * unincremented timestamp for successive discarded frames.
3275 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3276 int size, int distance, int flags)
3278 AVIndexEntry *entries, *ie;
3280 const size_t min_size_needed = (st->nb_index_entries + 1) * sizeof(AVIndexEntry);
3282 // Double the allocation each time, to lower memory fragmentation.
3283 // Another difference from ff_add_index_entry function.
3284 const size_t requested_size =
3285 min_size_needed > st->index_entries_allocated_size ?
3286 FFMAX(min_size_needed, 2 * st->index_entries_allocated_size) :
3289 if((unsigned)st->nb_index_entries + 1 >= UINT_MAX / sizeof(AVIndexEntry))
3292 entries = av_fast_realloc(st->index_entries,
3293 &st->index_entries_allocated_size,
3298 st->index_entries= entries;
3300 index= st->nb_index_entries++;
3301 ie= &entries[index];
3304 ie->timestamp = timestamp;
3305 ie->min_distance= distance;
3312 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3313 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3315 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3316 int64_t* frame_duration_buffer,
3317 int frame_duration_buffer_size) {
3319 av_assert0(end_index >= 0 && end_index <= st->nb_index_entries);
3320 for (i = 0; i < frame_duration_buffer_size; i++) {
3321 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3322 st->index_entries[end_index - 1 - i].timestamp = end_ts;
3327 * Append a new ctts entry to ctts_data.
3328 * Returns the new ctts_count if successful, else returns -1.
3330 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3331 int count, int duration)
3333 MOVStts *ctts_buf_new;
3334 const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVStts);
3335 const size_t requested_size =
3336 min_size_needed > *allocated_size ?
3337 FFMAX(min_size_needed, 2 * (*allocated_size)) :
3340 if((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
3343 ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3348 *ctts_data = ctts_buf_new;
3350 ctts_buf_new[*ctts_count].count = count;
3351 ctts_buf_new[*ctts_count].duration = duration;
3353 *ctts_count = (*ctts_count) + 1;
3357 #define MAX_REORDER_DELAY 16
3358 static void mov_estimate_video_delay(MOVContext *c, AVStream* st) {
3359 MOVStreamContext *msc = st->priv_data;
3362 int ctts_sample = 0;
3363 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3365 int j, r, num_swaps;
3367 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3368 pts_buf[j] = INT64_MIN;
3370 if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3371 st->codecpar->codec_id == AV_CODEC_ID_H264) {
3372 st->codecpar->video_delay = 0;
3373 for(ind = 0; ind < st->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3374 // Point j to the last elem of the buffer and insert the current pts there.
3376 buf_start = (buf_start + 1);
3377 if (buf_start == MAX_REORDER_DELAY + 1)
3380 pts_buf[j] = st->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3382 // The timestamps that are already in the sorted buffer, and are greater than the
3383 // current pts, are exactly the timestamps that need to be buffered to output PTS
3384 // in correct sorted order.
3385 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3386 // can be computed as the maximum no. of swaps any particular timestamp needs to
3387 // go through, to keep this buffer in sorted order.
3389 while (j != buf_start) {
3391 if (r < 0) r = MAX_REORDER_DELAY;
3392 if (pts_buf[j] < pts_buf[r]) {
3393 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3400 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3403 if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3408 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3409 st->codecpar->video_delay, st->index);
3413 static void mov_current_sample_inc(MOVStreamContext *sc)
3415 sc->current_sample++;
3416 sc->current_index++;
3417 if (sc->index_ranges &&
3418 sc->current_index >= sc->current_index_range->end &&
3419 sc->current_index_range->end) {
3420 sc->current_index_range++;
3421 sc->current_index = sc->current_index_range->start;
3425 static void mov_current_sample_dec(MOVStreamContext *sc)
3427 sc->current_sample--;
3428 sc->current_index--;
3429 if (sc->index_ranges &&
3430 sc->current_index < sc->current_index_range->start &&
3431 sc->current_index_range > sc->index_ranges) {
3432 sc->current_index_range--;
3433 sc->current_index = sc->current_index_range->end - 1;
3437 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3441 sc->current_sample = current_sample;
3442 sc->current_index = current_sample;
3443 if (!sc->index_ranges) {
3447 for (sc->current_index_range = sc->index_ranges;
3448 sc->current_index_range->end;
3449 sc->current_index_range++) {
3450 range_size = sc->current_index_range->end - sc->current_index_range->start;
3451 if (range_size > current_sample) {
3452 sc->current_index = sc->current_index_range->start + current_sample;
3455 current_sample -= range_size;
3460 * Fix st->index_entries, so that it contains only the entries (and the entries
3461 * which are needed to decode them) that fall in the edit list time ranges.
3462 * Also fixes the timestamps of the index entries to match the timeline
3463 * specified the edit lists.
3465 static void mov_fix_index(MOVContext *mov, AVStream *st)
3467 MOVStreamContext *msc = st->priv_data;
3468 AVIndexEntry *e_old = st->index_entries;
3469 int nb_old = st->nb_index_entries;
3470 const AVIndexEntry *e_old_end = e_old + nb_old;
3471 const AVIndexEntry *current = NULL;
3472 MOVStts *ctts_data_old = msc->ctts_data;
3473 int64_t ctts_index_old = 0;
3474 int64_t ctts_sample_old = 0;
3475 int64_t ctts_count_old = msc->ctts_count;
3476 int64_t edit_list_media_time = 0;
3477 int64_t edit_list_duration = 0;
3478 int64_t frame_duration = 0;
3479 int64_t edit_list_dts_counter = 0;
3480 int64_t edit_list_dts_entry_end = 0;
3481 int64_t edit_list_start_ctts_sample = 0;
3483 int64_t curr_ctts = 0;
3484 int64_t empty_edits_sum_duration = 0;
3485 int64_t edit_list_index = 0;
3488 int64_t start_dts = 0;
3489 int64_t edit_list_start_encountered = 0;
3490 int64_t search_timestamp = 0;
3491 int64_t* frame_duration_buffer = NULL;
3492 int num_discarded_begin = 0;
3493 int first_non_zero_audio_edit = -1;
3494 int packet_skip_samples = 0;
3495 MOVIndexRange *current_index_range;
3497 int found_keyframe_after_edit = 0;
3498 int found_non_empty_edit = 0;
3500 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
3504 // allocate the index ranges array
3505 msc->index_ranges = av_malloc((msc->elst_count + 1) * sizeof(msc->index_ranges[0]));
3506 if (!msc->index_ranges) {
3507 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
3510 msc->current_index_range = msc->index_ranges;
3511 current_index_range = msc->index_ranges - 1;
3513 // Clean AVStream from traces of old index
3514 st->index_entries = NULL;
3515 st->index_entries_allocated_size = 0;
3516 st->nb_index_entries = 0;
3518 // Clean ctts fields of MOVStreamContext
3519 msc->ctts_data = NULL;
3520 msc->ctts_count = 0;
3521 msc->ctts_index = 0;
3522 msc->ctts_sample = 0;
3523 msc->ctts_allocated_size = 0;
3525 // Reinitialize min_corrected_pts so that it can be computed again.
3526 msc->min_corrected_pts = -1;
3528 // If the dts_shift is positive (in case of negative ctts values in mov),
3529 // then negate the DTS by dts_shift
3530 if (msc->dts_shift > 0) {
3531 edit_list_dts_entry_end -= msc->dts_shift;
3532 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
3535 start_dts = edit_list_dts_entry_end;
3537 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
3538 &edit_list_duration, mov->time_scale)) {
3539 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
3540 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
3542 edit_list_dts_counter = edit_list_dts_entry_end;
3543 edit_list_dts_entry_end += edit_list_duration;
3544 num_discarded_begin = 0;
3545 if (!found_non_empty_edit && edit_list_media_time == -1) {
3546 empty_edits_sum_duration += edit_list_duration;
3549 found_non_empty_edit = 1;
3551 // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
3552 // according to the edit list below.
3553 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3554 if (first_non_zero_audio_edit < 0) {
3555 first_non_zero_audio_edit = 1;
3557 first_non_zero_audio_edit = 0;
3560 if (first_non_zero_audio_edit > 0)
3561 st->skip_samples = msc->start_pad = 0;
3564 // While reordering frame index according to edit list we must handle properly
3565 // the scenario when edit list entry starts from none key frame.
3566 // We find closest previous key frame and preserve it and consequent frames in index.
3567 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
3568 search_timestamp = edit_list_media_time;
3569 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3570 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
3571 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
3572 // edit_list_media_time to cover the decoder delay.
3573 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
3576 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
3577 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3578 av_log(mov->fc, AV_LOG_WARNING,
3579 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
3580 st->index, edit_list_index, search_timestamp);
3581 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
3582 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3583 av_log(mov->fc, AV_LOG_WARNING,
3584 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
3585 st->index, edit_list_index, search_timestamp);
3588 ctts_sample_old = 0;
3591 current = e_old + index;
3592 edit_list_start_ctts_sample = ctts_sample_old;
3594 // Iterate over index and arrange it according to edit list
3595 edit_list_start_encountered = 0;
3596 found_keyframe_after_edit = 0;
3597 for (; current < e_old_end; current++, index++) {
3598 // check if frame outside edit list mark it for discard
3599 frame_duration = (current + 1 < e_old_end) ?
3600 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
3602 flags = current->flags;
3604 // frames (pts) before or after edit list
3605 curr_cts = current->timestamp + msc->dts_shift;
3608 if (ctts_data_old && ctts_index_old < ctts_count_old) {
3609 curr_ctts = ctts_data_old[ctts_index_old].duration;
3610 av_log(mov->fc, AV_LOG_DEBUG, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
3611 curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
3612 curr_cts += curr_ctts;
3614 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
3615 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3616 &msc->ctts_allocated_size,
3617 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3618 ctts_data_old[ctts_index_old].duration) == -1) {
3619 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3621 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3622 ctts_data_old[ctts_index_old].duration);
3626 ctts_sample_old = 0;
3627 edit_list_start_ctts_sample = 0;
3631 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
3632 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
3633 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
3634 first_non_zero_audio_edit > 0) {
3635 packet_skip_samples = edit_list_media_time - curr_cts;
3636 st->skip_samples += packet_skip_samples;
3638 // Shift the index entry timestamp by packet_skip_samples to be correct.
3639 edit_list_dts_counter -= packet_skip_samples;
3640 if (edit_list_start_encountered == 0) {
3641 edit_list_start_encountered = 1;
3642 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
3643 // discarded packets.
3644 if (frame_duration_buffer) {
3645 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3646 frame_duration_buffer, num_discarded_begin);
3647 av_freep(&frame_duration_buffer);
3651 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
3653 flags |= AVINDEX_DISCARD_FRAME;
3654 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
3656 if (edit_list_start_encountered == 0) {
3657 num_discarded_begin++;
3658 frame_duration_buffer = av_realloc(frame_duration_buffer,
3659 num_discarded_begin * sizeof(int64_t));
3660 if (!frame_duration_buffer) {
3661 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
3664 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
3666 // Increment skip_samples for the first non-zero audio edit list
3667 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3668 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
3669 st->skip_samples += frame_duration;
3674 if (msc->min_corrected_pts < 0) {
3675 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
3677 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
3679 if (edit_list_start_encountered == 0) {
3680 edit_list_start_encountered = 1;
3681 // Make timestamps strictly monotonically increasing by rewriting timestamps for
3682 // discarded packets.
3683 if (frame_duration_buffer) {
3684 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3685 frame_duration_buffer, num_discarded_begin);
3686 av_freep(&frame_duration_buffer);
3691 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
3692 current->min_distance, flags) == -1) {
3693 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
3697 // Update the index ranges array
3698 if (current_index_range < msc->index_ranges || index != current_index_range->end) {
3699 current_index_range++;
3700 current_index_range->start = index;
3702 current_index_range->end = index + 1;
3704 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
3705 if (edit_list_start_encountered > 0) {
3706 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
3709 // Break when found first key frame after edit entry completion
3710 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
3711 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
3712 if (ctts_data_old) {
3713 // If we have CTTS and this is the first keyframe after edit elist,
3714 // wait for one more, because there might be trailing B-frames after this I-frame
3715 // that do belong to the edit.
3716 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
3717 found_keyframe_after_edit = 1;
3720 if (ctts_sample_old != 0) {
3721 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3722 &msc->ctts_allocated_size,
3723 ctts_sample_old - edit_list_start_ctts_sample,
3724 ctts_data_old[ctts_index_old].duration) == -1) {
3725 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3726 ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
3727 ctts_data_old[ctts_index_old].duration);
3736 // If there are empty edits, then msc->min_corrected_pts might be positive
3737 // intentionally. So we subtract the sum duration of emtpy edits here.
3738 msc->min_corrected_pts -= empty_edits_sum_duration;
3740 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
3741 // dts by that amount to make the first pts zero.
3742 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
3743 if (msc->min_corrected_pts > 0) {
3744 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
3745 for (i = 0; i < st->nb_index_entries; ++i) {
3746 st->index_entries[i].timestamp -= msc->min_corrected_pts;
3750 // Start time should be equal to zero or the duration of any empty edits.
3751 st->start_time = empty_edits_sum_duration;
3753 // Update av stream length, if it ends up shorter than the track's media duration
3754 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
3755 msc->start_pad = st->skip_samples;
3757 // Free the old index and the old CTTS structures
3759 av_free(ctts_data_old);
3760 av_freep(&frame_duration_buffer);
3762 // Null terminate the index ranges array
3763 current_index_range++;
3764 current_index_range->start = 0;
3765 current_index_range->end = 0;
3766 msc->current_index = msc->index_ranges[0].start;
3769 static void mov_build_index(MOVContext *mov, AVStream *st)
3771 MOVStreamContext *sc = st->priv_data;
3772 int64_t current_offset;
3773 int64_t current_dts = 0;
3774 unsigned int stts_index = 0;
3775 unsigned int stsc_index = 0;
3776 unsigned int stss_index = 0;
3777 unsigned int stps_index = 0;
3779 uint64_t stream_size = 0;
3780 MOVStts *ctts_data_old = sc->ctts_data;
3781 unsigned int ctts_count_old = sc->ctts_count;
3783 if (sc->elst_count) {
3784 int i, edit_start_index = 0, multiple_edits = 0;
3785 int64_t empty_duration = 0; // empty duration of the first edit list entry
3786 int64_t start_time = 0; // start time of the media
3788 for (i = 0; i < sc->elst_count; i++) {
3789 const MOVElst *e = &sc->elst_data[i];
3790 if (i == 0 && e->time == -1) {
3791 /* if empty, the first entry is the start time of the stream
3792 * relative to the presentation itself */
3793 empty_duration = e->duration;
3794 edit_start_index = 1;
3795 } else if (i == edit_start_index && e->time >= 0) {
3796 start_time = e->time;
3802 if (multiple_edits && !mov->advanced_editlist)
3803 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
3804 "Use -advanced_editlist to correctly decode otherwise "
3805 "a/v desync might occur\n");
3807 /* adjust first dts according to edit list */
3808 if ((empty_duration || start_time) && mov->time_scale > 0) {
3810 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
3811 sc->time_offset = start_time - empty_duration;
3812 sc->min_corrected_pts = start_time;
3813 if (!mov->advanced_editlist)
3814 current_dts = -sc->time_offset;
3817 if (!multiple_edits && !mov->advanced_editlist &&
3818 st->codecpar->codec_id == AV_CODEC_ID_AAC && start_time > 0)
3819 sc->start_pad = start_time;
3822 /* only use old uncompressed audio chunk demuxing when stts specifies it */
3823 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3824 sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
3825 unsigned int current_sample = 0;
3826 unsigned int stts_sample = 0;
3827 unsigned int sample_size;
3828 unsigned int distance = 0;
3829 unsigned int rap_group_index = 0;
3830 unsigned int rap_group_sample = 0;
3831 int64_t last_dts = 0;
3832 int64_t dts_correction = 0;
3833 int rap_group_present = sc->rap_group_count && sc->rap_group;
3834 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
3836 current_dts -= sc->dts_shift;
3837 last_dts = current_dts;
3839 if (!sc->sample_count || st->nb_index_entries)
3841 if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
3843 if (av_reallocp_array(&st->index_entries,
3844 st->nb_index_entries + sc->sample_count,
3845 sizeof(*st->index_entries)) < 0) {
3846 st->nb_index_entries = 0;
3849 st->index_entries_allocated_size = (st->nb_index_entries + sc->sample_count) * sizeof(*st->index_entries);
3851 if (ctts_data_old) {
3852 // Expand ctts entries such that we have a 1-1 mapping with samples
3853 if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
3856 sc->ctts_allocated_size = 0;
3857 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size,
3858 sc->sample_count * sizeof(*sc->ctts_data));
3859 if (!sc->ctts_data) {
3860 av_free(ctts_data_old);
3864 memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
3866 for (i = 0; i < ctts_count_old &&
3867 sc->ctts_count < sc->sample_count; i++)
3868 for (j = 0; j < ctts_data_old[i].count &&
3869 sc->ctts_count < sc->sample_count; j++)
3870 add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
3871 &sc->ctts_allocated_size, 1,
3872 ctts_data_old[i].duration);
3873 av_free(ctts_data_old);
3876 for (i = 0; i < sc->chunk_count; i++) {
3877 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
3878 current_offset = sc->chunk_offsets[i];
3879 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3880 i + 1 == sc->stsc_data[stsc_index + 1].first)
3883 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
3884 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
3885 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
3886 sc->stsz_sample_size = sc->sample_size;
3888 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
3889 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
3890 sc->stsz_sample_size = sc->sample_size;
3893 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
3895 if (current_sample >= sc->sample_count) {
3896 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
3900 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
3902 if (stss_index + 1 < sc->keyframe_count)
3904 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
3906 if (stps_index + 1 < sc->stps_count)
3909 if (rap_group_present && rap_group_index < sc->rap_group_count) {
3910 if (sc->rap_group[rap_group_index].index > 0)
3912 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
3913 rap_group_sample = 0;
3917 if (sc->keyframe_absent
3919 && !rap_group_present
3920 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
3924 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
3925 if (sc->pseudo_stream_id == -1 ||
3926 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
3928 if (sample_size > 0x3FFFFFFF) {
3929 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
3932 e = &st->index_entries[st->nb_index_entries++];
3933 e->pos = current_offset;
3934 e->timestamp = current_dts;
3935 e->size = sample_size;
3936 e->min_distance = distance;
3937 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
3938 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
3939 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
3940 current_offset, current_dts, sample_size, distance, keyframe);
3941 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries < 100)
3942 ff_rfps_add_frame(mov->fc, st, current_dts);
3945 current_offset += sample_size;
3946 stream_size += sample_size;
3948 /* A negative sample duration is invalid based on the spec,
3949 * but some samples need it to correct the DTS. */
3950 if (sc->stts_data[stts_index].duration < 0) {
3951 av_log(mov->fc, AV_LOG_WARNING,
3952 "Invalid SampleDelta %d in STTS, at %d st:%d\n",
3953 sc->stts_data[stts_index].duration, stts_index,
3955 dts_correction += sc->stts_data[stts_index].duration - 1;
3956 sc->stts_data[stts_index].duration = 1;
3958 current_dts += sc->stts_data[stts_index].duration;
3959 if (!dts_correction || current_dts + dts_correction > last_dts) {
3960 current_dts += dts_correction;
3963 /* Avoid creating non-monotonous DTS */
3964 dts_correction += current_dts - last_dts - 1;
3965 current_dts = last_dts + 1;
3967 last_dts = current_dts;
3971 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
3977 if (st->duration > 0)
3978 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
3980 unsigned chunk_samples, total = 0;
3982 if (!sc->chunk_count)
3985 // compute total chunk count
3986 for (i = 0; i < sc->stsc_count; i++) {
3987 unsigned count, chunk_count;
3989 chunk_samples = sc->stsc_data[i].count;
3990 if (i != sc->stsc_count - 1 &&
3991 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
3992 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
3996 if (sc->samples_per_frame >= 160) { // gsm
3997 count = chunk_samples / sc->samples_per_frame;
3998 } else if (sc->samples_per_frame > 1) {
3999 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4000 count = (chunk_samples+samples-1) / samples;
4002 count = (chunk_samples+1023) / 1024;
4005 if (mov_stsc_index_valid(i, sc->stsc_count))
4006 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4008 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4009 total += chunk_count * count;
4012 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4013 if (total >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
4015 if (av_reallocp_array(&st->index_entries,
4016 st->nb_index_entries + total,
4017 sizeof(*st->index_entries)) < 0) {
4018 st->nb_index_entries = 0;
4021 st->index_entries_allocated_size = (st->nb_index_entries + total) * sizeof(*st->index_entries);
4024 for (i = 0; i < sc->chunk_count; i++) {
4025 current_offset = sc->chunk_offsets[i];
4026 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4027 i + 1 == sc->stsc_data[stsc_index + 1].first)
4029 chunk_samples = sc->stsc_data[stsc_index].count;
4031 while (chunk_samples > 0) {
4033 unsigned size, samples;
4035 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4036 avpriv_request_sample(mov->fc,
4037 "Zero bytes per frame, but %d samples per frame",
4038 sc->samples_per_frame);
4042 if (sc->samples_per_frame >= 160) { // gsm
4043 samples = sc->samples_per_frame;
4044 size = sc->bytes_per_frame;
4046 if (sc->samples_per_frame > 1) {
4047 samples = FFMIN((1024 / sc->samples_per_frame)*
4048 sc->samples_per_frame, chunk_samples);
4049 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
4051 samples = FFMIN(1024, chunk_samples);
4052 size = samples * sc->sample_size;
4056 if (st->nb_index_entries >= total) {
4057 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4060 if (size > 0x3FFFFFFF) {
4061 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4064 e = &st->index_entries[st->nb_index_entries++];
4065 e->pos = current_offset;
4066 e->timestamp = current_dts;
4068 e->min_distance = 0;
4069 e->flags = AVINDEX_KEYFRAME;
4070 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4071 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4074 current_offset += size;
4075 current_dts += samples;
4076 chunk_samples -= samples;
4081 if (!mov->ignore_editlist && mov->advanced_editlist) {
4082 // Fix index according to edit lists.
4083 mov_fix_index(mov, st);
4086 // Update start time of the stream.
4087 if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries > 0) {
4088 st->start_time = st->index_entries[0].timestamp + sc->dts_shift;
4089 if (sc->ctts_data) {
4090 st->start_time += sc->ctts_data[0].duration;
4094 mov_estimate_video_delay(mov, st);
4097 static int test_same_origin(const char *src, const char *ref) {
4107 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4108 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4110 if (strlen(src) == 0) {
4112 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4113 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4114 strlen(src_host) + 1 >= sizeof(src_host) ||
4115 strlen(ref_host) + 1 >= sizeof(ref_host)) {
4117 } else if (strcmp(src_proto, ref_proto) ||
4118 strcmp(src_auth, ref_auth) ||
4119 strcmp(src_host, ref_host) ||
4120 src_port != ref_port) {
4126 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4128 /* try relative path, we do not try the absolute because it can leak information about our
4129 system to an attacker */
4130 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4131 char filename[1025];
4132 const char *src_path;
4135 /* find a source dir */
4136 src_path = strrchr(src, '/');
4142 /* find a next level down to target */
4143 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4144 if (ref->path[l] == '/') {
4145 if (i == ref->nlvl_to - 1)
4151 /* compose filename if next level down to target was found */
4152 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4153 memcpy(filename, src, src_path - src);
4154 filename[src_path - src] = 0;
4156 for (i = 1; i < ref->nlvl_from; i++)
4157 av_strlcat(filename, "../", sizeof(filename));
4159 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4160 if (!c->use_absolute_path) {
4161 int same_origin = test_same_origin(src, filename);
4164 av_log(c->fc, AV_LOG_ERROR,
4165 "Reference with mismatching origin, %s not tried for security reasons, "
4166 "set demuxer option use_absolute_path to allow it anyway\n",
4168 return AVERROR(ENOENT);
4171 if(strstr(ref->path + l + 1, "..") ||
4172 strstr(ref->path + l + 1, ":") ||
4173 (ref->nlvl_from > 1 && same_origin < 0) ||
4174 (filename[0] == '/' && src_path == src))
4175 return AVERROR(ENOENT);
4178 if (strlen(filename) + 1 == sizeof(filename))
4179 return AVERROR(ENOENT);
4180 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4183 } else if (c->use_absolute_path) {
4184 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4185 "this is a possible security issue\n");
4186 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4189 av_log(c->fc, AV_LOG_ERROR,
4190 "Absolute path %s not tried for security reasons, "
4191 "set demuxer option use_absolute_path to allow absolute paths\n",
4195 return AVERROR(ENOENT);
4198 static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
4200 if (sc->time_scale <= 0) {
4201 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4202 sc->time_scale = c->time_scale;
4203 if (sc->time_scale <= 0)
4208 static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4211 MOVStreamContext *sc;
4214 st = avformat_new_stream(c->fc, NULL);
4215 if (!st) return AVERROR(ENOMEM);
4217 sc = av_mallocz(sizeof(MOVStreamContext));
4218 if (!sc) return AVERROR(ENOMEM);
4221 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
4222 sc->ffindex = st->index;
4223 c->trak_index = st->index;
4225 if ((ret = mov_read_default(c, pb, atom)) < 0)
4230 // Here stsc refers to a chunk not described in stco. This is technically invalid,
4231 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4232 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4234 av_freep(&sc->stsc_data);
4238 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4239 (!sc->sample_size && !sc->sample_count))) ||
4240 (!sc->chunk_count && sc->sample_count)) {
4241 av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4245 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4246 av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4248 return AVERROR_INVALIDDATA;
4251 fix_timescale(c, sc);
4253 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4255 mov_build_index(c, st);
4257 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4258 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4259 if (c->enable_drefs) {
4260 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4261 av_log(c->fc, AV_LOG_ERROR,
4262 "stream %d, error opening alias: path='%s', dir='%s', "
4263 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4264 st->index, dref->path, dref->dir, dref->filename,
4265 dref->volume, dref->nlvl_from, dref->nlvl_to);
4267 av_log(c->fc, AV_LOG_WARNING,
4268 "Skipped opening external track: "
4269 "stream %d, alias: path='%s', dir='%s', "
4270 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4271 "Set enable_drefs to allow this.\n",
4272 st->index, dref->path, dref->dir, dref->filename,
4273 dref->volume, dref->nlvl_from, dref->nlvl_to);
4277 sc->pb_is_copied = 1;
4280 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4281 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4282 sc->height && sc->width &&
4283 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4284 st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4285 ((double)st->codecpar->width * sc->height), INT_MAX);
4288 #if FF_API_R_FRAME_RATE
4289 if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4290 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
4291 sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4295 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4296 if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4297 TAG_IS_AVCI(st->codecpar->codec_tag)) {
4298 ret = ff_generate_avci_extradata(st);
4303 switch (st->codecpar->codec_id) {
4304 #if CONFIG_H261_DECODER
4305 case AV_CODEC_ID_H261:
4307 #if CONFIG_H263_DECODER
4308 case AV_CODEC_ID_H263:
4310 #if CONFIG_MPEG4_DECODER
4311 case AV_CODEC_ID_MPEG4:
4313 st->codecpar->width = 0; /* let decoder init width/height */
4314 st->codecpar->height= 0;
4318 // If the duration of the mp3 packets is not constant, then they could need a parser
4319 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4320 && sc->stts_count > 3
4321 && sc->stts_count*10 > st->nb_frames
4322 && sc->time_scale == st->codecpar->sample_rate) {
4323 st->need_parsing = AVSTREAM_PARSE_FULL;
4325 /* Do not need those anymore. */
4326 av_freep(&sc->chunk_offsets);
4327 av_freep(&sc->sample_sizes);
4328 av_freep(&sc->keyframes);
4329 av_freep(&sc->stts_data);
4330 av_freep(&sc->stps_data);
4331 av_freep(&sc->elst_data);
4332 av_freep(&sc->rap_group);
4337 static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4340 c->itunes_metadata = 1;
4341 ret = mov_read_default(c, pb, atom);
4342 c->itunes_metadata = 0;
4346 static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4355 count = avio_rb32(pb);
4356 if (count > UINT_MAX / sizeof(*c->meta_keys) - 1) {
4357 av_log(c->fc, AV_LOG_ERROR,
4358 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
4359 return AVERROR_INVALIDDATA;
4362 c->meta_keys_count = count + 1;
4363 c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
4365 return AVERROR(ENOMEM);
4367 for (i = 1; i <= count; ++i) {
4368 uint32_t key_size = avio_rb32(pb);
4369 uint32_t type = avio_rl32(pb);
4371 av_log(c->fc, AV_LOG_ERROR,
4372 "The key# %"PRIu32" in meta has invalid size:"
4373 "%"PRIu32"\n", i, key_size);
4374 return AVERROR_INVALIDDATA;
4377 if (type != MKTAG('m','d','t','a')) {
4378 avio_skip(pb, key_size);
4380 c->meta_keys[i] = av_mallocz(key_size + 1);
4381 if (!c->meta_keys[i])
4382 return AVERROR(ENOMEM);
4383 avio_read(pb, c->meta_keys[i], key_size);
4389 static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4391 int64_t end = avio_tell(pb) + atom.size;
4392 uint8_t *key = NULL, *val = NULL, *mean = NULL;
4396 MOVStreamContext *sc;
4398 if (c->fc->nb_streams < 1)
4400 st = c->fc->streams[c->fc->nb_streams-1];
4403 for (i = 0; i < 3; i++) {
4407 if (end - avio_tell(pb) <= 12)
4410 len = avio_rb32(pb);
4411 tag = avio_rl32(pb);
4412 avio_skip(pb, 4); // flags
4414 if (len < 12 || len - 12 > end - avio_tell(pb))
4418 if (tag == MKTAG('m', 'e', 'a', 'n'))
4420 else if (tag == MKTAG('n', 'a', 'm', 'e'))
4422 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
4432 *p = av_malloc(len + 1);
4434 ret = AVERROR(ENOMEM);
4437 ret = ffio_read_size(pb, *p, len);
4445 if (mean && key && val) {
4446 if (strcmp(key, "iTunSMPB") == 0) {
4447 int priming, remainder, samples;
4448 if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
4449 if(priming>0 && priming<16384)
4450 sc->start_pad = priming;
4453 if (strcmp(key, "cdec") != 0) {
4454 av_dict_set(&c->fc->metadata, key, val,
4455 AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
4459 av_log(c->fc, AV_LOG_VERBOSE,
4460 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
4463 avio_seek(pb, end, SEEK_SET);
4470 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4472 while (atom.size > 8) {
4476 tag = avio_rl32(pb);
4478 if (tag == MKTAG('h','d','l','r')) {
4479 avio_seek(pb, -8, SEEK_CUR);
4481 return mov_read_default(c, pb, atom);
4487 // return 1 when matrix is identity, 0 otherwise
4488 #define IS_MATRIX_IDENT(matrix) \
4489 ( (matrix)[0][0] == (1 << 16) && \
4490 (matrix)[1][1] == (1 << 16) && \
4491 (matrix)[2][2] == (1 << 30) && \
4492 !(matrix)[0][1] && !(matrix)[0][2] && \
4493 !(matrix)[1][0] && !(matrix)[1][2] && \
4494 !(matrix)[2][0] && !(matrix)[2][1])
4496 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4501 int display_matrix[3][3];
4502 int res_display_matrix[3][3] = { { 0 } };
4504 MOVStreamContext *sc;
4508 if (c->fc->nb_streams < 1)
4510 st = c->fc->streams[c->fc->nb_streams-1];
4513 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4514 // avoids corrupting AVStreams mapped to an earlier tkhd.
4516 return AVERROR_INVALIDDATA;
4518 version = avio_r8(pb);
4519 flags = avio_rb24(pb);
4520 st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
4526 avio_rb32(pb); /* creation time */
4527 avio_rb32(pb); /* modification time */
4529 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4530 avio_rb32(pb); /* reserved */
4532 /* highlevel (considering edits) duration in movie timebase */
4533 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4534 avio_rb32(pb); /* reserved */
4535 avio_rb32(pb); /* reserved */
4537 avio_rb16(pb); /* layer */
4538 avio_rb16(pb); /* alternate group */
4539 avio_rb16(pb); /* volume */
4540 avio_rb16(pb); /* reserved */
4542 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4543 // they're kept in fixed point format through all calculations
4544 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4545 // side data, but the scale factor is not needed to calculate aspect ratio
4546 for (i = 0; i < 3; i++) {
4547 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
4548 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
4549 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
4552 width = avio_rb32(pb); // 16.16 fixed point track width
4553 height = avio_rb32(pb); // 16.16 fixed point track height
4554 sc->width = width >> 16;
4555 sc->height = height >> 16;
4557 // apply the moov display matrix (after the tkhd one)
4558 for (i = 0; i < 3; i++) {
4559 const int sh[3] = { 16, 16, 30 };
4560 for (j = 0; j < 3; j++) {
4561 for (e = 0; e < 3; e++) {
4562 res_display_matrix[i][j] +=
4563 ((int64_t) display_matrix[i][e] *
4564 c->movie_display_matrix[e][j]) >> sh[e];
4569 // save the matrix when it is not the default identity
4570 if (!IS_MATRIX_IDENT(res_display_matrix)) {
4573 av_freep(&sc->display_matrix);
4574 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4575 if (!sc->display_matrix)
4576 return AVERROR(ENOMEM);
4578 for (i = 0; i < 3; i++)
4579 for (j = 0; j < 3; j++)
4580 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4582 #if FF_API_OLD_ROTATE_API
4583 rotate = av_display_rotation_get(sc->display_matrix);
4584 if (!isnan(rotate)) {
4585 char rotate_buf[64];
4587 if (rotate < 0) // for backward compatibility
4589 snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate);
4590 av_dict_set(&st->metadata, "rotate", rotate_buf, 0);
4595 // transform the display width/height according to the matrix
4596 // to keep the same scale, use [width height 1<<16]
4597 if (width && height && sc->display_matrix) {
4598 double disp_transform[2];
4600 for (i = 0; i < 2; i++)
4601 disp_transform[i] = hypot(sc->display_matrix[0 + i],
4602 sc->display_matrix[3 + i]);
4604 if (disp_transform[0] > 0 && disp_transform[1] > 0 &&
4605 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4606 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4607 st->sample_aspect_ratio = av_d2q(
4608 disp_transform[0] / disp_transform[1],
4614 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4616 MOVFragment *frag = &c->fragment;
4617 MOVTrackExt *trex = NULL;
4618 int flags, track_id, i;
4619 MOVFragmentStreamInfo * frag_stream_info;
4621 avio_r8(pb); /* version */
4622 flags = avio_rb24(pb);
4624 track_id = avio_rb32(pb);
4626 return AVERROR_INVALIDDATA;
4627 for (i = 0; i < c->trex_count; i++)
4628 if (c->trex_data[i].track_id == track_id) {
4629 trex = &c->trex_data[i];
4633 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4636 c->fragment.found_tfhd = 1;
4637 frag->track_id = track_id;
4638 set_frag_stream(&c->frag_index, track_id);
4640 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4641 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4642 frag->moof_offset : frag->implicit_offset;
4643 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4645 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4646 avio_rb32(pb) : trex->duration;
4647 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4648 avio_rb32(pb) : trex->size;
4649 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4650 avio_rb32(pb) : trex->flags;
4651 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4653 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4654 if (frag_stream_info)
4655 frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
4660 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4665 num = atom.size / 4;
4666 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4667 return AVERROR(ENOMEM);
4669 av_free(c->chapter_tracks);
4670 c->chapter_tracks = new_tracks;
4671 c->nb_chapter_tracks = num;
4673 for (i = 0; i < num && !pb->eof_reached; i++)
4674 c->chapter_tracks[i] = avio_rb32(pb);
4679 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4684 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4685 return AVERROR_INVALIDDATA;
4686 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4687 sizeof(*c->trex_data))) < 0) {
4692 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4694 trex = &c->trex_data[c->trex_count++];
4695 avio_r8(pb); /* version */
4696 avio_rb24(pb); /* flags */
4697 trex->track_id = avio_rb32(pb);
4698 trex->stsd_id = avio_rb32(pb);
4699 trex->duration = avio_rb32(pb);
4700 trex->size = avio_rb32(pb);
4701 trex->flags = avio_rb32(pb);
4705 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4707 MOVFragment *frag = &c->fragment;
4708 AVStream *st = NULL;
4709 MOVStreamContext *sc;
4711 MOVFragmentStreamInfo * frag_stream_info;
4712 int64_t base_media_decode_time;
4714 for (i = 0; i < c->fc->nb_streams; i++) {
4715 if (c->fc->streams[i]->id == frag->track_id) {
4716 st = c->fc->streams[i];
4721 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4725 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4727 version = avio_r8(pb);
4728 avio_rb24(pb); /* flags */
4730 base_media_decode_time = avio_rb64(pb);
4732 base_media_decode_time = avio_rb32(pb);
4735 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4736 if (frag_stream_info)
4737 frag_stream_info->tfdt_dts = base_media_decode_time;
4738 sc->track_end = base_media_decode_time;
4743 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4745 MOVFragment *frag = &c->fragment;
4746 AVStream *st = NULL;
4747 MOVStreamContext *sc;
4750 int64_t dts, pts = AV_NOPTS_VALUE;
4751 int data_offset = 0;
4752 unsigned entries, first_sample_flags = frag->flags;
4753 int flags, distance, i;
4754 int64_t prev_dts = AV_NOPTS_VALUE;
4755 int next_frag_index = -1, index_entry_pos;
4756 size_t requested_size;
4757 size_t old_ctts_allocated_size;
4758 AVIndexEntry *new_entries;
4759 MOVFragmentStreamInfo * frag_stream_info;
4761 if (!frag->found_tfhd) {
4762 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4763 return AVERROR_INVALIDDATA;
4766 for (i = 0; i < c->fc->nb_streams; i++) {
4767 if (c->fc->streams[i]->id == frag->track_id) {
4768 st = c->fc->streams[i];
4773 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4777 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4780 // Find the next frag_index index that has a valid index_entry for
4781 // the current track_id.
4783 // A valid index_entry means the trun for the fragment was read
4784 // and it's samples are in index_entries at the given position.
4785 // New index entries will be inserted before the index_entry found.
4786 index_entry_pos = st->nb_index_entries;
4787 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4788 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4789 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4790 next_frag_index = i;
4791 index_entry_pos = frag_stream_info->index_entry;
4795 av_assert0(index_entry_pos <= st->nb_index_entries);
4797 avio_r8(pb); /* version */
4798 flags = avio_rb24(pb);
4799 entries = avio_rb32(pb);
4800 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4802 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4803 return AVERROR_INVALIDDATA;
4804 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4805 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4807 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4808 if (frag_stream_info)
4810 if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
4811 dts = frag_stream_info->next_trun_dts - sc->time_offset;
4812 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4813 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4814 pts = frag_stream_info->first_tfra_pts;
4815 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4816 ", using it for pts\n", pts);
4817 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4818 c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
4819 dts = frag_stream_info->first_tfra_pts;
4820 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4821 ", using it for dts\n", pts);
4822 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4823 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4824 // pts = frag_stream_info->sidx_pts;
4825 dts = frag_stream_info->sidx_pts - sc->time_offset;
4826 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4827 ", using it for pts\n", pts);
4828 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4829 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4830 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4831 ", using it for dts\n", dts);
4833 dts = sc->track_end - sc->time_offset;
4834 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4835 ", using it for dts\n", dts);
4838 dts = sc->track_end - sc->time_offset;
4839 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4840 ", using it for dts\n", dts);
4842 offset = frag->base_data_offset + data_offset;
4844 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4846 // realloc space for new index entries
4847 if((uint64_t)st->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4848 entries = UINT_MAX / sizeof(AVIndexEntry) - st->nb_index_entries;
4849 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4854 requested_size = (st->nb_index_entries + entries) * sizeof(AVIndexEntry);
4855 new_entries = av_fast_realloc(st->index_entries,
4856 &st->index_entries_allocated_size,
4859 return AVERROR(ENOMEM);
4860 st->index_entries= new_entries;
4862 requested_size = (st->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4863 old_ctts_allocated_size = sc->ctts_allocated_size;
4864 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4867 return AVERROR(ENOMEM);
4868 sc->ctts_data = ctts_data;
4870 // In case there were samples without ctts entries, ensure they get
4871 // zero valued entries. This ensures clips which mix boxes with and
4872 // without ctts entries don't pickup uninitialized data.
4873 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4874 sc->ctts_allocated_size - old_ctts_allocated_size);
4876 if (index_entry_pos < st->nb_index_entries) {
4877 // Make hole in index_entries and ctts_data for new samples
4878 memmove(st->index_entries + index_entry_pos + entries,
4879 st->index_entries + index_entry_pos,
4880 sizeof(*st->index_entries) *
4881 (st->nb_index_entries - index_entry_pos));
4882 memmove(sc->ctts_data + index_entry_pos + entries,
4883 sc->ctts_data + index_entry_pos,
4884 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4885 if (index_entry_pos < sc->current_sample) {
4886 sc->current_sample += entries;
4890 st->nb_index_entries += entries;
4891 sc->ctts_count = st->nb_index_entries;
4893 // Record the index_entry position in frag_index of this fragment
4894 if (frag_stream_info)
4895 frag_stream_info->index_entry = index_entry_pos;
4897 if (index_entry_pos > 0)
4898 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4900 for (i = 0; i < entries && !pb->eof_reached; i++) {
4901 unsigned sample_size = frag->size;
4902 int sample_flags = i ? frag->flags : first_sample_flags;
4903 unsigned sample_duration = frag->duration;
4904 unsigned ctts_duration = 0;
4906 int index_entry_flags = 0;
4908 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4909 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4910 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4911 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4913 mov_update_dts_shift(sc, ctts_duration, c->fc);
4914 if (pts != AV_NOPTS_VALUE) {
4915 dts = pts - sc->dts_shift;
4916 if (flags & MOV_TRUN_SAMPLE_CTS) {
4917 dts -= ctts_duration;
4919 dts -= sc->time_offset;
4921 av_log(c->fc, AV_LOG_DEBUG,
4922 "pts %"PRId64" calculated dts %"PRId64
4923 " sc->dts_shift %d ctts.duration %d"
4924 " sc->time_offset %"PRId64
4925 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4927 sc->dts_shift, ctts_duration,
4928 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4929 pts = AV_NOPTS_VALUE;
4932 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4936 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4937 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4940 index_entry_flags |= AVINDEX_KEYFRAME;
4942 // Fragments can overlap in time. Discard overlapping frames after
4944 if (prev_dts >= dts)
4945 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4947 st->index_entries[index_entry_pos].pos = offset;
4948 st->index_entries[index_entry_pos].timestamp = dts;
4949 st->index_entries[index_entry_pos].size= sample_size;
4950 st->index_entries[index_entry_pos].min_distance= distance;
4951 st->index_entries[index_entry_pos].flags = index_entry_flags;
4953 sc->ctts_data[index_entry_pos].count = 1;
4954 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4957 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4958 "size %u, distance %d, keyframe %d\n", st->index,
4959 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4961 dts += sample_duration;
4962 offset += sample_size;
4963 sc->data_size += sample_size;
4965 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4966 1 <= INT_MAX - sc->nb_frames_for_fps
4968 sc->duration_for_fps += sample_duration;
4969 sc->nb_frames_for_fps ++;
4972 if (frag_stream_info)
4973 frag_stream_info->next_trun_dts = dts + sc->time_offset;
4975 // EOF found before reading all entries. Fix the hole this would
4976 // leave in index_entries and ctts_data
4977 int gap = entries - i;
4978 memmove(st->index_entries + index_entry_pos,
4979 st->index_entries + index_entry_pos + gap,
4980 sizeof(*st->index_entries) *
4981 (st->nb_index_entries - (index_entry_pos + gap)));
4982 memmove(sc->ctts_data + index_entry_pos,
4983 sc->ctts_data + index_entry_pos + gap,
4984 sizeof(*sc->ctts_data) *
4985 (sc->ctts_count - (index_entry_pos + gap)));
4987 st->nb_index_entries -= gap;
4988 sc->ctts_count -= gap;
4989 if (index_entry_pos < sc->current_sample) {
4990 sc->current_sample -= gap;
4995 // The end of this new fragment may overlap in time with the start
4996 // of the next fragment in index_entries. Mark the samples in the next
4997 // fragment that overlap with AVINDEX_DISCARD_FRAME
4998 prev_dts = AV_NOPTS_VALUE;
4999 if (index_entry_pos > 0)
5000 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
5001 for (i = index_entry_pos; i < st->nb_index_entries; i++) {
5002 if (prev_dts < st->index_entries[i].timestamp)
5004 st->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
5007 // If a hole was created to insert the new index_entries into,
5008 // the index_entry recorded for all subsequent moof must
5009 // be incremented by the number of entries inserted.
5010 fix_frag_index_entries(&c->frag_index, next_frag_index,
5011 frag->track_id, entries);
5013 if (pb->eof_reached) {
5014 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
5018 frag->implicit_offset = offset;
5020 sc->track_end = dts + sc->time_offset;
5021 if (st->duration < sc->track_end)
5022 st->duration = sc->track_end;
5027 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5029 int64_t offset = avio_tell(pb) + atom.size, pts, timestamp;
5031 unsigned i, j, track_id, item_count;
5032 AVStream *st = NULL;
5033 AVStream *ref_st = NULL;
5034 MOVStreamContext *sc, *ref_sc = NULL;
5035 AVRational timescale;
5037 version = avio_r8(pb);
5039 avpriv_request_sample(c->fc, "sidx version %u", version);
5043 avio_rb24(pb); // flags
5045 track_id = avio_rb32(pb); // Reference ID
5046 for (i = 0; i < c->fc->nb_streams; i++) {
5047 if (c->fc->streams[i]->id == track_id) {
5048 st = c->fc->streams[i];
5053 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5059 timescale = av_make_q(1, avio_rb32(pb));
5061 if (timescale.den <= 0) {
5062 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5063 return AVERROR_INVALIDDATA;
5067 pts = avio_rb32(pb);
5068 offset += avio_rb32(pb);
5070 pts = avio_rb64(pb);
5071 offset += avio_rb64(pb);
5074 avio_rb16(pb); // reserved
5076 item_count = avio_rb16(pb);
5078 for (i = 0; i < item_count; i++) {
5080 MOVFragmentStreamInfo * frag_stream_info;
5081 uint32_t size = avio_rb32(pb);
5082 uint32_t duration = avio_rb32(pb);
5083 if (size & 0x80000000) {
5084 avpriv_request_sample(c->fc, "sidx reference_type 1");
5085 return AVERROR_PATCHWELCOME;
5087 avio_rb32(pb); // sap_flags
5088 timestamp = av_rescale_q(pts, timescale, st->time_base);
5090 index = update_frag_index(c, offset);
5091 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5092 if (frag_stream_info)
5093 frag_stream_info->sidx_pts = timestamp;
5099 st->duration = sc->track_end = pts;
5103 if (offset == avio_size(pb)) {
5104 // Find first entry in fragment index that came from an sidx.
5105 // This will pretty much always be the first entry.
5106 for (i = 0; i < c->frag_index.nb_items; i++) {
5107 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5108 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5109 MOVFragmentStreamInfo * si;
5110 si = &item->stream_info[j];
5111 if (si->sidx_pts != AV_NOPTS_VALUE) {
5112 ref_st = c->fc->streams[j];
5113 ref_sc = ref_st->priv_data;
5118 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5119 st = c->fc->streams[i];
5121 if (!sc->has_sidx) {
5122 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5126 c->frag_index.complete = 1;
5132 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5133 /* like the files created with Adobe Premiere 5.0, for samples see */
5134 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5135 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5140 return 0; /* continue */
5141 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5142 avio_skip(pb, atom.size - 4);
5145 atom.type = avio_rl32(pb);
5147 if (atom.type != MKTAG('m','d','a','t')) {
5148 avio_skip(pb, atom.size);
5151 err = mov_read_mdat(c, pb, atom);
5155 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5160 uint8_t *moov_data; /* uncompressed data */
5161 long cmov_len, moov_len;
5164 avio_rb32(pb); /* dcom atom */
5165 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5166 return AVERROR_INVALIDDATA;
5167 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5168 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5169 return AVERROR_INVALIDDATA;
5171 avio_rb32(pb); /* cmvd atom */
5172 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5173 return AVERROR_INVALIDDATA;
5174 moov_len = avio_rb32(pb); /* uncompressed size */
5175 cmov_len = atom.size - 6 * 4;
5177 cmov_data = av_malloc(cmov_len);
5179 return AVERROR(ENOMEM);
5180 moov_data = av_malloc(moov_len);
5183 return AVERROR(ENOMEM);
5185 ret = ffio_read_size(pb, cmov_data, cmov_len);
5187 goto free_and_return;
5189 ret = AVERROR_INVALIDDATA;
5190 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5191 goto free_and_return;
5192 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5193 goto free_and_return;
5194 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5195 atom.type = MKTAG('m','o','o','v');
5196 atom.size = moov_len;
5197 ret = mov_read_default(c, &ctx, atom);
5203 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5204 return AVERROR(ENOSYS);
5208 /* edit list atom */
5209 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5211 MOVStreamContext *sc;
5212 int i, edit_count, version;
5213 int64_t elst_entry_size;
5215 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5217 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5219 version = avio_r8(pb); /* version */
5220 avio_rb24(pb); /* flags */
5221 edit_count = avio_rb32(pb); /* entries */
5224 elst_entry_size = version == 1 ? 20 : 12;
5225 if (atom.size != edit_count * elst_entry_size) {
5226 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5227 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5228 edit_count, atom.size + 8);
5229 return AVERROR_INVALIDDATA;
5231 edit_count = atom.size / elst_entry_size;
5232 if (edit_count * elst_entry_size != atom.size) {
5233 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.", atom.size, edit_count);
5241 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5242 av_free(sc->elst_data);
5244 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5246 return AVERROR(ENOMEM);
5248 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5249 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5250 MOVElst *e = &sc->elst_data[i];
5253 e->duration = avio_rb64(pb);
5254 e->time = avio_rb64(pb);
5257 e->duration = avio_rb32(pb); /* segment duration */
5258 e->time = (int32_t)avio_rb32(pb); /* media time */
5261 e->rate = avio_rb32(pb) / 65536.0;
5263 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5264 e->duration, e->time, e->rate);
5266 if (e->time < 0 && e->time != -1 &&
5267 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5268 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5269 c->fc->nb_streams-1, i, e->time);
5270 return AVERROR_INVALIDDATA;
5278 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5280 MOVStreamContext *sc;
5282 if (c->fc->nb_streams < 1)
5283 return AVERROR_INVALIDDATA;
5284 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5285 sc->timecode_track = avio_rb32(pb);
5289 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5294 if (c->fc->nb_streams < 1)
5296 st = c->fc->streams[c->fc->nb_streams - 1];
5298 if (atom.size < 4) {
5299 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5300 return AVERROR_INVALIDDATA;
5303 /* For now, propagate only the OBUs, if any. Once libavcodec is
5304 updated to handle isobmff style extradata this can be removed. */
5310 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5317 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5320 int version, color_range, color_primaries, color_trc, color_space;
5322 if (c->fc->nb_streams < 1)
5324 st = c->fc->streams[c->fc->nb_streams - 1];
5326 if (atom.size < 5) {
5327 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5328 return AVERROR_INVALIDDATA;
5331 version = avio_r8(pb);
5333 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5336 avio_skip(pb, 3); /* flags */
5338 avio_skip(pb, 2); /* profile + level */
5339 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5340 color_primaries = avio_r8(pb);
5341 color_trc = avio_r8(pb);
5342 color_space = avio_r8(pb);
5343 if (avio_rb16(pb)) /* codecIntializationDataSize */
5344 return AVERROR_INVALIDDATA;
5346 if (!av_color_primaries_name(color_primaries))
5347 color_primaries = AVCOL_PRI_UNSPECIFIED;
5348 if (!av_color_transfer_name(color_trc))
5349 color_trc = AVCOL_TRC_UNSPECIFIED;
5350 if (!av_color_space_name(color_space))
5351 color_space = AVCOL_SPC_UNSPECIFIED;
5353 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5354 st->codecpar->color_primaries = color_primaries;
5355 st->codecpar->color_trc = color_trc;
5356 st->codecpar->color_space = color_space;
5361 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5363 MOVStreamContext *sc;
5366 if (c->fc->nb_streams < 1)
5367 return AVERROR_INVALIDDATA;
5369 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5371 if (atom.size < 5) {
5372 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5373 return AVERROR_INVALIDDATA;
5376 version = avio_r8(pb);
5378 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5381 avio_skip(pb, 3); /* flags */
5383 sc->mastering = av_mastering_display_metadata_alloc();
5385 return AVERROR(ENOMEM);
5387 for (i = 0; i < 3; i++) {
5388 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5389 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5391 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5392 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5394 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5395 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5397 sc->mastering->has_primaries = 1;
5398 sc->mastering->has_luminance = 1;
5403 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5405 MOVStreamContext *sc;
5406 const int mapping[3] = {1, 2, 0};
5407 const int chroma_den = 50000;
5408 const int luma_den = 10000;
5411 if (c->fc->nb_streams < 1)
5412 return AVERROR_INVALIDDATA;
5414 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5416 if (atom.size < 24) {
5417 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5418 return AVERROR_INVALIDDATA;
5421 sc->mastering = av_mastering_display_metadata_alloc();
5423 return AVERROR(ENOMEM);
5425 for (i = 0; i < 3; i++) {
5426 const int j = mapping[i];
5427 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5428 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5430 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5431 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5433 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5434 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5436 sc->mastering->has_luminance = 1;
5437 sc->mastering->has_primaries = 1;
5442 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5444 MOVStreamContext *sc;
5447 if (c->fc->nb_streams < 1)
5448 return AVERROR_INVALIDDATA;
5450 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5452 if (atom.size < 5) {
5453 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5454 return AVERROR_INVALIDDATA;
5457 version = avio_r8(pb);
5459 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5462 avio_skip(pb, 3); /* flags */
5464 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5466 return AVERROR(ENOMEM);
5468 sc->coll->MaxCLL = avio_rb16(pb);
5469 sc->coll->MaxFALL = avio_rb16(pb);
5474 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5476 MOVStreamContext *sc;
5478 if (c->fc->nb_streams < 1)
5479 return AVERROR_INVALIDDATA;
5481 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5483 if (atom.size < 4) {
5484 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5485 return AVERROR_INVALIDDATA;
5488 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5490 return AVERROR(ENOMEM);
5492 sc->coll->MaxCLL = avio_rb16(pb);
5493 sc->coll->MaxFALL = avio_rb16(pb);
5498 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5501 MOVStreamContext *sc;
5502 enum AVStereo3DType type;
5505 if (c->fc->nb_streams < 1)
5508 st = c->fc->streams[c->fc->nb_streams - 1];
5511 if (atom.size < 5) {
5512 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5513 return AVERROR_INVALIDDATA;
5515 avio_skip(pb, 4); /* version + flags */
5520 type = AV_STEREO3D_2D;
5523 type = AV_STEREO3D_TOPBOTTOM;
5526 type = AV_STEREO3D_SIDEBYSIDE;
5529 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5533 sc->stereo3d = av_stereo3d_alloc();
5535 return AVERROR(ENOMEM);
5537 sc->stereo3d->type = type;
5541 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5544 MOVStreamContext *sc;
5545 int size, version, layout;
5546 int32_t yaw, pitch, roll;
5547 uint32_t l = 0, t = 0, r = 0, b = 0;
5548 uint32_t tag, padding = 0;
5549 enum AVSphericalProjection projection;
5551 if (c->fc->nb_streams < 1)
5554 st = c->fc->streams[c->fc->nb_streams - 1];
5557 if (atom.size < 8) {
5558 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5559 return AVERROR_INVALIDDATA;
5562 size = avio_rb32(pb);
5563 if (size <= 12 || size > atom.size)
5564 return AVERROR_INVALIDDATA;
5566 tag = avio_rl32(pb);
5567 if (tag != MKTAG('s','v','h','d')) {
5568 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5571 version = avio_r8(pb);
5573 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5577 avio_skip(pb, 3); /* flags */
5578 avio_skip(pb, size - 12); /* metadata_source */
5580 size = avio_rb32(pb);
5581 if (size > atom.size)
5582 return AVERROR_INVALIDDATA;
5584 tag = avio_rl32(pb);
5585 if (tag != MKTAG('p','r','o','j')) {
5586 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5590 size = avio_rb32(pb);
5591 if (size > atom.size)
5592 return AVERROR_INVALIDDATA;
5594 tag = avio_rl32(pb);
5595 if (tag != MKTAG('p','r','h','d')) {
5596 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5599 version = avio_r8(pb);
5601 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5605 avio_skip(pb, 3); /* flags */
5607 /* 16.16 fixed point */
5608 yaw = avio_rb32(pb);
5609 pitch = avio_rb32(pb);
5610 roll = avio_rb32(pb);
5612 size = avio_rb32(pb);
5613 if (size > atom.size)
5614 return AVERROR_INVALIDDATA;
5616 tag = avio_rl32(pb);
5617 version = avio_r8(pb);
5619 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5623 avio_skip(pb, 3); /* flags */
5625 case MKTAG('c','b','m','p'):
5626 layout = avio_rb32(pb);
5628 av_log(c->fc, AV_LOG_WARNING,
5629 "Unsupported cubemap layout %d\n", layout);
5632 projection = AV_SPHERICAL_CUBEMAP;
5633 padding = avio_rb32(pb);
5635 case MKTAG('e','q','u','i'):
5641 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5642 av_log(c->fc, AV_LOG_ERROR,
5643 "Invalid bounding rectangle coordinates "
5644 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5645 return AVERROR_INVALIDDATA;
5648 if (l || t || r || b)
5649 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5651 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5654 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5658 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5660 return AVERROR(ENOMEM);
5662 sc->spherical->projection = projection;
5664 sc->spherical->yaw = yaw;
5665 sc->spherical->pitch = pitch;
5666 sc->spherical->roll = roll;
5668 sc->spherical->padding = padding;
5670 sc->spherical->bound_left = l;
5671 sc->spherical->bound_top = t;
5672 sc->spherical->bound_right = r;
5673 sc->spherical->bound_bottom = b;
5678 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5681 uint8_t *buffer = av_malloc(len + 1);
5685 return AVERROR(ENOMEM);
5688 ret = ffio_read_size(pb, buffer, len);
5692 /* Check for mandatory keys and values, try to support XML as best-effort */
5693 if (!sc->spherical &&
5694 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5695 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5696 av_stristr(val, "true") &&
5697 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5698 av_stristr(val, "true") &&
5699 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5700 av_stristr(val, "equirectangular")) {
5701 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5705 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5707 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5708 enum AVStereo3DType mode;
5710 if (av_stristr(buffer, "left-right"))
5711 mode = AV_STEREO3D_SIDEBYSIDE;
5712 else if (av_stristr(buffer, "top-bottom"))
5713 mode = AV_STEREO3D_TOPBOTTOM;
5715 mode = AV_STEREO3D_2D;
5717 sc->stereo3d = av_stereo3d_alloc();
5721 sc->stereo3d->type = mode;
5725 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5727 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5728 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5730 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5731 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5733 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5741 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5744 MOVStreamContext *sc;
5747 static const uint8_t uuid_isml_manifest[] = {
5748 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5749 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5751 static const uint8_t uuid_xmp[] = {
5752 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5753 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5755 static const uint8_t uuid_spherical[] = {
5756 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5757 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5760 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5761 return AVERROR_INVALIDDATA;
5763 if (c->fc->nb_streams < 1)
5765 st = c->fc->streams[c->fc->nb_streams - 1];
5768 ret = avio_read(pb, uuid, sizeof(uuid));
5771 } else if (ret != sizeof(uuid)) {
5772 return AVERROR_INVALIDDATA;
5774 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5775 uint8_t *buffer, *ptr;
5777 size_t len = atom.size - sizeof(uuid);
5780 return AVERROR_INVALIDDATA;
5782 ret = avio_skip(pb, 4); // zeroes
5785 buffer = av_mallocz(len + 1);
5787 return AVERROR(ENOMEM);
5789 ret = avio_read(pb, buffer, len);
5793 } else if (ret != len) {
5795 return AVERROR_INVALIDDATA;
5799 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5800 ptr += sizeof("systemBitrate=\"") - 1;
5801 c->bitrates_count++;
5802 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5804 c->bitrates_count = 0;
5806 return AVERROR(ENOMEM);
5809 ret = strtol(ptr, &endptr, 10);
5810 if (ret < 0 || errno || *endptr != '"') {
5811 c->bitrates[c->bitrates_count - 1] = 0;
5813 c->bitrates[c->bitrates_count - 1] = ret;
5818 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5820 size_t len = atom.size - sizeof(uuid);
5821 if (c->export_xmp) {
5822 buffer = av_mallocz(len + 1);
5824 return AVERROR(ENOMEM);
5826 ret = avio_read(pb, buffer, len);
5830 } else if (ret != len) {
5832 return AVERROR_INVALIDDATA;
5835 av_dict_set(&c->fc->metadata, "xmp",
5836 buffer, AV_DICT_DONT_STRDUP_VAL);
5838 // skip all uuid atom, which makes it fast for long uuid-xmp file
5839 ret = avio_skip(pb, len);
5843 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5844 size_t len = atom.size - sizeof(uuid);
5845 ret = mov_parse_uuid_spherical(sc, pb, len);
5849 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5855 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5858 uint8_t content[16];
5863 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5869 && !memcmp(content, "Anevia\x1A\x1A", 8)
5870 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5871 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5877 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5879 uint32_t format = avio_rl32(pb);
5880 MOVStreamContext *sc;
5884 if (c->fc->nb_streams < 1)
5886 st = c->fc->streams[c->fc->nb_streams - 1];
5891 case MKTAG('e','n','c','v'): // encrypted video
5892 case MKTAG('e','n','c','a'): // encrypted audio
5893 id = mov_codec_id(st, format);
5894 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5895 st->codecpar->codec_id != id) {
5896 av_log(c->fc, AV_LOG_WARNING,
5897 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5898 (char*)&format, st->codecpar->codec_id);
5902 st->codecpar->codec_id = id;
5903 sc->format = format;
5907 if (format != sc->format) {
5908 av_log(c->fc, AV_LOG_WARNING,
5909 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5910 (char*)&format, (char*)&sc->format);
5919 * Gets the current encryption info and associated current stream context. If
5920 * we are parsing a track fragment, this will return the specific encryption
5921 * info for this fragment; otherwise this will return the global encryption
5922 * info for the current stream.
5924 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5926 MOVFragmentStreamInfo *frag_stream_info;
5930 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5931 if (frag_stream_info) {
5932 for (i = 0; i < c->fc->nb_streams; i++) {
5933 if (c->fc->streams[i]->id == frag_stream_info->id) {
5934 st = c->fc->streams[i];
5938 if (i == c->fc->nb_streams)
5940 *sc = st->priv_data;
5942 if (!frag_stream_info->encryption_index) {
5943 // If this stream isn't encrypted, don't create the index.
5944 if (!(*sc)->cenc.default_encrypted_sample)
5946 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5947 if (!frag_stream_info->encryption_index)
5948 return AVERROR(ENOMEM);
5950 *encryption_index = frag_stream_info->encryption_index;
5953 // No current track fragment, using stream level encryption info.
5955 if (c->fc->nb_streams < 1)
5957 st = c->fc->streams[c->fc->nb_streams - 1];
5958 *sc = st->priv_data;
5960 if (!(*sc)->cenc.encryption_index) {
5961 // If this stream isn't encrypted, don't create the index.
5962 if (!(*sc)->cenc.default_encrypted_sample)
5964 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5965 if (!(*sc)->cenc.encryption_index)
5966 return AVERROR(ENOMEM);
5969 *encryption_index = (*sc)->cenc.encryption_index;
5974 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
5977 unsigned int subsample_count;
5978 AVSubsampleEncryptionInfo *subsamples;
5980 if (!sc->cenc.default_encrypted_sample) {
5981 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
5982 return AVERROR_INVALIDDATA;
5985 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
5987 return AVERROR(ENOMEM);
5989 if (sc->cenc.per_sample_iv_size != 0) {
5990 if (avio_read(pb, (*sample)->iv, sc->cenc.per_sample_iv_size) != sc->cenc.per_sample_iv_size) {
5991 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
5992 av_encryption_info_free(*sample);
5994 return AVERROR_INVALIDDATA;
5998 if (use_subsamples) {
5999 subsample_count = avio_rb16(pb);
6000 av_free((*sample)->subsamples);
6001 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
6002 if (!(*sample)->subsamples) {
6003 av_encryption_info_free(*sample);
6005 return AVERROR(ENOMEM);
6008 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
6009 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
6010 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
6013 if (pb->eof_reached) {
6014 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
6015 av_encryption_info_free(*sample);
6017 return AVERROR_INVALIDDATA;
6019 (*sample)->subsample_count = subsample_count;
6025 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6027 AVEncryptionInfo **encrypted_samples;
6028 MOVEncryptionIndex *encryption_index;
6029 MOVStreamContext *sc;
6030 int use_subsamples, ret;
6031 unsigned int sample_count, i, alloc_size = 0;
6033 ret = get_current_encryption_info(c, &encryption_index, &sc);
6037 if (encryption_index->nb_encrypted_samples) {
6038 // This can happen if we have both saio/saiz and senc atoms.
6039 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6043 avio_r8(pb); /* version */
6044 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6046 sample_count = avio_rb32(pb);
6047 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6048 return AVERROR(ENOMEM);
6050 for (i = 0; i < sample_count; i++) {
6051 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6052 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6053 min_samples * sizeof(*encrypted_samples));
6054 if (encrypted_samples) {
6055 encryption_index->encrypted_samples = encrypted_samples;
6057 ret = mov_read_sample_encryption_info(
6058 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6060 ret = AVERROR(ENOMEM);
6062 if (pb->eof_reached) {
6063 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6064 ret = AVERROR_INVALIDDATA;
6069 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6070 av_freep(&encryption_index->encrypted_samples);
6074 encryption_index->nb_encrypted_samples = sample_count;
6079 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6081 AVEncryptionInfo **sample, **encrypted_samples;
6083 size_t sample_count, sample_info_size, i;
6085 unsigned int alloc_size = 0;
6087 if (encryption_index->nb_encrypted_samples)
6089 sample_count = encryption_index->auxiliary_info_sample_count;
6090 if (encryption_index->auxiliary_offsets_count != 1) {
6091 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6092 return AVERROR_PATCHWELCOME;
6094 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6095 return AVERROR(ENOMEM);
6097 prev_pos = avio_tell(pb);
6098 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6099 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6100 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6104 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6105 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6106 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6107 min_samples * sizeof(*encrypted_samples));
6108 if (!encrypted_samples) {
6109 ret = AVERROR(ENOMEM);
6112 encryption_index->encrypted_samples = encrypted_samples;
6114 sample = &encryption_index->encrypted_samples[i];
6115 sample_info_size = encryption_index->auxiliary_info_default_size
6116 ? encryption_index->auxiliary_info_default_size
6117 : encryption_index->auxiliary_info_sizes[i];
6119 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6123 if (pb->eof_reached) {
6124 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6125 ret = AVERROR_INVALIDDATA;
6127 encryption_index->nb_encrypted_samples = sample_count;
6131 avio_seek(pb, prev_pos, SEEK_SET);
6133 for (; i > 0; i--) {
6134 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6136 av_freep(&encryption_index->encrypted_samples);
6142 * Tries to read the given number of bytes from the stream and puts it in a
6143 * newly allocated buffer. This reads in small chunks to avoid allocating large
6144 * memory if the file contains an invalid/malicious size value.
6146 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6148 const unsigned int block_size = 1024 * 1024;
6149 uint8_t *buffer = NULL;
6150 unsigned int alloc_size = 0, offset = 0;
6151 while (offset < size) {
6152 unsigned int new_size =
6153 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6154 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6155 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6158 return AVERROR(ENOMEM);
6160 buffer = new_buffer;
6162 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6164 return AVERROR_INVALIDDATA;
6173 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6175 MOVEncryptionIndex *encryption_index;
6176 MOVStreamContext *sc;
6178 unsigned int sample_count, aux_info_type, aux_info_param;
6180 ret = get_current_encryption_info(c, &encryption_index, &sc);
6184 if (encryption_index->nb_encrypted_samples) {
6185 // This can happen if we have both saio/saiz and senc atoms.
6186 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6190 if (encryption_index->auxiliary_info_sample_count) {
6191 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6192 return AVERROR_INVALIDDATA;
6195 avio_r8(pb); /* version */
6196 if (avio_rb24(pb) & 0x01) { /* flags */
6197 aux_info_type = avio_rb32(pb);
6198 aux_info_param = avio_rb32(pb);
6199 if (sc->cenc.default_encrypted_sample) {
6200 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6201 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6204 if (aux_info_param != 0) {
6205 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6209 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6210 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6211 aux_info_type == MKBETAG('c','e','n','s') ||
6212 aux_info_type == MKBETAG('c','b','c','1') ||
6213 aux_info_type == MKBETAG('c','b','c','s')) &&
6214 aux_info_param == 0) {
6215 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6216 return AVERROR_INVALIDDATA;
6221 } else if (!sc->cenc.default_encrypted_sample) {
6222 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6226 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6227 sample_count = avio_rb32(pb);
6228 encryption_index->auxiliary_info_sample_count = sample_count;
6230 if (encryption_index->auxiliary_info_default_size == 0) {
6231 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6233 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6238 if (encryption_index->auxiliary_offsets_count) {
6239 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6245 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6247 uint64_t *auxiliary_offsets;
6248 MOVEncryptionIndex *encryption_index;
6249 MOVStreamContext *sc;
6251 unsigned int version, entry_count, aux_info_type, aux_info_param;
6252 unsigned int alloc_size = 0;
6254 ret = get_current_encryption_info(c, &encryption_index, &sc);
6258 if (encryption_index->nb_encrypted_samples) {
6259 // This can happen if we have both saio/saiz and senc atoms.
6260 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6264 if (encryption_index->auxiliary_offsets_count) {
6265 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6266 return AVERROR_INVALIDDATA;
6269 version = avio_r8(pb); /* version */
6270 if (avio_rb24(pb) & 0x01) { /* flags */
6271 aux_info_type = avio_rb32(pb);
6272 aux_info_param = avio_rb32(pb);
6273 if (sc->cenc.default_encrypted_sample) {
6274 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6275 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6278 if (aux_info_param != 0) {
6279 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6283 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6284 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6285 aux_info_type == MKBETAG('c','e','n','s') ||
6286 aux_info_type == MKBETAG('c','b','c','1') ||
6287 aux_info_type == MKBETAG('c','b','c','s')) &&
6288 aux_info_param == 0) {
6289 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6290 return AVERROR_INVALIDDATA;
6295 } else if (!sc->cenc.default_encrypted_sample) {
6296 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6300 entry_count = avio_rb32(pb);
6301 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6302 return AVERROR(ENOMEM);
6304 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6305 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6306 auxiliary_offsets = av_fast_realloc(
6307 encryption_index->auxiliary_offsets, &alloc_size,
6308 min_offsets * sizeof(*auxiliary_offsets));
6309 if (!auxiliary_offsets) {
6310 av_freep(&encryption_index->auxiliary_offsets);
6311 return AVERROR(ENOMEM);
6313 encryption_index->auxiliary_offsets = auxiliary_offsets;
6316 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6318 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6320 if (c->frag_index.current >= 0) {
6321 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6325 if (pb->eof_reached) {
6326 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6327 av_freep(&encryption_index->auxiliary_offsets);
6328 return AVERROR_INVALIDDATA;
6331 encryption_index->auxiliary_offsets_count = entry_count;
6333 if (encryption_index->auxiliary_info_sample_count) {
6334 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6340 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6342 AVEncryptionInitInfo *info, *old_init_info;
6345 uint8_t *side_data, *extra_data, *old_side_data;
6346 size_t side_data_size;
6347 int ret = 0, old_side_data_size;
6348 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6350 if (c->fc->nb_streams < 1)
6352 st = c->fc->streams[c->fc->nb_streams-1];
6354 version = avio_r8(pb); /* version */
6355 avio_rb24(pb); /* flags */
6357 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6358 /* key_id_size */ 16, /* data_size */ 0);
6360 return AVERROR(ENOMEM);
6362 if (avio_read(pb, info->system_id, 16) != 16) {
6363 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6364 ret = AVERROR_INVALIDDATA;
6369 kid_count = avio_rb32(pb);
6370 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
6371 ret = AVERROR(ENOMEM);
6375 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6376 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6377 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6378 min_kid_count * sizeof(*key_ids));
6380 ret = AVERROR(ENOMEM);
6383 info->key_ids = key_ids;
6385 info->key_ids[i] = av_mallocz(16);
6386 if (!info->key_ids[i]) {
6387 ret = AVERROR(ENOMEM);
6390 info->num_key_ids = i + 1;
6392 if (avio_read(pb, info->key_ids[i], 16) != 16) {
6393 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6394 ret = AVERROR_INVALIDDATA;
6399 if (pb->eof_reached) {
6400 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6401 ret = AVERROR_INVALIDDATA;
6406 extra_data_size = avio_rb32(pb);
6407 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6411 av_freep(&info->data); // malloc(0) may still allocate something.
6412 info->data = extra_data;
6413 info->data_size = extra_data_size;
6415 // If there is existing initialization data, append to the list.
6416 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6417 if (old_side_data) {
6418 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6419 if (old_init_info) {
6420 // Append to the end of the list.
6421 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6427 info = old_init_info;
6429 // Assume existing side-data will be valid, so the only error we could get is OOM.
6430 ret = AVERROR(ENOMEM);
6435 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6437 ret = AVERROR(ENOMEM);
6440 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6441 side_data, side_data_size);
6446 av_encryption_init_info_free(info);
6450 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6453 MOVStreamContext *sc;
6455 if (c->fc->nb_streams < 1)
6457 st = c->fc->streams[c->fc->nb_streams-1];
6460 if (sc->pseudo_stream_id != 0) {
6461 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6462 return AVERROR_PATCHWELCOME;
6466 return AVERROR_INVALIDDATA;
6468 avio_rb32(pb); /* version and flags */
6470 if (!sc->cenc.default_encrypted_sample) {
6471 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6472 if (!sc->cenc.default_encrypted_sample) {
6473 return AVERROR(ENOMEM);
6477 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6481 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6484 MOVStreamContext *sc;
6485 unsigned int version, pattern, is_protected, iv_size;
6487 if (c->fc->nb_streams < 1)
6489 st = c->fc->streams[c->fc->nb_streams-1];
6492 if (sc->pseudo_stream_id != 0) {
6493 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6494 return AVERROR_PATCHWELCOME;
6497 if (!sc->cenc.default_encrypted_sample) {
6498 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6499 if (!sc->cenc.default_encrypted_sample) {
6500 return AVERROR(ENOMEM);
6505 return AVERROR_INVALIDDATA;
6507 version = avio_r8(pb); /* version */
6508 avio_rb24(pb); /* flags */
6510 avio_r8(pb); /* reserved */
6511 pattern = avio_r8(pb);
6514 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6515 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6518 is_protected = avio_r8(pb);
6519 if (is_protected && !sc->cenc.encryption_index) {
6520 // The whole stream should be by-default encrypted.
6521 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6522 if (!sc->cenc.encryption_index)
6523 return AVERROR(ENOMEM);
6525 sc->cenc.per_sample_iv_size = avio_r8(pb);
6526 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6527 sc->cenc.per_sample_iv_size != 16) {
6528 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6529 return AVERROR_INVALIDDATA;
6531 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6532 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6533 return AVERROR_INVALIDDATA;
6536 if (is_protected && !sc->cenc.per_sample_iv_size) {
6537 iv_size = avio_r8(pb);
6538 if (iv_size != 8 && iv_size != 16) {
6539 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6540 return AVERROR_INVALIDDATA;
6543 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6544 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6545 return AVERROR_INVALIDDATA;
6552 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6555 int last, type, size, ret;
6558 if (c->fc->nb_streams < 1)
6560 st = c->fc->streams[c->fc->nb_streams-1];
6562 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6563 return AVERROR_INVALIDDATA;
6565 /* Check FlacSpecificBox version. */
6566 if (avio_r8(pb) != 0)
6567 return AVERROR_INVALIDDATA;
6569 avio_rb24(pb); /* Flags */
6571 avio_read(pb, buf, sizeof(buf));
6572 flac_parse_block_header(buf, &last, &type, &size);
6574 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6575 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6576 return AVERROR_INVALIDDATA;
6579 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6584 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6589 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6593 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6594 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6595 return AVERROR_PATCHWELCOME;
6598 if (!sc->cenc.aes_ctr) {
6599 /* initialize the cipher */
6600 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6601 if (!sc->cenc.aes_ctr) {
6602 return AVERROR(ENOMEM);
6605 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6611 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6613 if (!sample->subsample_count)
6615 /* decrypt the whole packet */
6616 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6620 for (i = 0; i < sample->subsample_count; i++)
6622 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6623 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6624 return AVERROR_INVALIDDATA;
6627 /* skip the clear bytes */
6628 input += sample->subsamples[i].bytes_of_clear_data;
6629 size -= sample->subsamples[i].bytes_of_clear_data;
6631 /* decrypt the encrypted bytes */
6632 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6633 input += sample->subsamples[i].bytes_of_protected_data;
6634 size -= sample->subsamples[i].bytes_of_protected_data;
6638 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6639 return AVERROR_INVALIDDATA;
6645 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6647 MOVFragmentStreamInfo *frag_stream_info;
6648 MOVEncryptionIndex *encryption_index;
6649 AVEncryptionInfo *encrypted_sample;
6650 int encrypted_index, ret;
6652 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6653 encrypted_index = current_index;
6654 encryption_index = NULL;
6655 if (frag_stream_info) {
6656 // Note this only supports encryption info in the first sample descriptor.
6657 if (mov->fragment.stsd_id == 1) {
6658 if (frag_stream_info->encryption_index) {
6659 encrypted_index = current_index - frag_stream_info->index_entry;
6660 encryption_index = frag_stream_info->encryption_index;
6662 encryption_index = sc->cenc.encryption_index;
6666 encryption_index = sc->cenc.encryption_index;
6669 if (encryption_index) {
6670 if (encryption_index->auxiliary_info_sample_count &&
6671 !encryption_index->nb_encrypted_samples) {
6672 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6673 return AVERROR_INVALIDDATA;
6675 if (encryption_index->auxiliary_offsets_count &&
6676 !encryption_index->nb_encrypted_samples) {
6677 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6678 return AVERROR_INVALIDDATA;
6681 if (!encryption_index->nb_encrypted_samples) {
6682 // Full-sample encryption with default settings.
6683 encrypted_sample = sc->cenc.default_encrypted_sample;
6684 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6685 // Per-sample setting override.
6686 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6688 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6689 return AVERROR_INVALIDDATA;
6692 if (mov->decryption_key) {
6693 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6696 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6698 return AVERROR(ENOMEM);
6699 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6709 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6711 const int OPUS_SEEK_PREROLL_MS = 80;
6717 if (c->fc->nb_streams < 1)
6719 st = c->fc->streams[c->fc->nb_streams-1];
6721 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6722 return AVERROR_INVALIDDATA;
6724 /* Check OpusSpecificBox version. */
6725 if (avio_r8(pb) != 0) {
6726 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6727 return AVERROR_INVALIDDATA;
6730 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6731 size = atom.size + 8;
6733 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
6736 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6737 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6738 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6739 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6741 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6742 little-endian; aside from the preceeding magic and version they're
6743 otherwise currently identical. Data after output gain at offset 16
6744 doesn't need to be bytewapped. */
6745 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6746 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6747 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6748 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6750 st->codecpar->initial_padding = pre_skip;
6751 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6752 (AVRational){1, 1000},
6753 (AVRational){1, 48000});
6758 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6761 unsigned format_info;
6762 int channel_assignment, channel_assignment1, channel_assignment2;
6765 if (c->fc->nb_streams < 1)
6767 st = c->fc->streams[c->fc->nb_streams-1];
6770 return AVERROR_INVALIDDATA;
6772 format_info = avio_rb32(pb);
6774 ratebits = (format_info >> 28) & 0xF;
6775 channel_assignment1 = (format_info >> 15) & 0x1F;
6776 channel_assignment2 = format_info & 0x1FFF;
6777 if (channel_assignment2)
6778 channel_assignment = channel_assignment2;
6780 channel_assignment = channel_assignment1;
6782 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6783 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6784 st->codecpar->channels = truehd_channels(channel_assignment);
6785 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6790 static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6794 AVDOVIDecoderConfigurationRecord *dovi;
6798 if (c->fc->nb_streams < 1)
6800 st = c->fc->streams[c->fc->nb_streams-1];
6802 if ((uint64_t)atom.size > (1<<30) || atom.size < 4)
6803 return AVERROR_INVALIDDATA;
6805 dovi = av_dovi_alloc(&dovi_size);
6807 return AVERROR(ENOMEM);
6809 dovi->dv_version_major = avio_r8(pb);
6810 dovi->dv_version_minor = avio_r8(pb);
6812 buf = avio_rb16(pb);
6813 dovi->dv_profile = (buf >> 9) & 0x7f; // 7 bits
6814 dovi->dv_level = (buf >> 3) & 0x3f; // 6 bits
6815 dovi->rpu_present_flag = (buf >> 2) & 0x01; // 1 bit
6816 dovi->el_present_flag = (buf >> 1) & 0x01; // 1 bit
6817 dovi->bl_present_flag = buf & 0x01; // 1 bit
6818 if (atom.size >= 24) { // 4 + 4 + 4 * 4
6820 dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits
6822 // 0 stands for None
6823 // Dolby Vision V1.2.93 profiles and levels
6824 dovi->dv_bl_signal_compatibility_id = 0;
6827 ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF,
6828 (uint8_t *)dovi, dovi_size);
6834 av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC box, version: %d.%d, profile: %d, level: %d, "
6835 "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n",
6836 dovi->dv_version_major, dovi->dv_version_minor,
6837 dovi->dv_profile, dovi->dv_level,
6838 dovi->rpu_present_flag,
6839 dovi->el_present_flag,
6840 dovi->bl_present_flag,
6841 dovi->dv_bl_signal_compatibility_id
6847 static const MOVParseTableEntry mov_default_parse_table[] = {
6848 { MKTAG('A','C','L','R'), mov_read_aclr },
6849 { MKTAG('A','P','R','G'), mov_read_avid },
6850 { MKTAG('A','A','L','P'), mov_read_avid },
6851 { MKTAG('A','R','E','S'), mov_read_ares },
6852 { MKTAG('a','v','s','s'), mov_read_avss },
6853 { MKTAG('a','v','1','C'), mov_read_av1c },
6854 { MKTAG('c','h','p','l'), mov_read_chpl },
6855 { MKTAG('c','o','6','4'), mov_read_stco },
6856 { MKTAG('c','o','l','r'), mov_read_colr },
6857 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6858 { MKTAG('d','i','n','f'), mov_read_default },
6859 { MKTAG('D','p','x','E'), mov_read_dpxe },
6860 { MKTAG('d','r','e','f'), mov_read_dref },
6861 { MKTAG('e','d','t','s'), mov_read_default },
6862 { MKTAG('e','l','s','t'), mov_read_elst },
6863 { MKTAG('e','n','d','a'), mov_read_enda },
6864 { MKTAG('f','i','e','l'), mov_read_fiel },
6865 { MKTAG('a','d','r','m'), mov_read_adrm },
6866 { MKTAG('f','t','y','p'), mov_read_ftyp },
6867 { MKTAG('g','l','b','l'), mov_read_glbl },
6868 { MKTAG('h','d','l','r'), mov_read_hdlr },
6869 { MKTAG('i','l','s','t'), mov_read_ilst },
6870 { MKTAG('j','p','2','h'), mov_read_jp2h },
6871 { MKTAG('m','d','a','t'), mov_read_mdat },
6872 { MKTAG('m','d','h','d'), mov_read_mdhd },
6873 { MKTAG('m','d','i','a'), mov_read_default },
6874 { MKTAG('m','e','t','a'), mov_read_meta },
6875 { MKTAG('m','i','n','f'), mov_read_default },
6876 { MKTAG('m','o','o','f'), mov_read_moof },
6877 { MKTAG('m','o','o','v'), mov_read_moov },
6878 { MKTAG('m','v','e','x'), mov_read_default },
6879 { MKTAG('m','v','h','d'), mov_read_mvhd },
6880 { MKTAG('S','M','I',' '), mov_read_svq3 },
6881 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6882 { MKTAG('a','v','c','C'), mov_read_glbl },
6883 { MKTAG('p','a','s','p'), mov_read_pasp },
6884 { MKTAG('s','i','d','x'), mov_read_sidx },
6885 { MKTAG('s','t','b','l'), mov_read_default },
6886 { MKTAG('s','t','c','o'), mov_read_stco },
6887 { MKTAG('s','t','p','s'), mov_read_stps },
6888 { MKTAG('s','t','r','f'), mov_read_strf },
6889 { MKTAG('s','t','s','c'), mov_read_stsc },
6890 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6891 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6892 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6893 { MKTAG('s','t','t','s'), mov_read_stts },
6894 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6895 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
6896 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6897 { MKTAG('t','f','d','t'), mov_read_tfdt },
6898 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6899 { MKTAG('t','r','a','k'), mov_read_trak },
6900 { MKTAG('t','r','a','f'), mov_read_default },
6901 { MKTAG('t','r','e','f'), mov_read_default },
6902 { MKTAG('t','m','c','d'), mov_read_tmcd },
6903 { MKTAG('c','h','a','p'), mov_read_chap },
6904 { MKTAG('t','r','e','x'), mov_read_trex },
6905 { MKTAG('t','r','u','n'), mov_read_trun },
6906 { MKTAG('u','d','t','a'), mov_read_default },
6907 { MKTAG('w','a','v','e'), mov_read_wave },
6908 { MKTAG('e','s','d','s'), mov_read_esds },
6909 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6910 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6911 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6912 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6913 { MKTAG('w','f','e','x'), mov_read_wfex },
6914 { MKTAG('c','m','o','v'), mov_read_cmov },
6915 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6916 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6917 { MKTAG('s','b','g','p'), mov_read_sbgp },
6918 { MKTAG('h','v','c','C'), mov_read_glbl },
6919 { MKTAG('u','u','i','d'), mov_read_uuid },
6920 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6921 { MKTAG('f','r','e','e'), mov_read_free },
6922 { MKTAG('-','-','-','-'), mov_read_custom },
6923 { MKTAG('s','i','n','f'), mov_read_default },
6924 { MKTAG('f','r','m','a'), mov_read_frma },
6925 { MKTAG('s','e','n','c'), mov_read_senc },
6926 { MKTAG('s','a','i','z'), mov_read_saiz },
6927 { MKTAG('s','a','i','o'), mov_read_saio },
6928 { MKTAG('p','s','s','h'), mov_read_pssh },
6929 { MKTAG('s','c','h','m'), mov_read_schm },
6930 { MKTAG('s','c','h','i'), mov_read_default },
6931 { MKTAG('t','e','n','c'), mov_read_tenc },
6932 { MKTAG('d','f','L','a'), mov_read_dfla },
6933 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6934 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6935 { MKTAG('d','O','p','s'), mov_read_dops },
6936 { MKTAG('d','m','l','p'), mov_read_dmlp },
6937 { MKTAG('S','m','D','m'), mov_read_smdm },
6938 { MKTAG('C','o','L','L'), mov_read_coll },
6939 { MKTAG('v','p','c','C'), mov_read_vpcc },
6940 { MKTAG('m','d','c','v'), mov_read_mdcv },
6941 { MKTAG('c','l','l','i'), mov_read_clli },
6942 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
6943 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
6947 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6949 int64_t total_size = 0;
6953 if (c->atom_depth > 10) {
6954 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6955 return AVERROR_INVALIDDATA;
6960 atom.size = INT64_MAX;
6961 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6962 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
6965 if (atom.size >= 8) {
6966 a.size = avio_rb32(pb);
6967 a.type = avio_rl32(pb);
6968 if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
6969 a.type == MKTAG('h','o','o','v')) &&
6971 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
6973 uint32_t *type = (uint32_t *)buf + 1;
6974 if (avio_read(pb, buf, 8) != 8)
6975 return AVERROR_INVALIDDATA;
6976 avio_seek(pb, -8, SEEK_CUR);
6977 if (*type == MKTAG('m','v','h','d') ||
6978 *type == MKTAG('c','m','o','v')) {
6979 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
6980 a.type = MKTAG('m','o','o','v');
6983 if (atom.type != MKTAG('r','o','o','t') &&
6984 atom.type != MKTAG('m','o','o','v'))
6986 if (a.type == MKTAG('t','r','a','k') || a.type == MKTAG('m','d','a','t'))
6988 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
6995 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
6996 a.size = avio_rb64(pb) - 8;
7000 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
7001 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
7003 a.size = atom.size - total_size + 8;
7008 a.size = FFMIN(a.size, atom.size - total_size);
7010 for (i = 0; mov_default_parse_table[i].type; i++)
7011 if (mov_default_parse_table[i].type == a.type) {
7012 parse = mov_default_parse_table[i].parse;
7016 // container is user data
7017 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
7018 atom.type == MKTAG('i','l','s','t')))
7019 parse = mov_read_udta_string;
7021 // Supports parsing the QuickTime Metadata Keys.
7022 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
7023 if (!parse && c->found_hdlr_mdta &&
7024 atom.type == MKTAG('m','e','t','a') &&
7025 a.type == MKTAG('k','e','y','s') &&
7026 c->meta_keys_count == 0) {
7027 parse = mov_read_keys;
7030 if (!parse) { /* skip leaf atoms data */
7031 avio_skip(pb, a.size);
7033 int64_t start_pos = avio_tell(pb);
7035 int err = parse(c, pb, a);
7040 if (c->found_moov && c->found_mdat &&
7041 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
7042 start_pos + a.size == avio_size(pb))) {
7043 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
7044 c->next_root_atom = start_pos + a.size;
7048 left = a.size - avio_tell(pb) + start_pos;
7049 if (left > 0) /* skip garbage at atom end */
7050 avio_skip(pb, left);
7051 else if (left < 0) {
7052 av_log(c->fc, AV_LOG_WARNING,
7053 "overread end of atom '%.4s' by %"PRId64" bytes\n",
7054 (char*)&a.type, -left);
7055 avio_seek(pb, left, SEEK_CUR);
7059 total_size += a.size;
7062 if (total_size < atom.size && atom.size < 0x7ffff)
7063 avio_skip(pb, atom.size - total_size);
7069 static int mov_probe(const AVProbeData *p)
7074 int moov_offset = -1;
7076 /* check file header */
7079 /* ignore invalid offset */
7080 if ((offset + 8) > (unsigned int)p->buf_size)
7082 tag = AV_RL32(p->buf + offset + 4);
7084 /* check for obvious tags */
7085 case MKTAG('m','o','o','v'):
7086 moov_offset = offset + 4;
7087 case MKTAG('m','d','a','t'):
7088 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
7089 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
7090 case MKTAG('f','t','y','p'):
7091 if (AV_RB32(p->buf+offset) < 8 &&
7092 (AV_RB32(p->buf+offset) != 1 ||
7093 offset + 12 > (unsigned int)p->buf_size ||
7094 AV_RB64(p->buf+offset + 8) == 0)) {
7095 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7096 } else if (tag == MKTAG('f','t','y','p') &&
7097 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
7098 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
7100 score = FFMAX(score, 5);
7102 score = AVPROBE_SCORE_MAX;
7104 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7106 /* those are more common words, so rate then a bit less */
7107 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
7108 case MKTAG('w','i','d','e'):
7109 case MKTAG('f','r','e','e'):
7110 case MKTAG('j','u','n','k'):
7111 case MKTAG('p','i','c','t'):
7112 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
7113 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7115 case MKTAG(0x82,0x82,0x7f,0x7d):
7116 case MKTAG('s','k','i','p'):
7117 case MKTAG('u','u','i','d'):
7118 case MKTAG('p','r','f','l'):
7119 /* if we only find those cause probedata is too small at least rate them */
7120 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7121 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7124 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7127 if(score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
7128 /* moov atom in the header - we should make sure that this is not a
7129 * MOV-packed MPEG-PS */
7130 offset = moov_offset;
7132 while(offset < (p->buf_size - 16)){ /* Sufficient space */
7133 /* We found an actual hdlr atom */
7134 if(AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7135 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7136 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')){
7137 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7138 /* We found a media handler reference atom describing an
7139 * MPEG-PS-in-MOV, return a
7140 * low score to force expanding the probe window until
7141 * mpegps_probe finds what it needs */
7152 // must be done after parsing all trak because there's no order requirement
7153 static void mov_read_chapters(AVFormatContext *s)
7155 MOVContext *mov = s->priv_data;
7157 MOVStreamContext *sc;
7162 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7163 chapter_track = mov->chapter_tracks[j];
7165 for (i = 0; i < s->nb_streams; i++)
7166 if (s->streams[i]->id == chapter_track) {
7171 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7176 cur_pos = avio_tell(sc->pb);
7178 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7179 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7180 if (st->nb_index_entries) {
7181 // Retrieve the first frame, if possible
7182 AVIndexEntry *sample = &st->index_entries[0];
7183 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7184 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7188 if (av_get_packet(sc->pb, &st->attached_pic, sample->size) < 0)
7191 st->attached_pic.stream_index = st->index;
7192 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
7195 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7196 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7197 st->discard = AVDISCARD_ALL;
7198 for (i = 0; i < st->nb_index_entries; i++) {
7199 AVIndexEntry *sample = &st->index_entries[i];
7200 int64_t end = i+1 < st->nb_index_entries ? st->index_entries[i+1].timestamp : st->duration;
7205 if (end < sample->timestamp) {
7206 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7207 end = AV_NOPTS_VALUE;
7210 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7211 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7215 // the first two bytes are the length of the title
7216 len = avio_rb16(sc->pb);
7217 if (len > sample->size-2)
7219 title_len = 2*len + 1;
7220 if (!(title = av_mallocz(title_len)))
7223 // The samples could theoretically be in any encoding if there's an encd
7224 // atom following, but in practice are only utf-8 or utf-16, distinguished
7225 // instead by the presence of a BOM
7229 ch = avio_rb16(sc->pb);
7231 avio_get_str16be(sc->pb, len, title, title_len);
7232 else if (ch == 0xfffe)
7233 avio_get_str16le(sc->pb, len, title, title_len);
7236 if (len == 1 || len == 2)
7239 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7243 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7248 avio_seek(sc->pb, cur_pos, SEEK_SET);
7252 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7253 uint32_t value, int flags)
7256 char buf[AV_TIMECODE_STR_SIZE];
7257 AVRational rate = st->avg_frame_rate;
7258 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7261 av_dict_set(&st->metadata, "timecode",
7262 av_timecode_make_string(&tc, buf, value), 0);
7266 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7268 MOVStreamContext *sc = st->priv_data;
7269 char buf[AV_TIMECODE_STR_SIZE];
7270 int64_t cur_pos = avio_tell(sc->pb);
7271 int hh, mm, ss, ff, drop;
7273 if (!st->nb_index_entries)
7276 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7277 avio_skip(s->pb, 13);
7278 hh = avio_r8(s->pb);
7279 mm = avio_r8(s->pb);
7280 ss = avio_r8(s->pb);
7281 drop = avio_r8(s->pb);
7282 ff = avio_r8(s->pb);
7283 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7284 hh, mm, ss, drop ? ';' : ':', ff);
7285 av_dict_set(&st->metadata, "timecode", buf, 0);
7287 avio_seek(sc->pb, cur_pos, SEEK_SET);
7291 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7293 MOVStreamContext *sc = st->priv_data;
7295 int64_t cur_pos = avio_tell(sc->pb);
7298 if (!st->nb_index_entries)
7301 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7302 value = avio_rb32(s->pb);
7304 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7305 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7306 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7308 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7309 * not the case) and thus assume "frame number format" instead of QT one.
7310 * No sample with tmcd track can be found with a QT timecode at the moment,
7311 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7313 parse_timecode_in_framenum_format(s, st, value, flags);
7315 avio_seek(sc->pb, cur_pos, SEEK_SET);
7319 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7321 if (!index || !*index) return;
7322 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7323 av_encryption_info_free((*index)->encrypted_samples[i]);
7325 av_freep(&(*index)->encrypted_samples);
7326 av_freep(&(*index)->auxiliary_info_sizes);
7327 av_freep(&(*index)->auxiliary_offsets);
7331 static int mov_read_close(AVFormatContext *s)
7333 MOVContext *mov = s->priv_data;
7336 for (i = 0; i < s->nb_streams; i++) {
7337 AVStream *st = s->streams[i];
7338 MOVStreamContext *sc = st->priv_data;
7343 av_freep(&sc->ctts_data);
7344 for (j = 0; j < sc->drefs_count; j++) {
7345 av_freep(&sc->drefs[j].path);
7346 av_freep(&sc->drefs[j].dir);
7348 av_freep(&sc->drefs);
7350 sc->drefs_count = 0;
7352 if (!sc->pb_is_copied)
7353 ff_format_io_close(s, &sc->pb);
7356 av_freep(&sc->chunk_offsets);
7357 av_freep(&sc->stsc_data);
7358 av_freep(&sc->sample_sizes);
7359 av_freep(&sc->keyframes);
7360 av_freep(&sc->stts_data);
7361 av_freep(&sc->sdtp_data);
7362 av_freep(&sc->stps_data);
7363 av_freep(&sc->elst_data);
7364 av_freep(&sc->rap_group);
7365 av_freep(&sc->display_matrix);
7366 av_freep(&sc->index_ranges);
7369 for (j = 0; j < sc->stsd_count; j++)
7370 av_free(sc->extradata[j]);
7371 av_freep(&sc->extradata);
7372 av_freep(&sc->extradata_size);
7374 mov_free_encryption_index(&sc->cenc.encryption_index);
7375 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7376 av_aes_ctr_free(sc->cenc.aes_ctr);
7378 av_freep(&sc->stereo3d);
7379 av_freep(&sc->spherical);
7380 av_freep(&sc->mastering);
7381 av_freep(&sc->coll);
7384 if (mov->dv_demux) {
7385 avformat_free_context(mov->dv_fctx);
7386 mov->dv_fctx = NULL;
7389 if (mov->meta_keys) {
7390 for (i = 1; i < mov->meta_keys_count; i++) {
7391 av_freep(&mov->meta_keys[i]);
7393 av_freep(&mov->meta_keys);
7396 av_freep(&mov->trex_data);
7397 av_freep(&mov->bitrates);
7399 for (i = 0; i < mov->frag_index.nb_items; i++) {
7400 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7401 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7402 mov_free_encryption_index(&frag[j].encryption_index);
7404 av_freep(&mov->frag_index.item[i].stream_info);
7406 av_freep(&mov->frag_index.item);
7408 av_freep(&mov->aes_decrypt);
7409 av_freep(&mov->chapter_tracks);
7414 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7418 for (i = 0; i < s->nb_streams; i++) {
7419 AVStream *st = s->streams[i];
7420 MOVStreamContext *sc = st->priv_data;
7422 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7423 sc->timecode_track == tmcd_id)
7429 /* look for a tmcd track not referenced by any video track, and export it globally */
7430 static void export_orphan_timecode(AVFormatContext *s)
7434 for (i = 0; i < s->nb_streams; i++) {
7435 AVStream *st = s->streams[i];
7437 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7438 !tmcd_is_referenced(s, i + 1)) {
7439 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7441 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7448 static int read_tfra(MOVContext *mov, AVIOContext *f)
7450 int version, fieldlength, i, j;
7451 int64_t pos = avio_tell(f);
7452 uint32_t size = avio_rb32(f);
7453 unsigned track_id, item_count;
7455 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7458 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7460 version = avio_r8(f);
7462 track_id = avio_rb32(f);
7463 fieldlength = avio_rb32(f);
7464 item_count = avio_rb32(f);
7465 for (i = 0; i < item_count; i++) {
7466 int64_t time, offset;
7468 MOVFragmentStreamInfo * frag_stream_info;
7471 return AVERROR_INVALIDDATA;
7475 time = avio_rb64(f);
7476 offset = avio_rb64(f);
7478 time = avio_rb32(f);
7479 offset = avio_rb32(f);
7482 // The first sample of each stream in a fragment is always a random
7483 // access sample. So it's entry in the tfra can be used as the
7484 // initial PTS of the fragment.
7485 index = update_frag_index(mov, offset);
7486 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7487 if (frag_stream_info &&
7488 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7489 frag_stream_info->first_tfra_pts = time;
7491 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7493 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7495 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7499 avio_seek(f, pos + size, SEEK_SET);
7503 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7505 int64_t stream_size = avio_size(f);
7506 int64_t original_pos = avio_tell(f);
7510 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7514 mfra_size = avio_rb32(f);
7515 if (mfra_size < 0 || mfra_size > stream_size) {
7516 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7519 if ((seek_ret = avio_seek(f, -mfra_size, SEEK_CUR)) < 0) {
7523 if (avio_rb32(f) != mfra_size) {
7524 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7527 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7528 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7531 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7533 ret = read_tfra(c, f);
7539 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7541 av_log(c->fc, AV_LOG_ERROR,
7542 "failed to seek back after looking for mfra\n");
7548 static int mov_read_header(AVFormatContext *s)
7550 MOVContext *mov = s->priv_data;
7551 AVIOContext *pb = s->pb;
7553 MOVAtom atom = { AV_RL32("root") };
7556 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7557 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7558 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7559 return AVERROR(EINVAL);
7563 mov->trak_index = -1;
7564 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7565 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7566 atom.size = avio_size(pb);
7568 atom.size = INT64_MAX;
7570 /* check MOV header */
7572 if (mov->moov_retry)
7573 avio_seek(pb, 0, SEEK_SET);
7574 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7575 av_log(s, AV_LOG_ERROR, "error reading header\n");
7578 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7579 if (!mov->found_moov) {
7580 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7581 err = AVERROR_INVALIDDATA;
7584 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7586 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7587 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7588 mov_read_chapters(s);
7589 for (i = 0; i < s->nb_streams; i++)
7590 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7591 mov_read_timecode_track(s, s->streams[i]);
7592 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7593 mov_read_rtmd_track(s, s->streams[i]);
7597 /* copy timecode metadata from tmcd tracks to the related video streams */
7598 for (i = 0; i < s->nb_streams; i++) {
7599 AVStream *st = s->streams[i];
7600 MOVStreamContext *sc = st->priv_data;
7601 if (sc->timecode_track > 0) {
7602 AVDictionaryEntry *tcr;
7603 int tmcd_st_id = -1;
7605 for (j = 0; j < s->nb_streams; j++)
7606 if (s->streams[j]->id == sc->timecode_track)
7609 if (tmcd_st_id < 0 || tmcd_st_id == i)
7611 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7613 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7616 export_orphan_timecode(s);
7618 for (i = 0; i < s->nb_streams; i++) {
7619 AVStream *st = s->streams[i];
7620 MOVStreamContext *sc = st->priv_data;
7621 fix_timescale(mov, sc);
7622 if(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7623 st->skip_samples = sc->start_pad;
7625 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7626 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7627 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7628 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7629 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7630 st->codecpar->width = sc->width;
7631 st->codecpar->height = sc->height;
7633 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7634 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7638 if (mov->handbrake_version &&
7639 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7640 st->codecpar->codec_id == AV_CODEC_ID_MP3
7642 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7643 st->need_parsing = AVSTREAM_PARSE_FULL;
7647 if (mov->trex_data) {
7648 for (i = 0; i < s->nb_streams; i++) {
7649 AVStream *st = s->streams[i];
7650 MOVStreamContext *sc = st->priv_data;
7651 if (st->duration > 0) {
7652 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7653 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7654 sc->data_size, sc->time_scale);
7655 err = AVERROR_INVALIDDATA;
7658 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7663 if (mov->use_mfra_for > 0) {
7664 for (i = 0; i < s->nb_streams; i++) {
7665 AVStream *st = s->streams[i];
7666 MOVStreamContext *sc = st->priv_data;
7667 if (sc->duration_for_fps > 0) {
7668 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7669 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7670 sc->data_size, sc->time_scale);
7671 err = AVERROR_INVALIDDATA;
7674 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7675 sc->duration_for_fps;
7680 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7681 if (mov->bitrates[i]) {
7682 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7686 ff_rfps_calculate(s);
7688 for (i = 0; i < s->nb_streams; i++) {
7689 AVStream *st = s->streams[i];
7690 MOVStreamContext *sc = st->priv_data;
7692 switch (st->codecpar->codec_type) {
7693 case AVMEDIA_TYPE_AUDIO:
7694 err = ff_replaygain_export(st, s->metadata);
7699 case AVMEDIA_TYPE_VIDEO:
7700 if (sc->display_matrix) {
7701 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7702 sizeof(int32_t) * 9);
7706 sc->display_matrix = NULL;
7709 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7710 (uint8_t *)sc->stereo3d,
7711 sizeof(*sc->stereo3d));
7715 sc->stereo3d = NULL;
7717 if (sc->spherical) {
7718 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7719 (uint8_t *)sc->spherical,
7720 sc->spherical_size);
7724 sc->spherical = NULL;
7726 if (sc->mastering) {
7727 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7728 (uint8_t *)sc->mastering,
7729 sizeof(*sc->mastering));
7733 sc->mastering = NULL;
7736 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7737 (uint8_t *)sc->coll,
7747 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7749 for (i = 0; i < mov->frag_index.nb_items; i++)
7750 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7751 mov->frag_index.item[i].headers_read = 1;
7759 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7761 AVIndexEntry *sample = NULL;
7762 int64_t best_dts = INT64_MAX;
7764 for (i = 0; i < s->nb_streams; i++) {
7765 AVStream *avst = s->streams[i];
7766 MOVStreamContext *msc = avst->priv_data;
7767 if (msc->pb && msc->current_sample < avst->nb_index_entries) {
7768 AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample];
7769 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7770 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7771 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7772 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7773 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
7774 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7775 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7776 sample = current_sample;
7785 static int should_retry(AVIOContext *pb, int error_code) {
7786 if (error_code == AVERROR_EOF || avio_feof(pb))
7792 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7795 MOVContext *mov = s->priv_data;
7797 if (index >= 0 && index < mov->frag_index.nb_items)
7798 target = mov->frag_index.item[index].moof_offset;
7799 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7800 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7801 return AVERROR_INVALIDDATA;
7804 mov->next_root_atom = 0;
7805 if (index < 0 || index >= mov->frag_index.nb_items)
7806 index = search_frag_moof_offset(&mov->frag_index, target);
7807 if (index < mov->frag_index.nb_items &&
7808 mov->frag_index.item[index].moof_offset == target) {
7809 if (index + 1 < mov->frag_index.nb_items)
7810 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7811 if (mov->frag_index.item[index].headers_read)
7813 mov->frag_index.item[index].headers_read = 1;
7816 mov->found_mdat = 0;
7818 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7821 if (avio_feof(s->pb))
7823 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7828 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7830 uint8_t *side, *extradata;
7833 /* Save the current index. */
7834 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7836 /* Notify the decoder that extradata changed. */
7837 extradata_size = sc->extradata_size[sc->last_stsd_index];
7838 extradata = sc->extradata[sc->last_stsd_index];
7839 if (extradata_size > 0 && extradata) {
7840 side = av_packet_new_side_data(pkt,
7841 AV_PKT_DATA_NEW_EXTRADATA,
7844 return AVERROR(ENOMEM);
7845 memcpy(side, extradata, extradata_size);
7851 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int size)
7856 return AVERROR_INVALIDDATA;
7857 new_size = ((size - 8) / 2) * 3;
7858 ret = av_new_packet(pkt, new_size);
7863 for (int j = 0; j < new_size; j += 3) {
7864 pkt->data[j] = 0xFC;
7865 pkt->data[j+1] = avio_r8(pb);
7866 pkt->data[j+2] = avio_r8(pb);
7872 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7874 MOVContext *mov = s->priv_data;
7875 MOVStreamContext *sc;
7876 AVIndexEntry *sample;
7877 AVStream *st = NULL;
7878 int64_t current_index;
7882 sample = mov_find_next_sample(s, &st);
7883 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7884 if (!mov->next_root_atom)
7886 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7891 /* must be done just before reading, to avoid infinite loop on sample */
7892 current_index = sc->current_index;
7893 mov_current_sample_inc(sc);
7895 if (mov->next_root_atom) {
7896 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7897 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7900 if (st->discard != AVDISCARD_ALL) {
7901 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7902 if (ret64 != sample->pos) {
7903 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7904 sc->ffindex, sample->pos);
7905 if (should_retry(sc->pb, ret64)) {
7906 mov_current_sample_dec(sc);
7908 return AVERROR_INVALIDDATA;
7911 if( st->discard == AVDISCARD_NONKEY && 0==(sample->flags & AVINDEX_KEYFRAME) ) {
7912 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7916 if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
7917 ret = get_eia608_packet(sc->pb, pkt, sample->size);
7919 ret = av_get_packet(sc->pb, pkt, sample->size);
7921 if (should_retry(sc->pb, ret)) {
7922 mov_current_sample_dec(sc);
7926 if (sc->has_palette) {
7929 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7931 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7933 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7934 sc->has_palette = 0;
7937 #if CONFIG_DV_DEMUXER
7938 if (mov->dv_demux && sc->dv_audio_container) {
7939 avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7940 av_freep(&pkt->data);
7942 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7947 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7948 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7949 st->need_parsing = AVSTREAM_PARSE_FULL;
7953 pkt->stream_index = sc->ffindex;
7954 pkt->dts = sample->timestamp;
7955 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7956 pkt->flags |= AV_PKT_FLAG_DISCARD;
7958 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7959 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
7960 /* update ctts context */
7962 if (sc->ctts_index < sc->ctts_count &&
7963 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
7965 sc->ctts_sample = 0;
7968 int64_t next_dts = (sc->current_sample < st->nb_index_entries) ?
7969 st->index_entries[sc->current_sample].timestamp : st->duration;
7971 if (next_dts >= pkt->dts)
7972 pkt->duration = next_dts - pkt->dts;
7973 pkt->pts = pkt->dts;
7975 if (st->discard == AVDISCARD_ALL)
7977 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
7978 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
7979 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
7980 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
7982 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
7983 pkt->pos = sample->pos;
7985 /* Multiple stsd handling. */
7986 if (sc->stsc_data) {
7987 /* Keep track of the stsc index for the given sample, then check
7988 * if the stsd index is different from the last used one. */
7990 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
7991 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
7993 sc->stsc_sample = 0;
7994 /* Do not check indexes after a switch. */
7995 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
7996 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
7997 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
7998 ret = mov_change_extradata(sc, pkt);
8005 aax_filter(pkt->data, pkt->size, mov);
8007 ret = cenc_filter(mov, st, sc, pkt, current_index);
8015 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
8017 MOVContext *mov = s->priv_data;
8020 if (!mov->frag_index.complete)
8023 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
8026 if (!mov->frag_index.item[index].headers_read)
8027 return mov_switch_root(s, -1, index);
8028 if (index + 1 < mov->frag_index.nb_items)
8029 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
8034 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
8036 MOVStreamContext *sc = st->priv_data;
8037 int sample, time_sample, ret;
8040 // Here we consider timestamp to be PTS, hence try to offset it so that we
8041 // can search over the DTS timeline.
8042 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
8044 ret = mov_seek_fragment(s, st, timestamp);
8048 sample = av_index_search_timestamp(st, timestamp, flags);
8049 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
8050 if (sample < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp)
8052 if (sample < 0) /* not sure what to do */
8053 return AVERROR_INVALIDDATA;
8054 mov_current_sample_set(sc, sample);
8055 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
8056 /* adjust ctts index */
8057 if (sc->ctts_data) {
8059 for (i = 0; i < sc->ctts_count; i++) {
8060 int next = time_sample + sc->ctts_data[i].count;
8061 if (next > sc->current_sample) {
8063 sc->ctts_sample = sc->current_sample - time_sample;
8070 /* adjust stsd index */
8071 if (sc->chunk_count) {
8073 for (i = 0; i < sc->stsc_count; i++) {
8074 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
8075 if (next > sc->current_sample) {
8077 sc->stsc_sample = sc->current_sample - time_sample;
8080 av_assert0(next == (int)next);
8088 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
8090 MOVContext *mc = s->priv_data;
8095 if (stream_index >= s->nb_streams)
8096 return AVERROR_INVALIDDATA;
8098 st = s->streams[stream_index];
8099 sample = mov_seek_stream(s, st, sample_time, flags);
8103 if (mc->seek_individually) {
8104 /* adjust seek timestamp to found sample timestamp */
8105 int64_t seek_timestamp = st->index_entries[sample].timestamp;
8107 for (i = 0; i < s->nb_streams; i++) {
8109 MOVStreamContext *sc = s->streams[i]->priv_data;
8111 st->skip_samples = (sample_time <= 0) ? sc->start_pad : 0;
8113 if (stream_index == i)
8116 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
8117 mov_seek_stream(s, st, timestamp, flags);
8120 for (i = 0; i < s->nb_streams; i++) {
8121 MOVStreamContext *sc;
8124 mov_current_sample_set(sc, 0);
8127 MOVStreamContext *sc;
8128 AVIndexEntry *entry = mov_find_next_sample(s, &st);
8130 return AVERROR_INVALIDDATA;
8132 if (sc->ffindex == stream_index && sc->current_sample == sample)
8134 mov_current_sample_inc(sc);
8140 #define OFFSET(x) offsetof(MOVContext, x)
8141 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
8142 static const AVOption mov_options[] = {
8143 {"use_absolute_path",
8144 "allow using absolute path when opening alias, this is a possible security issue",
8145 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
8147 {"seek_streams_individually",
8148 "Seek each stream individually to the closest point",
8149 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
8151 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
8153 {"advanced_editlist",
8154 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
8155 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
8157 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8160 "use mfra for fragment timestamps",
8161 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8162 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8164 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8165 FLAGS, "use_mfra_for" },
8166 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8167 FLAGS, "use_mfra_for" },
8168 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8169 FLAGS, "use_mfra_for" },
8170 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8171 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8172 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8173 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8174 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8175 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8176 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8177 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8178 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8179 .flags = AV_OPT_FLAG_DECODING_PARAM },
8180 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8181 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8182 {.i64 = 0}, 0, 1, FLAGS },
8187 static const AVClass mov_class = {
8188 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8189 .item_name = av_default_item_name,
8190 .option = mov_options,
8191 .version = LIBAVUTIL_VERSION_INT,
8194 AVInputFormat ff_mov_demuxer = {
8195 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8196 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8197 .priv_class = &mov_class,
8198 .priv_data_size = sizeof(MOVContext),
8199 .extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
8200 .read_probe = mov_probe,
8201 .read_header = mov_read_header,
8202 .read_packet = mov_read_packet,
8203 .read_close = mov_read_close,
8204 .read_seek = mov_read_seek,
8205 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,