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 if (n_hmmt > len / 4)
292 return AVERROR_INVALIDDATA;
293 for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
294 int moment_time = avio_rb32(pb);
295 avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
300 static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
302 char tmp_key[AV_FOURCC_MAX_STRING_SIZE] = {0};
303 char key2[32], language[4] = {0};
305 const char *key = NULL;
306 uint16_t langcode = 0;
307 uint32_t data_type = 0, str_size, str_size_alloc;
308 int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
313 case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
314 case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
315 case MKTAG( 'X','M','P','_'):
316 if (c->export_xmp) { key = "xmp"; raw = 1; } break;
317 case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
318 case MKTAG( 'a','k','I','D'): key = "account_type";
319 parse = mov_metadata_int8_no_padding; break;
320 case MKTAG( 'a','p','I','D'): key = "account_id"; break;
321 case MKTAG( 'c','a','t','g'): key = "category"; break;
322 case MKTAG( 'c','p','i','l'): key = "compilation";
323 parse = mov_metadata_int8_no_padding; break;
324 case MKTAG( 'c','p','r','t'): key = "copyright"; break;
325 case MKTAG( 'd','e','s','c'): key = "description"; break;
326 case MKTAG( 'd','i','s','k'): key = "disc";
327 parse = mov_metadata_track_or_disc_number; break;
328 case MKTAG( 'e','g','i','d'): key = "episode_uid";
329 parse = mov_metadata_int8_no_padding; break;
330 case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
331 case MKTAG( 'g','n','r','e'): key = "genre";
332 parse = mov_metadata_gnre; break;
333 case MKTAG( 'h','d','v','d'): key = "hd_video";
334 parse = mov_metadata_int8_no_padding; break;
335 case MKTAG( 'H','M','M','T'):
336 return mov_metadata_hmmt(c, pb, atom.size);
337 case MKTAG( 'k','e','y','w'): key = "keywords"; break;
338 case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
339 case MKTAG( 'l','o','c','i'):
340 return mov_metadata_loci(c, pb, atom.size);
341 case MKTAG( 'm','a','n','u'): key = "make"; break;
342 case MKTAG( 'm','o','d','l'): key = "model"; break;
343 case MKTAG( 'p','c','s','t'): key = "podcast";
344 parse = mov_metadata_int8_no_padding; break;
345 case MKTAG( 'p','g','a','p'): key = "gapless_playback";
346 parse = mov_metadata_int8_no_padding; break;
347 case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
348 case MKTAG( 'r','t','n','g'): key = "rating";
349 parse = mov_metadata_int8_no_padding; break;
350 case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
351 case MKTAG( 's','o','a','l'): key = "sort_album"; break;
352 case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
353 case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
354 case MKTAG( 's','o','n','m'): key = "sort_name"; break;
355 case MKTAG( 's','o','s','n'): key = "sort_show"; break;
356 case MKTAG( 's','t','i','k'): key = "media_type";
357 parse = mov_metadata_int8_no_padding; break;
358 case MKTAG( 't','r','k','n'): key = "track";
359 parse = mov_metadata_track_or_disc_number; break;
360 case MKTAG( 't','v','e','n'): key = "episode_id"; break;
361 case MKTAG( 't','v','e','s'): key = "episode_sort";
362 parse = mov_metadata_int8_bypass_padding; break;
363 case MKTAG( 't','v','n','n'): key = "network"; break;
364 case MKTAG( 't','v','s','h'): key = "show"; break;
365 case MKTAG( 't','v','s','n'): key = "season_number";
366 parse = mov_metadata_int8_bypass_padding; break;
367 case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
368 case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
369 case MKTAG(0xa9,'a','l','b'): key = "album"; break;
370 case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
371 case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
372 case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
373 case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
374 case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
375 case MKTAG(0xa9,'d','a','y'): key = "date"; break;
376 case MKTAG(0xa9,'d','i','r'): key = "director"; break;
377 case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
378 case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
379 case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
380 case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
381 case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
382 case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
383 case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
384 case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
385 case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
386 case MKTAG(0xa9,'m','a','k'): key = "make"; break;
387 case MKTAG(0xa9,'m','o','d'): key = "model"; break;
388 case MKTAG(0xa9,'n','a','m'): key = "title"; break;
389 case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
390 case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
391 case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
392 case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
393 case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
394 case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
395 case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
396 case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
397 case MKTAG(0xa9,'t','r','k'): key = "track"; break;
398 case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
399 case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
400 case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
401 case MKTAG(0xa9,'x','y','z'): key = "location"; break;
404 if (c->itunes_metadata && atom.size > 8) {
405 int data_size = avio_rb32(pb);
406 int tag = avio_rl32(pb);
407 if (tag == MKTAG('d','a','t','a') && data_size <= atom.size && data_size >= 16) {
408 data_type = avio_rb32(pb); // type
409 avio_rb32(pb); // unknown
410 str_size = data_size - 16;
413 if (atom.type == MKTAG('c', 'o', 'v', 'r')) {
414 int ret = mov_read_covr(c, pb, data_type, str_size);
416 av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
419 atom.size -= str_size;
423 } else if (!key && c->found_hdlr_mdta && c->meta_keys) {
424 uint32_t index = AV_RB32(&atom.type);
425 if (index < c->meta_keys_count && index > 0) {
426 key = c->meta_keys[index];
428 av_log(c->fc, AV_LOG_WARNING,
429 "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
430 index, c->meta_keys_count);
434 } else if (atom.size > 4 && key && !c->itunes_metadata && !raw) {
435 str_size = avio_rb16(pb); // string length
436 if (str_size > atom.size) {
438 avio_seek(pb, -2, SEEK_CUR);
439 av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
442 langcode = avio_rb16(pb);
443 ff_mov_lang_to_iso639(langcode, language);
446 str_size = atom.size;
448 if (c->export_all && !key) {
449 key = av_fourcc_make_string(tmp_key, atom.type);
454 if (atom.size < 0 || str_size >= INT_MAX/2)
455 return AVERROR_INVALIDDATA;
457 // Allocates enough space if data_type is a int32 or float32 number, otherwise
458 // worst-case requirement for output string in case of utf8 coded input
459 num = (data_type >= 21 && data_type <= 23);
460 str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
461 str = av_mallocz(str_size_alloc);
463 return AVERROR(ENOMEM);
466 parse(c, pb, str_size, key);
468 if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
469 mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
470 } else if (data_type == 21) { // BE signed integer, variable size
473 val = (int8_t)avio_r8(pb);
474 else if (str_size == 2)
475 val = (int16_t)avio_rb16(pb);
476 else if (str_size == 3)
477 val = ((int32_t)(avio_rb24(pb)<<8))>>8;
478 else if (str_size == 4)
479 val = (int32_t)avio_rb32(pb);
480 if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
481 av_log(c->fc, AV_LOG_ERROR,
482 "Failed to store the number (%d) in string.\n", val);
484 return AVERROR_INVALIDDATA;
486 } else if (data_type == 22) { // BE unsigned integer, variable size
487 unsigned int val = 0;
490 else if (str_size == 2)
492 else if (str_size == 3)
494 else if (str_size == 4)
496 if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
497 av_log(c->fc, AV_LOG_ERROR,
498 "Failed to store the number (%u) in string.\n", val);
500 return AVERROR_INVALIDDATA;
502 } else if (data_type == 23 && str_size >= 4) { // BE float32
503 float val = av_int2float(avio_rb32(pb));
504 if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
505 av_log(c->fc, AV_LOG_ERROR,
506 "Failed to store the float32 number (%f) in string.\n", val);
508 return AVERROR_INVALIDDATA;
511 int ret = ffio_read_size(pb, str, str_size);
518 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
519 av_dict_set(&c->fc->metadata, key, str, 0);
520 if (*language && strcmp(language, "und")) {
521 snprintf(key2, sizeof(key2), "%s-%s", key, language);
522 av_dict_set(&c->fc->metadata, key2, str, 0);
524 if (!strcmp(key, "encoder")) {
525 int major, minor, micro;
526 if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, µ) == 3) {
527 c->handbrake_version = 1000000*major + 1000*minor + micro;
536 static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
539 int i, nb_chapters, str_len, version;
543 if (c->ignore_chapters)
546 if ((atom.size -= 5) < 0)
549 version = avio_r8(pb);
552 avio_rb32(pb); // ???
553 nb_chapters = avio_r8(pb);
555 for (i = 0; i < nb_chapters; i++) {
559 start = avio_rb64(pb);
560 str_len = avio_r8(pb);
562 if ((atom.size -= 9+str_len) < 0)
565 ret = ffio_read_size(pb, str, str_len);
569 avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
574 #define MIN_DATA_ENTRY_BOX_SIZE 12
575 static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
578 MOVStreamContext *sc;
581 if (c->fc->nb_streams < 1)
583 st = c->fc->streams[c->fc->nb_streams-1];
586 avio_rb32(pb); // version + flags
587 entries = avio_rb32(pb);
589 entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
590 entries >= UINT_MAX / sizeof(*sc->drefs))
591 return AVERROR_INVALIDDATA;
593 for (i = 0; i < sc->drefs_count; i++) {
594 MOVDref *dref = &sc->drefs[i];
595 av_freep(&dref->path);
596 av_freep(&dref->dir);
600 sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
602 return AVERROR(ENOMEM);
603 sc->drefs_count = entries;
605 for (i = 0; i < entries; i++) {
606 MOVDref *dref = &sc->drefs[i];
607 uint32_t size = avio_rb32(pb);
608 int64_t next = avio_tell(pb) + size - 4;
611 return AVERROR_INVALIDDATA;
613 dref->type = avio_rl32(pb);
614 avio_rb32(pb); // version + flags
616 if (dref->type == MKTAG('a','l','i','s') && size > 150) {
617 /* macintosh alias record */
618 uint16_t volume_len, len;
624 volume_len = avio_r8(pb);
625 volume_len = FFMIN(volume_len, 27);
626 ret = ffio_read_size(pb, dref->volume, 27);
629 dref->volume[volume_len] = 0;
630 av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
635 len = FFMIN(len, 63);
636 ret = ffio_read_size(pb, dref->filename, 63);
639 dref->filename[len] = 0;
640 av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
644 /* read next level up_from_alias/down_to_target */
645 dref->nlvl_from = avio_rb16(pb);
646 dref->nlvl_to = avio_rb16(pb);
647 av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
648 dref->nlvl_from, dref->nlvl_to);
652 for (type = 0; type != -1 && avio_tell(pb) < next; ) {
655 type = avio_rb16(pb);
657 av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
660 if (type == 2) { // absolute path
662 dref->path = av_mallocz(len+1);
664 return AVERROR(ENOMEM);
666 ret = ffio_read_size(pb, dref->path, len);
668 av_freep(&dref->path);
671 if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
673 memmove(dref->path, dref->path+volume_len, len);
676 // trim string of any ending zeros
677 for (j = len - 1; j >= 0; j--) {
678 if (dref->path[j] == 0)
683 for (j = 0; j < len; j++)
684 if (dref->path[j] == ':' || dref->path[j] == 0)
686 av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
687 } else if (type == 0) { // directory name
689 dref->dir = av_malloc(len+1);
691 return AVERROR(ENOMEM);
693 ret = ffio_read_size(pb, dref->dir, len);
695 av_freep(&dref->dir);
699 for (j = 0; j < len; j++)
700 if (dref->dir[j] == ':')
702 av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
707 av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
712 avio_seek(pb, next, SEEK_SET);
717 static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
726 avio_r8(pb); /* version */
727 avio_rb24(pb); /* flags */
730 ctype = avio_rl32(pb);
731 type = avio_rl32(pb); /* component subtype */
733 av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
734 av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
736 if (c->trak_index < 0) { // meta not inside a trak
737 if (type == MKTAG('m','d','t','a')) {
738 c->found_hdlr_mdta = 1;
743 st = c->fc->streams[c->fc->nb_streams-1];
745 if (type == MKTAG('v','i','d','e'))
746 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
747 else if (type == MKTAG('s','o','u','n'))
748 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
749 else if (type == MKTAG('m','1','a',' '))
750 st->codecpar->codec_id = AV_CODEC_ID_MP2;
751 else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
752 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
754 avio_rb32(pb); /* component manufacture */
755 avio_rb32(pb); /* component flags */
756 avio_rb32(pb); /* component flags mask */
758 title_size = atom.size - 24;
759 if (title_size > 0) {
760 if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
761 return AVERROR_INVALIDDATA;
762 title_str = av_malloc(title_size + 1); /* Add null terminator */
764 return AVERROR(ENOMEM);
766 ret = ffio_read_size(pb, title_str, title_size);
768 av_freep(&title_str);
771 title_str[title_size] = 0;
773 int off = (!c->isom && title_str[0] == title_size - 1);
774 // flag added so as to not set stream handler name if already set from mdia->hdlr
775 av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
777 av_freep(&title_str);
783 static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
785 return ff_mov_read_esds(c->fc, pb);
788 static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
791 enum AVAudioServiceType *ast;
792 int ac3info, acmod, lfeon, bsmod;
794 if (c->fc->nb_streams < 1)
796 st = c->fc->streams[c->fc->nb_streams-1];
798 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
801 return AVERROR(ENOMEM);
803 ac3info = avio_rb24(pb);
804 bsmod = (ac3info >> 14) & 0x7;
805 acmod = (ac3info >> 11) & 0x7;
806 lfeon = (ac3info >> 10) & 0x1;
807 st->codecpar->channels = ((int[]){2,1,2,3,3,4,4,5})[acmod] + lfeon;
808 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
810 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
812 if (st->codecpar->channels > 1 && bsmod == 0x7)
813 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
815 #if FF_API_LAVF_AVCTX
816 FF_DISABLE_DEPRECATION_WARNINGS
817 st->codec->audio_service_type = *ast;
818 FF_ENABLE_DEPRECATION_WARNINGS
824 static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
827 enum AVAudioServiceType *ast;
828 int eac3info, acmod, lfeon, bsmod;
830 if (c->fc->nb_streams < 1)
832 st = c->fc->streams[c->fc->nb_streams-1];
834 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
837 return AVERROR(ENOMEM);
839 /* No need to parse fields for additional independent substreams and its
840 * associated dependent substreams since libavcodec's E-AC-3 decoder
841 * does not support them yet. */
842 avio_rb16(pb); /* data_rate and num_ind_sub */
843 eac3info = avio_rb24(pb);
844 bsmod = (eac3info >> 12) & 0x1f;
845 acmod = (eac3info >> 9) & 0x7;
846 lfeon = (eac3info >> 8) & 0x1;
847 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
849 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
850 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
852 if (st->codecpar->channels > 1 && bsmod == 0x7)
853 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
855 #if FF_API_LAVF_AVCTX
856 FF_DISABLE_DEPRECATION_WARNINGS
857 st->codec->audio_service_type = *ast;
858 FF_ENABLE_DEPRECATION_WARNINGS
864 static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
867 uint8_t buf[DDTS_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
869 uint32_t frame_duration_code = 0;
870 uint32_t channel_layout_code = 0;
874 if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
877 init_get_bits(&gb, buf, 8 * DDTS_SIZE);
879 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);
887 return AVERROR_INVALIDDATA;
889 skip_bits_long(&gb, 32); /* max bitrate */
890 st->codecpar->bit_rate = get_bits_long(&gb, 32);
891 st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
892 frame_duration_code = get_bits(&gb, 2);
893 skip_bits(&gb, 30); /* various fields */
894 channel_layout_code = get_bits(&gb, 16);
896 st->codecpar->frame_size =
897 (frame_duration_code == 0) ? 512 :
898 (frame_duration_code == 1) ? 1024 :
899 (frame_duration_code == 2) ? 2048 :
900 (frame_duration_code == 3) ? 4096 : 0;
902 if (channel_layout_code > 0xff) {
903 av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout\n");
905 st->codecpar->channel_layout =
906 ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
907 ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
908 ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
909 ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
910 ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
911 ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0);
913 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
918 static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
922 if (c->fc->nb_streams < 1)
924 st = c->fc->streams[c->fc->nb_streams-1];
929 /* skip version and flags */
932 ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
937 static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
942 if (c->fc->nb_streams < 1)
944 st = c->fc->streams[c->fc->nb_streams-1];
946 if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
947 av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
952 static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
954 const int num = avio_rb32(pb);
955 const int den = avio_rb32(pb);
958 if (c->fc->nb_streams < 1)
960 st = c->fc->streams[c->fc->nb_streams-1];
962 if ((st->sample_aspect_ratio.den != 1 || st->sample_aspect_ratio.num) && // default
963 (den != st->sample_aspect_ratio.den || num != st->sample_aspect_ratio.num)) {
964 av_log(c->fc, AV_LOG_WARNING,
965 "sample aspect ratio already set to %d:%d, ignoring 'pasp' atom (%d:%d)\n",
966 st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
968 } else if (den != 0) {
969 av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den,
975 /* this atom contains actual media data */
976 static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
978 if (atom.size == 0) /* wrong one (MP4) */
981 return 0; /* now go for moov */
984 #define DRM_BLOB_SIZE 56
986 static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
988 uint8_t intermediate_key[20];
989 uint8_t intermediate_iv[20];
992 uint8_t file_checksum[20];
993 uint8_t calculated_checksum[20];
997 uint8_t *activation_bytes = c->activation_bytes;
998 uint8_t *fixed_key = c->audible_fixed_key;
1002 sha = av_sha_alloc();
1004 return AVERROR(ENOMEM);
1005 av_free(c->aes_decrypt);
1006 c->aes_decrypt = av_aes_alloc();
1007 if (!c->aes_decrypt) {
1008 ret = AVERROR(ENOMEM);
1012 /* drm blob processing */
1013 avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1014 avio_read(pb, input, DRM_BLOB_SIZE);
1015 avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1016 avio_read(pb, file_checksum, 20);
1018 av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == "); // required by external tools
1019 for (i = 0; i < 20; i++)
1020 av_log(c->fc, AV_LOG_INFO, "%02x", file_checksum[i]);
1021 av_log(c->fc, AV_LOG_INFO, "\n");
1023 /* verify activation data */
1024 if (!activation_bytes) {
1025 av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1026 ret = 0; /* allow ffprobe to continue working on .aax files */
1029 if (c->activation_bytes_size != 4) {
1030 av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1031 ret = AVERROR(EINVAL);
1035 /* verify fixed key */
1036 if (c->audible_fixed_key_size != 16) {
1037 av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1038 ret = AVERROR(EINVAL);
1042 /* AAX (and AAX+) key derivation */
1043 av_sha_init(sha, 160);
1044 av_sha_update(sha, fixed_key, 16);
1045 av_sha_update(sha, activation_bytes, 4);
1046 av_sha_final(sha, intermediate_key);
1047 av_sha_init(sha, 160);
1048 av_sha_update(sha, fixed_key, 16);
1049 av_sha_update(sha, intermediate_key, 20);
1050 av_sha_update(sha, activation_bytes, 4);
1051 av_sha_final(sha, intermediate_iv);
1052 av_sha_init(sha, 160);
1053 av_sha_update(sha, intermediate_key, 16);
1054 av_sha_update(sha, intermediate_iv, 16);
1055 av_sha_final(sha, calculated_checksum);
1056 if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1057 av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1058 ret = AVERROR_INVALIDDATA;
1061 av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1062 av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1063 for (i = 0; i < 4; i++) {
1064 // file data (in output) is stored in big-endian mode
1065 if (activation_bytes[i] != output[3 - i]) { // critical error
1066 av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1067 ret = AVERROR_INVALIDDATA;
1071 memcpy(c->file_key, output + 8, 16);
1072 memcpy(input, output + 26, 16);
1073 av_sha_init(sha, 160);
1074 av_sha_update(sha, input, 16);
1075 av_sha_update(sha, c->file_key, 16);
1076 av_sha_update(sha, fixed_key, 16);
1077 av_sha_final(sha, c->file_iv);
1085 static int mov_aaxc_crypto(MOVContext *c)
1087 if (c->audible_key_size != 16) {
1088 av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
1089 return AVERROR(EINVAL);
1092 if (c->audible_iv_size != 16) {
1093 av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
1094 return AVERROR(EINVAL);
1097 c->aes_decrypt = av_aes_alloc();
1098 if (!c->aes_decrypt) {
1099 return AVERROR(ENOMEM);
1102 memcpy(c->file_key, c->audible_key, 16);
1103 memcpy(c->file_iv, c->audible_iv, 16);
1109 // Audible AAX (and AAX+) bytestream decryption
1110 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1113 unsigned char iv[16];
1115 memcpy(iv, c->file_iv, 16); // iv is overwritten
1116 blocks = size >> 4; // trailing bytes are not encrypted!
1117 av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1118 av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1123 /* read major brand, minor version and compatible brands and store them as metadata */
1124 static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1127 int comp_brand_size;
1128 char* comp_brands_str;
1129 uint8_t type[5] = {0};
1130 int ret = ffio_read_size(pb, type, 4);
1134 if (strcmp(type, "qt "))
1136 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1137 av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1138 minor_ver = avio_rb32(pb); /* minor version */
1139 av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1141 comp_brand_size = atom.size - 8;
1142 if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1143 return AVERROR_INVALIDDATA;
1144 comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1145 if (!comp_brands_str)
1146 return AVERROR(ENOMEM);
1148 ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1150 av_freep(&comp_brands_str);
1153 comp_brands_str[comp_brand_size] = 0;
1154 av_dict_set(&c->fc->metadata, "compatible_brands",
1155 comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1157 // Logic for handling Audible's .aaxc files
1158 if (!strcmp(type, "aaxc")) {
1165 /* this atom should contain all header atoms */
1166 static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1170 if (c->found_moov) {
1171 av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1172 avio_skip(pb, atom.size);
1176 if ((ret = mov_read_default(c, pb, atom)) < 0)
1178 /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1179 /* so we don't parse the whole file if over a network */
1181 return 0; /* now go for mdat */
1184 static MOVFragmentStreamInfo * get_frag_stream_info(
1185 MOVFragmentIndex *frag_index,
1190 MOVFragmentIndexItem * item;
1192 if (index < 0 || index >= frag_index->nb_items)
1194 item = &frag_index->item[index];
1195 for (i = 0; i < item->nb_stream_info; i++)
1196 if (item->stream_info[i].id == id)
1197 return &item->stream_info[i];
1199 // This shouldn't happen
1203 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1206 MOVFragmentIndexItem * item;
1208 if (frag_index->current < 0 ||
1209 frag_index->current >= frag_index->nb_items)
1212 item = &frag_index->item[frag_index->current];
1213 for (i = 0; i < item->nb_stream_info; i++)
1214 if (item->stream_info[i].id == id) {
1219 // id not found. This shouldn't happen.
1223 static MOVFragmentStreamInfo * get_current_frag_stream_info(
1224 MOVFragmentIndex *frag_index)
1226 MOVFragmentIndexItem *item;
1227 if (frag_index->current < 0 ||
1228 frag_index->current >= frag_index->nb_items)
1231 item = &frag_index->item[frag_index->current];
1232 if (item->current >= 0 && item->current < item->nb_stream_info)
1233 return &item->stream_info[item->current];
1235 // This shouldn't happen
1239 static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
1242 int64_t moof_offset;
1244 // Optimize for appending new entries
1245 if (!frag_index->nb_items ||
1246 frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1247 return frag_index->nb_items;
1250 b = frag_index->nb_items;
1254 moof_offset = frag_index->item[m].moof_offset;
1255 if (moof_offset >= offset)
1257 if (moof_offset <= offset)
1263 static int64_t get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
1265 av_assert0(frag_stream_info);
1266 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1267 return frag_stream_info->sidx_pts;
1268 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1269 return frag_stream_info->first_tfra_pts;
1270 return frag_stream_info->tfdt_dts;
1273 static int64_t get_frag_time(MOVFragmentIndex *frag_index,
1274 int index, int track_id)
1276 MOVFragmentStreamInfo * frag_stream_info;
1280 if (track_id >= 0) {
1281 frag_stream_info = get_frag_stream_info(frag_index, index, track_id);
1282 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1283 return frag_stream_info->sidx_pts;
1284 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1285 return frag_stream_info->first_tfra_pts;
1286 return frag_stream_info->sidx_pts;
1289 for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1290 frag_stream_info = &frag_index->item[index].stream_info[i];
1291 timestamp = get_stream_info_time(frag_stream_info);
1292 if (timestamp != AV_NOPTS_VALUE)
1295 return AV_NOPTS_VALUE;
1298 static int search_frag_timestamp(MOVFragmentIndex *frag_index,
1299 AVStream *st, int64_t timestamp)
1306 // If the stream is referenced by any sidx, limit the search
1307 // to fragments that referenced this stream in the sidx
1308 MOVStreamContext *sc = st->priv_data;
1314 b = frag_index->nb_items;
1317 m0 = m = (a + b) >> 1;
1320 (frag_time = get_frag_time(frag_index, m, id)) == AV_NOPTS_VALUE)
1323 if (m < b && frag_time <= timestamp)
1332 static int update_frag_index(MOVContext *c, int64_t offset)
1335 MOVFragmentIndexItem * item;
1336 MOVFragmentStreamInfo * frag_stream_info;
1338 // If moof_offset already exists in frag_index, return index to it
1339 index = search_frag_moof_offset(&c->frag_index, offset);
1340 if (index < c->frag_index.nb_items &&
1341 c->frag_index.item[index].moof_offset == offset)
1344 // offset is not yet in frag index.
1345 // Insert new item at index (sorted by moof offset)
1346 item = av_fast_realloc(c->frag_index.item,
1347 &c->frag_index.allocated_size,
1348 (c->frag_index.nb_items + 1) *
1349 sizeof(*c->frag_index.item));
1352 c->frag_index.item = item;
1354 frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1355 sizeof(*item->stream_info));
1356 if (!frag_stream_info)
1359 for (i = 0; i < c->fc->nb_streams; i++) {
1360 // Avoid building frag index if streams lack track id.
1361 if (c->fc->streams[i]->id < 0) {
1362 av_free(frag_stream_info);
1363 return AVERROR_INVALIDDATA;
1366 frag_stream_info[i].id = c->fc->streams[i]->id;
1367 frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1368 frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1369 frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1370 frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1371 frag_stream_info[i].index_entry = -1;
1372 frag_stream_info[i].encryption_index = NULL;
1375 if (index < c->frag_index.nb_items)
1376 memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1377 (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1379 item = &c->frag_index.item[index];
1380 item->headers_read = 0;
1382 item->nb_stream_info = c->fc->nb_streams;
1383 item->moof_offset = offset;
1384 item->stream_info = frag_stream_info;
1385 c->frag_index.nb_items++;
1390 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1391 int id, int entries)
1394 MOVFragmentStreamInfo * frag_stream_info;
1398 for (i = index; i < frag_index->nb_items; i++) {
1399 frag_stream_info = get_frag_stream_info(frag_index, i, id);
1400 if (frag_stream_info && frag_stream_info->index_entry >= 0)
1401 frag_stream_info->index_entry += entries;
1405 static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1407 // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1408 c->fragment.found_tfhd = 0;
1410 if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1411 c->has_looked_for_mfra = 1;
1412 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1414 av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1416 if ((ret = mov_read_mfra(c, pb)) < 0) {
1417 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1418 "read the mfra (may be a live ismv)\n");
1421 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1422 "seekable, can not look for mfra\n");
1425 c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1426 av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1427 c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1428 return mov_read_default(c, pb, atom);
1431 static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time, void *logctx)
1434 if (time >= 2082844800)
1435 time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1437 if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1438 av_log(logctx, AV_LOG_DEBUG, "creation_time is not representable\n");
1442 avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1446 static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1449 MOVStreamContext *sc;
1451 char language[4] = {0};
1453 int64_t creation_time;
1455 if (c->fc->nb_streams < 1)
1457 st = c->fc->streams[c->fc->nb_streams-1];
1460 if (sc->time_scale) {
1461 av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1462 return AVERROR_INVALIDDATA;
1465 version = avio_r8(pb);
1467 avpriv_request_sample(c->fc, "Version %d", version);
1468 return AVERROR_PATCHWELCOME;
1470 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(&st->metadata, creation_time, c->fc);
1480 sc->time_scale = avio_rb32(pb);
1481 if (sc->time_scale <= 0) {
1482 av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1485 st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1487 lang = avio_rb16(pb); /* language */
1488 if (ff_mov_lang_to_iso639(lang, language))
1489 av_dict_set(&st->metadata, "language", language, 0);
1490 avio_rb16(pb); /* quality */
1495 static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1498 int64_t creation_time;
1499 int version = avio_r8(pb); /* version */
1500 avio_rb24(pb); /* flags */
1503 creation_time = avio_rb64(pb);
1506 creation_time = avio_rb32(pb);
1507 avio_rb32(pb); /* modification time */
1509 mov_metadata_creation_time(&c->fc->metadata, creation_time, c->fc);
1510 c->time_scale = avio_rb32(pb); /* time scale */
1511 if (c->time_scale <= 0) {
1512 av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1515 av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1517 c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1518 // set the AVFormatContext duration because the duration of individual tracks
1519 // may be inaccurate
1521 c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale);
1522 avio_rb32(pb); /* preferred scale */
1524 avio_rb16(pb); /* preferred volume */
1526 avio_skip(pb, 10); /* reserved */
1528 /* movie display matrix, store it in main context and use it later on */
1529 for (i = 0; i < 3; i++) {
1530 c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1531 c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1532 c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1535 avio_rb32(pb); /* preview time */
1536 avio_rb32(pb); /* preview duration */
1537 avio_rb32(pb); /* poster time */
1538 avio_rb32(pb); /* selection time */
1539 avio_rb32(pb); /* selection duration */
1540 avio_rb32(pb); /* current time */
1541 avio_rb32(pb); /* next track ID */
1546 static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1551 if (c->fc->nb_streams < 1)
1553 st = c->fc->streams[c->fc->nb_streams-1];
1555 little_endian = avio_rb16(pb) & 0xFF;
1556 av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1557 if (little_endian == 1) {
1558 switch (st->codecpar->codec_id) {
1559 case AV_CODEC_ID_PCM_S24BE:
1560 st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE;
1562 case AV_CODEC_ID_PCM_S32BE:
1563 st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE;
1565 case AV_CODEC_ID_PCM_F32BE:
1566 st->codecpar->codec_id = AV_CODEC_ID_PCM_F32LE;
1568 case AV_CODEC_ID_PCM_F64BE:
1569 st->codecpar->codec_id = AV_CODEC_ID_PCM_F64LE;
1578 static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1581 uint8_t *icc_profile;
1582 char color_parameter_type[5] = { 0 };
1583 uint16_t color_primaries, color_trc, color_matrix;
1586 if (c->fc->nb_streams < 1)
1588 st = c->fc->streams[c->fc->nb_streams - 1];
1590 ret = ffio_read_size(pb, color_parameter_type, 4);
1593 if (strncmp(color_parameter_type, "nclx", 4) &&
1594 strncmp(color_parameter_type, "nclc", 4) &&
1595 strncmp(color_parameter_type, "prof", 4)) {
1596 av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
1597 color_parameter_type);
1601 if (!strncmp(color_parameter_type, "prof", 4)) {
1602 icc_profile = av_stream_new_side_data(st, AV_PKT_DATA_ICC_PROFILE, atom.size - 4);
1604 return AVERROR(ENOMEM);
1605 ret = ffio_read_size(pb, icc_profile, atom.size - 4);
1609 color_primaries = avio_rb16(pb);
1610 color_trc = avio_rb16(pb);
1611 color_matrix = avio_rb16(pb);
1613 av_log(c->fc, AV_LOG_TRACE,
1614 "%s: pri %d trc %d matrix %d",
1615 color_parameter_type, color_primaries, color_trc, color_matrix);
1617 if (!strncmp(color_parameter_type, "nclx", 4)) {
1618 uint8_t color_range = avio_r8(pb) >> 7;
1619 av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
1621 st->codecpar->color_range = AVCOL_RANGE_JPEG;
1623 st->codecpar->color_range = AVCOL_RANGE_MPEG;
1626 if (!av_color_primaries_name(color_primaries))
1627 color_primaries = AVCOL_PRI_UNSPECIFIED;
1628 if (!av_color_transfer_name(color_trc))
1629 color_trc = AVCOL_TRC_UNSPECIFIED;
1630 if (!av_color_space_name(color_matrix))
1631 color_matrix = AVCOL_SPC_UNSPECIFIED;
1633 st->codecpar->color_primaries = color_primaries;
1634 st->codecpar->color_trc = color_trc;
1635 st->codecpar->color_space = color_matrix;
1636 av_log(c->fc, AV_LOG_TRACE, "\n");
1641 static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1644 unsigned mov_field_order;
1645 enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
1647 if (c->fc->nb_streams < 1) // will happen with jp2 files
1649 st = c->fc->streams[c->fc->nb_streams-1];
1651 return AVERROR_INVALIDDATA;
1652 mov_field_order = avio_rb16(pb);
1653 if ((mov_field_order & 0xFF00) == 0x0100)
1654 decoded_field_order = AV_FIELD_PROGRESSIVE;
1655 else if ((mov_field_order & 0xFF00) == 0x0200) {
1656 switch (mov_field_order & 0xFF) {
1657 case 0x01: decoded_field_order = AV_FIELD_TT;
1659 case 0x06: decoded_field_order = AV_FIELD_BB;
1661 case 0x09: decoded_field_order = AV_FIELD_TB;
1663 case 0x0E: decoded_field_order = AV_FIELD_BT;
1667 if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
1668 av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
1670 st->codecpar->field_order = decoded_field_order;
1675 static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
1678 uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
1679 if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
1680 return AVERROR_INVALIDDATA;
1681 if ((err = av_reallocp(&par->extradata, size)) < 0) {
1682 par->extradata_size = 0;
1685 par->extradata_size = size - AV_INPUT_BUFFER_PADDING_SIZE;
1689 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
1690 static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1691 AVCodecParameters *par, uint8_t *buf)
1693 int64_t result = atom.size;
1696 AV_WB32(buf , atom.size + 8);
1697 AV_WL32(buf + 4, atom.type);
1698 err = ffio_read_size(pb, buf + 8, atom.size);
1700 par->extradata_size -= atom.size;
1702 } else if (err < atom.size) {
1703 av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
1704 par->extradata_size -= atom.size - err;
1707 memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1711 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
1712 static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1713 enum AVCodecID codec_id)
1716 uint64_t original_size;
1719 if (c->fc->nb_streams < 1) // will happen with jp2 files
1721 st = c->fc->streams[c->fc->nb_streams-1];
1723 if (st->codecpar->codec_id != codec_id)
1724 return 0; /* unexpected codec_id - don't mess with extradata */
1726 original_size = st->codecpar->extradata_size;
1727 err = mov_realloc_extradata(st->codecpar, atom);
1731 err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
1734 return 0; // Note: this is the original behavior to ignore truncation.
1737 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
1738 static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1740 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
1743 static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1745 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS);
1748 static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1750 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
1753 static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1755 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
1758 static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1760 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
1762 ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
1766 static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1768 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
1770 if (!ret && c->fc->nb_streams >= 1) {
1771 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1772 if (par->extradata_size >= 40) {
1773 par->height = AV_RB16(&par->extradata[36]);
1774 par->width = AV_RB16(&par->extradata[38]);
1780 static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1782 if (c->fc->nb_streams >= 1) {
1783 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1784 if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
1785 par->codec_id == AV_CODEC_ID_H264 &&
1789 cid = avio_rb16(pb);
1790 /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
1791 if (cid == 0xd4d || cid == 0xd4e)
1794 } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
1795 par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
1796 par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
1800 num = avio_rb32(pb);
1801 den = avio_rb32(pb);
1802 if (num <= 0 || den <= 0)
1804 switch (avio_rb32(pb)) {
1806 if (den >= INT_MAX / 2)
1810 c->fc->streams[c->fc->nb_streams-1]->internal->display_aspect_ratio.num = num;
1811 c->fc->streams[c->fc->nb_streams-1]->internal->display_aspect_ratio.den = den;
1818 return mov_read_avid(c, pb, atom);
1821 static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1825 uint64_t original_size;
1826 if (c->fc->nb_streams >= 1) {
1827 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1828 if (par->codec_id == AV_CODEC_ID_H264)
1830 if (atom.size == 16) {
1831 original_size = par->extradata_size;
1832 ret = mov_realloc_extradata(par, atom);
1834 length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
1835 if (length == atom.size) {
1836 const uint8_t range_value = par->extradata[original_size + 19];
1837 switch (range_value) {
1839 par->color_range = AVCOL_RANGE_MPEG;
1842 par->color_range = AVCOL_RANGE_JPEG;
1845 av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
1848 ff_dlog(c->fc, "color_range: %d\n", par->color_range);
1850 /* For some reason the whole atom was not added to the extradata */
1851 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
1854 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
1857 av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
1864 static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1866 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
1869 static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1874 if (c->fc->nb_streams < 1)
1876 st = c->fc->streams[c->fc->nb_streams-1];
1878 if ((uint64_t)atom.size > (1<<30))
1879 return AVERROR_INVALIDDATA;
1881 if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
1882 st->codecpar->codec_id == AV_CODEC_ID_QDMC ||
1883 st->codecpar->codec_id == AV_CODEC_ID_SPEEX) {
1884 // pass all frma atom to codec, needed at least for QDMC and QDM2
1885 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1888 } else if (atom.size > 8) { /* to read frma, esds atoms */
1889 if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
1891 ret = ffio_ensure_seekback(pb, 8);
1894 buffer = avio_rb64(pb);
1896 if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
1897 && buffer >> 32 <= atom.size
1898 && buffer >> 32 >= 8) {
1901 } else if (!st->codecpar->extradata_size) {
1902 #define ALAC_EXTRADATA_SIZE 36
1903 st->codecpar->extradata = av_mallocz(ALAC_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
1904 if (!st->codecpar->extradata)
1905 return AVERROR(ENOMEM);
1906 st->codecpar->extradata_size = ALAC_EXTRADATA_SIZE;
1907 AV_WB32(st->codecpar->extradata , ALAC_EXTRADATA_SIZE);
1908 AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
1909 AV_WB64(st->codecpar->extradata + 12, buffer);
1910 avio_read(pb, st->codecpar->extradata + 20, 16);
1911 avio_skip(pb, atom.size - 24);
1915 if ((ret = mov_read_default(c, pb, atom)) < 0)
1918 avio_skip(pb, atom.size);
1923 * This function reads atom content and puts data in extradata without tag
1924 * nor size unlike mov_read_extradata.
1926 static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1931 if (c->fc->nb_streams < 1)
1933 st = c->fc->streams[c->fc->nb_streams-1];
1935 if ((uint64_t)atom.size > (1<<30))
1936 return AVERROR_INVALIDDATA;
1938 if (atom.size >= 10) {
1939 // Broken files created by legacy versions of libavformat will
1940 // wrap a whole fiel atom inside of a glbl atom.
1941 unsigned size = avio_rb32(pb);
1942 unsigned type = avio_rl32(pb);
1943 avio_seek(pb, -8, SEEK_CUR);
1944 if (type == MKTAG('f','i','e','l') && size == atom.size)
1945 return mov_read_default(c, pb, atom);
1947 if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
1948 av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
1951 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1954 if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
1955 /* HEVC-based Dolby Vision derived from hvc1.
1956 Happens to match with an identifier
1957 previously utilized for DV. Thus, if we have
1958 the hvcC extradata box available as specified,
1959 set codec to HEVC */
1960 st->codecpar->codec_id = AV_CODEC_ID_HEVC;
1965 static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1968 uint8_t profile_level;
1971 if (c->fc->nb_streams < 1)
1973 st = c->fc->streams[c->fc->nb_streams-1];
1975 if (atom.size >= (1<<28) || atom.size < 7)
1976 return AVERROR_INVALIDDATA;
1978 profile_level = avio_r8(pb);
1979 if ((profile_level & 0xf0) != 0xc0)
1982 avio_seek(pb, 6, SEEK_CUR);
1983 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
1991 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
1992 * but can have extradata appended at the end after the 40 bytes belonging
1995 static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2000 if (c->fc->nb_streams < 1)
2002 if (atom.size <= 40)
2004 st = c->fc->streams[c->fc->nb_streams-1];
2006 if ((uint64_t)atom.size > (1<<30))
2007 return AVERROR_INVALIDDATA;
2010 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2017 static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2020 MOVStreamContext *sc;
2021 unsigned int i, entries;
2023 if (c->trak_index < 0) {
2024 av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2027 if (c->fc->nb_streams < 1)
2029 st = c->fc->streams[c->fc->nb_streams-1];
2032 avio_r8(pb); /* version */
2033 avio_rb24(pb); /* flags */
2035 entries = avio_rb32(pb);
2040 if (sc->chunk_offsets)
2041 av_log(c->fc, AV_LOG_WARNING, "Duplicated STCO atom\n");
2042 av_free(sc->chunk_offsets);
2043 sc->chunk_count = 0;
2044 sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2045 if (!sc->chunk_offsets)
2046 return AVERROR(ENOMEM);
2047 sc->chunk_count = entries;
2049 if (atom.type == MKTAG('s','t','c','o'))
2050 for (i = 0; i < entries && !pb->eof_reached; i++)
2051 sc->chunk_offsets[i] = avio_rb32(pb);
2052 else if (atom.type == MKTAG('c','o','6','4'))
2053 for (i = 0; i < entries && !pb->eof_reached; i++)
2054 sc->chunk_offsets[i] = avio_rb64(pb);
2056 return AVERROR_INVALIDDATA;
2058 sc->chunk_count = i;
2060 if (pb->eof_reached) {
2061 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2068 static int mov_codec_id(AVStream *st, uint32_t format)
2070 int id = ff_codec_get_id(ff_codec_movaudio_tags, format);
2073 ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2074 (format & 0xFFFF) == 'T' + ('S' << 8)))
2075 id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format) & 0xFFFF);
2077 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2078 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2079 } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2080 /* skip old ASF MPEG-4 tag */
2081 format && format != MKTAG('m','p','4','s')) {
2082 id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2084 id = ff_codec_get_id(ff_codec_bmp_tags, format);
2086 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
2087 else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2088 (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE &&
2089 st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2090 id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
2092 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
2094 id = ff_codec_get_id(ff_codec_movdata_tags, format);
2098 st->codecpar->codec_tag = format;
2103 static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
2104 AVStream *st, MOVStreamContext *sc)
2106 uint8_t codec_name[32] = { 0 };
2111 /* The first 16 bytes of the video sample description are already
2112 * read in ff_mov_read_stsd_entries() */
2113 stsd_start = avio_tell(pb) - 16;
2115 avio_rb16(pb); /* version */
2116 avio_rb16(pb); /* revision level */
2117 id = avio_rl32(pb); /* vendor */
2118 av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2119 avio_rb32(pb); /* temporal quality */
2120 avio_rb32(pb); /* spatial quality */
2122 st->codecpar->width = avio_rb16(pb); /* width */
2123 st->codecpar->height = avio_rb16(pb); /* height */
2125 avio_rb32(pb); /* horiz resolution */
2126 avio_rb32(pb); /* vert resolution */
2127 avio_rb32(pb); /* data size, always 0 */
2128 avio_rb16(pb); /* frames per samples */
2130 len = avio_r8(pb); /* codec name, pascal string */
2133 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2135 avio_skip(pb, 31 - len);
2138 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2140 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2141 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2142 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2143 st->codecpar->width &= ~1;
2144 st->codecpar->height &= ~1;
2146 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2147 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2148 !strncmp(codec_name, "Sorenson H263", 13))
2149 st->codecpar->codec_id = AV_CODEC_ID_FLV1;
2151 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2153 avio_seek(pb, stsd_start, SEEK_SET);
2155 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2156 st->codecpar->bits_per_coded_sample &= 0x1F;
2157 sc->has_palette = 1;
2161 static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
2162 AVStream *st, MOVStreamContext *sc)
2164 int bits_per_sample, flags;
2165 uint16_t version = avio_rb16(pb);
2167 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2169 avio_rb16(pb); /* revision level */
2170 id = avio_rl32(pb); /* vendor */
2171 av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2173 st->codecpar->channels = avio_rb16(pb); /* channel count */
2174 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2175 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", st->codecpar->channels);
2177 sc->audio_cid = avio_rb16(pb);
2178 avio_rb16(pb); /* packet size = 0 */
2180 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2182 // Read QT version 1 fields. In version 0 these do not exist.
2183 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2185 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2186 (sc->stsd_version == 0 && version > 0)) {
2188 sc->samples_per_frame = avio_rb32(pb);
2189 avio_rb32(pb); /* bytes per packet */
2190 sc->bytes_per_frame = avio_rb32(pb);
2191 avio_rb32(pb); /* bytes per sample */
2192 } else if (version == 2) {
2193 avio_rb32(pb); /* sizeof struct only */
2194 st->codecpar->sample_rate = av_int2double(avio_rb64(pb));
2195 st->codecpar->channels = avio_rb32(pb);
2196 avio_rb32(pb); /* always 0x7F000000 */
2197 st->codecpar->bits_per_coded_sample = avio_rb32(pb);
2199 flags = avio_rb32(pb); /* lpcm format specific flag */
2200 sc->bytes_per_frame = avio_rb32(pb);
2201 sc->samples_per_frame = avio_rb32(pb);
2202 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2203 st->codecpar->codec_id =
2204 ff_mov_get_lpcm_codec_id(st->codecpar->bits_per_coded_sample,
2207 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2208 /* can't correctly handle variable sized packet as audio unit */
2209 switch (st->codecpar->codec_id) {
2210 case AV_CODEC_ID_MP2:
2211 case AV_CODEC_ID_MP3:
2212 st->need_parsing = AVSTREAM_PARSE_FULL;
2218 if (sc->format == 0) {
2219 if (st->codecpar->bits_per_coded_sample == 8)
2220 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2221 else if (st->codecpar->bits_per_coded_sample == 16)
2222 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2225 switch (st->codecpar->codec_id) {
2226 case AV_CODEC_ID_PCM_S8:
2227 case AV_CODEC_ID_PCM_U8:
2228 if (st->codecpar->bits_per_coded_sample == 16)
2229 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16BE;
2231 case AV_CODEC_ID_PCM_S16LE:
2232 case AV_CODEC_ID_PCM_S16BE:
2233 if (st->codecpar->bits_per_coded_sample == 8)
2234 st->codecpar->codec_id = AV_CODEC_ID_PCM_S8;
2235 else if (st->codecpar->bits_per_coded_sample == 24)
2236 st->codecpar->codec_id =
2237 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2238 AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
2239 else if (st->codecpar->bits_per_coded_sample == 32)
2240 st->codecpar->codec_id =
2241 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2242 AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
2244 /* set values for old format before stsd version 1 appeared */
2245 case AV_CODEC_ID_MACE3:
2246 sc->samples_per_frame = 6;
2247 sc->bytes_per_frame = 2 * st->codecpar->channels;
2249 case AV_CODEC_ID_MACE6:
2250 sc->samples_per_frame = 6;
2251 sc->bytes_per_frame = 1 * st->codecpar->channels;
2253 case AV_CODEC_ID_ADPCM_IMA_QT:
2254 sc->samples_per_frame = 64;
2255 sc->bytes_per_frame = 34 * st->codecpar->channels;
2257 case AV_CODEC_ID_GSM:
2258 sc->samples_per_frame = 160;
2259 sc->bytes_per_frame = 33;
2265 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2266 if (bits_per_sample) {
2267 st->codecpar->bits_per_coded_sample = bits_per_sample;
2268 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->channels;
2272 static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
2273 AVStream *st, MOVStreamContext *sc,
2276 // ttxt stsd contains display flags, justification, background
2277 // color, fonts, and default styles, so fake an atom to read it
2278 MOVAtom fake_atom = { .size = size };
2279 // mp4s contains a regular esds atom
2280 if (st->codecpar->codec_tag != AV_RL32("mp4s"))
2281 mov_read_glbl(c, pb, fake_atom);
2282 st->codecpar->width = sc->width;
2283 st->codecpar->height = sc->height;
2286 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2291 y = (ycbcr >> 16) & 0xFF;
2292 cr = (ycbcr >> 8) & 0xFF;
2295 b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
2296 g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
2297 r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
2299 return (r << 16) | (g << 8) | b;
2302 static int mov_rewrite_dvd_sub_extradata(AVStream *st)
2304 char buf[256] = {0};
2305 uint8_t *src = st->codecpar->extradata;
2308 if (st->codecpar->extradata_size != 64)
2311 if (st->codecpar->width > 0 && st->codecpar->height > 0)
2312 snprintf(buf, sizeof(buf), "size: %dx%d\n",
2313 st->codecpar->width, st->codecpar->height);
2314 av_strlcat(buf, "palette: ", sizeof(buf));
2316 for (i = 0; i < 16; i++) {
2317 uint32_t yuv = AV_RB32(src + i * 4);
2318 uint32_t rgba = yuv_to_rgba(yuv);
2320 av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2323 if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2326 ret = ff_alloc_extradata(st->codecpar, strlen(buf));
2329 memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2334 static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
2335 AVStream *st, MOVStreamContext *sc,
2340 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2341 if ((int)size != size)
2342 return AVERROR(ENOMEM);
2344 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2348 MOVStreamContext *tmcd_ctx = st->priv_data;
2350 val = AV_RB32(st->codecpar->extradata + 4);
2351 tmcd_ctx->tmcd_flags = val;
2352 st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2353 st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2354 #if FF_API_LAVF_AVCTX
2355 FF_DISABLE_DEPRECATION_WARNINGS
2356 st->codec->time_base = av_inv_q(st->avg_frame_rate);
2357 FF_ENABLE_DEPRECATION_WARNINGS
2360 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2361 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2362 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2363 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2364 if (str_size > 0 && size >= (int)str_size + 30 &&
2365 st->codecpar->extradata[30] /* Don't add empty string */) {
2366 char *reel_name = av_malloc(str_size + 1);
2368 return AVERROR(ENOMEM);
2369 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2370 reel_name[str_size] = 0; /* Add null terminator */
2371 av_dict_set(&st->metadata, "reel_name", reel_name,
2372 AV_DICT_DONT_STRDUP_VAL);
2378 /* other codec type, just skip (rtp, mp4s ...) */
2379 avio_skip(pb, size);
2384 static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
2385 AVStream *st, MOVStreamContext *sc)
2387 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2388 !st->codecpar->sample_rate && sc->time_scale > 1)
2389 st->codecpar->sample_rate = sc->time_scale;
2391 /* special codec parameters handling */
2392 switch (st->codecpar->codec_id) {
2393 #if CONFIG_DV_DEMUXER
2394 case AV_CODEC_ID_DVAUDIO:
2395 c->dv_fctx = avformat_alloc_context();
2397 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2398 return AVERROR(ENOMEM);
2400 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2402 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2403 return AVERROR(ENOMEM);
2405 sc->dv_audio_container = 1;
2406 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
2409 /* no ifdef since parameters are always those */
2410 case AV_CODEC_ID_QCELP:
2411 st->codecpar->channels = 1;
2412 // force sample rate for qcelp when not stored in mov
2413 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2414 st->codecpar->sample_rate = 8000;
2415 // FIXME: Why is the following needed for some files?
2416 sc->samples_per_frame = 160;
2417 if (!sc->bytes_per_frame)
2418 sc->bytes_per_frame = 35;
2420 case AV_CODEC_ID_AMR_NB:
2421 st->codecpar->channels = 1;
2422 /* force sample rate for amr, stsd in 3gp does not store sample rate */
2423 st->codecpar->sample_rate = 8000;
2425 case AV_CODEC_ID_AMR_WB:
2426 st->codecpar->channels = 1;
2427 st->codecpar->sample_rate = 16000;
2429 case AV_CODEC_ID_MP2:
2430 case AV_CODEC_ID_MP3:
2431 /* force type after stsd for m1a hdlr */
2432 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2434 case AV_CODEC_ID_GSM:
2435 case AV_CODEC_ID_ADPCM_MS:
2436 case AV_CODEC_ID_ADPCM_IMA_WAV:
2437 case AV_CODEC_ID_ILBC:
2438 case AV_CODEC_ID_MACE3:
2439 case AV_CODEC_ID_MACE6:
2440 case AV_CODEC_ID_QDM2:
2441 st->codecpar->block_align = sc->bytes_per_frame;
2443 case AV_CODEC_ID_ALAC:
2444 if (st->codecpar->extradata_size == 36) {
2445 st->codecpar->channels = AV_RB8 (st->codecpar->extradata + 21);
2446 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2449 case AV_CODEC_ID_AC3:
2450 case AV_CODEC_ID_EAC3:
2451 case AV_CODEC_ID_MPEG1VIDEO:
2452 case AV_CODEC_ID_VC1:
2453 case AV_CODEC_ID_VP8:
2454 case AV_CODEC_ID_VP9:
2455 st->need_parsing = AVSTREAM_PARSE_FULL;
2457 case AV_CODEC_ID_AV1:
2458 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2466 static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
2467 int codec_tag, int format,
2470 int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2473 (codec_tag != format &&
2474 // AVID 1:1 samples with differing data format and codec tag exist
2475 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
2476 // prores is allowed to have differing data format and codec tag
2477 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
2479 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
2480 (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id
2481 : codec_tag != MKTAG('j','p','e','g')))) {
2482 /* Multiple fourcc, we skip JPEG. This is not correct, we should
2483 * export it as a separate AVStream but this needs a few changes
2484 * in the MOV demuxer, patch welcome. */
2486 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
2487 avio_skip(pb, size);
2494 int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
2497 MOVStreamContext *sc;
2498 int pseudo_stream_id;
2500 av_assert0 (c->fc->nb_streams >= 1);
2501 st = c->fc->streams[c->fc->nb_streams-1];
2504 for (pseudo_stream_id = 0;
2505 pseudo_stream_id < entries && !pb->eof_reached;
2506 pseudo_stream_id++) {
2507 //Parsing Sample description table
2509 int ret, dref_id = 1;
2510 MOVAtom a = { AV_RL32("stsd") };
2511 int64_t start_pos = avio_tell(pb);
2512 int64_t size = avio_rb32(pb); /* size */
2513 uint32_t format = avio_rl32(pb); /* data format */
2516 avio_rb32(pb); /* reserved */
2517 avio_rb16(pb); /* reserved */
2518 dref_id = avio_rb16(pb);
2519 } else if (size <= 7) {
2520 av_log(c->fc, AV_LOG_ERROR,
2521 "invalid size %"PRId64" in stsd\n", size);
2522 return AVERROR_INVALIDDATA;
2525 if (mov_skip_multiple_stsd(c, pb, st->codecpar->codec_tag, format,
2526 size - (avio_tell(pb) - start_pos))) {
2531 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
2532 sc->dref_id= dref_id;
2533 sc->format = format;
2535 id = mov_codec_id(st, format);
2537 av_log(c->fc, AV_LOG_TRACE,
2538 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
2539 av_fourcc2str(format), st->codecpar->codec_type);
2541 st->codecpar->codec_id = id;
2542 if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) {
2543 mov_parse_stsd_video(c, pb, st, sc);
2544 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
2545 mov_parse_stsd_audio(c, pb, st, sc);
2546 if (st->codecpar->sample_rate < 0) {
2547 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
2548 return AVERROR_INVALIDDATA;
2550 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
2551 mov_parse_stsd_subtitle(c, pb, st, sc,
2552 size - (avio_tell(pb) - start_pos));
2554 ret = mov_parse_stsd_data(c, pb, st, sc,
2555 size - (avio_tell(pb) - start_pos));
2559 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
2560 a.size = size - (avio_tell(pb) - start_pos);
2562 if ((ret = mov_read_default(c, pb, a)) < 0)
2564 } else if (a.size > 0)
2565 avio_skip(pb, a.size);
2567 if (sc->extradata && st->codecpar->extradata) {
2568 int extra_size = st->codecpar->extradata_size;
2570 /* Move the current stream extradata to the stream context one. */
2571 sc->extradata_size[pseudo_stream_id] = extra_size;
2572 sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
2573 st->codecpar->extradata = NULL;
2574 st->codecpar->extradata_size = 0;
2579 if (pb->eof_reached) {
2580 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
2587 static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2590 MOVStreamContext *sc;
2593 if (c->fc->nb_streams < 1)
2595 st = c->fc->streams[c->fc->nb_streams - 1];
2598 sc->stsd_version = avio_r8(pb);
2599 avio_rb24(pb); /* flags */
2600 entries = avio_rb32(pb);
2602 /* Each entry contains a size (4 bytes) and format (4 bytes). */
2603 if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
2604 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
2605 return AVERROR_INVALIDDATA;
2608 if (sc->extradata) {
2609 av_log(c->fc, AV_LOG_ERROR,
2610 "Duplicate stsd found in this track.\n");
2611 return AVERROR_INVALIDDATA;
2614 /* Prepare space for hosting multiple extradata. */
2615 sc->extradata = av_mallocz_array(entries, sizeof(*sc->extradata));
2617 return AVERROR(ENOMEM);
2619 sc->extradata_size = av_mallocz_array(entries, sizeof(*sc->extradata_size));
2620 if (!sc->extradata_size) {
2621 ret = AVERROR(ENOMEM);
2625 ret = ff_mov_read_stsd_entries(c, pb, entries);
2629 /* Restore back the primary extradata. */
2630 av_freep(&st->codecpar->extradata);
2631 st->codecpar->extradata_size = sc->extradata_size[0];
2632 if (sc->extradata_size[0]) {
2633 st->codecpar->extradata = av_mallocz(sc->extradata_size[0] + AV_INPUT_BUFFER_PADDING_SIZE);
2634 if (!st->codecpar->extradata)
2635 return AVERROR(ENOMEM);
2636 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
2639 return mov_finalize_stsd_codec(c, pb, st, sc);
2641 if (sc->extradata) {
2643 for (j = 0; j < sc->stsd_count; j++)
2644 av_freep(&sc->extradata[j]);
2647 av_freep(&sc->extradata);
2648 av_freep(&sc->extradata_size);
2652 static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2655 MOVStreamContext *sc;
2656 unsigned int i, entries;
2658 if (c->fc->nb_streams < 1)
2660 st = c->fc->streams[c->fc->nb_streams-1];
2663 avio_r8(pb); /* version */
2664 avio_rb24(pb); /* flags */
2666 entries = avio_rb32(pb);
2667 if ((uint64_t)entries * 12 + 4 > atom.size)
2668 return AVERROR_INVALIDDATA;
2670 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
2675 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSC atom\n");
2676 av_free(sc->stsc_data);
2678 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
2680 return AVERROR(ENOMEM);
2682 for (i = 0; i < entries && !pb->eof_reached; i++) {
2683 sc->stsc_data[i].first = avio_rb32(pb);
2684 sc->stsc_data[i].count = avio_rb32(pb);
2685 sc->stsc_data[i].id = avio_rb32(pb);
2689 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
2690 int64_t first_min = i + 1;
2691 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
2692 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
2693 sc->stsc_data[i].first < first_min ||
2694 sc->stsc_data[i].count < 1 ||
2695 sc->stsc_data[i].id < 1) {
2696 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);
2697 if (i+1 >= sc->stsc_count) {
2698 if (sc->stsc_data[i].count == 0 && i > 0) {
2702 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
2703 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
2704 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
2705 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
2706 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
2709 av_assert0(sc->stsc_data[i+1].first >= 2);
2710 // We replace this entry by the next valid
2711 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
2712 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
2713 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
2717 if (pb->eof_reached) {
2718 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
2725 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
2727 return index < count - 1;
2730 /* Compute the samples value for the stsc entry at the given index. */
2731 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
2735 if (mov_stsc_index_valid(index, sc->stsc_count))
2736 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
2738 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
2739 av_assert0(sc->stsc_data[index].first <= sc->chunk_count);
2740 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
2743 return sc->stsc_data[index].count * (int64_t)chunk_count;
2746 static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2749 MOVStreamContext *sc;
2750 unsigned i, entries;
2752 if (c->fc->nb_streams < 1)
2754 st = c->fc->streams[c->fc->nb_streams-1];
2757 avio_rb32(pb); // version + flags
2759 entries = avio_rb32(pb);
2761 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
2762 av_free(sc->stps_data);
2764 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
2766 return AVERROR(ENOMEM);
2768 for (i = 0; i < entries && !pb->eof_reached; i++) {
2769 sc->stps_data[i] = avio_rb32(pb);
2774 if (pb->eof_reached) {
2775 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
2782 static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2785 MOVStreamContext *sc;
2786 unsigned int i, entries;
2788 if (c->fc->nb_streams < 1)
2790 st = c->fc->streams[c->fc->nb_streams-1];
2793 avio_r8(pb); /* version */
2794 avio_rb24(pb); /* flags */
2796 entries = avio_rb32(pb);
2798 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
2801 sc->keyframe_absent = 1;
2802 if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
2803 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2807 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
2808 if (entries >= UINT_MAX / sizeof(int))
2809 return AVERROR_INVALIDDATA;
2810 av_freep(&sc->keyframes);
2811 sc->keyframe_count = 0;
2812 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
2814 return AVERROR(ENOMEM);
2816 for (i = 0; i < entries && !pb->eof_reached; i++) {
2817 sc->keyframes[i] = avio_rb32(pb);
2820 sc->keyframe_count = i;
2822 if (pb->eof_reached) {
2823 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
2830 static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2833 MOVStreamContext *sc;
2834 unsigned int i, entries, sample_size, field_size, num_bytes;
2839 if (c->fc->nb_streams < 1)
2841 st = c->fc->streams[c->fc->nb_streams-1];
2844 avio_r8(pb); /* version */
2845 avio_rb24(pb); /* flags */
2847 if (atom.type == MKTAG('s','t','s','z')) {
2848 sample_size = avio_rb32(pb);
2849 if (!sc->sample_size) /* do not overwrite value computed in stsd */
2850 sc->sample_size = sample_size;
2851 sc->stsz_sample_size = sample_size;
2855 avio_rb24(pb); /* reserved */
2856 field_size = avio_r8(pb);
2858 entries = avio_rb32(pb);
2860 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
2862 sc->sample_count = entries;
2866 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
2867 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
2868 return AVERROR_INVALIDDATA;
2873 if (entries >= (UINT_MAX - 4) / field_size)
2874 return AVERROR_INVALIDDATA;
2875 if (sc->sample_sizes)
2876 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
2877 av_free(sc->sample_sizes);
2878 sc->sample_count = 0;
2879 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
2880 if (!sc->sample_sizes)
2881 return AVERROR(ENOMEM);
2883 num_bytes = (entries*field_size+4)>>3;
2885 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
2887 av_freep(&sc->sample_sizes);
2888 return AVERROR(ENOMEM);
2891 ret = ffio_read_size(pb, buf, num_bytes);
2893 av_freep(&sc->sample_sizes);
2895 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
2899 init_get_bits(&gb, buf, 8*num_bytes);
2901 for (i = 0; i < entries && !pb->eof_reached; i++) {
2902 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
2903 if (sc->sample_sizes[i] < 0) {
2905 av_log(c->fc, AV_LOG_ERROR, "Invalid sample size %d\n", sc->sample_sizes[i]);
2906 return AVERROR_INVALIDDATA;
2908 sc->data_size += sc->sample_sizes[i];
2911 sc->sample_count = i;
2915 if (pb->eof_reached) {
2916 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSZ atom\n");
2923 static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2926 MOVStreamContext *sc;
2927 unsigned int i, entries, alloc_size = 0;
2928 int64_t duration = 0;
2929 int64_t total_sample_count = 0;
2931 if (c->fc->nb_streams < 1)
2933 st = c->fc->streams[c->fc->nb_streams-1];
2936 avio_r8(pb); /* version */
2937 avio_rb24(pb); /* flags */
2938 entries = avio_rb32(pb);
2940 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
2941 c->fc->nb_streams-1, entries);
2944 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
2945 av_freep(&sc->stts_data);
2947 if (entries >= INT_MAX / sizeof(*sc->stts_data))
2948 return AVERROR(ENOMEM);
2950 for (i = 0; i < entries && !pb->eof_reached; i++) {
2951 int sample_duration;
2952 unsigned int sample_count;
2953 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
2954 MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
2955 min_entries * sizeof(*sc->stts_data));
2957 av_freep(&sc->stts_data);
2959 return AVERROR(ENOMEM);
2961 sc->stts_count = min_entries;
2962 sc->stts_data = stts_data;
2964 sample_count = avio_rb32(pb);
2965 sample_duration = avio_rb32(pb);
2967 sc->stts_data[i].count= sample_count;
2968 sc->stts_data[i].duration= sample_duration;
2970 av_log(c->fc, AV_LOG_TRACE, "sample_count=%d, sample_duration=%d\n",
2971 sample_count, sample_duration);
2973 duration+=(int64_t)sample_duration*(uint64_t)sample_count;
2974 total_sample_count+=sample_count;
2980 duration <= INT64_MAX - sc->duration_for_fps &&
2981 total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
2982 sc->duration_for_fps += duration;
2983 sc->nb_frames_for_fps += total_sample_count;
2986 if (pb->eof_reached) {
2987 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
2991 st->nb_frames= total_sample_count;
2993 st->duration= FFMIN(st->duration, duration);
2994 sc->track_end = duration;
2998 static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3001 MOVStreamContext *sc;
3004 if (c->fc->nb_streams < 1)
3006 st = c->fc->streams[c->fc->nb_streams - 1];
3009 avio_r8(pb); /* version */
3010 avio_rb24(pb); /* flags */
3011 entries = atom.size - 4;
3013 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3014 c->fc->nb_streams - 1, entries);
3017 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3018 av_freep(&sc->sdtp_data);
3021 sc->sdtp_data = av_mallocz(entries);
3023 return AVERROR(ENOMEM);
3025 for (i = 0; i < entries && !pb->eof_reached; i++)
3026 sc->sdtp_data[i] = avio_r8(pb);
3032 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3035 if (duration == INT_MIN) {
3036 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3039 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3043 static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3046 MOVStreamContext *sc;
3047 unsigned int i, entries, ctts_count = 0;
3049 if (c->fc->nb_streams < 1)
3051 st = c->fc->streams[c->fc->nb_streams-1];
3054 avio_r8(pb); /* version */
3055 avio_rb24(pb); /* flags */
3056 entries = avio_rb32(pb);
3058 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3062 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3063 return AVERROR_INVALIDDATA;
3064 av_freep(&sc->ctts_data);
3065 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3067 return AVERROR(ENOMEM);
3069 for (i = 0; i < entries && !pb->eof_reached; i++) {
3070 int count = avio_rb32(pb);
3071 int duration = avio_rb32(pb);
3074 av_log(c->fc, AV_LOG_TRACE,
3075 "ignoring CTTS entry with count=%d duration=%d\n",
3080 add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3083 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3086 if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3087 av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3088 av_freep(&sc->ctts_data);
3094 mov_update_dts_shift(sc, duration, c->fc);
3097 sc->ctts_count = ctts_count;
3099 if (pb->eof_reached) {
3100 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3104 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3109 static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3112 MOVStreamContext *sc;
3113 unsigned int i, entries;
3115 uint32_t grouping_type;
3117 if (c->fc->nb_streams < 1)
3119 st = c->fc->streams[c->fc->nb_streams-1];
3122 version = avio_r8(pb); /* version */
3123 avio_rb24(pb); /* flags */
3124 grouping_type = avio_rl32(pb);
3125 if (grouping_type != MKTAG( 'r','a','p',' '))
3126 return 0; /* only support 'rap ' grouping */
3128 avio_rb32(pb); /* grouping_type_parameter */
3130 entries = avio_rb32(pb);
3134 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP atom\n");
3135 av_free(sc->rap_group);
3136 sc->rap_group_count = 0;
3137 sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group));
3139 return AVERROR(ENOMEM);
3141 for (i = 0; i < entries && !pb->eof_reached; i++) {
3142 sc->rap_group[i].count = avio_rb32(pb); /* sample_count */
3143 sc->rap_group[i].index = avio_rb32(pb); /* group_description_index */
3146 sc->rap_group_count = i;
3148 if (pb->eof_reached) {
3149 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3157 * Get ith edit list entry (media time, duration).
3159 static int get_edit_list_entry(MOVContext *mov,
3160 const MOVStreamContext *msc,
3161 unsigned int edit_list_index,
3162 int64_t *edit_list_media_time,
3163 int64_t *edit_list_duration,
3164 int64_t global_timescale)
3166 if (edit_list_index == msc->elst_count) {
3169 *edit_list_media_time = msc->elst_data[edit_list_index].time;
3170 *edit_list_duration = msc->elst_data[edit_list_index].duration;
3172 /* duration is in global timescale units;convert to msc timescale */
3173 if (global_timescale == 0) {
3174 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3177 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3183 * Find the closest previous frame to the timestamp_pts, in e_old index
3184 * entries. Searching for just any frame / just key frames can be controlled by
3185 * last argument 'flag'.
3186 * Note that if ctts_data is not NULL, we will always search for a key frame
3187 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3188 * return the first frame of the video.
3190 * Here the timestamp_pts is considered to be a presentation timestamp and
3191 * the timestamp of index entries are considered to be decoding timestamps.
3193 * Returns 0 if successful in finding a frame, else returns -1.
3194 * Places the found index corresponding output arg.
3196 * If ctts_old is not NULL, then refines the searched entry by searching
3197 * backwards from the found timestamp, to find the frame with correct PTS.
3199 * Places the found ctts_index and ctts_sample in corresponding output args.
3201 static int find_prev_closest_index(AVStream *st,
3202 AVIndexEntry *e_old,
3206 int64_t timestamp_pts,
3209 int64_t* ctts_index,
3210 int64_t* ctts_sample)
3212 MOVStreamContext *msc = st->priv_data;
3213 AVIndexEntry *e_keep = st->internal->index_entries;
3214 int nb_keep = st->internal->nb_index_entries;
3216 int64_t index_ctts_count;
3220 // If dts_shift > 0, then all the index timestamps will have to be offset by
3221 // at least dts_shift amount to obtain PTS.
3222 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3223 if (msc->dts_shift > 0) {
3224 timestamp_pts -= msc->dts_shift;
3227 st->internal->index_entries = e_old;
3228 st->internal->nb_index_entries = nb_old;
3229 *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3231 // Keep going backwards in the index entries until the timestamp is the same.
3233 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3235 if ((flag & AVSEEK_FLAG_ANY) ||
3236 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3242 // If we have CTTS then refine the search, by searching backwards over PTS
3243 // computed by adding corresponding CTTS durations to index timestamps.
3244 if (ctts_data && *index >= 0) {
3245 av_assert0(ctts_index);
3246 av_assert0(ctts_sample);
3247 // Find out the ctts_index for the found frame.
3250 for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3251 if (*ctts_index < ctts_count) {
3253 if (ctts_data[*ctts_index].count == *ctts_sample) {
3260 while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3261 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3262 // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3263 // compensated by dts_shift above.
3264 if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3265 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3270 if (*ctts_sample == 0) {
3272 if (*ctts_index >= 0)
3273 *ctts_sample = ctts_data[*ctts_index].count - 1;
3280 /* restore AVStream state*/
3281 st->internal->index_entries = e_keep;
3282 st->internal->nb_index_entries = nb_keep;
3283 return *index >= 0 ? 0 : -1;
3287 * Add index entry with the given values, to the end of st->internal->index_entries.
3288 * Returns the new size st->internal->index_entries if successful, else returns -1.
3290 * This function is similar to ff_add_index_entry in libavformat/utils.c
3291 * except that here we are always unconditionally adding an index entry to
3292 * the end, instead of searching the entries list and skipping the add if
3293 * there is an existing entry with the same timestamp.
3294 * This is needed because the mov_fix_index calls this func with the same
3295 * unincremented timestamp for successive discarded frames.
3297 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3298 int size, int distance, int flags)
3300 AVIndexEntry *entries, *ie;
3302 const size_t min_size_needed = (st->internal->nb_index_entries + 1) * sizeof(AVIndexEntry);
3304 // Double the allocation each time, to lower memory fragmentation.
3305 // Another difference from ff_add_index_entry function.
3306 const size_t requested_size =
3307 min_size_needed > st->internal->index_entries_allocated_size ?
3308 FFMAX(min_size_needed, 2 * st->internal->index_entries_allocated_size) :
3311 if (st->internal->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
3314 entries = av_fast_realloc(st->internal->index_entries,
3315 &st->internal->index_entries_allocated_size,
3320 st->internal->index_entries= entries;
3322 index= st->internal->nb_index_entries++;
3323 ie= &entries[index];
3326 ie->timestamp = timestamp;
3327 ie->min_distance= distance;
3334 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3335 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3337 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3338 int64_t* frame_duration_buffer,
3339 int frame_duration_buffer_size) {
3341 av_assert0(end_index >= 0 && end_index <= st->internal->nb_index_entries);
3342 for (i = 0; i < frame_duration_buffer_size; i++) {
3343 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3344 st->internal->index_entries[end_index - 1 - i].timestamp = end_ts;
3349 * Append a new ctts entry to ctts_data.
3350 * Returns the new ctts_count if successful, else returns -1.
3352 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3353 int count, int duration)
3355 MOVStts *ctts_buf_new;
3356 const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVStts);
3357 const size_t requested_size =
3358 min_size_needed > *allocated_size ?
3359 FFMAX(min_size_needed, 2 * (*allocated_size)) :
3362 if ((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
3365 ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3370 *ctts_data = ctts_buf_new;
3372 ctts_buf_new[*ctts_count].count = count;
3373 ctts_buf_new[*ctts_count].duration = duration;
3375 *ctts_count = (*ctts_count) + 1;
3379 #define MAX_REORDER_DELAY 16
3380 static void mov_estimate_video_delay(MOVContext *c, AVStream* st)
3382 MOVStreamContext *msc = st->priv_data;
3385 int ctts_sample = 0;
3386 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3388 int j, r, num_swaps;
3390 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3391 pts_buf[j] = INT64_MIN;
3393 if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3394 st->codecpar->codec_id == AV_CODEC_ID_H264) {
3395 st->codecpar->video_delay = 0;
3396 for (ind = 0; ind < st->internal->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3397 // Point j to the last elem of the buffer and insert the current pts there.
3399 buf_start = (buf_start + 1);
3400 if (buf_start == MAX_REORDER_DELAY + 1)
3403 pts_buf[j] = st->internal->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3405 // The timestamps that are already in the sorted buffer, and are greater than the
3406 // current pts, are exactly the timestamps that need to be buffered to output PTS
3407 // in correct sorted order.
3408 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3409 // can be computed as the maximum no. of swaps any particular timestamp needs to
3410 // go through, to keep this buffer in sorted order.
3412 while (j != buf_start) {
3414 if (r < 0) r = MAX_REORDER_DELAY;
3415 if (pts_buf[j] < pts_buf[r]) {
3416 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3423 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3426 if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3431 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3432 st->codecpar->video_delay, st->index);
3436 static void mov_current_sample_inc(MOVStreamContext *sc)
3438 sc->current_sample++;
3439 sc->current_index++;
3440 if (sc->index_ranges &&
3441 sc->current_index >= sc->current_index_range->end &&
3442 sc->current_index_range->end) {
3443 sc->current_index_range++;
3444 sc->current_index = sc->current_index_range->start;
3448 static void mov_current_sample_dec(MOVStreamContext *sc)
3450 sc->current_sample--;
3451 sc->current_index--;
3452 if (sc->index_ranges &&
3453 sc->current_index < sc->current_index_range->start &&
3454 sc->current_index_range > sc->index_ranges) {
3455 sc->current_index_range--;
3456 sc->current_index = sc->current_index_range->end - 1;
3460 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3464 sc->current_sample = current_sample;
3465 sc->current_index = current_sample;
3466 if (!sc->index_ranges) {
3470 for (sc->current_index_range = sc->index_ranges;
3471 sc->current_index_range->end;
3472 sc->current_index_range++) {
3473 range_size = sc->current_index_range->end - sc->current_index_range->start;
3474 if (range_size > current_sample) {
3475 sc->current_index = sc->current_index_range->start + current_sample;
3478 current_sample -= range_size;
3483 * Fix st->internal->index_entries, so that it contains only the entries (and the entries
3484 * which are needed to decode them) that fall in the edit list time ranges.
3485 * Also fixes the timestamps of the index entries to match the timeline
3486 * specified the edit lists.
3488 static void mov_fix_index(MOVContext *mov, AVStream *st)
3490 MOVStreamContext *msc = st->priv_data;
3491 AVIndexEntry *e_old = st->internal->index_entries;
3492 int nb_old = st->internal->nb_index_entries;
3493 const AVIndexEntry *e_old_end = e_old + nb_old;
3494 const AVIndexEntry *current = NULL;
3495 MOVStts *ctts_data_old = msc->ctts_data;
3496 int64_t ctts_index_old = 0;
3497 int64_t ctts_sample_old = 0;
3498 int64_t ctts_count_old = msc->ctts_count;
3499 int64_t edit_list_media_time = 0;
3500 int64_t edit_list_duration = 0;
3501 int64_t frame_duration = 0;
3502 int64_t edit_list_dts_counter = 0;
3503 int64_t edit_list_dts_entry_end = 0;
3504 int64_t edit_list_start_ctts_sample = 0;
3506 int64_t curr_ctts = 0;
3507 int64_t empty_edits_sum_duration = 0;
3508 int64_t edit_list_index = 0;
3511 int64_t start_dts = 0;
3512 int64_t edit_list_start_encountered = 0;
3513 int64_t search_timestamp = 0;
3514 int64_t* frame_duration_buffer = NULL;
3515 int num_discarded_begin = 0;
3516 int first_non_zero_audio_edit = -1;
3517 int packet_skip_samples = 0;
3518 MOVIndexRange *current_index_range;
3520 int found_keyframe_after_edit = 0;
3521 int found_non_empty_edit = 0;
3523 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
3527 // allocate the index ranges array
3528 msc->index_ranges = av_malloc((msc->elst_count + 1) * sizeof(msc->index_ranges[0]));
3529 if (!msc->index_ranges) {
3530 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
3533 msc->current_index_range = msc->index_ranges;
3534 current_index_range = msc->index_ranges - 1;
3536 // Clean AVStream from traces of old index
3537 st->internal->index_entries = NULL;
3538 st->internal->index_entries_allocated_size = 0;
3539 st->internal->nb_index_entries = 0;
3541 // Clean ctts fields of MOVStreamContext
3542 msc->ctts_data = NULL;
3543 msc->ctts_count = 0;
3544 msc->ctts_index = 0;
3545 msc->ctts_sample = 0;
3546 msc->ctts_allocated_size = 0;
3548 // Reinitialize min_corrected_pts so that it can be computed again.
3549 msc->min_corrected_pts = -1;
3551 // If the dts_shift is positive (in case of negative ctts values in mov),
3552 // then negate the DTS by dts_shift
3553 if (msc->dts_shift > 0) {
3554 edit_list_dts_entry_end -= msc->dts_shift;
3555 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
3558 start_dts = edit_list_dts_entry_end;
3560 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
3561 &edit_list_duration, mov->time_scale)) {
3562 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
3563 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
3565 edit_list_dts_counter = edit_list_dts_entry_end;
3566 edit_list_dts_entry_end += edit_list_duration;
3567 num_discarded_begin = 0;
3568 if (!found_non_empty_edit && edit_list_media_time == -1) {
3569 empty_edits_sum_duration += edit_list_duration;
3572 found_non_empty_edit = 1;
3574 // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
3575 // according to the edit list below.
3576 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3577 if (first_non_zero_audio_edit < 0) {
3578 first_non_zero_audio_edit = 1;
3580 first_non_zero_audio_edit = 0;
3583 if (first_non_zero_audio_edit > 0)
3584 st->internal->skip_samples = msc->start_pad = 0;
3587 // While reordering frame index according to edit list we must handle properly
3588 // the scenario when edit list entry starts from none key frame.
3589 // We find closest previous key frame and preserve it and consequent frames in index.
3590 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
3591 search_timestamp = edit_list_media_time;
3592 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3593 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
3594 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
3595 // edit_list_media_time to cover the decoder delay.
3596 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
3599 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
3600 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3601 av_log(mov->fc, AV_LOG_WARNING,
3602 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
3603 st->index, edit_list_index, search_timestamp);
3604 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
3605 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3606 av_log(mov->fc, AV_LOG_WARNING,
3607 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
3608 st->index, edit_list_index, search_timestamp);
3611 ctts_sample_old = 0;
3614 current = e_old + index;
3615 edit_list_start_ctts_sample = ctts_sample_old;
3617 // Iterate over index and arrange it according to edit list
3618 edit_list_start_encountered = 0;
3619 found_keyframe_after_edit = 0;
3620 for (; current < e_old_end; current++, index++) {
3621 // check if frame outside edit list mark it for discard
3622 frame_duration = (current + 1 < e_old_end) ?
3623 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
3625 flags = current->flags;
3627 // frames (pts) before or after edit list
3628 curr_cts = current->timestamp + msc->dts_shift;
3631 if (ctts_data_old && ctts_index_old < ctts_count_old) {
3632 curr_ctts = ctts_data_old[ctts_index_old].duration;
3633 av_log(mov->fc, AV_LOG_DEBUG, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
3634 curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
3635 curr_cts += curr_ctts;
3637 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
3638 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3639 &msc->ctts_allocated_size,
3640 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3641 ctts_data_old[ctts_index_old].duration) == -1) {
3642 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3644 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3645 ctts_data_old[ctts_index_old].duration);
3649 ctts_sample_old = 0;
3650 edit_list_start_ctts_sample = 0;
3654 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
3655 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
3656 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
3657 first_non_zero_audio_edit > 0) {
3658 packet_skip_samples = edit_list_media_time - curr_cts;
3659 st->internal->skip_samples += packet_skip_samples;
3661 // Shift the index entry timestamp by packet_skip_samples to be correct.
3662 edit_list_dts_counter -= packet_skip_samples;
3663 if (edit_list_start_encountered == 0) {
3664 edit_list_start_encountered = 1;
3665 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
3666 // discarded packets.
3667 if (frame_duration_buffer) {
3668 fix_index_entry_timestamps(st, st->internal->nb_index_entries, edit_list_dts_counter,
3669 frame_duration_buffer, num_discarded_begin);
3670 av_freep(&frame_duration_buffer);
3674 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
3676 flags |= AVINDEX_DISCARD_FRAME;
3677 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
3679 if (edit_list_start_encountered == 0) {
3680 num_discarded_begin++;
3681 frame_duration_buffer = av_realloc(frame_duration_buffer,
3682 num_discarded_begin * sizeof(int64_t));
3683 if (!frame_duration_buffer) {
3684 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
3687 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
3689 // Increment skip_samples for the first non-zero audio edit list
3690 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3691 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
3692 st->internal->skip_samples += frame_duration;
3697 if (msc->min_corrected_pts < 0) {
3698 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
3700 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
3702 if (edit_list_start_encountered == 0) {
3703 edit_list_start_encountered = 1;
3704 // Make timestamps strictly monotonically increasing by rewriting timestamps for
3705 // discarded packets.
3706 if (frame_duration_buffer) {
3707 fix_index_entry_timestamps(st, st->internal->nb_index_entries, edit_list_dts_counter,
3708 frame_duration_buffer, num_discarded_begin);
3709 av_freep(&frame_duration_buffer);
3714 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
3715 current->min_distance, flags) == -1) {
3716 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
3720 // Update the index ranges array
3721 if (current_index_range < msc->index_ranges || index != current_index_range->end) {
3722 current_index_range++;
3723 current_index_range->start = index;
3725 current_index_range->end = index + 1;
3727 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
3728 if (edit_list_start_encountered > 0) {
3729 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
3732 // Break when found first key frame after edit entry completion
3733 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
3734 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
3735 if (ctts_data_old) {
3736 // If we have CTTS and this is the first keyframe after edit elist,
3737 // wait for one more, because there might be trailing B-frames after this I-frame
3738 // that do belong to the edit.
3739 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
3740 found_keyframe_after_edit = 1;
3743 if (ctts_sample_old != 0) {
3744 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3745 &msc->ctts_allocated_size,
3746 ctts_sample_old - edit_list_start_ctts_sample,
3747 ctts_data_old[ctts_index_old].duration) == -1) {
3748 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3749 ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
3750 ctts_data_old[ctts_index_old].duration);
3759 // If there are empty edits, then msc->min_corrected_pts might be positive
3760 // intentionally. So we subtract the sum duration of emtpy edits here.
3761 msc->min_corrected_pts -= empty_edits_sum_duration;
3763 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
3764 // dts by that amount to make the first pts zero.
3765 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
3766 if (msc->min_corrected_pts > 0) {
3767 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
3768 for (i = 0; i < st->internal->nb_index_entries; ++i) {
3769 st->internal->index_entries[i].timestamp -= msc->min_corrected_pts;
3773 // Start time should be equal to zero or the duration of any empty edits.
3774 st->start_time = empty_edits_sum_duration;
3776 // Update av stream length, if it ends up shorter than the track's media duration
3777 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
3778 msc->start_pad = st->internal->skip_samples;
3780 // Free the old index and the old CTTS structures
3782 av_free(ctts_data_old);
3783 av_freep(&frame_duration_buffer);
3785 // Null terminate the index ranges array
3786 current_index_range++;
3787 current_index_range->start = 0;
3788 current_index_range->end = 0;
3789 msc->current_index = msc->index_ranges[0].start;
3792 static void mov_build_index(MOVContext *mov, AVStream *st)
3794 MOVStreamContext *sc = st->priv_data;
3795 int64_t current_offset;
3796 int64_t current_dts = 0;
3797 unsigned int stts_index = 0;
3798 unsigned int stsc_index = 0;
3799 unsigned int stss_index = 0;
3800 unsigned int stps_index = 0;
3802 uint64_t stream_size = 0;
3803 MOVStts *ctts_data_old = sc->ctts_data;
3804 unsigned int ctts_count_old = sc->ctts_count;
3806 if (sc->elst_count) {
3807 int i, edit_start_index = 0, multiple_edits = 0;
3808 int64_t empty_duration = 0; // empty duration of the first edit list entry
3809 int64_t start_time = 0; // start time of the media
3811 for (i = 0; i < sc->elst_count; i++) {
3812 const MOVElst *e = &sc->elst_data[i];
3813 if (i == 0 && e->time == -1) {
3814 /* if empty, the first entry is the start time of the stream
3815 * relative to the presentation itself */
3816 empty_duration = e->duration;
3817 edit_start_index = 1;
3818 } else if (i == edit_start_index && e->time >= 0) {
3819 start_time = e->time;
3825 if (multiple_edits && !mov->advanced_editlist)
3826 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
3827 "Use -advanced_editlist to correctly decode otherwise "
3828 "a/v desync might occur\n");
3830 /* adjust first dts according to edit list */
3831 if ((empty_duration || start_time) && mov->time_scale > 0) {
3833 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
3834 sc->time_offset = start_time - empty_duration;
3835 sc->min_corrected_pts = start_time;
3836 if (!mov->advanced_editlist)
3837 current_dts = -sc->time_offset;
3840 if (!multiple_edits && !mov->advanced_editlist &&
3841 st->codecpar->codec_id == AV_CODEC_ID_AAC && start_time > 0)
3842 sc->start_pad = start_time;
3845 /* only use old uncompressed audio chunk demuxing when stts specifies it */
3846 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3847 sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
3848 unsigned int current_sample = 0;
3849 unsigned int stts_sample = 0;
3850 unsigned int sample_size;
3851 unsigned int distance = 0;
3852 unsigned int rap_group_index = 0;
3853 unsigned int rap_group_sample = 0;
3854 int64_t last_dts = 0;
3855 int64_t dts_correction = 0;
3856 int rap_group_present = sc->rap_group_count && sc->rap_group;
3857 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
3859 current_dts -= sc->dts_shift;
3860 last_dts = current_dts;
3862 if (!sc->sample_count || st->internal->nb_index_entries)
3864 if (sc->sample_count >= UINT_MAX / sizeof(*st->internal->index_entries) - st->internal->nb_index_entries)
3866 if (av_reallocp_array(&st->internal->index_entries,
3867 st->internal->nb_index_entries + sc->sample_count,
3868 sizeof(*st->internal->index_entries)) < 0) {
3869 st->internal->nb_index_entries = 0;
3872 st->internal->index_entries_allocated_size = (st->internal->nb_index_entries + sc->sample_count) * sizeof(*st->internal->index_entries);
3874 if (ctts_data_old) {
3875 // Expand ctts entries such that we have a 1-1 mapping with samples
3876 if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
3879 sc->ctts_allocated_size = 0;
3880 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size,
3881 sc->sample_count * sizeof(*sc->ctts_data));
3882 if (!sc->ctts_data) {
3883 av_free(ctts_data_old);
3887 memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
3889 for (i = 0; i < ctts_count_old &&
3890 sc->ctts_count < sc->sample_count; i++)
3891 for (j = 0; j < ctts_data_old[i].count &&
3892 sc->ctts_count < sc->sample_count; j++)
3893 add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
3894 &sc->ctts_allocated_size, 1,
3895 ctts_data_old[i].duration);
3896 av_free(ctts_data_old);
3899 for (i = 0; i < sc->chunk_count; i++) {
3900 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
3901 current_offset = sc->chunk_offsets[i];
3902 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3903 i + 1 == sc->stsc_data[stsc_index + 1].first)
3906 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
3907 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
3908 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
3909 sc->stsz_sample_size = sc->sample_size;
3911 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
3912 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
3913 sc->stsz_sample_size = sc->sample_size;
3916 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
3918 if (current_sample >= sc->sample_count) {
3919 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
3923 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
3925 if (stss_index + 1 < sc->keyframe_count)
3927 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
3929 if (stps_index + 1 < sc->stps_count)
3932 if (rap_group_present && rap_group_index < sc->rap_group_count) {
3933 if (sc->rap_group[rap_group_index].index > 0)
3935 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
3936 rap_group_sample = 0;
3940 if (sc->keyframe_absent
3942 && !rap_group_present
3943 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
3947 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
3948 if (sc->pseudo_stream_id == -1 ||
3949 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
3951 if (sample_size > 0x3FFFFFFF) {
3952 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
3955 e = &st->internal->index_entries[st->internal->nb_index_entries++];
3956 e->pos = current_offset;
3957 e->timestamp = current_dts;
3958 e->size = sample_size;
3959 e->min_distance = distance;
3960 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
3961 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
3962 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
3963 current_offset, current_dts, sample_size, distance, keyframe);
3964 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->internal->nb_index_entries < 100)
3965 ff_rfps_add_frame(mov->fc, st, current_dts);
3968 current_offset += sample_size;
3969 stream_size += sample_size;
3971 /* A negative sample duration is invalid based on the spec,
3972 * but some samples need it to correct the DTS. */
3973 if (sc->stts_data[stts_index].duration < 0) {
3974 av_log(mov->fc, AV_LOG_WARNING,
3975 "Invalid SampleDelta %d in STTS, at %d st:%d\n",
3976 sc->stts_data[stts_index].duration, stts_index,
3978 dts_correction += sc->stts_data[stts_index].duration - 1;
3979 sc->stts_data[stts_index].duration = 1;
3981 current_dts += sc->stts_data[stts_index].duration;
3982 if (!dts_correction || current_dts + dts_correction > last_dts) {
3983 current_dts += dts_correction;
3986 /* Avoid creating non-monotonous DTS */
3987 dts_correction += current_dts - last_dts - 1;
3988 current_dts = last_dts + 1;
3990 last_dts = current_dts;
3994 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
4000 if (st->duration > 0)
4001 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
4003 unsigned chunk_samples, total = 0;
4005 if (!sc->chunk_count)
4008 // compute total chunk count
4009 for (i = 0; i < sc->stsc_count; i++) {
4010 unsigned count, chunk_count;
4012 chunk_samples = sc->stsc_data[i].count;
4013 if (i != sc->stsc_count - 1 &&
4014 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
4015 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
4019 if (sc->samples_per_frame >= 160) { // gsm
4020 count = chunk_samples / sc->samples_per_frame;
4021 } else if (sc->samples_per_frame > 1) {
4022 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4023 count = (chunk_samples+samples-1) / samples;
4025 count = (chunk_samples+1023) / 1024;
4028 if (mov_stsc_index_valid(i, sc->stsc_count))
4029 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4031 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4032 total += chunk_count * count;
4035 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4036 if (total >= UINT_MAX / sizeof(*st->internal->index_entries) - st->internal->nb_index_entries)
4038 if (av_reallocp_array(&st->internal->index_entries,
4039 st->internal->nb_index_entries + total,
4040 sizeof(*st->internal->index_entries)) < 0) {
4041 st->internal->nb_index_entries = 0;
4044 st->internal->index_entries_allocated_size = (st->internal->nb_index_entries + total) * sizeof(*st->internal->index_entries);
4047 for (i = 0; i < sc->chunk_count; i++) {
4048 current_offset = sc->chunk_offsets[i];
4049 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4050 i + 1 == sc->stsc_data[stsc_index + 1].first)
4052 chunk_samples = sc->stsc_data[stsc_index].count;
4054 while (chunk_samples > 0) {
4056 unsigned size, samples;
4058 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4059 avpriv_request_sample(mov->fc,
4060 "Zero bytes per frame, but %d samples per frame",
4061 sc->samples_per_frame);
4065 if (sc->samples_per_frame >= 160) { // gsm
4066 samples = sc->samples_per_frame;
4067 size = sc->bytes_per_frame;
4069 if (sc->samples_per_frame > 1) {
4070 samples = FFMIN((1024 / sc->samples_per_frame)*
4071 sc->samples_per_frame, chunk_samples);
4072 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
4074 samples = FFMIN(1024, chunk_samples);
4075 size = samples * sc->sample_size;
4079 if (st->internal->nb_index_entries >= total) {
4080 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4083 if (size > 0x3FFFFFFF) {
4084 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4087 e = &st->internal->index_entries[st->internal->nb_index_entries++];
4088 e->pos = current_offset;
4089 e->timestamp = current_dts;
4091 e->min_distance = 0;
4092 e->flags = AVINDEX_KEYFRAME;
4093 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4094 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4097 current_offset += size;
4098 current_dts += samples;
4099 chunk_samples -= samples;
4104 if (!mov->ignore_editlist && mov->advanced_editlist) {
4105 // Fix index according to edit lists.
4106 mov_fix_index(mov, st);
4109 // Update start time of the stream.
4110 if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->internal->nb_index_entries > 0) {
4111 st->start_time = st->internal->index_entries[0].timestamp + sc->dts_shift;
4112 if (sc->ctts_data) {
4113 st->start_time += sc->ctts_data[0].duration;
4117 mov_estimate_video_delay(mov, st);
4120 static int test_same_origin(const char *src, const char *ref) {
4130 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4131 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4133 if (strlen(src) == 0) {
4135 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4136 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4137 strlen(src_host) + 1 >= sizeof(src_host) ||
4138 strlen(ref_host) + 1 >= sizeof(ref_host)) {
4140 } else if (strcmp(src_proto, ref_proto) ||
4141 strcmp(src_auth, ref_auth) ||
4142 strcmp(src_host, ref_host) ||
4143 src_port != ref_port) {
4149 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4151 /* try relative path, we do not try the absolute because it can leak information about our
4152 system to an attacker */
4153 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4154 char filename[1025];
4155 const char *src_path;
4158 /* find a source dir */
4159 src_path = strrchr(src, '/');
4165 /* find a next level down to target */
4166 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4167 if (ref->path[l] == '/') {
4168 if (i == ref->nlvl_to - 1)
4174 /* compose filename if next level down to target was found */
4175 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4176 memcpy(filename, src, src_path - src);
4177 filename[src_path - src] = 0;
4179 for (i = 1; i < ref->nlvl_from; i++)
4180 av_strlcat(filename, "../", sizeof(filename));
4182 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4183 if (!c->use_absolute_path) {
4184 int same_origin = test_same_origin(src, filename);
4187 av_log(c->fc, AV_LOG_ERROR,
4188 "Reference with mismatching origin, %s not tried for security reasons, "
4189 "set demuxer option use_absolute_path to allow it anyway\n",
4191 return AVERROR(ENOENT);
4194 if (strstr(ref->path + l + 1, "..") ||
4195 strstr(ref->path + l + 1, ":") ||
4196 (ref->nlvl_from > 1 && same_origin < 0) ||
4197 (filename[0] == '/' && src_path == src))
4198 return AVERROR(ENOENT);
4201 if (strlen(filename) + 1 == sizeof(filename))
4202 return AVERROR(ENOENT);
4203 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4206 } else if (c->use_absolute_path) {
4207 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4208 "this is a possible security issue\n");
4209 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4212 av_log(c->fc, AV_LOG_ERROR,
4213 "Absolute path %s not tried for security reasons, "
4214 "set demuxer option use_absolute_path to allow absolute paths\n",
4218 return AVERROR(ENOENT);
4221 static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
4223 if (sc->time_scale <= 0) {
4224 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4225 sc->time_scale = c->time_scale;
4226 if (sc->time_scale <= 0)
4231 static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4234 MOVStreamContext *sc;
4237 st = avformat_new_stream(c->fc, NULL);
4238 if (!st) return AVERROR(ENOMEM);
4240 sc = av_mallocz(sizeof(MOVStreamContext));
4241 if (!sc) return AVERROR(ENOMEM);
4244 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
4245 sc->ffindex = st->index;
4246 c->trak_index = st->index;
4248 if ((ret = mov_read_default(c, pb, atom)) < 0)
4253 // Here stsc refers to a chunk not described in stco. This is technically invalid,
4254 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4255 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4257 av_freep(&sc->stsc_data);
4261 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4262 (!sc->sample_size && !sc->sample_count))) ||
4263 (!sc->chunk_count && sc->sample_count)) {
4264 av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4268 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4269 av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4271 return AVERROR_INVALIDDATA;
4274 fix_timescale(c, sc);
4276 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4278 mov_build_index(c, st);
4280 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4281 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4282 if (c->enable_drefs) {
4283 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4284 av_log(c->fc, AV_LOG_ERROR,
4285 "stream %d, error opening alias: path='%s', dir='%s', "
4286 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4287 st->index, dref->path, dref->dir, dref->filename,
4288 dref->volume, dref->nlvl_from, dref->nlvl_to);
4290 av_log(c->fc, AV_LOG_WARNING,
4291 "Skipped opening external track: "
4292 "stream %d, alias: path='%s', dir='%s', "
4293 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4294 "Set enable_drefs to allow this.\n",
4295 st->index, dref->path, dref->dir, dref->filename,
4296 dref->volume, dref->nlvl_from, dref->nlvl_to);
4300 sc->pb_is_copied = 1;
4303 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4304 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4305 sc->height && sc->width &&
4306 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4307 st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4308 ((double)st->codecpar->width * sc->height), INT_MAX);
4311 #if FF_API_R_FRAME_RATE
4312 if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4313 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
4314 sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4318 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4319 if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4320 TAG_IS_AVCI(st->codecpar->codec_tag)) {
4321 ret = ff_generate_avci_extradata(st);
4326 switch (st->codecpar->codec_id) {
4327 #if CONFIG_H261_DECODER
4328 case AV_CODEC_ID_H261:
4330 #if CONFIG_H263_DECODER
4331 case AV_CODEC_ID_H263:
4333 #if CONFIG_MPEG4_DECODER
4334 case AV_CODEC_ID_MPEG4:
4336 st->codecpar->width = 0; /* let decoder init width/height */
4337 st->codecpar->height= 0;
4341 // If the duration of the mp3 packets is not constant, then they could need a parser
4342 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4343 && sc->stts_count > 3
4344 && sc->stts_count*10 > st->nb_frames
4345 && sc->time_scale == st->codecpar->sample_rate) {
4346 st->need_parsing = AVSTREAM_PARSE_FULL;
4348 /* Do not need those anymore. */
4349 av_freep(&sc->chunk_offsets);
4350 av_freep(&sc->sample_sizes);
4351 av_freep(&sc->keyframes);
4352 av_freep(&sc->stts_data);
4353 av_freep(&sc->stps_data);
4354 av_freep(&sc->elst_data);
4355 av_freep(&sc->rap_group);
4360 static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4363 c->itunes_metadata = 1;
4364 ret = mov_read_default(c, pb, atom);
4365 c->itunes_metadata = 0;
4369 static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4378 count = avio_rb32(pb);
4379 if (count > UINT_MAX / sizeof(*c->meta_keys) - 1) {
4380 av_log(c->fc, AV_LOG_ERROR,
4381 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
4382 return AVERROR_INVALIDDATA;
4385 c->meta_keys_count = count + 1;
4386 c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
4388 return AVERROR(ENOMEM);
4390 for (i = 1; i <= count; ++i) {
4391 uint32_t key_size = avio_rb32(pb);
4392 uint32_t type = avio_rl32(pb);
4394 av_log(c->fc, AV_LOG_ERROR,
4395 "The key# %"PRIu32" in meta has invalid size:"
4396 "%"PRIu32"\n", i, key_size);
4397 return AVERROR_INVALIDDATA;
4400 if (type != MKTAG('m','d','t','a')) {
4401 avio_skip(pb, key_size);
4403 c->meta_keys[i] = av_mallocz(key_size + 1);
4404 if (!c->meta_keys[i])
4405 return AVERROR(ENOMEM);
4406 avio_read(pb, c->meta_keys[i], key_size);
4412 static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4414 int64_t end = av_sat_add64(avio_tell(pb), atom.size);
4415 uint8_t *key = NULL, *val = NULL, *mean = NULL;
4419 MOVStreamContext *sc;
4421 if (c->fc->nb_streams < 1)
4423 st = c->fc->streams[c->fc->nb_streams-1];
4426 for (i = 0; i < 3; i++) {
4430 if (end - avio_tell(pb) <= 12)
4433 len = avio_rb32(pb);
4434 tag = avio_rl32(pb);
4435 avio_skip(pb, 4); // flags
4437 if (len < 12 || len - 12 > end - avio_tell(pb))
4441 if (tag == MKTAG('m', 'e', 'a', 'n'))
4443 else if (tag == MKTAG('n', 'a', 'm', 'e'))
4445 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
4455 *p = av_malloc(len + 1);
4457 ret = AVERROR(ENOMEM);
4460 ret = ffio_read_size(pb, *p, len);
4468 if (mean && key && val) {
4469 if (strcmp(key, "iTunSMPB") == 0) {
4470 int priming, remainder, samples;
4471 if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
4472 if(priming>0 && priming<16384)
4473 sc->start_pad = priming;
4476 if (strcmp(key, "cdec") != 0) {
4477 av_dict_set(&c->fc->metadata, key, val,
4478 AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
4482 av_log(c->fc, AV_LOG_VERBOSE,
4483 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
4486 avio_seek(pb, end, SEEK_SET);
4493 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4495 while (atom.size > 8) {
4499 tag = avio_rl32(pb);
4501 if (tag == MKTAG('h','d','l','r')) {
4502 avio_seek(pb, -8, SEEK_CUR);
4504 return mov_read_default(c, pb, atom);
4510 // return 1 when matrix is identity, 0 otherwise
4511 #define IS_MATRIX_IDENT(matrix) \
4512 ( (matrix)[0][0] == (1 << 16) && \
4513 (matrix)[1][1] == (1 << 16) && \
4514 (matrix)[2][2] == (1 << 30) && \
4515 !(matrix)[0][1] && !(matrix)[0][2] && \
4516 !(matrix)[1][0] && !(matrix)[1][2] && \
4517 !(matrix)[2][0] && !(matrix)[2][1])
4519 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4524 int display_matrix[3][3];
4525 int res_display_matrix[3][3] = { { 0 } };
4527 MOVStreamContext *sc;
4531 if (c->fc->nb_streams < 1)
4533 st = c->fc->streams[c->fc->nb_streams-1];
4536 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4537 // avoids corrupting AVStreams mapped to an earlier tkhd.
4539 return AVERROR_INVALIDDATA;
4541 version = avio_r8(pb);
4542 flags = avio_rb24(pb);
4543 st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
4549 avio_rb32(pb); /* creation time */
4550 avio_rb32(pb); /* modification time */
4552 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4553 avio_rb32(pb); /* reserved */
4555 /* highlevel (considering edits) duration in movie timebase */
4556 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4557 avio_rb32(pb); /* reserved */
4558 avio_rb32(pb); /* reserved */
4560 avio_rb16(pb); /* layer */
4561 avio_rb16(pb); /* alternate group */
4562 avio_rb16(pb); /* volume */
4563 avio_rb16(pb); /* reserved */
4565 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4566 // they're kept in fixed point format through all calculations
4567 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4568 // side data, but the scale factor is not needed to calculate aspect ratio
4569 for (i = 0; i < 3; i++) {
4570 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
4571 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
4572 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
4575 width = avio_rb32(pb); // 16.16 fixed point track width
4576 height = avio_rb32(pb); // 16.16 fixed point track height
4577 sc->width = width >> 16;
4578 sc->height = height >> 16;
4580 // apply the moov display matrix (after the tkhd one)
4581 for (i = 0; i < 3; i++) {
4582 const int sh[3] = { 16, 16, 30 };
4583 for (j = 0; j < 3; j++) {
4584 for (e = 0; e < 3; e++) {
4585 res_display_matrix[i][j] +=
4586 ((int64_t) display_matrix[i][e] *
4587 c->movie_display_matrix[e][j]) >> sh[e];
4592 // save the matrix when it is not the default identity
4593 if (!IS_MATRIX_IDENT(res_display_matrix)) {
4596 av_freep(&sc->display_matrix);
4597 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4598 if (!sc->display_matrix)
4599 return AVERROR(ENOMEM);
4601 for (i = 0; i < 3; i++)
4602 for (j = 0; j < 3; j++)
4603 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4605 #if FF_API_OLD_ROTATE_API
4606 rotate = av_display_rotation_get(sc->display_matrix);
4607 if (!isnan(rotate)) {
4608 char rotate_buf[64];
4610 if (rotate < 0) // for backward compatibility
4612 snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate);
4613 av_dict_set(&st->metadata, "rotate", rotate_buf, 0);
4618 // transform the display width/height according to the matrix
4619 // to keep the same scale, use [width height 1<<16]
4620 if (width && height && sc->display_matrix) {
4621 double disp_transform[2];
4623 for (i = 0; i < 2; i++)
4624 disp_transform[i] = hypot(sc->display_matrix[0 + i],
4625 sc->display_matrix[3 + i]);
4627 if (disp_transform[0] > 0 && disp_transform[1] > 0 &&
4628 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4629 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4630 st->sample_aspect_ratio = av_d2q(
4631 disp_transform[0] / disp_transform[1],
4637 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4639 MOVFragment *frag = &c->fragment;
4640 MOVTrackExt *trex = NULL;
4641 int flags, track_id, i;
4642 MOVFragmentStreamInfo * frag_stream_info;
4644 avio_r8(pb); /* version */
4645 flags = avio_rb24(pb);
4647 track_id = avio_rb32(pb);
4649 return AVERROR_INVALIDDATA;
4650 for (i = 0; i < c->trex_count; i++)
4651 if (c->trex_data[i].track_id == track_id) {
4652 trex = &c->trex_data[i];
4656 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4659 c->fragment.found_tfhd = 1;
4660 frag->track_id = track_id;
4661 set_frag_stream(&c->frag_index, track_id);
4663 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4664 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4665 frag->moof_offset : frag->implicit_offset;
4666 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4668 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4669 avio_rb32(pb) : trex->duration;
4670 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4671 avio_rb32(pb) : trex->size;
4672 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4673 avio_rb32(pb) : trex->flags;
4674 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4676 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4677 if (frag_stream_info)
4678 frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
4683 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4688 num = atom.size / 4;
4689 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4690 return AVERROR(ENOMEM);
4692 av_free(c->chapter_tracks);
4693 c->chapter_tracks = new_tracks;
4694 c->nb_chapter_tracks = num;
4696 for (i = 0; i < num && !pb->eof_reached; i++)
4697 c->chapter_tracks[i] = avio_rb32(pb);
4702 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4707 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4708 return AVERROR_INVALIDDATA;
4709 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4710 sizeof(*c->trex_data))) < 0) {
4715 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4717 trex = &c->trex_data[c->trex_count++];
4718 avio_r8(pb); /* version */
4719 avio_rb24(pb); /* flags */
4720 trex->track_id = avio_rb32(pb);
4721 trex->stsd_id = avio_rb32(pb);
4722 trex->duration = avio_rb32(pb);
4723 trex->size = avio_rb32(pb);
4724 trex->flags = avio_rb32(pb);
4728 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4730 MOVFragment *frag = &c->fragment;
4731 AVStream *st = NULL;
4732 MOVStreamContext *sc;
4734 MOVFragmentStreamInfo * frag_stream_info;
4735 int64_t base_media_decode_time;
4737 for (i = 0; i < c->fc->nb_streams; i++) {
4738 if (c->fc->streams[i]->id == frag->track_id) {
4739 st = c->fc->streams[i];
4744 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4748 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4750 version = avio_r8(pb);
4751 avio_rb24(pb); /* flags */
4753 base_media_decode_time = avio_rb64(pb);
4755 base_media_decode_time = avio_rb32(pb);
4758 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4759 if (frag_stream_info)
4760 frag_stream_info->tfdt_dts = base_media_decode_time;
4761 sc->track_end = base_media_decode_time;
4766 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4768 MOVFragment *frag = &c->fragment;
4769 AVStream *st = NULL;
4770 MOVStreamContext *sc;
4773 int64_t dts, pts = AV_NOPTS_VALUE;
4774 int data_offset = 0;
4775 unsigned entries, first_sample_flags = frag->flags;
4776 int flags, distance, i;
4777 int64_t prev_dts = AV_NOPTS_VALUE;
4778 int next_frag_index = -1, index_entry_pos;
4779 size_t requested_size;
4780 size_t old_ctts_allocated_size;
4781 AVIndexEntry *new_entries;
4782 MOVFragmentStreamInfo * frag_stream_info;
4784 if (!frag->found_tfhd) {
4785 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4786 return AVERROR_INVALIDDATA;
4789 for (i = 0; i < c->fc->nb_streams; i++) {
4790 if (c->fc->streams[i]->id == frag->track_id) {
4791 st = c->fc->streams[i];
4796 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4800 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4803 // Find the next frag_index index that has a valid index_entry for
4804 // the current track_id.
4806 // A valid index_entry means the trun for the fragment was read
4807 // and it's samples are in index_entries at the given position.
4808 // New index entries will be inserted before the index_entry found.
4809 index_entry_pos = st->internal->nb_index_entries;
4810 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4811 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4812 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4813 next_frag_index = i;
4814 index_entry_pos = frag_stream_info->index_entry;
4818 av_assert0(index_entry_pos <= st->internal->nb_index_entries);
4820 avio_r8(pb); /* version */
4821 flags = avio_rb24(pb);
4822 entries = avio_rb32(pb);
4823 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4825 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4826 return AVERROR_INVALIDDATA;
4827 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4828 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4830 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4831 if (frag_stream_info) {
4832 if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
4833 dts = frag_stream_info->next_trun_dts - sc->time_offset;
4834 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4835 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4836 pts = frag_stream_info->first_tfra_pts;
4837 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4838 ", using it for pts\n", pts);
4839 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4840 c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
4841 dts = frag_stream_info->first_tfra_pts;
4842 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4843 ", using it for dts\n", pts);
4844 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4845 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4846 // pts = frag_stream_info->sidx_pts;
4847 dts = frag_stream_info->sidx_pts - sc->time_offset;
4848 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4849 ", using it for pts\n", pts);
4850 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4851 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4852 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4853 ", using it for dts\n", dts);
4855 dts = sc->track_end - sc->time_offset;
4856 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4857 ", using it for dts\n", dts);
4860 dts = sc->track_end - sc->time_offset;
4861 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4862 ", using it for dts\n", dts);
4864 offset = frag->base_data_offset + data_offset;
4866 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4868 // realloc space for new index entries
4869 if((uint64_t)st->internal->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4870 entries = UINT_MAX / sizeof(AVIndexEntry) - st->internal->nb_index_entries;
4871 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4876 requested_size = (st->internal->nb_index_entries + entries) * sizeof(AVIndexEntry);
4877 new_entries = av_fast_realloc(st->internal->index_entries,
4878 &st->internal->index_entries_allocated_size,
4881 return AVERROR(ENOMEM);
4882 st->internal->index_entries= new_entries;
4884 requested_size = (st->internal->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4885 old_ctts_allocated_size = sc->ctts_allocated_size;
4886 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4889 return AVERROR(ENOMEM);
4890 sc->ctts_data = ctts_data;
4892 // In case there were samples without ctts entries, ensure they get
4893 // zero valued entries. This ensures clips which mix boxes with and
4894 // without ctts entries don't pickup uninitialized data.
4895 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4896 sc->ctts_allocated_size - old_ctts_allocated_size);
4898 if (index_entry_pos < st->internal->nb_index_entries) {
4899 // Make hole in index_entries and ctts_data for new samples
4900 memmove(st->internal->index_entries + index_entry_pos + entries,
4901 st->internal->index_entries + index_entry_pos,
4902 sizeof(*st->internal->index_entries) *
4903 (st->internal->nb_index_entries - index_entry_pos));
4904 memmove(sc->ctts_data + index_entry_pos + entries,
4905 sc->ctts_data + index_entry_pos,
4906 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4907 if (index_entry_pos < sc->current_sample) {
4908 sc->current_sample += entries;
4912 st->internal->nb_index_entries += entries;
4913 sc->ctts_count = st->internal->nb_index_entries;
4915 // Record the index_entry position in frag_index of this fragment
4916 if (frag_stream_info)
4917 frag_stream_info->index_entry = index_entry_pos;
4919 if (index_entry_pos > 0)
4920 prev_dts = st->internal->index_entries[index_entry_pos-1].timestamp;
4922 for (i = 0; i < entries && !pb->eof_reached; i++) {
4923 unsigned sample_size = frag->size;
4924 int sample_flags = i ? frag->flags : first_sample_flags;
4925 unsigned sample_duration = frag->duration;
4926 unsigned ctts_duration = 0;
4928 int index_entry_flags = 0;
4930 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4931 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4932 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4933 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4935 mov_update_dts_shift(sc, ctts_duration, c->fc);
4936 if (pts != AV_NOPTS_VALUE) {
4937 dts = pts - sc->dts_shift;
4938 if (flags & MOV_TRUN_SAMPLE_CTS) {
4939 dts -= ctts_duration;
4941 dts -= sc->time_offset;
4943 av_log(c->fc, AV_LOG_DEBUG,
4944 "pts %"PRId64" calculated dts %"PRId64
4945 " sc->dts_shift %d ctts.duration %d"
4946 " sc->time_offset %"PRId64
4947 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4949 sc->dts_shift, ctts_duration,
4950 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4951 pts = AV_NOPTS_VALUE;
4954 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4958 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4959 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4962 index_entry_flags |= AVINDEX_KEYFRAME;
4964 // Fragments can overlap in time. Discard overlapping frames after
4966 if (prev_dts >= dts)
4967 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4969 st->internal->index_entries[index_entry_pos].pos = offset;
4970 st->internal->index_entries[index_entry_pos].timestamp = dts;
4971 st->internal->index_entries[index_entry_pos].size= sample_size;
4972 st->internal->index_entries[index_entry_pos].min_distance= distance;
4973 st->internal->index_entries[index_entry_pos].flags = index_entry_flags;
4975 sc->ctts_data[index_entry_pos].count = 1;
4976 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4979 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4980 "size %u, distance %d, keyframe %d\n", st->index,
4981 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4983 dts += sample_duration;
4984 offset += sample_size;
4985 sc->data_size += sample_size;
4987 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4988 1 <= INT_MAX - sc->nb_frames_for_fps
4990 sc->duration_for_fps += sample_duration;
4991 sc->nb_frames_for_fps ++;
4994 if (frag_stream_info)
4995 frag_stream_info->next_trun_dts = dts + sc->time_offset;
4997 // EOF found before reading all entries. Fix the hole this would
4998 // leave in index_entries and ctts_data
4999 int gap = entries - i;
5000 memmove(st->internal->index_entries + index_entry_pos,
5001 st->internal->index_entries + index_entry_pos + gap,
5002 sizeof(*st->internal->index_entries) *
5003 (st->internal->nb_index_entries - (index_entry_pos + gap)));
5004 memmove(sc->ctts_data + index_entry_pos,
5005 sc->ctts_data + index_entry_pos + gap,
5006 sizeof(*sc->ctts_data) *
5007 (sc->ctts_count - (index_entry_pos + gap)));
5009 st->internal->nb_index_entries -= gap;
5010 sc->ctts_count -= gap;
5011 if (index_entry_pos < sc->current_sample) {
5012 sc->current_sample -= gap;
5017 // The end of this new fragment may overlap in time with the start
5018 // of the next fragment in index_entries. Mark the samples in the next
5019 // fragment that overlap with AVINDEX_DISCARD_FRAME
5020 prev_dts = AV_NOPTS_VALUE;
5021 if (index_entry_pos > 0)
5022 prev_dts = st->internal->index_entries[index_entry_pos-1].timestamp;
5023 for (i = index_entry_pos; i < st->internal->nb_index_entries; i++) {
5024 if (prev_dts < st->internal->index_entries[i].timestamp)
5026 st->internal->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
5029 // If a hole was created to insert the new index_entries into,
5030 // the index_entry recorded for all subsequent moof must
5031 // be incremented by the number of entries inserted.
5032 fix_frag_index_entries(&c->frag_index, next_frag_index,
5033 frag->track_id, entries);
5035 if (pb->eof_reached) {
5036 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
5040 frag->implicit_offset = offset;
5042 sc->track_end = dts + sc->time_offset;
5043 if (st->duration < sc->track_end)
5044 st->duration = sc->track_end;
5049 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5051 int64_t stream_size = avio_size(pb);
5052 int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
5053 uint8_t version, is_complete;
5055 unsigned i, j, track_id, item_count;
5056 AVStream *st = NULL;
5057 AVStream *ref_st = NULL;
5058 MOVStreamContext *sc, *ref_sc = NULL;
5059 AVRational timescale;
5061 version = avio_r8(pb);
5063 avpriv_request_sample(c->fc, "sidx version %u", version);
5067 avio_rb24(pb); // flags
5069 track_id = avio_rb32(pb); // Reference ID
5070 for (i = 0; i < c->fc->nb_streams; i++) {
5071 if (c->fc->streams[i]->id == track_id) {
5072 st = c->fc->streams[i];
5077 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5083 timescale = av_make_q(1, avio_rb32(pb));
5085 if (timescale.den <= 0) {
5086 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5087 return AVERROR_INVALIDDATA;
5091 pts = avio_rb32(pb);
5092 offadd= avio_rb32(pb);
5094 pts = avio_rb64(pb);
5095 offadd= avio_rb64(pb);
5097 if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
5098 return AVERROR_INVALIDDATA;
5100 offset += (uint64_t)offadd;
5102 avio_rb16(pb); // reserved
5104 item_count = avio_rb16(pb);
5106 for (i = 0; i < item_count; i++) {
5108 MOVFragmentStreamInfo * frag_stream_info;
5109 uint32_t size = avio_rb32(pb);
5110 uint32_t duration = avio_rb32(pb);
5111 if (size & 0x80000000) {
5112 avpriv_request_sample(c->fc, "sidx reference_type 1");
5113 return AVERROR_PATCHWELCOME;
5115 avio_rb32(pb); // sap_flags
5116 timestamp = av_rescale_q(pts, timescale, st->time_base);
5118 index = update_frag_index(c, offset);
5119 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5120 if (frag_stream_info)
5121 frag_stream_info->sidx_pts = timestamp;
5123 if (av_sat_add64(offset, size) != offset + size)
5124 return AVERROR_INVALIDDATA;
5129 st->duration = sc->track_end = pts;
5133 // See if the remaining bytes are just an mfra which we can ignore.
5134 is_complete = offset == stream_size;
5135 if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL)) {
5137 int64_t original_pos = avio_tell(pb);
5138 if (!c->have_read_mfra_size) {
5139 if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
5141 c->mfra_size = avio_rb32(pb);
5142 c->have_read_mfra_size = 1;
5143 if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
5146 if (offset + c->mfra_size == stream_size)
5151 // Find first entry in fragment index that came from an sidx.
5152 // This will pretty much always be the first entry.
5153 for (i = 0; i < c->frag_index.nb_items; i++) {
5154 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5155 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5156 MOVFragmentStreamInfo * si;
5157 si = &item->stream_info[j];
5158 if (si->sidx_pts != AV_NOPTS_VALUE) {
5159 ref_st = c->fc->streams[j];
5160 ref_sc = ref_st->priv_data;
5165 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5166 st = c->fc->streams[i];
5168 if (!sc->has_sidx) {
5169 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5173 c->frag_index.complete = 1;
5179 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5180 /* like the files created with Adobe Premiere 5.0, for samples see */
5181 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5182 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5187 return 0; /* continue */
5188 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5189 avio_skip(pb, atom.size - 4);
5192 atom.type = avio_rl32(pb);
5194 if (atom.type != MKTAG('m','d','a','t')) {
5195 avio_skip(pb, atom.size);
5198 err = mov_read_mdat(c, pb, atom);
5202 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5207 uint8_t *moov_data; /* uncompressed data */
5208 long cmov_len, moov_len;
5211 avio_rb32(pb); /* dcom atom */
5212 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5213 return AVERROR_INVALIDDATA;
5214 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5215 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5216 return AVERROR_INVALIDDATA;
5218 avio_rb32(pb); /* cmvd atom */
5219 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5220 return AVERROR_INVALIDDATA;
5221 moov_len = avio_rb32(pb); /* uncompressed size */
5222 cmov_len = atom.size - 6 * 4;
5224 cmov_data = av_malloc(cmov_len);
5226 return AVERROR(ENOMEM);
5227 moov_data = av_malloc(moov_len);
5230 return AVERROR(ENOMEM);
5232 ret = ffio_read_size(pb, cmov_data, cmov_len);
5234 goto free_and_return;
5236 ret = AVERROR_INVALIDDATA;
5237 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5238 goto free_and_return;
5239 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5240 goto free_and_return;
5241 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5242 atom.type = MKTAG('m','o','o','v');
5243 atom.size = moov_len;
5244 ret = mov_read_default(c, &ctx, atom);
5250 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5251 return AVERROR(ENOSYS);
5255 /* edit list atom */
5256 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5258 MOVStreamContext *sc;
5259 int i, edit_count, version;
5260 int64_t elst_entry_size;
5262 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5264 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5266 version = avio_r8(pb); /* version */
5267 avio_rb24(pb); /* flags */
5268 edit_count = avio_rb32(pb); /* entries */
5271 elst_entry_size = version == 1 ? 20 : 12;
5272 if (atom.size != edit_count * elst_entry_size) {
5273 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5274 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5275 edit_count, atom.size + 8);
5276 return AVERROR_INVALIDDATA;
5278 edit_count = atom.size / elst_entry_size;
5279 if (edit_count * elst_entry_size != atom.size) {
5280 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
5288 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5289 av_free(sc->elst_data);
5291 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5293 return AVERROR(ENOMEM);
5295 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5296 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5297 MOVElst *e = &sc->elst_data[i];
5300 e->duration = avio_rb64(pb);
5301 e->time = avio_rb64(pb);
5304 e->duration = avio_rb32(pb); /* segment duration */
5305 e->time = (int32_t)avio_rb32(pb); /* media time */
5308 e->rate = avio_rb32(pb) / 65536.0;
5310 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5311 e->duration, e->time, e->rate);
5313 if (e->time < 0 && e->time != -1 &&
5314 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5315 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5316 c->fc->nb_streams-1, i, e->time);
5317 return AVERROR_INVALIDDATA;
5325 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5327 MOVStreamContext *sc;
5329 if (c->fc->nb_streams < 1)
5330 return AVERROR_INVALIDDATA;
5331 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5332 sc->timecode_track = avio_rb32(pb);
5336 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5341 if (c->fc->nb_streams < 1)
5343 st = c->fc->streams[c->fc->nb_streams - 1];
5345 if (atom.size < 4) {
5346 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5347 return AVERROR_INVALIDDATA;
5350 /* For now, propagate only the OBUs, if any. Once libavcodec is
5351 updated to handle isobmff style extradata this can be removed. */
5357 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5364 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5367 int version, color_range, color_primaries, color_trc, color_space;
5369 if (c->fc->nb_streams < 1)
5371 st = c->fc->streams[c->fc->nb_streams - 1];
5373 if (atom.size < 5) {
5374 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5375 return AVERROR_INVALIDDATA;
5378 version = avio_r8(pb);
5380 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5383 avio_skip(pb, 3); /* flags */
5385 avio_skip(pb, 2); /* profile + level */
5386 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5387 color_primaries = avio_r8(pb);
5388 color_trc = avio_r8(pb);
5389 color_space = avio_r8(pb);
5390 if (avio_rb16(pb)) /* codecIntializationDataSize */
5391 return AVERROR_INVALIDDATA;
5393 if (!av_color_primaries_name(color_primaries))
5394 color_primaries = AVCOL_PRI_UNSPECIFIED;
5395 if (!av_color_transfer_name(color_trc))
5396 color_trc = AVCOL_TRC_UNSPECIFIED;
5397 if (!av_color_space_name(color_space))
5398 color_space = AVCOL_SPC_UNSPECIFIED;
5400 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5401 st->codecpar->color_primaries = color_primaries;
5402 st->codecpar->color_trc = color_trc;
5403 st->codecpar->color_space = color_space;
5408 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5410 MOVStreamContext *sc;
5413 if (c->fc->nb_streams < 1)
5414 return AVERROR_INVALIDDATA;
5416 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5418 if (atom.size < 5) {
5419 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5420 return AVERROR_INVALIDDATA;
5423 version = avio_r8(pb);
5425 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5428 avio_skip(pb, 3); /* flags */
5430 sc->mastering = av_mastering_display_metadata_alloc();
5432 return AVERROR(ENOMEM);
5434 for (i = 0; i < 3; i++) {
5435 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5436 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5438 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5439 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5441 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5442 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5444 sc->mastering->has_primaries = 1;
5445 sc->mastering->has_luminance = 1;
5450 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5452 MOVStreamContext *sc;
5453 const int mapping[3] = {1, 2, 0};
5454 const int chroma_den = 50000;
5455 const int luma_den = 10000;
5458 if (c->fc->nb_streams < 1)
5459 return AVERROR_INVALIDDATA;
5461 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5463 if (atom.size < 24) {
5464 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5465 return AVERROR_INVALIDDATA;
5468 sc->mastering = av_mastering_display_metadata_alloc();
5470 return AVERROR(ENOMEM);
5472 for (i = 0; i < 3; i++) {
5473 const int j = mapping[i];
5474 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5475 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5477 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5478 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5480 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5481 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5483 sc->mastering->has_luminance = 1;
5484 sc->mastering->has_primaries = 1;
5489 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5491 MOVStreamContext *sc;
5494 if (c->fc->nb_streams < 1)
5495 return AVERROR_INVALIDDATA;
5497 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5499 if (atom.size < 5) {
5500 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5501 return AVERROR_INVALIDDATA;
5504 version = avio_r8(pb);
5506 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5509 avio_skip(pb, 3); /* flags */
5511 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5513 return AVERROR(ENOMEM);
5515 sc->coll->MaxCLL = avio_rb16(pb);
5516 sc->coll->MaxFALL = avio_rb16(pb);
5521 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5523 MOVStreamContext *sc;
5525 if (c->fc->nb_streams < 1)
5526 return AVERROR_INVALIDDATA;
5528 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5530 if (atom.size < 4) {
5531 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5532 return AVERROR_INVALIDDATA;
5535 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5537 return AVERROR(ENOMEM);
5539 sc->coll->MaxCLL = avio_rb16(pb);
5540 sc->coll->MaxFALL = avio_rb16(pb);
5545 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5548 MOVStreamContext *sc;
5549 enum AVStereo3DType type;
5552 if (c->fc->nb_streams < 1)
5555 st = c->fc->streams[c->fc->nb_streams - 1];
5558 if (atom.size < 5) {
5559 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5560 return AVERROR_INVALIDDATA;
5564 return AVERROR_INVALIDDATA;
5566 avio_skip(pb, 4); /* version + flags */
5571 type = AV_STEREO3D_2D;
5574 type = AV_STEREO3D_TOPBOTTOM;
5577 type = AV_STEREO3D_SIDEBYSIDE;
5580 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5584 sc->stereo3d = av_stereo3d_alloc();
5586 return AVERROR(ENOMEM);
5588 sc->stereo3d->type = type;
5592 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5595 MOVStreamContext *sc;
5596 int size, version, layout;
5597 int32_t yaw, pitch, roll;
5598 uint32_t l = 0, t = 0, r = 0, b = 0;
5599 uint32_t tag, padding = 0;
5600 enum AVSphericalProjection projection;
5602 if (c->fc->nb_streams < 1)
5605 st = c->fc->streams[c->fc->nb_streams - 1];
5608 if (atom.size < 8) {
5609 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5610 return AVERROR_INVALIDDATA;
5613 size = avio_rb32(pb);
5614 if (size <= 12 || size > atom.size)
5615 return AVERROR_INVALIDDATA;
5617 tag = avio_rl32(pb);
5618 if (tag != MKTAG('s','v','h','d')) {
5619 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5622 version = avio_r8(pb);
5624 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5628 avio_skip(pb, 3); /* flags */
5629 avio_skip(pb, size - 12); /* metadata_source */
5631 size = avio_rb32(pb);
5632 if (size > atom.size)
5633 return AVERROR_INVALIDDATA;
5635 tag = avio_rl32(pb);
5636 if (tag != MKTAG('p','r','o','j')) {
5637 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5641 size = avio_rb32(pb);
5642 if (size > atom.size)
5643 return AVERROR_INVALIDDATA;
5645 tag = avio_rl32(pb);
5646 if (tag != MKTAG('p','r','h','d')) {
5647 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5650 version = avio_r8(pb);
5652 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5656 avio_skip(pb, 3); /* flags */
5658 /* 16.16 fixed point */
5659 yaw = avio_rb32(pb);
5660 pitch = avio_rb32(pb);
5661 roll = avio_rb32(pb);
5663 size = avio_rb32(pb);
5664 if (size > atom.size)
5665 return AVERROR_INVALIDDATA;
5667 tag = avio_rl32(pb);
5668 version = avio_r8(pb);
5670 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5674 avio_skip(pb, 3); /* flags */
5676 case MKTAG('c','b','m','p'):
5677 layout = avio_rb32(pb);
5679 av_log(c->fc, AV_LOG_WARNING,
5680 "Unsupported cubemap layout %d\n", layout);
5683 projection = AV_SPHERICAL_CUBEMAP;
5684 padding = avio_rb32(pb);
5686 case MKTAG('e','q','u','i'):
5692 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5693 av_log(c->fc, AV_LOG_ERROR,
5694 "Invalid bounding rectangle coordinates "
5695 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5696 return AVERROR_INVALIDDATA;
5699 if (l || t || r || b)
5700 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5702 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5705 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5709 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5711 return AVERROR(ENOMEM);
5713 sc->spherical->projection = projection;
5715 sc->spherical->yaw = yaw;
5716 sc->spherical->pitch = pitch;
5717 sc->spherical->roll = roll;
5719 sc->spherical->padding = padding;
5721 sc->spherical->bound_left = l;
5722 sc->spherical->bound_top = t;
5723 sc->spherical->bound_right = r;
5724 sc->spherical->bound_bottom = b;
5729 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5732 uint8_t *buffer = av_malloc(len + 1);
5736 return AVERROR(ENOMEM);
5739 ret = ffio_read_size(pb, buffer, len);
5743 /* Check for mandatory keys and values, try to support XML as best-effort */
5744 if (!sc->spherical &&
5745 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5746 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5747 av_stristr(val, "true") &&
5748 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5749 av_stristr(val, "true") &&
5750 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5751 av_stristr(val, "equirectangular")) {
5752 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5756 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5758 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5759 enum AVStereo3DType mode;
5761 if (av_stristr(buffer, "left-right"))
5762 mode = AV_STEREO3D_SIDEBYSIDE;
5763 else if (av_stristr(buffer, "top-bottom"))
5764 mode = AV_STEREO3D_TOPBOTTOM;
5766 mode = AV_STEREO3D_2D;
5768 sc->stereo3d = av_stereo3d_alloc();
5772 sc->stereo3d->type = mode;
5776 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5778 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5779 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5781 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5782 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5784 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5792 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5795 MOVStreamContext *sc;
5798 static const uint8_t uuid_isml_manifest[] = {
5799 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5800 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5802 static const uint8_t uuid_xmp[] = {
5803 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5804 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5806 static const uint8_t uuid_spherical[] = {
5807 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5808 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5811 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5812 return AVERROR_INVALIDDATA;
5814 if (c->fc->nb_streams < 1)
5816 st = c->fc->streams[c->fc->nb_streams - 1];
5819 ret = ffio_read_size(pb, uuid, sizeof(uuid));
5822 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5823 uint8_t *buffer, *ptr;
5825 size_t len = atom.size - sizeof(uuid);
5828 return AVERROR_INVALIDDATA;
5830 ret = avio_skip(pb, 4); // zeroes
5833 buffer = av_mallocz(len + 1);
5835 return AVERROR(ENOMEM);
5837 ret = ffio_read_size(pb, buffer, len);
5844 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5845 ptr += sizeof("systemBitrate=\"") - 1;
5846 c->bitrates_count++;
5847 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5849 c->bitrates_count = 0;
5851 return AVERROR(ENOMEM);
5854 ret = strtol(ptr, &endptr, 10);
5855 if (ret < 0 || errno || *endptr != '"') {
5856 c->bitrates[c->bitrates_count - 1] = 0;
5858 c->bitrates[c->bitrates_count - 1] = ret;
5863 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5865 size_t len = atom.size - sizeof(uuid);
5866 if (c->export_xmp) {
5867 buffer = av_mallocz(len + 1);
5869 return AVERROR(ENOMEM);
5871 ret = ffio_read_size(pb, buffer, len);
5877 av_dict_set(&c->fc->metadata, "xmp",
5878 buffer, AV_DICT_DONT_STRDUP_VAL);
5880 // skip all uuid atom, which makes it fast for long uuid-xmp file
5881 ret = avio_skip(pb, len);
5885 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5886 size_t len = atom.size - sizeof(uuid);
5887 ret = mov_parse_uuid_spherical(sc, pb, len);
5891 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5897 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5900 uint8_t content[16];
5905 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5911 && !memcmp(content, "Anevia\x1A\x1A", 8)
5912 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5913 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5919 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5921 uint32_t format = avio_rl32(pb);
5922 MOVStreamContext *sc;
5926 if (c->fc->nb_streams < 1)
5928 st = c->fc->streams[c->fc->nb_streams - 1];
5933 case MKTAG('e','n','c','v'): // encrypted video
5934 case MKTAG('e','n','c','a'): // encrypted audio
5935 id = mov_codec_id(st, format);
5936 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5937 st->codecpar->codec_id != id) {
5938 av_log(c->fc, AV_LOG_WARNING,
5939 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5940 (char*)&format, st->codecpar->codec_id);
5944 st->codecpar->codec_id = id;
5945 sc->format = format;
5949 if (format != sc->format) {
5950 av_log(c->fc, AV_LOG_WARNING,
5951 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5952 (char*)&format, (char*)&sc->format);
5961 * Gets the current encryption info and associated current stream context. If
5962 * we are parsing a track fragment, this will return the specific encryption
5963 * info for this fragment; otherwise this will return the global encryption
5964 * info for the current stream.
5966 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5968 MOVFragmentStreamInfo *frag_stream_info;
5972 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5973 if (frag_stream_info) {
5974 for (i = 0; i < c->fc->nb_streams; i++) {
5975 if (c->fc->streams[i]->id == frag_stream_info->id) {
5976 st = c->fc->streams[i];
5980 if (i == c->fc->nb_streams)
5982 *sc = st->priv_data;
5984 if (!frag_stream_info->encryption_index) {
5985 // If this stream isn't encrypted, don't create the index.
5986 if (!(*sc)->cenc.default_encrypted_sample)
5988 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5989 if (!frag_stream_info->encryption_index)
5990 return AVERROR(ENOMEM);
5992 *encryption_index = frag_stream_info->encryption_index;
5995 // No current track fragment, using stream level encryption info.
5997 if (c->fc->nb_streams < 1)
5999 st = c->fc->streams[c->fc->nb_streams - 1];
6000 *sc = st->priv_data;
6002 if (!(*sc)->cenc.encryption_index) {
6003 // If this stream isn't encrypted, don't create the index.
6004 if (!(*sc)->cenc.default_encrypted_sample)
6006 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
6007 if (!(*sc)->cenc.encryption_index)
6008 return AVERROR(ENOMEM);
6011 *encryption_index = (*sc)->cenc.encryption_index;
6016 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
6019 unsigned int subsample_count;
6020 AVSubsampleEncryptionInfo *subsamples;
6022 if (!sc->cenc.default_encrypted_sample) {
6023 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
6024 return AVERROR_INVALIDDATA;
6027 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
6029 return AVERROR(ENOMEM);
6031 if (sc->cenc.per_sample_iv_size != 0) {
6032 if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
6033 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
6034 av_encryption_info_free(*sample);
6040 if (use_subsamples) {
6041 subsample_count = avio_rb16(pb);
6042 av_free((*sample)->subsamples);
6043 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
6044 if (!(*sample)->subsamples) {
6045 av_encryption_info_free(*sample);
6047 return AVERROR(ENOMEM);
6050 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
6051 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
6052 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
6055 if (pb->eof_reached) {
6056 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
6057 av_encryption_info_free(*sample);
6059 return AVERROR_INVALIDDATA;
6061 (*sample)->subsample_count = subsample_count;
6067 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6069 AVEncryptionInfo **encrypted_samples;
6070 MOVEncryptionIndex *encryption_index;
6071 MOVStreamContext *sc;
6072 int use_subsamples, ret;
6073 unsigned int sample_count, i, alloc_size = 0;
6075 ret = get_current_encryption_info(c, &encryption_index, &sc);
6079 if (encryption_index->nb_encrypted_samples) {
6080 // This can happen if we have both saio/saiz and senc atoms.
6081 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6085 avio_r8(pb); /* version */
6086 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6088 sample_count = avio_rb32(pb);
6089 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6090 return AVERROR(ENOMEM);
6092 for (i = 0; i < sample_count; i++) {
6093 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6094 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6095 min_samples * sizeof(*encrypted_samples));
6096 if (encrypted_samples) {
6097 encryption_index->encrypted_samples = encrypted_samples;
6099 ret = mov_read_sample_encryption_info(
6100 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6102 ret = AVERROR(ENOMEM);
6104 if (pb->eof_reached) {
6105 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6106 ret = AVERROR_INVALIDDATA;
6111 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6112 av_freep(&encryption_index->encrypted_samples);
6116 encryption_index->nb_encrypted_samples = sample_count;
6121 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6123 AVEncryptionInfo **sample, **encrypted_samples;
6125 size_t sample_count, sample_info_size, i;
6127 unsigned int alloc_size = 0;
6129 if (encryption_index->nb_encrypted_samples)
6131 sample_count = encryption_index->auxiliary_info_sample_count;
6132 if (encryption_index->auxiliary_offsets_count != 1) {
6133 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6134 return AVERROR_PATCHWELCOME;
6136 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6137 return AVERROR(ENOMEM);
6139 prev_pos = avio_tell(pb);
6140 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6141 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6142 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6146 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6147 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6148 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6149 min_samples * sizeof(*encrypted_samples));
6150 if (!encrypted_samples) {
6151 ret = AVERROR(ENOMEM);
6154 encryption_index->encrypted_samples = encrypted_samples;
6156 sample = &encryption_index->encrypted_samples[i];
6157 sample_info_size = encryption_index->auxiliary_info_default_size
6158 ? encryption_index->auxiliary_info_default_size
6159 : encryption_index->auxiliary_info_sizes[i];
6161 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6165 if (pb->eof_reached) {
6166 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6167 ret = AVERROR_INVALIDDATA;
6169 encryption_index->nb_encrypted_samples = sample_count;
6173 avio_seek(pb, prev_pos, SEEK_SET);
6175 for (; i > 0; i--) {
6176 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6178 av_freep(&encryption_index->encrypted_samples);
6184 * Tries to read the given number of bytes from the stream and puts it in a
6185 * newly allocated buffer. This reads in small chunks to avoid allocating large
6186 * memory if the file contains an invalid/malicious size value.
6188 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6190 const unsigned int block_size = 1024 * 1024;
6191 uint8_t *buffer = NULL;
6192 unsigned int alloc_size = 0, offset = 0;
6193 while (offset < size) {
6194 unsigned int new_size =
6195 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6196 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6197 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6200 return AVERROR(ENOMEM);
6202 buffer = new_buffer;
6204 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6206 return AVERROR_INVALIDDATA;
6215 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6217 MOVEncryptionIndex *encryption_index;
6218 MOVStreamContext *sc;
6220 unsigned int sample_count, aux_info_type, aux_info_param;
6222 ret = get_current_encryption_info(c, &encryption_index, &sc);
6226 if (encryption_index->nb_encrypted_samples) {
6227 // This can happen if we have both saio/saiz and senc atoms.
6228 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6232 if (encryption_index->auxiliary_info_sample_count) {
6233 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6234 return AVERROR_INVALIDDATA;
6237 avio_r8(pb); /* version */
6238 if (avio_rb24(pb) & 0x01) { /* flags */
6239 aux_info_type = avio_rb32(pb);
6240 aux_info_param = avio_rb32(pb);
6241 if (sc->cenc.default_encrypted_sample) {
6242 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6243 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6246 if (aux_info_param != 0) {
6247 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6251 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6252 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6253 aux_info_type == MKBETAG('c','e','n','s') ||
6254 aux_info_type == MKBETAG('c','b','c','1') ||
6255 aux_info_type == MKBETAG('c','b','c','s')) &&
6256 aux_info_param == 0) {
6257 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6258 return AVERROR_INVALIDDATA;
6263 } else if (!sc->cenc.default_encrypted_sample) {
6264 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6268 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6269 sample_count = avio_rb32(pb);
6270 encryption_index->auxiliary_info_sample_count = sample_count;
6272 if (encryption_index->auxiliary_info_default_size == 0) {
6273 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6275 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6280 if (encryption_index->auxiliary_offsets_count) {
6281 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6287 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6289 uint64_t *auxiliary_offsets;
6290 MOVEncryptionIndex *encryption_index;
6291 MOVStreamContext *sc;
6293 unsigned int version, entry_count, aux_info_type, aux_info_param;
6294 unsigned int alloc_size = 0;
6296 ret = get_current_encryption_info(c, &encryption_index, &sc);
6300 if (encryption_index->nb_encrypted_samples) {
6301 // This can happen if we have both saio/saiz and senc atoms.
6302 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6306 if (encryption_index->auxiliary_offsets_count) {
6307 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6308 return AVERROR_INVALIDDATA;
6311 version = avio_r8(pb); /* version */
6312 if (avio_rb24(pb) & 0x01) { /* flags */
6313 aux_info_type = avio_rb32(pb);
6314 aux_info_param = avio_rb32(pb);
6315 if (sc->cenc.default_encrypted_sample) {
6316 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6317 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6320 if (aux_info_param != 0) {
6321 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6325 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6326 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6327 aux_info_type == MKBETAG('c','e','n','s') ||
6328 aux_info_type == MKBETAG('c','b','c','1') ||
6329 aux_info_type == MKBETAG('c','b','c','s')) &&
6330 aux_info_param == 0) {
6331 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6332 return AVERROR_INVALIDDATA;
6337 } else if (!sc->cenc.default_encrypted_sample) {
6338 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6342 entry_count = avio_rb32(pb);
6343 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6344 return AVERROR(ENOMEM);
6346 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6347 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6348 auxiliary_offsets = av_fast_realloc(
6349 encryption_index->auxiliary_offsets, &alloc_size,
6350 min_offsets * sizeof(*auxiliary_offsets));
6351 if (!auxiliary_offsets) {
6352 av_freep(&encryption_index->auxiliary_offsets);
6353 return AVERROR(ENOMEM);
6355 encryption_index->auxiliary_offsets = auxiliary_offsets;
6358 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6360 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6362 if (c->frag_index.current >= 0) {
6363 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6367 if (pb->eof_reached) {
6368 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6369 av_freep(&encryption_index->auxiliary_offsets);
6370 return AVERROR_INVALIDDATA;
6373 encryption_index->auxiliary_offsets_count = entry_count;
6375 if (encryption_index->auxiliary_info_sample_count) {
6376 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6382 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6384 AVEncryptionInitInfo *info, *old_init_info;
6387 uint8_t *side_data, *extra_data, *old_side_data;
6388 size_t side_data_size;
6389 buffer_size_t old_side_data_size;
6391 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6393 if (c->fc->nb_streams < 1)
6395 st = c->fc->streams[c->fc->nb_streams-1];
6397 version = avio_r8(pb); /* version */
6398 avio_rb24(pb); /* flags */
6400 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6401 /* key_id_size */ 16, /* data_size */ 0);
6403 return AVERROR(ENOMEM);
6405 if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
6406 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6411 kid_count = avio_rb32(pb);
6412 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
6413 ret = AVERROR(ENOMEM);
6417 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6418 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6419 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6420 min_kid_count * sizeof(*key_ids));
6422 ret = AVERROR(ENOMEM);
6425 info->key_ids = key_ids;
6427 info->key_ids[i] = av_mallocz(16);
6428 if (!info->key_ids[i]) {
6429 ret = AVERROR(ENOMEM);
6432 info->num_key_ids = i + 1;
6434 if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
6435 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6440 if (pb->eof_reached) {
6441 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6442 ret = AVERROR_INVALIDDATA;
6447 extra_data_size = avio_rb32(pb);
6448 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6452 av_freep(&info->data); // malloc(0) may still allocate something.
6453 info->data = extra_data;
6454 info->data_size = extra_data_size;
6456 // If there is existing initialization data, append to the list.
6457 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6458 if (old_side_data) {
6459 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6460 if (old_init_info) {
6461 // Append to the end of the list.
6462 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6468 info = old_init_info;
6470 // Assume existing side-data will be valid, so the only error we could get is OOM.
6471 ret = AVERROR(ENOMEM);
6476 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6478 ret = AVERROR(ENOMEM);
6481 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6482 side_data, side_data_size);
6487 av_encryption_init_info_free(info);
6491 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6494 MOVStreamContext *sc;
6496 if (c->fc->nb_streams < 1)
6498 st = c->fc->streams[c->fc->nb_streams-1];
6501 if (sc->pseudo_stream_id != 0) {
6502 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6503 return AVERROR_PATCHWELCOME;
6507 return AVERROR_INVALIDDATA;
6509 avio_rb32(pb); /* version and flags */
6511 if (!sc->cenc.default_encrypted_sample) {
6512 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6513 if (!sc->cenc.default_encrypted_sample) {
6514 return AVERROR(ENOMEM);
6518 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6522 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6525 MOVStreamContext *sc;
6526 unsigned int version, pattern, is_protected, iv_size;
6528 if (c->fc->nb_streams < 1)
6530 st = c->fc->streams[c->fc->nb_streams-1];
6533 if (sc->pseudo_stream_id != 0) {
6534 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6535 return AVERROR_PATCHWELCOME;
6538 if (!sc->cenc.default_encrypted_sample) {
6539 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6540 if (!sc->cenc.default_encrypted_sample) {
6541 return AVERROR(ENOMEM);
6546 return AVERROR_INVALIDDATA;
6548 version = avio_r8(pb); /* version */
6549 avio_rb24(pb); /* flags */
6551 avio_r8(pb); /* reserved */
6552 pattern = avio_r8(pb);
6555 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6556 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6559 is_protected = avio_r8(pb);
6560 if (is_protected && !sc->cenc.encryption_index) {
6561 // The whole stream should be by-default encrypted.
6562 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6563 if (!sc->cenc.encryption_index)
6564 return AVERROR(ENOMEM);
6566 sc->cenc.per_sample_iv_size = avio_r8(pb);
6567 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6568 sc->cenc.per_sample_iv_size != 16) {
6569 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6570 return AVERROR_INVALIDDATA;
6572 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6573 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6574 return AVERROR_INVALIDDATA;
6577 if (is_protected && !sc->cenc.per_sample_iv_size) {
6578 iv_size = avio_r8(pb);
6579 if (iv_size != 8 && iv_size != 16) {
6580 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6581 return AVERROR_INVALIDDATA;
6584 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6585 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6586 return AVERROR_INVALIDDATA;
6593 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6596 int last, type, size, ret;
6599 if (c->fc->nb_streams < 1)
6601 st = c->fc->streams[c->fc->nb_streams-1];
6603 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6604 return AVERROR_INVALIDDATA;
6606 /* Check FlacSpecificBox version. */
6607 if (avio_r8(pb) != 0)
6608 return AVERROR_INVALIDDATA;
6610 avio_rb24(pb); /* Flags */
6612 avio_read(pb, buf, sizeof(buf));
6613 flac_parse_block_header(buf, &last, &type, &size);
6615 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6616 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6617 return AVERROR_INVALIDDATA;
6620 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6625 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6630 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6634 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6635 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6636 return AVERROR_PATCHWELCOME;
6639 if (!sc->cenc.aes_ctr) {
6640 /* initialize the cipher */
6641 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6642 if (!sc->cenc.aes_ctr) {
6643 return AVERROR(ENOMEM);
6646 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6652 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6654 if (!sample->subsample_count) {
6655 /* decrypt the whole packet */
6656 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6660 for (i = 0; i < sample->subsample_count; i++) {
6661 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6662 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6663 return AVERROR_INVALIDDATA;
6666 /* skip the clear bytes */
6667 input += sample->subsamples[i].bytes_of_clear_data;
6668 size -= sample->subsamples[i].bytes_of_clear_data;
6670 /* decrypt the encrypted bytes */
6671 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6672 input += sample->subsamples[i].bytes_of_protected_data;
6673 size -= sample->subsamples[i].bytes_of_protected_data;
6677 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6678 return AVERROR_INVALIDDATA;
6684 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6686 MOVFragmentStreamInfo *frag_stream_info;
6687 MOVEncryptionIndex *encryption_index;
6688 AVEncryptionInfo *encrypted_sample;
6689 int encrypted_index, ret;
6691 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6692 encrypted_index = current_index;
6693 encryption_index = NULL;
6694 if (frag_stream_info) {
6695 // Note this only supports encryption info in the first sample descriptor.
6696 if (mov->fragment.stsd_id == 1) {
6697 if (frag_stream_info->encryption_index) {
6698 encrypted_index = current_index - frag_stream_info->index_entry;
6699 encryption_index = frag_stream_info->encryption_index;
6701 encryption_index = sc->cenc.encryption_index;
6705 encryption_index = sc->cenc.encryption_index;
6708 if (encryption_index) {
6709 if (encryption_index->auxiliary_info_sample_count &&
6710 !encryption_index->nb_encrypted_samples) {
6711 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6712 return AVERROR_INVALIDDATA;
6714 if (encryption_index->auxiliary_offsets_count &&
6715 !encryption_index->nb_encrypted_samples) {
6716 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6717 return AVERROR_INVALIDDATA;
6720 if (!encryption_index->nb_encrypted_samples) {
6721 // Full-sample encryption with default settings.
6722 encrypted_sample = sc->cenc.default_encrypted_sample;
6723 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6724 // Per-sample setting override.
6725 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6727 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6728 return AVERROR_INVALIDDATA;
6731 if (mov->decryption_key) {
6732 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6735 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6737 return AVERROR(ENOMEM);
6738 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6748 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6750 const int OPUS_SEEK_PREROLL_MS = 80;
6756 if (c->fc->nb_streams < 1)
6758 st = c->fc->streams[c->fc->nb_streams-1];
6760 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6761 return AVERROR_INVALIDDATA;
6763 /* Check OpusSpecificBox version. */
6764 if (avio_r8(pb) != 0) {
6765 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6766 return AVERROR_INVALIDDATA;
6769 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6770 size = atom.size + 8;
6772 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
6775 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6776 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6777 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6778 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6780 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6781 little-endian; aside from the preceeding magic and version they're
6782 otherwise currently identical. Data after output gain at offset 16
6783 doesn't need to be bytewapped. */
6784 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6785 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6786 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6787 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6789 st->codecpar->initial_padding = pre_skip;
6790 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6791 (AVRational){1, 1000},
6792 (AVRational){1, 48000});
6797 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6800 unsigned format_info;
6801 int channel_assignment, channel_assignment1, channel_assignment2;
6804 if (c->fc->nb_streams < 1)
6806 st = c->fc->streams[c->fc->nb_streams-1];
6809 return AVERROR_INVALIDDATA;
6811 format_info = avio_rb32(pb);
6813 ratebits = (format_info >> 28) & 0xF;
6814 channel_assignment1 = (format_info >> 15) & 0x1F;
6815 channel_assignment2 = format_info & 0x1FFF;
6816 if (channel_assignment2)
6817 channel_assignment = channel_assignment2;
6819 channel_assignment = channel_assignment1;
6821 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6822 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6823 st->codecpar->channels = truehd_channels(channel_assignment);
6824 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6829 static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6833 AVDOVIDecoderConfigurationRecord *dovi;
6837 if (c->fc->nb_streams < 1)
6839 st = c->fc->streams[c->fc->nb_streams-1];
6841 if ((uint64_t)atom.size > (1<<30) || atom.size < 4)
6842 return AVERROR_INVALIDDATA;
6844 dovi = av_dovi_alloc(&dovi_size);
6846 return AVERROR(ENOMEM);
6848 dovi->dv_version_major = avio_r8(pb);
6849 dovi->dv_version_minor = avio_r8(pb);
6851 buf = avio_rb16(pb);
6852 dovi->dv_profile = (buf >> 9) & 0x7f; // 7 bits
6853 dovi->dv_level = (buf >> 3) & 0x3f; // 6 bits
6854 dovi->rpu_present_flag = (buf >> 2) & 0x01; // 1 bit
6855 dovi->el_present_flag = (buf >> 1) & 0x01; // 1 bit
6856 dovi->bl_present_flag = buf & 0x01; // 1 bit
6857 if (atom.size >= 24) { // 4 + 4 + 4 * 4
6859 dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits
6861 // 0 stands for None
6862 // Dolby Vision V1.2.93 profiles and levels
6863 dovi->dv_bl_signal_compatibility_id = 0;
6866 ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF,
6867 (uint8_t *)dovi, dovi_size);
6873 av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC box, version: %d.%d, profile: %d, level: %d, "
6874 "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n",
6875 dovi->dv_version_major, dovi->dv_version_minor,
6876 dovi->dv_profile, dovi->dv_level,
6877 dovi->rpu_present_flag,
6878 dovi->el_present_flag,
6879 dovi->bl_present_flag,
6880 dovi->dv_bl_signal_compatibility_id
6886 static const MOVParseTableEntry mov_default_parse_table[] = {
6887 { MKTAG('A','C','L','R'), mov_read_aclr },
6888 { MKTAG('A','P','R','G'), mov_read_avid },
6889 { MKTAG('A','A','L','P'), mov_read_avid },
6890 { MKTAG('A','R','E','S'), mov_read_ares },
6891 { MKTAG('a','v','s','s'), mov_read_avss },
6892 { MKTAG('a','v','1','C'), mov_read_av1c },
6893 { MKTAG('c','h','p','l'), mov_read_chpl },
6894 { MKTAG('c','o','6','4'), mov_read_stco },
6895 { MKTAG('c','o','l','r'), mov_read_colr },
6896 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6897 { MKTAG('d','i','n','f'), mov_read_default },
6898 { MKTAG('D','p','x','E'), mov_read_dpxe },
6899 { MKTAG('d','r','e','f'), mov_read_dref },
6900 { MKTAG('e','d','t','s'), mov_read_default },
6901 { MKTAG('e','l','s','t'), mov_read_elst },
6902 { MKTAG('e','n','d','a'), mov_read_enda },
6903 { MKTAG('f','i','e','l'), mov_read_fiel },
6904 { MKTAG('a','d','r','m'), mov_read_adrm },
6905 { MKTAG('f','t','y','p'), mov_read_ftyp },
6906 { MKTAG('g','l','b','l'), mov_read_glbl },
6907 { MKTAG('h','d','l','r'), mov_read_hdlr },
6908 { MKTAG('i','l','s','t'), mov_read_ilst },
6909 { MKTAG('j','p','2','h'), mov_read_jp2h },
6910 { MKTAG('m','d','a','t'), mov_read_mdat },
6911 { MKTAG('m','d','h','d'), mov_read_mdhd },
6912 { MKTAG('m','d','i','a'), mov_read_default },
6913 { MKTAG('m','e','t','a'), mov_read_meta },
6914 { MKTAG('m','i','n','f'), mov_read_default },
6915 { MKTAG('m','o','o','f'), mov_read_moof },
6916 { MKTAG('m','o','o','v'), mov_read_moov },
6917 { MKTAG('m','v','e','x'), mov_read_default },
6918 { MKTAG('m','v','h','d'), mov_read_mvhd },
6919 { MKTAG('S','M','I',' '), mov_read_svq3 },
6920 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6921 { MKTAG('a','v','c','C'), mov_read_glbl },
6922 { MKTAG('p','a','s','p'), mov_read_pasp },
6923 { MKTAG('s','i','d','x'), mov_read_sidx },
6924 { MKTAG('s','t','b','l'), mov_read_default },
6925 { MKTAG('s','t','c','o'), mov_read_stco },
6926 { MKTAG('s','t','p','s'), mov_read_stps },
6927 { MKTAG('s','t','r','f'), mov_read_strf },
6928 { MKTAG('s','t','s','c'), mov_read_stsc },
6929 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6930 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6931 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6932 { MKTAG('s','t','t','s'), mov_read_stts },
6933 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6934 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
6935 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6936 { MKTAG('t','f','d','t'), mov_read_tfdt },
6937 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6938 { MKTAG('t','r','a','k'), mov_read_trak },
6939 { MKTAG('t','r','a','f'), mov_read_default },
6940 { MKTAG('t','r','e','f'), mov_read_default },
6941 { MKTAG('t','m','c','d'), mov_read_tmcd },
6942 { MKTAG('c','h','a','p'), mov_read_chap },
6943 { MKTAG('t','r','e','x'), mov_read_trex },
6944 { MKTAG('t','r','u','n'), mov_read_trun },
6945 { MKTAG('u','d','t','a'), mov_read_default },
6946 { MKTAG('w','a','v','e'), mov_read_wave },
6947 { MKTAG('e','s','d','s'), mov_read_esds },
6948 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6949 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6950 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6951 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6952 { MKTAG('w','f','e','x'), mov_read_wfex },
6953 { MKTAG('c','m','o','v'), mov_read_cmov },
6954 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6955 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6956 { MKTAG('s','b','g','p'), mov_read_sbgp },
6957 { MKTAG('h','v','c','C'), mov_read_glbl },
6958 { MKTAG('u','u','i','d'), mov_read_uuid },
6959 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6960 { MKTAG('f','r','e','e'), mov_read_free },
6961 { MKTAG('-','-','-','-'), mov_read_custom },
6962 { MKTAG('s','i','n','f'), mov_read_default },
6963 { MKTAG('f','r','m','a'), mov_read_frma },
6964 { MKTAG('s','e','n','c'), mov_read_senc },
6965 { MKTAG('s','a','i','z'), mov_read_saiz },
6966 { MKTAG('s','a','i','o'), mov_read_saio },
6967 { MKTAG('p','s','s','h'), mov_read_pssh },
6968 { MKTAG('s','c','h','m'), mov_read_schm },
6969 { MKTAG('s','c','h','i'), mov_read_default },
6970 { MKTAG('t','e','n','c'), mov_read_tenc },
6971 { MKTAG('d','f','L','a'), mov_read_dfla },
6972 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6973 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6974 { MKTAG('d','O','p','s'), mov_read_dops },
6975 { MKTAG('d','m','l','p'), mov_read_dmlp },
6976 { MKTAG('S','m','D','m'), mov_read_smdm },
6977 { MKTAG('C','o','L','L'), mov_read_coll },
6978 { MKTAG('v','p','c','C'), mov_read_vpcc },
6979 { MKTAG('m','d','c','v'), mov_read_mdcv },
6980 { MKTAG('c','l','l','i'), mov_read_clli },
6981 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
6982 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
6986 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6988 int64_t total_size = 0;
6992 if (c->atom_depth > 10) {
6993 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6994 return AVERROR_INVALIDDATA;
6999 atom.size = INT64_MAX;
7000 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
7001 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
7004 if (atom.size >= 8) {
7005 a.size = avio_rb32(pb);
7006 a.type = avio_rl32(pb);
7007 if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
7008 a.type == MKTAG('h','o','o','v')) &&
7010 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
7013 type = avio_rl32(pb);
7016 avio_seek(pb, -8, SEEK_CUR);
7017 if (type == MKTAG('m','v','h','d') ||
7018 type == MKTAG('c','m','o','v')) {
7019 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
7020 a.type = MKTAG('m','o','o','v');
7023 if (atom.type != MKTAG('r','o','o','t') &&
7024 atom.type != MKTAG('m','o','o','v')) {
7025 if (a.type == MKTAG('t','r','a','k') ||
7026 a.type == MKTAG('m','d','a','t')) {
7027 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
7034 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
7035 a.size = avio_rb64(pb) - 8;
7039 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
7040 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
7042 a.size = atom.size - total_size + 8;
7047 a.size = FFMIN(a.size, atom.size - total_size);
7049 for (i = 0; mov_default_parse_table[i].type; i++)
7050 if (mov_default_parse_table[i].type == a.type) {
7051 parse = mov_default_parse_table[i].parse;
7055 // container is user data
7056 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
7057 atom.type == MKTAG('i','l','s','t')))
7058 parse = mov_read_udta_string;
7060 // Supports parsing the QuickTime Metadata Keys.
7061 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
7062 if (!parse && c->found_hdlr_mdta &&
7063 atom.type == MKTAG('m','e','t','a') &&
7064 a.type == MKTAG('k','e','y','s') &&
7065 c->meta_keys_count == 0) {
7066 parse = mov_read_keys;
7069 if (!parse) { /* skip leaf atoms data */
7070 avio_skip(pb, a.size);
7072 int64_t start_pos = avio_tell(pb);
7074 int err = parse(c, pb, a);
7079 if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
7080 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
7081 start_pos + a.size == avio_size(pb))) {
7082 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
7083 c->next_root_atom = start_pos + a.size;
7087 left = a.size - avio_tell(pb) + start_pos;
7088 if (left > 0) /* skip garbage at atom end */
7089 avio_skip(pb, left);
7090 else if (left < 0) {
7091 av_log(c->fc, AV_LOG_WARNING,
7092 "overread end of atom '%s' by %"PRId64" bytes\n",
7093 av_fourcc2str(a.type), -left);
7094 avio_seek(pb, left, SEEK_CUR);
7098 total_size += a.size;
7101 if (total_size < atom.size && atom.size < 0x7ffff)
7102 avio_skip(pb, atom.size - total_size);
7108 static int mov_probe(const AVProbeData *p)
7113 int moov_offset = -1;
7115 /* check file header */
7120 /* ignore invalid offset */
7121 if ((offset + 8) > (unsigned int)p->buf_size)
7123 size = AV_RB32(p->buf + offset);
7124 if (size == 1 && offset + 16 > (unsigned int)p->buf_size) {
7125 size = AV_RB64(p->buf+offset + 8);
7127 } else if (size == 0) {
7128 size = p->buf_size - offset;
7130 if (size < minsize) {
7134 tag = AV_RL32(p->buf + offset + 4);
7136 /* check for obvious tags */
7137 case MKTAG('m','o','o','v'):
7138 moov_offset = offset + 4;
7139 case MKTAG('m','d','a','t'):
7140 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
7141 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
7142 case MKTAG('f','t','y','p'):
7143 if (tag == MKTAG('f','t','y','p') &&
7144 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
7145 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
7147 score = FFMAX(score, 5);
7149 score = AVPROBE_SCORE_MAX;
7152 /* those are more common words, so rate then a bit less */
7153 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
7154 case MKTAG('w','i','d','e'):
7155 case MKTAG('f','r','e','e'):
7156 case MKTAG('j','u','n','k'):
7157 case MKTAG('p','i','c','t'):
7158 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
7160 case MKTAG(0x82,0x82,0x7f,0x7d):
7161 case MKTAG('s','k','i','p'):
7162 case MKTAG('u','u','i','d'):
7163 case MKTAG('p','r','f','l'):
7164 /* if we only find those cause probedata is too small at least rate them */
7165 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7170 if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
7171 /* moov atom in the header - we should make sure that this is not a
7172 * MOV-packed MPEG-PS */
7173 offset = moov_offset;
7175 while (offset < (p->buf_size - 16)) { /* Sufficient space */
7176 /* We found an actual hdlr atom */
7177 if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7178 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7179 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
7180 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7181 /* We found a media handler reference atom describing an
7182 * MPEG-PS-in-MOV, return a
7183 * low score to force expanding the probe window until
7184 * mpegps_probe finds what it needs */
7196 // must be done after parsing all trak because there's no order requirement
7197 static void mov_read_chapters(AVFormatContext *s)
7199 MOVContext *mov = s->priv_data;
7201 MOVStreamContext *sc;
7206 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7207 chapter_track = mov->chapter_tracks[j];
7209 for (i = 0; i < s->nb_streams; i++)
7210 if (s->streams[i]->id == chapter_track) {
7215 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7220 cur_pos = avio_tell(sc->pb);
7222 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7223 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7224 if (st->internal->nb_index_entries) {
7225 // Retrieve the first frame, if possible
7226 AVIndexEntry *sample = &st->internal->index_entries[0];
7227 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7228 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7232 if (av_get_packet(sc->pb, &st->attached_pic, sample->size) < 0)
7235 st->attached_pic.stream_index = st->index;
7236 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
7239 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7240 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7241 st->discard = AVDISCARD_ALL;
7242 for (i = 0; i < st->internal->nb_index_entries; i++) {
7243 AVIndexEntry *sample = &st->internal->index_entries[i];
7244 int64_t end = i+1 < st->internal->nb_index_entries ? st->internal->index_entries[i+1].timestamp : st->duration;
7249 if (end < sample->timestamp) {
7250 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7251 end = AV_NOPTS_VALUE;
7254 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7255 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7259 // the first two bytes are the length of the title
7260 len = avio_rb16(sc->pb);
7261 if (len > sample->size-2)
7263 title_len = 2*len + 1;
7264 if (!(title = av_mallocz(title_len)))
7267 // The samples could theoretically be in any encoding if there's an encd
7268 // atom following, but in practice are only utf-8 or utf-16, distinguished
7269 // instead by the presence of a BOM
7273 ch = avio_rb16(sc->pb);
7275 avio_get_str16be(sc->pb, len, title, title_len);
7276 else if (ch == 0xfffe)
7277 avio_get_str16le(sc->pb, len, title, title_len);
7280 if (len == 1 || len == 2)
7283 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7287 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7292 avio_seek(sc->pb, cur_pos, SEEK_SET);
7296 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7297 uint32_t value, int flags)
7300 char buf[AV_TIMECODE_STR_SIZE];
7301 AVRational rate = st->avg_frame_rate;
7302 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7305 av_dict_set(&st->metadata, "timecode",
7306 av_timecode_make_string(&tc, buf, value), 0);
7310 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7312 MOVStreamContext *sc = st->priv_data;
7313 char buf[AV_TIMECODE_STR_SIZE];
7314 int64_t cur_pos = avio_tell(sc->pb);
7315 int hh, mm, ss, ff, drop;
7317 if (!st->internal->nb_index_entries)
7320 avio_seek(sc->pb, st->internal->index_entries->pos, SEEK_SET);
7321 avio_skip(s->pb, 13);
7322 hh = avio_r8(s->pb);
7323 mm = avio_r8(s->pb);
7324 ss = avio_r8(s->pb);
7325 drop = avio_r8(s->pb);
7326 ff = avio_r8(s->pb);
7327 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7328 hh, mm, ss, drop ? ';' : ':', ff);
7329 av_dict_set(&st->metadata, "timecode", buf, 0);
7331 avio_seek(sc->pb, cur_pos, SEEK_SET);
7335 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7337 MOVStreamContext *sc = st->priv_data;
7339 int64_t cur_pos = avio_tell(sc->pb);
7342 if (!st->internal->nb_index_entries)
7345 avio_seek(sc->pb, st->internal->index_entries->pos, SEEK_SET);
7346 value = avio_rb32(s->pb);
7348 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7349 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7350 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7352 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7353 * not the case) and thus assume "frame number format" instead of QT one.
7354 * No sample with tmcd track can be found with a QT timecode at the moment,
7355 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7357 parse_timecode_in_framenum_format(s, st, value, flags);
7359 avio_seek(sc->pb, cur_pos, SEEK_SET);
7363 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7365 if (!index || !*index) return;
7366 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7367 av_encryption_info_free((*index)->encrypted_samples[i]);
7369 av_freep(&(*index)->encrypted_samples);
7370 av_freep(&(*index)->auxiliary_info_sizes);
7371 av_freep(&(*index)->auxiliary_offsets);
7375 static int mov_read_close(AVFormatContext *s)
7377 MOVContext *mov = s->priv_data;
7380 for (i = 0; i < s->nb_streams; i++) {
7381 AVStream *st = s->streams[i];
7382 MOVStreamContext *sc = st->priv_data;
7387 av_freep(&sc->ctts_data);
7388 for (j = 0; j < sc->drefs_count; j++) {
7389 av_freep(&sc->drefs[j].path);
7390 av_freep(&sc->drefs[j].dir);
7392 av_freep(&sc->drefs);
7394 sc->drefs_count = 0;
7396 if (!sc->pb_is_copied)
7397 ff_format_io_close(s, &sc->pb);
7400 av_freep(&sc->chunk_offsets);
7401 av_freep(&sc->stsc_data);
7402 av_freep(&sc->sample_sizes);
7403 av_freep(&sc->keyframes);
7404 av_freep(&sc->stts_data);
7405 av_freep(&sc->sdtp_data);
7406 av_freep(&sc->stps_data);
7407 av_freep(&sc->elst_data);
7408 av_freep(&sc->rap_group);
7409 av_freep(&sc->display_matrix);
7410 av_freep(&sc->index_ranges);
7413 for (j = 0; j < sc->stsd_count; j++)
7414 av_free(sc->extradata[j]);
7415 av_freep(&sc->extradata);
7416 av_freep(&sc->extradata_size);
7418 mov_free_encryption_index(&sc->cenc.encryption_index);
7419 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7420 av_aes_ctr_free(sc->cenc.aes_ctr);
7422 av_freep(&sc->stereo3d);
7423 av_freep(&sc->spherical);
7424 av_freep(&sc->mastering);
7425 av_freep(&sc->coll);
7428 av_freep(&mov->dv_demux);
7429 avformat_free_context(mov->dv_fctx);
7430 mov->dv_fctx = NULL;
7432 if (mov->meta_keys) {
7433 for (i = 1; i < mov->meta_keys_count; i++) {
7434 av_freep(&mov->meta_keys[i]);
7436 av_freep(&mov->meta_keys);
7439 av_freep(&mov->trex_data);
7440 av_freep(&mov->bitrates);
7442 for (i = 0; i < mov->frag_index.nb_items; i++) {
7443 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7444 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7445 mov_free_encryption_index(&frag[j].encryption_index);
7447 av_freep(&mov->frag_index.item[i].stream_info);
7449 av_freep(&mov->frag_index.item);
7451 av_freep(&mov->aes_decrypt);
7452 av_freep(&mov->chapter_tracks);
7457 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7461 for (i = 0; i < s->nb_streams; i++) {
7462 AVStream *st = s->streams[i];
7463 MOVStreamContext *sc = st->priv_data;
7465 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7466 sc->timecode_track == tmcd_id)
7472 /* look for a tmcd track not referenced by any video track, and export it globally */
7473 static void export_orphan_timecode(AVFormatContext *s)
7477 for (i = 0; i < s->nb_streams; i++) {
7478 AVStream *st = s->streams[i];
7480 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7481 !tmcd_is_referenced(s, i + 1)) {
7482 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7484 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7491 static int read_tfra(MOVContext *mov, AVIOContext *f)
7493 int version, fieldlength, i, j;
7494 int64_t pos = avio_tell(f);
7495 uint32_t size = avio_rb32(f);
7496 unsigned track_id, item_count;
7498 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7501 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7503 version = avio_r8(f);
7505 track_id = avio_rb32(f);
7506 fieldlength = avio_rb32(f);
7507 item_count = avio_rb32(f);
7508 for (i = 0; i < item_count; i++) {
7509 int64_t time, offset;
7511 MOVFragmentStreamInfo * frag_stream_info;
7514 return AVERROR_INVALIDDATA;
7518 time = avio_rb64(f);
7519 offset = avio_rb64(f);
7521 time = avio_rb32(f);
7522 offset = avio_rb32(f);
7525 // The first sample of each stream in a fragment is always a random
7526 // access sample. So it's entry in the tfra can be used as the
7527 // initial PTS of the fragment.
7528 index = update_frag_index(mov, offset);
7529 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7530 if (frag_stream_info &&
7531 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7532 frag_stream_info->first_tfra_pts = time;
7534 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7536 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7538 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7542 avio_seek(f, pos + size, SEEK_SET);
7546 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7548 int64_t stream_size = avio_size(f);
7549 int64_t original_pos = avio_tell(f);
7552 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7556 c->mfra_size = avio_rb32(f);
7557 c->have_read_mfra_size = 1;
7558 if (!c->mfra_size || c->mfra_size > stream_size) {
7559 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7562 if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
7566 if (avio_rb32(f) != c->mfra_size) {
7567 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7570 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7571 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7574 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7576 ret = read_tfra(c, f);
7581 c->frag_index.complete = 1;
7583 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7585 av_log(c->fc, AV_LOG_ERROR,
7586 "failed to seek back after looking for mfra\n");
7592 static int mov_read_header(AVFormatContext *s)
7594 MOVContext *mov = s->priv_data;
7595 AVIOContext *pb = s->pb;
7597 MOVAtom atom = { AV_RL32("root") };
7600 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7601 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7602 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7603 return AVERROR(EINVAL);
7607 mov->trak_index = -1;
7608 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7609 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7610 atom.size = avio_size(pb);
7612 atom.size = INT64_MAX;
7614 /* check MOV header */
7616 if (mov->moov_retry)
7617 avio_seek(pb, 0, SEEK_SET);
7618 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7619 av_log(s, AV_LOG_ERROR, "error reading header\n");
7622 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7623 if (!mov->found_moov) {
7624 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7625 err = AVERROR_INVALIDDATA;
7628 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7630 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7631 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7632 mov_read_chapters(s);
7633 for (i = 0; i < s->nb_streams; i++)
7634 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7635 mov_read_timecode_track(s, s->streams[i]);
7636 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7637 mov_read_rtmd_track(s, s->streams[i]);
7641 /* copy timecode metadata from tmcd tracks to the related video streams */
7642 for (i = 0; i < s->nb_streams; i++) {
7643 AVStream *st = s->streams[i];
7644 MOVStreamContext *sc = st->priv_data;
7645 if (sc->timecode_track > 0) {
7646 AVDictionaryEntry *tcr;
7647 int tmcd_st_id = -1;
7649 for (j = 0; j < s->nb_streams; j++)
7650 if (s->streams[j]->id == sc->timecode_track)
7653 if (tmcd_st_id < 0 || tmcd_st_id == i)
7655 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7657 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7660 export_orphan_timecode(s);
7662 for (i = 0; i < s->nb_streams; i++) {
7663 AVStream *st = s->streams[i];
7664 MOVStreamContext *sc = st->priv_data;
7665 fix_timescale(mov, sc);
7666 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
7667 st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7668 st->internal->skip_samples = sc->start_pad;
7670 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7671 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7672 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7673 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7674 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7675 st->codecpar->width = sc->width;
7676 st->codecpar->height = sc->height;
7678 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7679 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7683 if (mov->handbrake_version &&
7684 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7685 st->codecpar->codec_id == AV_CODEC_ID_MP3) {
7686 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7687 st->need_parsing = AVSTREAM_PARSE_FULL;
7691 if (mov->trex_data) {
7692 for (i = 0; i < s->nb_streams; i++) {
7693 AVStream *st = s->streams[i];
7694 MOVStreamContext *sc = st->priv_data;
7695 if (st->duration > 0) {
7696 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7697 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7698 sc->data_size, sc->time_scale);
7699 err = AVERROR_INVALIDDATA;
7702 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7707 if (mov->use_mfra_for > 0) {
7708 for (i = 0; i < s->nb_streams; i++) {
7709 AVStream *st = s->streams[i];
7710 MOVStreamContext *sc = st->priv_data;
7711 if (sc->duration_for_fps > 0) {
7712 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7713 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7714 sc->data_size, sc->time_scale);
7715 err = AVERROR_INVALIDDATA;
7718 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7719 sc->duration_for_fps;
7724 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7725 if (mov->bitrates[i]) {
7726 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7730 ff_rfps_calculate(s);
7732 for (i = 0; i < s->nb_streams; i++) {
7733 AVStream *st = s->streams[i];
7734 MOVStreamContext *sc = st->priv_data;
7736 switch (st->codecpar->codec_type) {
7737 case AVMEDIA_TYPE_AUDIO:
7738 err = ff_replaygain_export(st, s->metadata);
7742 case AVMEDIA_TYPE_VIDEO:
7743 if (sc->display_matrix) {
7744 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7745 sizeof(int32_t) * 9);
7749 sc->display_matrix = NULL;
7752 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7753 (uint8_t *)sc->stereo3d,
7754 sizeof(*sc->stereo3d));
7758 sc->stereo3d = NULL;
7760 if (sc->spherical) {
7761 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7762 (uint8_t *)sc->spherical,
7763 sc->spherical_size);
7767 sc->spherical = NULL;
7769 if (sc->mastering) {
7770 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7771 (uint8_t *)sc->mastering,
7772 sizeof(*sc->mastering));
7776 sc->mastering = NULL;
7779 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7780 (uint8_t *)sc->coll,
7790 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7792 for (i = 0; i < mov->frag_index.nb_items; i++)
7793 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7794 mov->frag_index.item[i].headers_read = 1;
7802 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7804 AVIndexEntry *sample = NULL;
7805 int64_t best_dts = INT64_MAX;
7807 for (i = 0; i < s->nb_streams; i++) {
7808 AVStream *avst = s->streams[i];
7809 MOVStreamContext *msc = avst->priv_data;
7810 if (msc->pb && msc->current_sample < avst->internal->nb_index_entries) {
7811 AVIndexEntry *current_sample = &avst->internal->index_entries[msc->current_sample];
7812 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7813 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7814 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7815 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7816 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
7817 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7818 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7819 sample = current_sample;
7828 static int should_retry(AVIOContext *pb, int error_code) {
7829 if (error_code == AVERROR_EOF || avio_feof(pb))
7835 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7838 MOVContext *mov = s->priv_data;
7840 if (index >= 0 && index < mov->frag_index.nb_items)
7841 target = mov->frag_index.item[index].moof_offset;
7842 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7843 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7844 return AVERROR_INVALIDDATA;
7847 mov->next_root_atom = 0;
7848 if (index < 0 || index >= mov->frag_index.nb_items)
7849 index = search_frag_moof_offset(&mov->frag_index, target);
7850 if (index < mov->frag_index.nb_items &&
7851 mov->frag_index.item[index].moof_offset == target) {
7852 if (index + 1 < mov->frag_index.nb_items)
7853 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7854 if (mov->frag_index.item[index].headers_read)
7856 mov->frag_index.item[index].headers_read = 1;
7859 mov->found_mdat = 0;
7861 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7864 if (avio_feof(s->pb))
7866 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7871 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7873 uint8_t *side, *extradata;
7876 /* Save the current index. */
7877 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7879 /* Notify the decoder that extradata changed. */
7880 extradata_size = sc->extradata_size[sc->last_stsd_index];
7881 extradata = sc->extradata[sc->last_stsd_index];
7882 if (extradata_size > 0 && extradata) {
7883 side = av_packet_new_side_data(pkt,
7884 AV_PKT_DATA_NEW_EXTRADATA,
7887 return AVERROR(ENOMEM);
7888 memcpy(side, extradata, extradata_size);
7894 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int size)
7899 return AVERROR_INVALIDDATA;
7900 new_size = ((size - 8) / 2) * 3;
7901 ret = av_new_packet(pkt, new_size);
7906 for (int j = 0; j < new_size; j += 3) {
7907 pkt->data[j] = 0xFC;
7908 pkt->data[j+1] = avio_r8(pb);
7909 pkt->data[j+2] = avio_r8(pb);
7915 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7917 MOVContext *mov = s->priv_data;
7918 MOVStreamContext *sc;
7919 AVIndexEntry *sample;
7920 AVStream *st = NULL;
7921 int64_t current_index;
7925 sample = mov_find_next_sample(s, &st);
7926 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7927 if (!mov->next_root_atom)
7929 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7934 /* must be done just before reading, to avoid infinite loop on sample */
7935 current_index = sc->current_index;
7936 mov_current_sample_inc(sc);
7938 if (mov->next_root_atom) {
7939 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7940 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7943 if (st->discard != AVDISCARD_ALL) {
7944 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7945 if (ret64 != sample->pos) {
7946 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7947 sc->ffindex, sample->pos);
7948 if (should_retry(sc->pb, ret64)) {
7949 mov_current_sample_dec(sc);
7951 return AVERROR_INVALIDDATA;
7954 if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
7955 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7959 if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
7960 ret = get_eia608_packet(sc->pb, pkt, sample->size);
7962 ret = av_get_packet(sc->pb, pkt, sample->size);
7964 if (should_retry(sc->pb, ret)) {
7965 mov_current_sample_dec(sc);
7969 #if CONFIG_DV_DEMUXER
7970 if (mov->dv_demux && sc->dv_audio_container) {
7971 AVBufferRef *buf = pkt->buf;
7972 ret = avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7974 av_packet_unref(pkt);
7977 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7982 if (sc->has_palette) {
7985 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7987 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7989 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7990 sc->has_palette = 0;
7993 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7994 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7995 st->need_parsing = AVSTREAM_PARSE_FULL;
7999 pkt->stream_index = sc->ffindex;
8000 pkt->dts = sample->timestamp;
8001 if (sample->flags & AVINDEX_DISCARD_FRAME) {
8002 pkt->flags |= AV_PKT_FLAG_DISCARD;
8004 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
8005 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
8006 /* update ctts context */
8008 if (sc->ctts_index < sc->ctts_count &&
8009 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
8011 sc->ctts_sample = 0;
8014 int64_t next_dts = (sc->current_sample < st->internal->nb_index_entries) ?
8015 st->internal->index_entries[sc->current_sample].timestamp : st->duration;
8017 if (next_dts >= pkt->dts)
8018 pkt->duration = next_dts - pkt->dts;
8019 pkt->pts = pkt->dts;
8021 if (st->discard == AVDISCARD_ALL)
8023 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
8024 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
8025 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
8026 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
8028 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
8029 pkt->pos = sample->pos;
8031 /* Multiple stsd handling. */
8032 if (sc->stsc_data) {
8033 /* Keep track of the stsc index for the given sample, then check
8034 * if the stsd index is different from the last used one. */
8036 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
8037 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
8039 sc->stsc_sample = 0;
8040 /* Do not check indexes after a switch. */
8041 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
8042 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
8043 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
8044 ret = mov_change_extradata(sc, pkt);
8051 aax_filter(pkt->data, pkt->size, mov);
8053 ret = cenc_filter(mov, st, sc, pkt, current_index);
8061 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
8063 MOVContext *mov = s->priv_data;
8066 if (!mov->frag_index.complete)
8069 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
8072 if (!mov->frag_index.item[index].headers_read)
8073 return mov_switch_root(s, -1, index);
8074 if (index + 1 < mov->frag_index.nb_items)
8075 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
8080 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
8082 MOVStreamContext *sc = st->priv_data;
8083 int sample, time_sample, ret;
8086 // Here we consider timestamp to be PTS, hence try to offset it so that we
8087 // can search over the DTS timeline.
8088 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
8090 ret = mov_seek_fragment(s, st, timestamp);
8094 sample = av_index_search_timestamp(st, timestamp, flags);
8095 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
8096 if (sample < 0 && st->internal->nb_index_entries && timestamp < st->internal->index_entries[0].timestamp)
8098 if (sample < 0) /* not sure what to do */
8099 return AVERROR_INVALIDDATA;
8100 mov_current_sample_set(sc, sample);
8101 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
8102 /* adjust ctts index */
8103 if (sc->ctts_data) {
8105 for (i = 0; i < sc->ctts_count; i++) {
8106 int next = time_sample + sc->ctts_data[i].count;
8107 if (next > sc->current_sample) {
8109 sc->ctts_sample = sc->current_sample - time_sample;
8116 /* adjust stsd index */
8117 if (sc->chunk_count) {
8119 for (i = 0; i < sc->stsc_count; i++) {
8120 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
8121 if (next > sc->current_sample) {
8123 sc->stsc_sample = sc->current_sample - time_sample;
8126 av_assert0(next == (int)next);
8134 static int64_t mov_get_skip_samples(AVStream *st, int sample)
8136 MOVStreamContext *sc = st->priv_data;
8137 int64_t first_ts = st->internal->index_entries[0].timestamp;
8138 int64_t ts = st->internal->index_entries[sample].timestamp;
8141 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO)
8144 /* compute skip samples according to stream start_pad, seek ts and first ts */
8145 off = av_rescale_q(ts - first_ts, st->time_base,
8146 (AVRational){1, st->codecpar->sample_rate});
8147 return FFMAX(sc->start_pad - off, 0);
8150 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
8152 MOVContext *mc = s->priv_data;
8157 if (stream_index >= s->nb_streams)
8158 return AVERROR_INVALIDDATA;
8160 st = s->streams[stream_index];
8161 sample = mov_seek_stream(s, st, sample_time, flags);
8165 if (mc->seek_individually) {
8166 /* adjust seek timestamp to found sample timestamp */
8167 int64_t seek_timestamp = st->internal->index_entries[sample].timestamp;
8168 st->internal->skip_samples = mov_get_skip_samples(st, sample);
8170 for (i = 0; i < s->nb_streams; i++) {
8174 if (stream_index == i)
8177 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
8178 sample = mov_seek_stream(s, st, timestamp, flags);
8180 st->internal->skip_samples = mov_get_skip_samples(st, sample);
8183 for (i = 0; i < s->nb_streams; i++) {
8184 MOVStreamContext *sc;
8187 mov_current_sample_set(sc, 0);
8190 MOVStreamContext *sc;
8191 AVIndexEntry *entry = mov_find_next_sample(s, &st);
8193 return AVERROR_INVALIDDATA;
8195 if (sc->ffindex == stream_index && sc->current_sample == sample)
8197 mov_current_sample_inc(sc);
8203 #define OFFSET(x) offsetof(MOVContext, x)
8204 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
8205 static const AVOption mov_options[] = {
8206 {"use_absolute_path",
8207 "allow using absolute path when opening alias, this is a possible security issue",
8208 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
8210 {"seek_streams_individually",
8211 "Seek each stream individually to the closest point",
8212 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
8214 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
8216 {"advanced_editlist",
8217 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
8218 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
8220 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8223 "use mfra for fragment timestamps",
8224 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8225 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8227 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8228 FLAGS, "use_mfra_for" },
8229 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8230 FLAGS, "use_mfra_for" },
8231 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8232 FLAGS, "use_mfra_for" },
8233 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8234 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8235 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8236 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8237 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8238 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8239 { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
8240 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8241 { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
8242 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8243 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8244 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8245 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8246 .flags = AV_OPT_FLAG_DECODING_PARAM },
8247 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8248 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8249 {.i64 = 0}, 0, 1, FLAGS },
8254 static const AVClass mov_class = {
8255 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8256 .item_name = av_default_item_name,
8257 .option = mov_options,
8258 .version = LIBAVUTIL_VERSION_INT,
8261 AVInputFormat ff_mov_demuxer = {
8262 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8263 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8264 .priv_class = &mov_class,
8265 .priv_data_size = sizeof(MOVContext),
8266 .extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
8267 .read_probe = mov_probe,
8268 .read_header = mov_read_header,
8269 .read_packet = mov_read_packet,
8270 .read_close = mov_read_close,
8271 .read_seek = mov_read_seek,
8272 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,