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 return frag_stream_info->sidx_pts;
1285 for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1286 frag_stream_info = &frag_index->item[index].stream_info[i];
1287 timestamp = get_stream_info_time(frag_stream_info);
1288 if (timestamp != AV_NOPTS_VALUE)
1291 return AV_NOPTS_VALUE;
1294 static int search_frag_timestamp(MOVFragmentIndex *frag_index,
1295 AVStream *st, int64_t timestamp)
1302 // If the stream is referenced by any sidx, limit the search
1303 // to fragments that referenced this stream in the sidx
1304 MOVStreamContext *sc = st->priv_data;
1310 b = frag_index->nb_items;
1313 m0 = m = (a + b) >> 1;
1316 (frag_time = get_frag_time(frag_index, m, id)) == AV_NOPTS_VALUE)
1319 if (m < b && frag_time <= timestamp)
1328 static int update_frag_index(MOVContext *c, int64_t offset)
1331 MOVFragmentIndexItem * item;
1332 MOVFragmentStreamInfo * frag_stream_info;
1334 // If moof_offset already exists in frag_index, return index to it
1335 index = search_frag_moof_offset(&c->frag_index, offset);
1336 if (index < c->frag_index.nb_items &&
1337 c->frag_index.item[index].moof_offset == offset)
1340 // offset is not yet in frag index.
1341 // Insert new item at index (sorted by moof offset)
1342 item = av_fast_realloc(c->frag_index.item,
1343 &c->frag_index.allocated_size,
1344 (c->frag_index.nb_items + 1) *
1345 sizeof(*c->frag_index.item));
1348 c->frag_index.item = item;
1350 frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1351 sizeof(*item->stream_info));
1352 if (!frag_stream_info)
1355 for (i = 0; i < c->fc->nb_streams; i++) {
1356 // Avoid building frag index if streams lack track id.
1357 if (c->fc->streams[i]->id < 0) {
1358 av_free(frag_stream_info);
1359 return AVERROR_INVALIDDATA;
1362 frag_stream_info[i].id = c->fc->streams[i]->id;
1363 frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1364 frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1365 frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1366 frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1367 frag_stream_info[i].index_entry = -1;
1368 frag_stream_info[i].encryption_index = NULL;
1371 if (index < c->frag_index.nb_items)
1372 memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1373 (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1375 item = &c->frag_index.item[index];
1376 item->headers_read = 0;
1378 item->nb_stream_info = c->fc->nb_streams;
1379 item->moof_offset = offset;
1380 item->stream_info = frag_stream_info;
1381 c->frag_index.nb_items++;
1386 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1387 int id, int entries)
1390 MOVFragmentStreamInfo * frag_stream_info;
1394 for (i = index; i < frag_index->nb_items; i++) {
1395 frag_stream_info = get_frag_stream_info(frag_index, i, id);
1396 if (frag_stream_info && frag_stream_info->index_entry >= 0)
1397 frag_stream_info->index_entry += entries;
1401 static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1403 // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1404 c->fragment.found_tfhd = 0;
1406 if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1407 c->has_looked_for_mfra = 1;
1408 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1410 av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1412 if ((ret = mov_read_mfra(c, pb)) < 0) {
1413 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1414 "read the mfra (may be a live ismv)\n");
1417 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1418 "seekable, can not look for mfra\n");
1421 c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1422 av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1423 c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1424 return mov_read_default(c, pb, atom);
1427 static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time, void *logctx)
1430 if (time >= 2082844800)
1431 time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1433 if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1434 av_log(logctx, AV_LOG_DEBUG, "creation_time is not representable\n");
1438 avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1442 static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1445 MOVStreamContext *sc;
1447 char language[4] = {0};
1449 int64_t creation_time;
1451 if (c->fc->nb_streams < 1)
1453 st = c->fc->streams[c->fc->nb_streams-1];
1456 if (sc->time_scale) {
1457 av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1458 return AVERROR_INVALIDDATA;
1461 version = avio_r8(pb);
1463 avpriv_request_sample(c->fc, "Version %d", version);
1464 return AVERROR_PATCHWELCOME;
1466 avio_rb24(pb); /* flags */
1468 creation_time = avio_rb64(pb);
1471 creation_time = avio_rb32(pb);
1472 avio_rb32(pb); /* modification time */
1474 mov_metadata_creation_time(&st->metadata, creation_time, c->fc);
1476 sc->time_scale = avio_rb32(pb);
1477 if (sc->time_scale <= 0) {
1478 av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1481 st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1483 lang = avio_rb16(pb); /* language */
1484 if (ff_mov_lang_to_iso639(lang, language))
1485 av_dict_set(&st->metadata, "language", language, 0);
1486 avio_rb16(pb); /* quality */
1491 static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1494 int64_t creation_time;
1495 int version = avio_r8(pb); /* version */
1496 avio_rb24(pb); /* flags */
1499 creation_time = avio_rb64(pb);
1502 creation_time = avio_rb32(pb);
1503 avio_rb32(pb); /* modification time */
1505 mov_metadata_creation_time(&c->fc->metadata, creation_time, c->fc);
1506 c->time_scale = avio_rb32(pb); /* time scale */
1507 if (c->time_scale <= 0) {
1508 av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1511 av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1513 c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1514 // set the AVFormatContext duration because the duration of individual tracks
1515 // may be inaccurate
1517 c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale);
1518 avio_rb32(pb); /* preferred scale */
1520 avio_rb16(pb); /* preferred volume */
1522 avio_skip(pb, 10); /* reserved */
1524 /* movie display matrix, store it in main context and use it later on */
1525 for (i = 0; i < 3; i++) {
1526 c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1527 c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1528 c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1531 avio_rb32(pb); /* preview time */
1532 avio_rb32(pb); /* preview duration */
1533 avio_rb32(pb); /* poster time */
1534 avio_rb32(pb); /* selection time */
1535 avio_rb32(pb); /* selection duration */
1536 avio_rb32(pb); /* current time */
1537 avio_rb32(pb); /* next track ID */
1542 static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1547 if (c->fc->nb_streams < 1)
1549 st = c->fc->streams[c->fc->nb_streams-1];
1551 little_endian = avio_rb16(pb) & 0xFF;
1552 av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1553 if (little_endian == 1) {
1554 switch (st->codecpar->codec_id) {
1555 case AV_CODEC_ID_PCM_S24BE:
1556 st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE;
1558 case AV_CODEC_ID_PCM_S32BE:
1559 st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE;
1561 case AV_CODEC_ID_PCM_F32BE:
1562 st->codecpar->codec_id = AV_CODEC_ID_PCM_F32LE;
1564 case AV_CODEC_ID_PCM_F64BE:
1565 st->codecpar->codec_id = AV_CODEC_ID_PCM_F64LE;
1574 static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1577 uint8_t *icc_profile;
1578 char color_parameter_type[5] = { 0 };
1579 uint16_t color_primaries, color_trc, color_matrix;
1582 if (c->fc->nb_streams < 1)
1584 st = c->fc->streams[c->fc->nb_streams - 1];
1586 ret = ffio_read_size(pb, color_parameter_type, 4);
1589 if (strncmp(color_parameter_type, "nclx", 4) &&
1590 strncmp(color_parameter_type, "nclc", 4) &&
1591 strncmp(color_parameter_type, "prof", 4)) {
1592 av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
1593 color_parameter_type);
1597 if (!strncmp(color_parameter_type, "prof", 4)) {
1598 icc_profile = av_stream_new_side_data(st, AV_PKT_DATA_ICC_PROFILE, atom.size - 4);
1600 return AVERROR(ENOMEM);
1601 ret = ffio_read_size(pb, icc_profile, atom.size - 4);
1605 color_primaries = avio_rb16(pb);
1606 color_trc = avio_rb16(pb);
1607 color_matrix = avio_rb16(pb);
1609 av_log(c->fc, AV_LOG_TRACE,
1610 "%s: pri %d trc %d matrix %d",
1611 color_parameter_type, color_primaries, color_trc, color_matrix);
1613 if (!strncmp(color_parameter_type, "nclx", 4)) {
1614 uint8_t color_range = avio_r8(pb) >> 7;
1615 av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
1617 st->codecpar->color_range = AVCOL_RANGE_JPEG;
1619 st->codecpar->color_range = AVCOL_RANGE_MPEG;
1622 if (!av_color_primaries_name(color_primaries))
1623 color_primaries = AVCOL_PRI_UNSPECIFIED;
1624 if (!av_color_transfer_name(color_trc))
1625 color_trc = AVCOL_TRC_UNSPECIFIED;
1626 if (!av_color_space_name(color_matrix))
1627 color_matrix = AVCOL_SPC_UNSPECIFIED;
1629 st->codecpar->color_primaries = color_primaries;
1630 st->codecpar->color_trc = color_trc;
1631 st->codecpar->color_space = color_matrix;
1632 av_log(c->fc, AV_LOG_TRACE, "\n");
1637 static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1640 unsigned mov_field_order;
1641 enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
1643 if (c->fc->nb_streams < 1) // will happen with jp2 files
1645 st = c->fc->streams[c->fc->nb_streams-1];
1647 return AVERROR_INVALIDDATA;
1648 mov_field_order = avio_rb16(pb);
1649 if ((mov_field_order & 0xFF00) == 0x0100)
1650 decoded_field_order = AV_FIELD_PROGRESSIVE;
1651 else if ((mov_field_order & 0xFF00) == 0x0200) {
1652 switch (mov_field_order & 0xFF) {
1653 case 0x01: decoded_field_order = AV_FIELD_TT;
1655 case 0x06: decoded_field_order = AV_FIELD_BB;
1657 case 0x09: decoded_field_order = AV_FIELD_TB;
1659 case 0x0E: decoded_field_order = AV_FIELD_BT;
1663 if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
1664 av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
1666 st->codecpar->field_order = decoded_field_order;
1671 static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
1674 uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
1675 if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
1676 return AVERROR_INVALIDDATA;
1677 if ((err = av_reallocp(&par->extradata, size)) < 0) {
1678 par->extradata_size = 0;
1681 par->extradata_size = size - AV_INPUT_BUFFER_PADDING_SIZE;
1685 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
1686 static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1687 AVCodecParameters *par, uint8_t *buf)
1689 int64_t result = atom.size;
1692 AV_WB32(buf , atom.size + 8);
1693 AV_WL32(buf + 4, atom.type);
1694 err = ffio_read_size(pb, buf + 8, atom.size);
1696 par->extradata_size -= atom.size;
1698 } else if (err < atom.size) {
1699 av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
1700 par->extradata_size -= atom.size - err;
1703 memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1707 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
1708 static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1709 enum AVCodecID codec_id)
1712 uint64_t original_size;
1715 if (c->fc->nb_streams < 1) // will happen with jp2 files
1717 st = c->fc->streams[c->fc->nb_streams-1];
1719 if (st->codecpar->codec_id != codec_id)
1720 return 0; /* unexpected codec_id - don't mess with extradata */
1722 original_size = st->codecpar->extradata_size;
1723 err = mov_realloc_extradata(st->codecpar, atom);
1727 err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
1730 return 0; // Note: this is the original behavior to ignore truncation.
1733 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
1734 static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1736 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
1739 static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1741 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS);
1744 static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1746 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
1749 static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1751 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
1754 static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1756 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
1758 ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
1762 static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1764 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
1766 if (!ret && c->fc->nb_streams >= 1) {
1767 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1768 if (par->extradata_size >= 40) {
1769 par->height = AV_RB16(&par->extradata[36]);
1770 par->width = AV_RB16(&par->extradata[38]);
1776 static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1778 if (c->fc->nb_streams >= 1) {
1779 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1780 if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
1781 par->codec_id == AV_CODEC_ID_H264 &&
1785 cid = avio_rb16(pb);
1786 /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
1787 if (cid == 0xd4d || cid == 0xd4e)
1790 } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
1791 par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
1792 par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
1796 num = avio_rb32(pb);
1797 den = avio_rb32(pb);
1798 if (num <= 0 || den <= 0)
1800 switch (avio_rb32(pb)) {
1802 if (den >= INT_MAX / 2)
1806 c->fc->streams[c->fc->nb_streams-1]->internal->display_aspect_ratio.num = num;
1807 c->fc->streams[c->fc->nb_streams-1]->internal->display_aspect_ratio.den = den;
1814 return mov_read_avid(c, pb, atom);
1817 static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1821 uint64_t original_size;
1822 if (c->fc->nb_streams >= 1) {
1823 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1824 if (par->codec_id == AV_CODEC_ID_H264)
1826 if (atom.size == 16) {
1827 original_size = par->extradata_size;
1828 ret = mov_realloc_extradata(par, atom);
1830 length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
1831 if (length == atom.size) {
1832 const uint8_t range_value = par->extradata[original_size + 19];
1833 switch (range_value) {
1835 par->color_range = AVCOL_RANGE_MPEG;
1838 par->color_range = AVCOL_RANGE_JPEG;
1841 av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
1844 ff_dlog(c->fc, "color_range: %d\n", par->color_range);
1846 /* For some reason the whole atom was not added to the extradata */
1847 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
1850 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
1853 av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
1860 static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1862 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
1865 static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1870 if (c->fc->nb_streams < 1)
1872 st = c->fc->streams[c->fc->nb_streams-1];
1874 if ((uint64_t)atom.size > (1<<30))
1875 return AVERROR_INVALIDDATA;
1877 if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
1878 st->codecpar->codec_id == AV_CODEC_ID_QDMC ||
1879 st->codecpar->codec_id == AV_CODEC_ID_SPEEX) {
1880 // pass all frma atom to codec, needed at least for QDMC and QDM2
1881 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1884 } else if (atom.size > 8) { /* to read frma, esds atoms */
1885 if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
1887 ret = ffio_ensure_seekback(pb, 8);
1890 buffer = avio_rb64(pb);
1892 if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
1893 && buffer >> 32 <= atom.size
1894 && buffer >> 32 >= 8) {
1897 } else if (!st->codecpar->extradata_size) {
1898 #define ALAC_EXTRADATA_SIZE 36
1899 st->codecpar->extradata = av_mallocz(ALAC_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
1900 if (!st->codecpar->extradata)
1901 return AVERROR(ENOMEM);
1902 st->codecpar->extradata_size = ALAC_EXTRADATA_SIZE;
1903 AV_WB32(st->codecpar->extradata , ALAC_EXTRADATA_SIZE);
1904 AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
1905 AV_WB64(st->codecpar->extradata + 12, buffer);
1906 avio_read(pb, st->codecpar->extradata + 20, 16);
1907 avio_skip(pb, atom.size - 24);
1911 if ((ret = mov_read_default(c, pb, atom)) < 0)
1914 avio_skip(pb, atom.size);
1919 * This function reads atom content and puts data in extradata without tag
1920 * nor size unlike mov_read_extradata.
1922 static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1927 if (c->fc->nb_streams < 1)
1929 st = c->fc->streams[c->fc->nb_streams-1];
1931 if ((uint64_t)atom.size > (1<<30))
1932 return AVERROR_INVALIDDATA;
1934 if (atom.size >= 10) {
1935 // Broken files created by legacy versions of libavformat will
1936 // wrap a whole fiel atom inside of a glbl atom.
1937 unsigned size = avio_rb32(pb);
1938 unsigned type = avio_rl32(pb);
1939 avio_seek(pb, -8, SEEK_CUR);
1940 if (type == MKTAG('f','i','e','l') && size == atom.size)
1941 return mov_read_default(c, pb, atom);
1943 if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
1944 av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
1947 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1950 if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
1951 /* HEVC-based Dolby Vision derived from hvc1.
1952 Happens to match with an identifier
1953 previously utilized for DV. Thus, if we have
1954 the hvcC extradata box available as specified,
1955 set codec to HEVC */
1956 st->codecpar->codec_id = AV_CODEC_ID_HEVC;
1961 static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1964 uint8_t profile_level;
1967 if (c->fc->nb_streams < 1)
1969 st = c->fc->streams[c->fc->nb_streams-1];
1971 if (atom.size >= (1<<28) || atom.size < 7)
1972 return AVERROR_INVALIDDATA;
1974 profile_level = avio_r8(pb);
1975 if ((profile_level & 0xf0) != 0xc0)
1978 avio_seek(pb, 6, SEEK_CUR);
1979 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
1987 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
1988 * but can have extradata appended at the end after the 40 bytes belonging
1991 static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1996 if (c->fc->nb_streams < 1)
1998 if (atom.size <= 40)
2000 st = c->fc->streams[c->fc->nb_streams-1];
2002 if ((uint64_t)atom.size > (1<<30))
2003 return AVERROR_INVALIDDATA;
2006 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2013 static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2016 MOVStreamContext *sc;
2017 unsigned int i, entries;
2019 if (c->trak_index < 0) {
2020 av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2023 if (c->fc->nb_streams < 1)
2025 st = c->fc->streams[c->fc->nb_streams-1];
2028 avio_r8(pb); /* version */
2029 avio_rb24(pb); /* flags */
2031 entries = avio_rb32(pb);
2036 if (sc->chunk_offsets)
2037 av_log(c->fc, AV_LOG_WARNING, "Duplicated STCO atom\n");
2038 av_free(sc->chunk_offsets);
2039 sc->chunk_count = 0;
2040 sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2041 if (!sc->chunk_offsets)
2042 return AVERROR(ENOMEM);
2043 sc->chunk_count = entries;
2045 if (atom.type == MKTAG('s','t','c','o'))
2046 for (i = 0; i < entries && !pb->eof_reached; i++)
2047 sc->chunk_offsets[i] = avio_rb32(pb);
2048 else if (atom.type == MKTAG('c','o','6','4'))
2049 for (i = 0; i < entries && !pb->eof_reached; i++)
2050 sc->chunk_offsets[i] = avio_rb64(pb);
2052 return AVERROR_INVALIDDATA;
2054 sc->chunk_count = i;
2056 if (pb->eof_reached) {
2057 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2064 static int mov_codec_id(AVStream *st, uint32_t format)
2066 int id = ff_codec_get_id(ff_codec_movaudio_tags, format);
2069 ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2070 (format & 0xFFFF) == 'T' + ('S' << 8)))
2071 id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format) & 0xFFFF);
2073 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2074 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2075 } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2076 /* skip old ASF MPEG-4 tag */
2077 format && format != MKTAG('m','p','4','s')) {
2078 id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2080 id = ff_codec_get_id(ff_codec_bmp_tags, format);
2082 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
2083 else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2084 (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE &&
2085 st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2086 id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
2088 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
2090 id = ff_codec_get_id(ff_codec_movdata_tags, format);
2094 st->codecpar->codec_tag = format;
2099 static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
2100 AVStream *st, MOVStreamContext *sc)
2102 uint8_t codec_name[32] = { 0 };
2107 /* The first 16 bytes of the video sample description are already
2108 * read in ff_mov_read_stsd_entries() */
2109 stsd_start = avio_tell(pb) - 16;
2111 avio_rb16(pb); /* version */
2112 avio_rb16(pb); /* revision level */
2113 id = avio_rl32(pb); /* vendor */
2114 av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2115 avio_rb32(pb); /* temporal quality */
2116 avio_rb32(pb); /* spatial quality */
2118 st->codecpar->width = avio_rb16(pb); /* width */
2119 st->codecpar->height = avio_rb16(pb); /* height */
2121 avio_rb32(pb); /* horiz resolution */
2122 avio_rb32(pb); /* vert resolution */
2123 avio_rb32(pb); /* data size, always 0 */
2124 avio_rb16(pb); /* frames per samples */
2126 len = avio_r8(pb); /* codec name, pascal string */
2129 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2131 avio_skip(pb, 31 - len);
2134 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2136 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2137 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2138 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2139 st->codecpar->width &= ~1;
2140 st->codecpar->height &= ~1;
2142 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2143 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2144 !strncmp(codec_name, "Sorenson H263", 13))
2145 st->codecpar->codec_id = AV_CODEC_ID_FLV1;
2147 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2149 avio_seek(pb, stsd_start, SEEK_SET);
2151 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2152 st->codecpar->bits_per_coded_sample &= 0x1F;
2153 sc->has_palette = 1;
2157 static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
2158 AVStream *st, MOVStreamContext *sc)
2160 int bits_per_sample, flags;
2161 uint16_t version = avio_rb16(pb);
2163 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2165 avio_rb16(pb); /* revision level */
2166 id = avio_rl32(pb); /* vendor */
2167 av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2169 st->codecpar->channels = avio_rb16(pb); /* channel count */
2170 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2171 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", st->codecpar->channels);
2173 sc->audio_cid = avio_rb16(pb);
2174 avio_rb16(pb); /* packet size = 0 */
2176 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2178 // Read QT version 1 fields. In version 0 these do not exist.
2179 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2181 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2182 (sc->stsd_version == 0 && version > 0)) {
2184 sc->samples_per_frame = avio_rb32(pb);
2185 avio_rb32(pb); /* bytes per packet */
2186 sc->bytes_per_frame = avio_rb32(pb);
2187 avio_rb32(pb); /* bytes per sample */
2188 } else if (version == 2) {
2189 avio_rb32(pb); /* sizeof struct only */
2190 st->codecpar->sample_rate = av_int2double(avio_rb64(pb));
2191 st->codecpar->channels = avio_rb32(pb);
2192 avio_rb32(pb); /* always 0x7F000000 */
2193 st->codecpar->bits_per_coded_sample = avio_rb32(pb);
2195 flags = avio_rb32(pb); /* lpcm format specific flag */
2196 sc->bytes_per_frame = avio_rb32(pb);
2197 sc->samples_per_frame = avio_rb32(pb);
2198 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2199 st->codecpar->codec_id =
2200 ff_mov_get_lpcm_codec_id(st->codecpar->bits_per_coded_sample,
2203 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2204 /* can't correctly handle variable sized packet as audio unit */
2205 switch (st->codecpar->codec_id) {
2206 case AV_CODEC_ID_MP2:
2207 case AV_CODEC_ID_MP3:
2208 st->need_parsing = AVSTREAM_PARSE_FULL;
2214 if (sc->format == 0) {
2215 if (st->codecpar->bits_per_coded_sample == 8)
2216 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2217 else if (st->codecpar->bits_per_coded_sample == 16)
2218 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2221 switch (st->codecpar->codec_id) {
2222 case AV_CODEC_ID_PCM_S8:
2223 case AV_CODEC_ID_PCM_U8:
2224 if (st->codecpar->bits_per_coded_sample == 16)
2225 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16BE;
2227 case AV_CODEC_ID_PCM_S16LE:
2228 case AV_CODEC_ID_PCM_S16BE:
2229 if (st->codecpar->bits_per_coded_sample == 8)
2230 st->codecpar->codec_id = AV_CODEC_ID_PCM_S8;
2231 else if (st->codecpar->bits_per_coded_sample == 24)
2232 st->codecpar->codec_id =
2233 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2234 AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
2235 else if (st->codecpar->bits_per_coded_sample == 32)
2236 st->codecpar->codec_id =
2237 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2238 AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
2240 /* set values for old format before stsd version 1 appeared */
2241 case AV_CODEC_ID_MACE3:
2242 sc->samples_per_frame = 6;
2243 sc->bytes_per_frame = 2 * st->codecpar->channels;
2245 case AV_CODEC_ID_MACE6:
2246 sc->samples_per_frame = 6;
2247 sc->bytes_per_frame = 1 * st->codecpar->channels;
2249 case AV_CODEC_ID_ADPCM_IMA_QT:
2250 sc->samples_per_frame = 64;
2251 sc->bytes_per_frame = 34 * st->codecpar->channels;
2253 case AV_CODEC_ID_GSM:
2254 sc->samples_per_frame = 160;
2255 sc->bytes_per_frame = 33;
2261 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2262 if (bits_per_sample) {
2263 st->codecpar->bits_per_coded_sample = bits_per_sample;
2264 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->channels;
2268 static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
2269 AVStream *st, MOVStreamContext *sc,
2272 // ttxt stsd contains display flags, justification, background
2273 // color, fonts, and default styles, so fake an atom to read it
2274 MOVAtom fake_atom = { .size = size };
2275 // mp4s contains a regular esds atom
2276 if (st->codecpar->codec_tag != AV_RL32("mp4s"))
2277 mov_read_glbl(c, pb, fake_atom);
2278 st->codecpar->width = sc->width;
2279 st->codecpar->height = sc->height;
2282 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2287 y = (ycbcr >> 16) & 0xFF;
2288 cr = (ycbcr >> 8) & 0xFF;
2291 b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
2292 g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
2293 r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
2295 return (r << 16) | (g << 8) | b;
2298 static int mov_rewrite_dvd_sub_extradata(AVStream *st)
2300 char buf[256] = {0};
2301 uint8_t *src = st->codecpar->extradata;
2304 if (st->codecpar->extradata_size != 64)
2307 if (st->codecpar->width > 0 && st->codecpar->height > 0)
2308 snprintf(buf, sizeof(buf), "size: %dx%d\n",
2309 st->codecpar->width, st->codecpar->height);
2310 av_strlcat(buf, "palette: ", sizeof(buf));
2312 for (i = 0; i < 16; i++) {
2313 uint32_t yuv = AV_RB32(src + i * 4);
2314 uint32_t rgba = yuv_to_rgba(yuv);
2316 av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2319 if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2322 ret = ff_alloc_extradata(st->codecpar, strlen(buf));
2325 memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2330 static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
2331 AVStream *st, MOVStreamContext *sc,
2336 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2337 if ((int)size != size)
2338 return AVERROR(ENOMEM);
2340 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2344 MOVStreamContext *tmcd_ctx = st->priv_data;
2346 val = AV_RB32(st->codecpar->extradata + 4);
2347 tmcd_ctx->tmcd_flags = val;
2348 st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2349 st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2350 #if FF_API_LAVF_AVCTX
2351 FF_DISABLE_DEPRECATION_WARNINGS
2352 st->codec->time_base = av_inv_q(st->avg_frame_rate);
2353 FF_ENABLE_DEPRECATION_WARNINGS
2356 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2357 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2358 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2359 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2360 if (str_size > 0 && size >= (int)str_size + 30 &&
2361 st->codecpar->extradata[30] /* Don't add empty string */) {
2362 char *reel_name = av_malloc(str_size + 1);
2364 return AVERROR(ENOMEM);
2365 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2366 reel_name[str_size] = 0; /* Add null terminator */
2367 av_dict_set(&st->metadata, "reel_name", reel_name,
2368 AV_DICT_DONT_STRDUP_VAL);
2374 /* other codec type, just skip (rtp, mp4s ...) */
2375 avio_skip(pb, size);
2380 static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
2381 AVStream *st, MOVStreamContext *sc)
2383 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2384 !st->codecpar->sample_rate && sc->time_scale > 1)
2385 st->codecpar->sample_rate = sc->time_scale;
2387 /* special codec parameters handling */
2388 switch (st->codecpar->codec_id) {
2389 #if CONFIG_DV_DEMUXER
2390 case AV_CODEC_ID_DVAUDIO:
2391 c->dv_fctx = avformat_alloc_context();
2393 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2394 return AVERROR(ENOMEM);
2396 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2398 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2399 return AVERROR(ENOMEM);
2401 sc->dv_audio_container = 1;
2402 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
2405 /* no ifdef since parameters are always those */
2406 case AV_CODEC_ID_QCELP:
2407 st->codecpar->channels = 1;
2408 // force sample rate for qcelp when not stored in mov
2409 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2410 st->codecpar->sample_rate = 8000;
2411 // FIXME: Why is the following needed for some files?
2412 sc->samples_per_frame = 160;
2413 if (!sc->bytes_per_frame)
2414 sc->bytes_per_frame = 35;
2416 case AV_CODEC_ID_AMR_NB:
2417 st->codecpar->channels = 1;
2418 /* force sample rate for amr, stsd in 3gp does not store sample rate */
2419 st->codecpar->sample_rate = 8000;
2421 case AV_CODEC_ID_AMR_WB:
2422 st->codecpar->channels = 1;
2423 st->codecpar->sample_rate = 16000;
2425 case AV_CODEC_ID_MP2:
2426 case AV_CODEC_ID_MP3:
2427 /* force type after stsd for m1a hdlr */
2428 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2430 case AV_CODEC_ID_GSM:
2431 case AV_CODEC_ID_ADPCM_MS:
2432 case AV_CODEC_ID_ADPCM_IMA_WAV:
2433 case AV_CODEC_ID_ILBC:
2434 case AV_CODEC_ID_MACE3:
2435 case AV_CODEC_ID_MACE6:
2436 case AV_CODEC_ID_QDM2:
2437 st->codecpar->block_align = sc->bytes_per_frame;
2439 case AV_CODEC_ID_ALAC:
2440 if (st->codecpar->extradata_size == 36) {
2441 st->codecpar->channels = AV_RB8 (st->codecpar->extradata + 21);
2442 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2445 case AV_CODEC_ID_AC3:
2446 case AV_CODEC_ID_EAC3:
2447 case AV_CODEC_ID_MPEG1VIDEO:
2448 case AV_CODEC_ID_VC1:
2449 case AV_CODEC_ID_VP8:
2450 case AV_CODEC_ID_VP9:
2451 st->need_parsing = AVSTREAM_PARSE_FULL;
2453 case AV_CODEC_ID_AV1:
2454 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2462 static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
2463 int codec_tag, int format,
2466 int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2469 (codec_tag != format &&
2470 // AVID 1:1 samples with differing data format and codec tag exist
2471 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
2472 // prores is allowed to have differing data format and codec tag
2473 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
2475 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
2476 (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id
2477 : codec_tag != MKTAG('j','p','e','g')))) {
2478 /* Multiple fourcc, we skip JPEG. This is not correct, we should
2479 * export it as a separate AVStream but this needs a few changes
2480 * in the MOV demuxer, patch welcome. */
2482 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
2483 avio_skip(pb, size);
2490 int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
2493 MOVStreamContext *sc;
2494 int pseudo_stream_id;
2496 av_assert0 (c->fc->nb_streams >= 1);
2497 st = c->fc->streams[c->fc->nb_streams-1];
2500 for (pseudo_stream_id = 0;
2501 pseudo_stream_id < entries && !pb->eof_reached;
2502 pseudo_stream_id++) {
2503 //Parsing Sample description table
2505 int ret, dref_id = 1;
2506 MOVAtom a = { AV_RL32("stsd") };
2507 int64_t start_pos = avio_tell(pb);
2508 int64_t size = avio_rb32(pb); /* size */
2509 uint32_t format = avio_rl32(pb); /* data format */
2512 avio_rb32(pb); /* reserved */
2513 avio_rb16(pb); /* reserved */
2514 dref_id = avio_rb16(pb);
2515 } else if (size <= 7) {
2516 av_log(c->fc, AV_LOG_ERROR,
2517 "invalid size %"PRId64" in stsd\n", size);
2518 return AVERROR_INVALIDDATA;
2521 if (mov_skip_multiple_stsd(c, pb, st->codecpar->codec_tag, format,
2522 size - (avio_tell(pb) - start_pos))) {
2527 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
2528 sc->dref_id= dref_id;
2529 sc->format = format;
2531 id = mov_codec_id(st, format);
2533 av_log(c->fc, AV_LOG_TRACE,
2534 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
2535 av_fourcc2str(format), st->codecpar->codec_type);
2537 st->codecpar->codec_id = id;
2538 if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) {
2539 mov_parse_stsd_video(c, pb, st, sc);
2540 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
2541 mov_parse_stsd_audio(c, pb, st, sc);
2542 if (st->codecpar->sample_rate < 0) {
2543 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
2544 return AVERROR_INVALIDDATA;
2546 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
2547 mov_parse_stsd_subtitle(c, pb, st, sc,
2548 size - (avio_tell(pb) - start_pos));
2550 ret = mov_parse_stsd_data(c, pb, st, sc,
2551 size - (avio_tell(pb) - start_pos));
2555 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
2556 a.size = size - (avio_tell(pb) - start_pos);
2558 if ((ret = mov_read_default(c, pb, a)) < 0)
2560 } else if (a.size > 0)
2561 avio_skip(pb, a.size);
2563 if (sc->extradata && st->codecpar->extradata) {
2564 int extra_size = st->codecpar->extradata_size;
2566 /* Move the current stream extradata to the stream context one. */
2567 sc->extradata_size[pseudo_stream_id] = extra_size;
2568 sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
2569 st->codecpar->extradata = NULL;
2570 st->codecpar->extradata_size = 0;
2575 if (pb->eof_reached) {
2576 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
2583 static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2586 MOVStreamContext *sc;
2589 if (c->fc->nb_streams < 1)
2591 st = c->fc->streams[c->fc->nb_streams - 1];
2594 sc->stsd_version = avio_r8(pb);
2595 avio_rb24(pb); /* flags */
2596 entries = avio_rb32(pb);
2598 /* Each entry contains a size (4 bytes) and format (4 bytes). */
2599 if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
2600 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
2601 return AVERROR_INVALIDDATA;
2604 if (sc->extradata) {
2605 av_log(c->fc, AV_LOG_ERROR,
2606 "Duplicate stsd found in this track.\n");
2607 return AVERROR_INVALIDDATA;
2610 /* Prepare space for hosting multiple extradata. */
2611 sc->extradata = av_mallocz_array(entries, sizeof(*sc->extradata));
2613 return AVERROR(ENOMEM);
2615 sc->extradata_size = av_mallocz_array(entries, sizeof(*sc->extradata_size));
2616 if (!sc->extradata_size) {
2617 ret = AVERROR(ENOMEM);
2621 ret = ff_mov_read_stsd_entries(c, pb, entries);
2625 /* Restore back the primary extradata. */
2626 av_freep(&st->codecpar->extradata);
2627 st->codecpar->extradata_size = sc->extradata_size[0];
2628 if (sc->extradata_size[0]) {
2629 st->codecpar->extradata = av_mallocz(sc->extradata_size[0] + AV_INPUT_BUFFER_PADDING_SIZE);
2630 if (!st->codecpar->extradata)
2631 return AVERROR(ENOMEM);
2632 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
2635 return mov_finalize_stsd_codec(c, pb, st, sc);
2637 if (sc->extradata) {
2639 for (j = 0; j < sc->stsd_count; j++)
2640 av_freep(&sc->extradata[j]);
2643 av_freep(&sc->extradata);
2644 av_freep(&sc->extradata_size);
2648 static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2651 MOVStreamContext *sc;
2652 unsigned int i, entries;
2654 if (c->fc->nb_streams < 1)
2656 st = c->fc->streams[c->fc->nb_streams-1];
2659 avio_r8(pb); /* version */
2660 avio_rb24(pb); /* flags */
2662 entries = avio_rb32(pb);
2663 if ((uint64_t)entries * 12 + 4 > atom.size)
2664 return AVERROR_INVALIDDATA;
2666 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
2671 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSC atom\n");
2672 av_free(sc->stsc_data);
2674 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
2676 return AVERROR(ENOMEM);
2678 for (i = 0; i < entries && !pb->eof_reached; i++) {
2679 sc->stsc_data[i].first = avio_rb32(pb);
2680 sc->stsc_data[i].count = avio_rb32(pb);
2681 sc->stsc_data[i].id = avio_rb32(pb);
2685 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
2686 int64_t first_min = i + 1;
2687 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
2688 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
2689 sc->stsc_data[i].first < first_min ||
2690 sc->stsc_data[i].count < 1 ||
2691 sc->stsc_data[i].id < 1) {
2692 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);
2693 if (i+1 >= sc->stsc_count) {
2694 if (sc->stsc_data[i].count == 0 && i > 0) {
2698 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
2699 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
2700 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
2701 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
2702 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
2705 av_assert0(sc->stsc_data[i+1].first >= 2);
2706 // We replace this entry by the next valid
2707 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
2708 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
2709 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
2713 if (pb->eof_reached) {
2714 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
2721 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
2723 return index < count - 1;
2726 /* Compute the samples value for the stsc entry at the given index. */
2727 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
2731 if (mov_stsc_index_valid(index, sc->stsc_count))
2732 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
2734 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
2735 av_assert0(sc->stsc_data[index].first <= sc->chunk_count);
2736 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
2739 return sc->stsc_data[index].count * (int64_t)chunk_count;
2742 static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2745 MOVStreamContext *sc;
2746 unsigned i, entries;
2748 if (c->fc->nb_streams < 1)
2750 st = c->fc->streams[c->fc->nb_streams-1];
2753 avio_rb32(pb); // version + flags
2755 entries = avio_rb32(pb);
2757 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
2758 av_free(sc->stps_data);
2760 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
2762 return AVERROR(ENOMEM);
2764 for (i = 0; i < entries && !pb->eof_reached; i++) {
2765 sc->stps_data[i] = avio_rb32(pb);
2770 if (pb->eof_reached) {
2771 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
2778 static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2781 MOVStreamContext *sc;
2782 unsigned int i, entries;
2784 if (c->fc->nb_streams < 1)
2786 st = c->fc->streams[c->fc->nb_streams-1];
2789 avio_r8(pb); /* version */
2790 avio_rb24(pb); /* flags */
2792 entries = avio_rb32(pb);
2794 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
2797 sc->keyframe_absent = 1;
2798 if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
2799 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2803 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
2804 if (entries >= UINT_MAX / sizeof(int))
2805 return AVERROR_INVALIDDATA;
2806 av_freep(&sc->keyframes);
2807 sc->keyframe_count = 0;
2808 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
2810 return AVERROR(ENOMEM);
2812 for (i = 0; i < entries && !pb->eof_reached; i++) {
2813 sc->keyframes[i] = avio_rb32(pb);
2816 sc->keyframe_count = i;
2818 if (pb->eof_reached) {
2819 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
2826 static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2829 MOVStreamContext *sc;
2830 unsigned int i, entries, sample_size, field_size, num_bytes;
2835 if (c->fc->nb_streams < 1)
2837 st = c->fc->streams[c->fc->nb_streams-1];
2840 avio_r8(pb); /* version */
2841 avio_rb24(pb); /* flags */
2843 if (atom.type == MKTAG('s','t','s','z')) {
2844 sample_size = avio_rb32(pb);
2845 if (!sc->sample_size) /* do not overwrite value computed in stsd */
2846 sc->sample_size = sample_size;
2847 sc->stsz_sample_size = sample_size;
2851 avio_rb24(pb); /* reserved */
2852 field_size = avio_r8(pb);
2854 entries = avio_rb32(pb);
2856 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
2858 sc->sample_count = entries;
2862 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
2863 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
2864 return AVERROR_INVALIDDATA;
2869 if (entries >= (UINT_MAX - 4) / field_size)
2870 return AVERROR_INVALIDDATA;
2871 if (sc->sample_sizes)
2872 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
2873 av_free(sc->sample_sizes);
2874 sc->sample_count = 0;
2875 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
2876 if (!sc->sample_sizes)
2877 return AVERROR(ENOMEM);
2879 num_bytes = (entries*field_size+4)>>3;
2881 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
2883 av_freep(&sc->sample_sizes);
2884 return AVERROR(ENOMEM);
2887 ret = ffio_read_size(pb, buf, num_bytes);
2889 av_freep(&sc->sample_sizes);
2891 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
2895 init_get_bits(&gb, buf, 8*num_bytes);
2897 for (i = 0; i < entries && !pb->eof_reached; i++) {
2898 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
2899 if (sc->sample_sizes[i] < 0) {
2901 av_log(c->fc, AV_LOG_ERROR, "Invalid sample size %d\n", sc->sample_sizes[i]);
2902 return AVERROR_INVALIDDATA;
2904 sc->data_size += sc->sample_sizes[i];
2907 sc->sample_count = i;
2911 if (pb->eof_reached) {
2912 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSZ atom\n");
2919 static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2922 MOVStreamContext *sc;
2923 unsigned int i, entries, alloc_size = 0;
2924 int64_t duration = 0;
2925 int64_t total_sample_count = 0;
2927 if (c->fc->nb_streams < 1)
2929 st = c->fc->streams[c->fc->nb_streams-1];
2932 avio_r8(pb); /* version */
2933 avio_rb24(pb); /* flags */
2934 entries = avio_rb32(pb);
2936 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
2937 c->fc->nb_streams-1, entries);
2940 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
2941 av_freep(&sc->stts_data);
2943 if (entries >= INT_MAX / sizeof(*sc->stts_data))
2944 return AVERROR(ENOMEM);
2946 for (i = 0; i < entries && !pb->eof_reached; i++) {
2947 int sample_duration;
2948 unsigned int sample_count;
2949 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
2950 MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
2951 min_entries * sizeof(*sc->stts_data));
2953 av_freep(&sc->stts_data);
2955 return AVERROR(ENOMEM);
2957 sc->stts_count = min_entries;
2958 sc->stts_data = stts_data;
2960 sample_count = avio_rb32(pb);
2961 sample_duration = avio_rb32(pb);
2963 sc->stts_data[i].count= sample_count;
2964 sc->stts_data[i].duration= sample_duration;
2966 av_log(c->fc, AV_LOG_TRACE, "sample_count=%d, sample_duration=%d\n",
2967 sample_count, sample_duration);
2969 duration+=(int64_t)sample_duration*(uint64_t)sample_count;
2970 total_sample_count+=sample_count;
2976 duration <= INT64_MAX - sc->duration_for_fps &&
2977 total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
2978 sc->duration_for_fps += duration;
2979 sc->nb_frames_for_fps += total_sample_count;
2982 if (pb->eof_reached) {
2983 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
2987 st->nb_frames= total_sample_count;
2989 st->duration= FFMIN(st->duration, duration);
2990 sc->track_end = duration;
2994 static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2997 MOVStreamContext *sc;
3000 if (c->fc->nb_streams < 1)
3002 st = c->fc->streams[c->fc->nb_streams - 1];
3005 avio_r8(pb); /* version */
3006 avio_rb24(pb); /* flags */
3007 entries = atom.size - 4;
3009 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3010 c->fc->nb_streams - 1, entries);
3013 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3014 av_freep(&sc->sdtp_data);
3017 sc->sdtp_data = av_mallocz(entries);
3019 return AVERROR(ENOMEM);
3021 for (i = 0; i < entries && !pb->eof_reached; i++)
3022 sc->sdtp_data[i] = avio_r8(pb);
3028 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3031 if (duration == INT_MIN) {
3032 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3035 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3039 static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3042 MOVStreamContext *sc;
3043 unsigned int i, entries, ctts_count = 0;
3045 if (c->fc->nb_streams < 1)
3047 st = c->fc->streams[c->fc->nb_streams-1];
3050 avio_r8(pb); /* version */
3051 avio_rb24(pb); /* flags */
3052 entries = avio_rb32(pb);
3054 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3058 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3059 return AVERROR_INVALIDDATA;
3060 av_freep(&sc->ctts_data);
3061 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3063 return AVERROR(ENOMEM);
3065 for (i = 0; i < entries && !pb->eof_reached; i++) {
3066 int count = avio_rb32(pb);
3067 int duration = avio_rb32(pb);
3070 av_log(c->fc, AV_LOG_TRACE,
3071 "ignoring CTTS entry with count=%d duration=%d\n",
3076 add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3079 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3082 if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3083 av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3084 av_freep(&sc->ctts_data);
3090 mov_update_dts_shift(sc, duration, c->fc);
3093 sc->ctts_count = ctts_count;
3095 if (pb->eof_reached) {
3096 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3100 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3105 static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3108 MOVStreamContext *sc;
3109 unsigned int i, entries;
3111 uint32_t grouping_type;
3113 if (c->fc->nb_streams < 1)
3115 st = c->fc->streams[c->fc->nb_streams-1];
3118 version = avio_r8(pb); /* version */
3119 avio_rb24(pb); /* flags */
3120 grouping_type = avio_rl32(pb);
3121 if (grouping_type != MKTAG( 'r','a','p',' '))
3122 return 0; /* only support 'rap ' grouping */
3124 avio_rb32(pb); /* grouping_type_parameter */
3126 entries = avio_rb32(pb);
3130 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP atom\n");
3131 av_free(sc->rap_group);
3132 sc->rap_group_count = 0;
3133 sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group));
3135 return AVERROR(ENOMEM);
3137 for (i = 0; i < entries && !pb->eof_reached; i++) {
3138 sc->rap_group[i].count = avio_rb32(pb); /* sample_count */
3139 sc->rap_group[i].index = avio_rb32(pb); /* group_description_index */
3142 sc->rap_group_count = i;
3144 if (pb->eof_reached) {
3145 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3153 * Get ith edit list entry (media time, duration).
3155 static int get_edit_list_entry(MOVContext *mov,
3156 const MOVStreamContext *msc,
3157 unsigned int edit_list_index,
3158 int64_t *edit_list_media_time,
3159 int64_t *edit_list_duration,
3160 int64_t global_timescale)
3162 if (edit_list_index == msc->elst_count) {
3165 *edit_list_media_time = msc->elst_data[edit_list_index].time;
3166 *edit_list_duration = msc->elst_data[edit_list_index].duration;
3168 /* duration is in global timescale units;convert to msc timescale */
3169 if (global_timescale == 0) {
3170 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3173 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3179 * Find the closest previous frame to the timestamp_pts, in e_old index
3180 * entries. Searching for just any frame / just key frames can be controlled by
3181 * last argument 'flag'.
3182 * Note that if ctts_data is not NULL, we will always search for a key frame
3183 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3184 * return the first frame of the video.
3186 * Here the timestamp_pts is considered to be a presentation timestamp and
3187 * the timestamp of index entries are considered to be decoding timestamps.
3189 * Returns 0 if successful in finding a frame, else returns -1.
3190 * Places the found index corresponding output arg.
3192 * If ctts_old is not NULL, then refines the searched entry by searching
3193 * backwards from the found timestamp, to find the frame with correct PTS.
3195 * Places the found ctts_index and ctts_sample in corresponding output args.
3197 static int find_prev_closest_index(AVStream *st,
3198 AVIndexEntry *e_old,
3202 int64_t timestamp_pts,
3205 int64_t* ctts_index,
3206 int64_t* ctts_sample)
3208 MOVStreamContext *msc = st->priv_data;
3209 AVIndexEntry *e_keep = st->internal->index_entries;
3210 int nb_keep = st->internal->nb_index_entries;
3212 int64_t index_ctts_count;
3216 // If dts_shift > 0, then all the index timestamps will have to be offset by
3217 // at least dts_shift amount to obtain PTS.
3218 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3219 if (msc->dts_shift > 0) {
3220 timestamp_pts -= msc->dts_shift;
3223 st->internal->index_entries = e_old;
3224 st->internal->nb_index_entries = nb_old;
3225 *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3227 // Keep going backwards in the index entries until the timestamp is the same.
3229 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3231 if ((flag & AVSEEK_FLAG_ANY) ||
3232 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3238 // If we have CTTS then refine the search, by searching backwards over PTS
3239 // computed by adding corresponding CTTS durations to index timestamps.
3240 if (ctts_data && *index >= 0) {
3241 av_assert0(ctts_index);
3242 av_assert0(ctts_sample);
3243 // Find out the ctts_index for the found frame.
3246 for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3247 if (*ctts_index < ctts_count) {
3249 if (ctts_data[*ctts_index].count == *ctts_sample) {
3256 while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3257 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3258 // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3259 // compensated by dts_shift above.
3260 if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3261 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3266 if (*ctts_sample == 0) {
3268 if (*ctts_index >= 0)
3269 *ctts_sample = ctts_data[*ctts_index].count - 1;
3276 /* restore AVStream state*/
3277 st->internal->index_entries = e_keep;
3278 st->internal->nb_index_entries = nb_keep;
3279 return *index >= 0 ? 0 : -1;
3283 * Add index entry with the given values, to the end of st->internal->index_entries.
3284 * Returns the new size st->internal->index_entries if successful, else returns -1.
3286 * This function is similar to ff_add_index_entry in libavformat/utils.c
3287 * except that here we are always unconditionally adding an index entry to
3288 * the end, instead of searching the entries list and skipping the add if
3289 * there is an existing entry with the same timestamp.
3290 * This is needed because the mov_fix_index calls this func with the same
3291 * unincremented timestamp for successive discarded frames.
3293 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3294 int size, int distance, int flags)
3296 AVIndexEntry *entries, *ie;
3298 const size_t min_size_needed = (st->internal->nb_index_entries + 1) * sizeof(AVIndexEntry);
3300 // Double the allocation each time, to lower memory fragmentation.
3301 // Another difference from ff_add_index_entry function.
3302 const size_t requested_size =
3303 min_size_needed > st->internal->index_entries_allocated_size ?
3304 FFMAX(min_size_needed, 2 * st->internal->index_entries_allocated_size) :
3307 if (st->internal->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
3310 entries = av_fast_realloc(st->internal->index_entries,
3311 &st->internal->index_entries_allocated_size,
3316 st->internal->index_entries= entries;
3318 index= st->internal->nb_index_entries++;
3319 ie= &entries[index];
3322 ie->timestamp = timestamp;
3323 ie->min_distance= distance;
3330 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3331 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3333 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3334 int64_t* frame_duration_buffer,
3335 int frame_duration_buffer_size) {
3337 av_assert0(end_index >= 0 && end_index <= st->internal->nb_index_entries);
3338 for (i = 0; i < frame_duration_buffer_size; i++) {
3339 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3340 st->internal->index_entries[end_index - 1 - i].timestamp = end_ts;
3345 * Append a new ctts entry to ctts_data.
3346 * Returns the new ctts_count if successful, else returns -1.
3348 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3349 int count, int duration)
3351 MOVStts *ctts_buf_new;
3352 const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVStts);
3353 const size_t requested_size =
3354 min_size_needed > *allocated_size ?
3355 FFMAX(min_size_needed, 2 * (*allocated_size)) :
3358 if ((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
3361 ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3366 *ctts_data = ctts_buf_new;
3368 ctts_buf_new[*ctts_count].count = count;
3369 ctts_buf_new[*ctts_count].duration = duration;
3371 *ctts_count = (*ctts_count) + 1;
3375 #define MAX_REORDER_DELAY 16
3376 static void mov_estimate_video_delay(MOVContext *c, AVStream* st)
3378 MOVStreamContext *msc = st->priv_data;
3381 int ctts_sample = 0;
3382 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3384 int j, r, num_swaps;
3386 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3387 pts_buf[j] = INT64_MIN;
3389 if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3390 st->codecpar->codec_id == AV_CODEC_ID_H264) {
3391 st->codecpar->video_delay = 0;
3392 for (ind = 0; ind < st->internal->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3393 // Point j to the last elem of the buffer and insert the current pts there.
3395 buf_start = (buf_start + 1);
3396 if (buf_start == MAX_REORDER_DELAY + 1)
3399 pts_buf[j] = st->internal->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3401 // The timestamps that are already in the sorted buffer, and are greater than the
3402 // current pts, are exactly the timestamps that need to be buffered to output PTS
3403 // in correct sorted order.
3404 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3405 // can be computed as the maximum no. of swaps any particular timestamp needs to
3406 // go through, to keep this buffer in sorted order.
3408 while (j != buf_start) {
3410 if (r < 0) r = MAX_REORDER_DELAY;
3411 if (pts_buf[j] < pts_buf[r]) {
3412 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3419 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3422 if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3427 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3428 st->codecpar->video_delay, st->index);
3432 static void mov_current_sample_inc(MOVStreamContext *sc)
3434 sc->current_sample++;
3435 sc->current_index++;
3436 if (sc->index_ranges &&
3437 sc->current_index >= sc->current_index_range->end &&
3438 sc->current_index_range->end) {
3439 sc->current_index_range++;
3440 sc->current_index = sc->current_index_range->start;
3444 static void mov_current_sample_dec(MOVStreamContext *sc)
3446 sc->current_sample--;
3447 sc->current_index--;
3448 if (sc->index_ranges &&
3449 sc->current_index < sc->current_index_range->start &&
3450 sc->current_index_range > sc->index_ranges) {
3451 sc->current_index_range--;
3452 sc->current_index = sc->current_index_range->end - 1;
3456 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3460 sc->current_sample = current_sample;
3461 sc->current_index = current_sample;
3462 if (!sc->index_ranges) {
3466 for (sc->current_index_range = sc->index_ranges;
3467 sc->current_index_range->end;
3468 sc->current_index_range++) {
3469 range_size = sc->current_index_range->end - sc->current_index_range->start;
3470 if (range_size > current_sample) {
3471 sc->current_index = sc->current_index_range->start + current_sample;
3474 current_sample -= range_size;
3479 * Fix st->internal->index_entries, so that it contains only the entries (and the entries
3480 * which are needed to decode them) that fall in the edit list time ranges.
3481 * Also fixes the timestamps of the index entries to match the timeline
3482 * specified the edit lists.
3484 static void mov_fix_index(MOVContext *mov, AVStream *st)
3486 MOVStreamContext *msc = st->priv_data;
3487 AVIndexEntry *e_old = st->internal->index_entries;
3488 int nb_old = st->internal->nb_index_entries;
3489 const AVIndexEntry *e_old_end = e_old + nb_old;
3490 const AVIndexEntry *current = NULL;
3491 MOVStts *ctts_data_old = msc->ctts_data;
3492 int64_t ctts_index_old = 0;
3493 int64_t ctts_sample_old = 0;
3494 int64_t ctts_count_old = msc->ctts_count;
3495 int64_t edit_list_media_time = 0;
3496 int64_t edit_list_duration = 0;
3497 int64_t frame_duration = 0;
3498 int64_t edit_list_dts_counter = 0;
3499 int64_t edit_list_dts_entry_end = 0;
3500 int64_t edit_list_start_ctts_sample = 0;
3502 int64_t curr_ctts = 0;
3503 int64_t empty_edits_sum_duration = 0;
3504 int64_t edit_list_index = 0;
3507 int64_t start_dts = 0;
3508 int64_t edit_list_start_encountered = 0;
3509 int64_t search_timestamp = 0;
3510 int64_t* frame_duration_buffer = NULL;
3511 int num_discarded_begin = 0;
3512 int first_non_zero_audio_edit = -1;
3513 int packet_skip_samples = 0;
3514 MOVIndexRange *current_index_range;
3516 int found_keyframe_after_edit = 0;
3517 int found_non_empty_edit = 0;
3519 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
3523 // allocate the index ranges array
3524 msc->index_ranges = av_malloc((msc->elst_count + 1) * sizeof(msc->index_ranges[0]));
3525 if (!msc->index_ranges) {
3526 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
3529 msc->current_index_range = msc->index_ranges;
3530 current_index_range = msc->index_ranges - 1;
3532 // Clean AVStream from traces of old index
3533 st->internal->index_entries = NULL;
3534 st->internal->index_entries_allocated_size = 0;
3535 st->internal->nb_index_entries = 0;
3537 // Clean ctts fields of MOVStreamContext
3538 msc->ctts_data = NULL;
3539 msc->ctts_count = 0;
3540 msc->ctts_index = 0;
3541 msc->ctts_sample = 0;
3542 msc->ctts_allocated_size = 0;
3544 // Reinitialize min_corrected_pts so that it can be computed again.
3545 msc->min_corrected_pts = -1;
3547 // If the dts_shift is positive (in case of negative ctts values in mov),
3548 // then negate the DTS by dts_shift
3549 if (msc->dts_shift > 0) {
3550 edit_list_dts_entry_end -= msc->dts_shift;
3551 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
3554 start_dts = edit_list_dts_entry_end;
3556 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
3557 &edit_list_duration, mov->time_scale)) {
3558 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
3559 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
3561 edit_list_dts_counter = edit_list_dts_entry_end;
3562 edit_list_dts_entry_end += edit_list_duration;
3563 num_discarded_begin = 0;
3564 if (!found_non_empty_edit && edit_list_media_time == -1) {
3565 empty_edits_sum_duration += edit_list_duration;
3568 found_non_empty_edit = 1;
3570 // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
3571 // according to the edit list below.
3572 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3573 if (first_non_zero_audio_edit < 0) {
3574 first_non_zero_audio_edit = 1;
3576 first_non_zero_audio_edit = 0;
3579 if (first_non_zero_audio_edit > 0)
3580 st->internal->skip_samples = msc->start_pad = 0;
3583 // While reordering frame index according to edit list we must handle properly
3584 // the scenario when edit list entry starts from none key frame.
3585 // We find closest previous key frame and preserve it and consequent frames in index.
3586 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
3587 search_timestamp = edit_list_media_time;
3588 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3589 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
3590 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
3591 // edit_list_media_time to cover the decoder delay.
3592 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
3595 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
3596 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3597 av_log(mov->fc, AV_LOG_WARNING,
3598 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
3599 st->index, edit_list_index, search_timestamp);
3600 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
3601 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3602 av_log(mov->fc, AV_LOG_WARNING,
3603 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
3604 st->index, edit_list_index, search_timestamp);
3607 ctts_sample_old = 0;
3610 current = e_old + index;
3611 edit_list_start_ctts_sample = ctts_sample_old;
3613 // Iterate over index and arrange it according to edit list
3614 edit_list_start_encountered = 0;
3615 found_keyframe_after_edit = 0;
3616 for (; current < e_old_end; current++, index++) {
3617 // check if frame outside edit list mark it for discard
3618 frame_duration = (current + 1 < e_old_end) ?
3619 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
3621 flags = current->flags;
3623 // frames (pts) before or after edit list
3624 curr_cts = current->timestamp + msc->dts_shift;
3627 if (ctts_data_old && ctts_index_old < ctts_count_old) {
3628 curr_ctts = ctts_data_old[ctts_index_old].duration;
3629 av_log(mov->fc, AV_LOG_DEBUG, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
3630 curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
3631 curr_cts += curr_ctts;
3633 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
3634 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3635 &msc->ctts_allocated_size,
3636 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3637 ctts_data_old[ctts_index_old].duration) == -1) {
3638 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3640 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3641 ctts_data_old[ctts_index_old].duration);
3645 ctts_sample_old = 0;
3646 edit_list_start_ctts_sample = 0;
3650 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
3651 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
3652 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
3653 first_non_zero_audio_edit > 0) {
3654 packet_skip_samples = edit_list_media_time - curr_cts;
3655 st->internal->skip_samples += packet_skip_samples;
3657 // Shift the index entry timestamp by packet_skip_samples to be correct.
3658 edit_list_dts_counter -= packet_skip_samples;
3659 if (edit_list_start_encountered == 0) {
3660 edit_list_start_encountered = 1;
3661 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
3662 // discarded packets.
3663 if (frame_duration_buffer) {
3664 fix_index_entry_timestamps(st, st->internal->nb_index_entries, edit_list_dts_counter,
3665 frame_duration_buffer, num_discarded_begin);
3666 av_freep(&frame_duration_buffer);
3670 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
3672 flags |= AVINDEX_DISCARD_FRAME;
3673 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
3675 if (edit_list_start_encountered == 0) {
3676 num_discarded_begin++;
3677 frame_duration_buffer = av_realloc(frame_duration_buffer,
3678 num_discarded_begin * sizeof(int64_t));
3679 if (!frame_duration_buffer) {
3680 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
3683 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
3685 // Increment skip_samples for the first non-zero audio edit list
3686 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3687 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
3688 st->internal->skip_samples += frame_duration;
3693 if (msc->min_corrected_pts < 0) {
3694 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
3696 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
3698 if (edit_list_start_encountered == 0) {
3699 edit_list_start_encountered = 1;
3700 // Make timestamps strictly monotonically increasing by rewriting timestamps for
3701 // discarded packets.
3702 if (frame_duration_buffer) {
3703 fix_index_entry_timestamps(st, st->internal->nb_index_entries, edit_list_dts_counter,
3704 frame_duration_buffer, num_discarded_begin);
3705 av_freep(&frame_duration_buffer);
3710 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
3711 current->min_distance, flags) == -1) {
3712 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
3716 // Update the index ranges array
3717 if (current_index_range < msc->index_ranges || index != current_index_range->end) {
3718 current_index_range++;
3719 current_index_range->start = index;
3721 current_index_range->end = index + 1;
3723 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
3724 if (edit_list_start_encountered > 0) {
3725 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
3728 // Break when found first key frame after edit entry completion
3729 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
3730 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
3731 if (ctts_data_old) {
3732 // If we have CTTS and this is the first keyframe after edit elist,
3733 // wait for one more, because there might be trailing B-frames after this I-frame
3734 // that do belong to the edit.
3735 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
3736 found_keyframe_after_edit = 1;
3739 if (ctts_sample_old != 0) {
3740 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3741 &msc->ctts_allocated_size,
3742 ctts_sample_old - edit_list_start_ctts_sample,
3743 ctts_data_old[ctts_index_old].duration) == -1) {
3744 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3745 ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
3746 ctts_data_old[ctts_index_old].duration);
3755 // If there are empty edits, then msc->min_corrected_pts might be positive
3756 // intentionally. So we subtract the sum duration of emtpy edits here.
3757 msc->min_corrected_pts -= empty_edits_sum_duration;
3759 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
3760 // dts by that amount to make the first pts zero.
3761 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
3762 if (msc->min_corrected_pts > 0) {
3763 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
3764 for (i = 0; i < st->internal->nb_index_entries; ++i) {
3765 st->internal->index_entries[i].timestamp -= msc->min_corrected_pts;
3769 // Start time should be equal to zero or the duration of any empty edits.
3770 st->start_time = empty_edits_sum_duration;
3772 // Update av stream length, if it ends up shorter than the track's media duration
3773 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
3774 msc->start_pad = st->internal->skip_samples;
3776 // Free the old index and the old CTTS structures
3778 av_free(ctts_data_old);
3779 av_freep(&frame_duration_buffer);
3781 // Null terminate the index ranges array
3782 current_index_range++;
3783 current_index_range->start = 0;
3784 current_index_range->end = 0;
3785 msc->current_index = msc->index_ranges[0].start;
3788 static void mov_build_index(MOVContext *mov, AVStream *st)
3790 MOVStreamContext *sc = st->priv_data;
3791 int64_t current_offset;
3792 int64_t current_dts = 0;
3793 unsigned int stts_index = 0;
3794 unsigned int stsc_index = 0;
3795 unsigned int stss_index = 0;
3796 unsigned int stps_index = 0;
3798 uint64_t stream_size = 0;
3799 MOVStts *ctts_data_old = sc->ctts_data;
3800 unsigned int ctts_count_old = sc->ctts_count;
3802 if (sc->elst_count) {
3803 int i, edit_start_index = 0, multiple_edits = 0;
3804 int64_t empty_duration = 0; // empty duration of the first edit list entry
3805 int64_t start_time = 0; // start time of the media
3807 for (i = 0; i < sc->elst_count; i++) {
3808 const MOVElst *e = &sc->elst_data[i];
3809 if (i == 0 && e->time == -1) {
3810 /* if empty, the first entry is the start time of the stream
3811 * relative to the presentation itself */
3812 empty_duration = e->duration;
3813 edit_start_index = 1;
3814 } else if (i == edit_start_index && e->time >= 0) {
3815 start_time = e->time;
3821 if (multiple_edits && !mov->advanced_editlist)
3822 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
3823 "Use -advanced_editlist to correctly decode otherwise "
3824 "a/v desync might occur\n");
3826 /* adjust first dts according to edit list */
3827 if ((empty_duration || start_time) && mov->time_scale > 0) {
3829 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
3830 sc->time_offset = start_time - empty_duration;
3831 sc->min_corrected_pts = start_time;
3832 if (!mov->advanced_editlist)
3833 current_dts = -sc->time_offset;
3836 if (!multiple_edits && !mov->advanced_editlist &&
3837 st->codecpar->codec_id == AV_CODEC_ID_AAC && start_time > 0)
3838 sc->start_pad = start_time;
3841 /* only use old uncompressed audio chunk demuxing when stts specifies it */
3842 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3843 sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
3844 unsigned int current_sample = 0;
3845 unsigned int stts_sample = 0;
3846 unsigned int sample_size;
3847 unsigned int distance = 0;
3848 unsigned int rap_group_index = 0;
3849 unsigned int rap_group_sample = 0;
3850 int64_t last_dts = 0;
3851 int64_t dts_correction = 0;
3852 int rap_group_present = sc->rap_group_count && sc->rap_group;
3853 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
3855 current_dts -= sc->dts_shift;
3856 last_dts = current_dts;
3858 if (!sc->sample_count || st->internal->nb_index_entries)
3860 if (sc->sample_count >= UINT_MAX / sizeof(*st->internal->index_entries) - st->internal->nb_index_entries)
3862 if (av_reallocp_array(&st->internal->index_entries,
3863 st->internal->nb_index_entries + sc->sample_count,
3864 sizeof(*st->internal->index_entries)) < 0) {
3865 st->internal->nb_index_entries = 0;
3868 st->internal->index_entries_allocated_size = (st->internal->nb_index_entries + sc->sample_count) * sizeof(*st->internal->index_entries);
3870 if (ctts_data_old) {
3871 // Expand ctts entries such that we have a 1-1 mapping with samples
3872 if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
3875 sc->ctts_allocated_size = 0;
3876 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size,
3877 sc->sample_count * sizeof(*sc->ctts_data));
3878 if (!sc->ctts_data) {
3879 av_free(ctts_data_old);
3883 memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
3885 for (i = 0; i < ctts_count_old &&
3886 sc->ctts_count < sc->sample_count; i++)
3887 for (j = 0; j < ctts_data_old[i].count &&
3888 sc->ctts_count < sc->sample_count; j++)
3889 add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
3890 &sc->ctts_allocated_size, 1,
3891 ctts_data_old[i].duration);
3892 av_free(ctts_data_old);
3895 for (i = 0; i < sc->chunk_count; i++) {
3896 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
3897 current_offset = sc->chunk_offsets[i];
3898 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3899 i + 1 == sc->stsc_data[stsc_index + 1].first)
3902 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
3903 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
3904 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
3905 sc->stsz_sample_size = sc->sample_size;
3907 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
3908 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
3909 sc->stsz_sample_size = sc->sample_size;
3912 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
3914 if (current_sample >= sc->sample_count) {
3915 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
3919 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
3921 if (stss_index + 1 < sc->keyframe_count)
3923 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
3925 if (stps_index + 1 < sc->stps_count)
3928 if (rap_group_present && rap_group_index < sc->rap_group_count) {
3929 if (sc->rap_group[rap_group_index].index > 0)
3931 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
3932 rap_group_sample = 0;
3936 if (sc->keyframe_absent
3938 && !rap_group_present
3939 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
3943 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
3944 if (sc->pseudo_stream_id == -1 ||
3945 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
3947 if (sample_size > 0x3FFFFFFF) {
3948 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
3951 e = &st->internal->index_entries[st->internal->nb_index_entries++];
3952 e->pos = current_offset;
3953 e->timestamp = current_dts;
3954 e->size = sample_size;
3955 e->min_distance = distance;
3956 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
3957 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
3958 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
3959 current_offset, current_dts, sample_size, distance, keyframe);
3960 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->internal->nb_index_entries < 100)
3961 ff_rfps_add_frame(mov->fc, st, current_dts);
3964 current_offset += sample_size;
3965 stream_size += sample_size;
3967 /* A negative sample duration is invalid based on the spec,
3968 * but some samples need it to correct the DTS. */
3969 if (sc->stts_data[stts_index].duration < 0) {
3970 av_log(mov->fc, AV_LOG_WARNING,
3971 "Invalid SampleDelta %d in STTS, at %d st:%d\n",
3972 sc->stts_data[stts_index].duration, stts_index,
3974 dts_correction += sc->stts_data[stts_index].duration - 1;
3975 sc->stts_data[stts_index].duration = 1;
3977 current_dts += sc->stts_data[stts_index].duration;
3978 if (!dts_correction || current_dts + dts_correction > last_dts) {
3979 current_dts += dts_correction;
3982 /* Avoid creating non-monotonous DTS */
3983 dts_correction += current_dts - last_dts - 1;
3984 current_dts = last_dts + 1;
3986 last_dts = current_dts;
3990 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
3996 if (st->duration > 0)
3997 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
3999 unsigned chunk_samples, total = 0;
4001 if (!sc->chunk_count)
4004 // compute total chunk count
4005 for (i = 0; i < sc->stsc_count; i++) {
4006 unsigned count, chunk_count;
4008 chunk_samples = sc->stsc_data[i].count;
4009 if (i != sc->stsc_count - 1 &&
4010 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
4011 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
4015 if (sc->samples_per_frame >= 160) { // gsm
4016 count = chunk_samples / sc->samples_per_frame;
4017 } else if (sc->samples_per_frame > 1) {
4018 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4019 count = (chunk_samples+samples-1) / samples;
4021 count = (chunk_samples+1023) / 1024;
4024 if (mov_stsc_index_valid(i, sc->stsc_count))
4025 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4027 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4028 total += chunk_count * count;
4031 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4032 if (total >= UINT_MAX / sizeof(*st->internal->index_entries) - st->internal->nb_index_entries)
4034 if (av_reallocp_array(&st->internal->index_entries,
4035 st->internal->nb_index_entries + total,
4036 sizeof(*st->internal->index_entries)) < 0) {
4037 st->internal->nb_index_entries = 0;
4040 st->internal->index_entries_allocated_size = (st->internal->nb_index_entries + total) * sizeof(*st->internal->index_entries);
4043 for (i = 0; i < sc->chunk_count; i++) {
4044 current_offset = sc->chunk_offsets[i];
4045 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4046 i + 1 == sc->stsc_data[stsc_index + 1].first)
4048 chunk_samples = sc->stsc_data[stsc_index].count;
4050 while (chunk_samples > 0) {
4052 unsigned size, samples;
4054 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4055 avpriv_request_sample(mov->fc,
4056 "Zero bytes per frame, but %d samples per frame",
4057 sc->samples_per_frame);
4061 if (sc->samples_per_frame >= 160) { // gsm
4062 samples = sc->samples_per_frame;
4063 size = sc->bytes_per_frame;
4065 if (sc->samples_per_frame > 1) {
4066 samples = FFMIN((1024 / sc->samples_per_frame)*
4067 sc->samples_per_frame, chunk_samples);
4068 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
4070 samples = FFMIN(1024, chunk_samples);
4071 size = samples * sc->sample_size;
4075 if (st->internal->nb_index_entries >= total) {
4076 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4079 if (size > 0x3FFFFFFF) {
4080 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4083 e = &st->internal->index_entries[st->internal->nb_index_entries++];
4084 e->pos = current_offset;
4085 e->timestamp = current_dts;
4087 e->min_distance = 0;
4088 e->flags = AVINDEX_KEYFRAME;
4089 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4090 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4093 current_offset += size;
4094 current_dts += samples;
4095 chunk_samples -= samples;
4100 if (!mov->ignore_editlist && mov->advanced_editlist) {
4101 // Fix index according to edit lists.
4102 mov_fix_index(mov, st);
4105 // Update start time of the stream.
4106 if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->internal->nb_index_entries > 0) {
4107 st->start_time = st->internal->index_entries[0].timestamp + sc->dts_shift;
4108 if (sc->ctts_data) {
4109 st->start_time += sc->ctts_data[0].duration;
4113 mov_estimate_video_delay(mov, st);
4116 static int test_same_origin(const char *src, const char *ref) {
4126 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4127 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4129 if (strlen(src) == 0) {
4131 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4132 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4133 strlen(src_host) + 1 >= sizeof(src_host) ||
4134 strlen(ref_host) + 1 >= sizeof(ref_host)) {
4136 } else if (strcmp(src_proto, ref_proto) ||
4137 strcmp(src_auth, ref_auth) ||
4138 strcmp(src_host, ref_host) ||
4139 src_port != ref_port) {
4145 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4147 /* try relative path, we do not try the absolute because it can leak information about our
4148 system to an attacker */
4149 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4150 char filename[1025];
4151 const char *src_path;
4154 /* find a source dir */
4155 src_path = strrchr(src, '/');
4161 /* find a next level down to target */
4162 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4163 if (ref->path[l] == '/') {
4164 if (i == ref->nlvl_to - 1)
4170 /* compose filename if next level down to target was found */
4171 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4172 memcpy(filename, src, src_path - src);
4173 filename[src_path - src] = 0;
4175 for (i = 1; i < ref->nlvl_from; i++)
4176 av_strlcat(filename, "../", sizeof(filename));
4178 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4179 if (!c->use_absolute_path) {
4180 int same_origin = test_same_origin(src, filename);
4183 av_log(c->fc, AV_LOG_ERROR,
4184 "Reference with mismatching origin, %s not tried for security reasons, "
4185 "set demuxer option use_absolute_path to allow it anyway\n",
4187 return AVERROR(ENOENT);
4190 if (strstr(ref->path + l + 1, "..") ||
4191 strstr(ref->path + l + 1, ":") ||
4192 (ref->nlvl_from > 1 && same_origin < 0) ||
4193 (filename[0] == '/' && src_path == src))
4194 return AVERROR(ENOENT);
4197 if (strlen(filename) + 1 == sizeof(filename))
4198 return AVERROR(ENOENT);
4199 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4202 } else if (c->use_absolute_path) {
4203 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4204 "this is a possible security issue\n");
4205 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4208 av_log(c->fc, AV_LOG_ERROR,
4209 "Absolute path %s not tried for security reasons, "
4210 "set demuxer option use_absolute_path to allow absolute paths\n",
4214 return AVERROR(ENOENT);
4217 static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
4219 if (sc->time_scale <= 0) {
4220 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4221 sc->time_scale = c->time_scale;
4222 if (sc->time_scale <= 0)
4227 static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4230 MOVStreamContext *sc;
4233 st = avformat_new_stream(c->fc, NULL);
4234 if (!st) return AVERROR(ENOMEM);
4236 sc = av_mallocz(sizeof(MOVStreamContext));
4237 if (!sc) return AVERROR(ENOMEM);
4240 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
4241 sc->ffindex = st->index;
4242 c->trak_index = st->index;
4244 if ((ret = mov_read_default(c, pb, atom)) < 0)
4249 // Here stsc refers to a chunk not described in stco. This is technically invalid,
4250 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4251 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4253 av_freep(&sc->stsc_data);
4257 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4258 (!sc->sample_size && !sc->sample_count))) ||
4259 (!sc->chunk_count && sc->sample_count)) {
4260 av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4264 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4265 av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4267 return AVERROR_INVALIDDATA;
4270 fix_timescale(c, sc);
4272 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4274 mov_build_index(c, st);
4276 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4277 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4278 if (c->enable_drefs) {
4279 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4280 av_log(c->fc, AV_LOG_ERROR,
4281 "stream %d, error opening alias: path='%s', dir='%s', "
4282 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4283 st->index, dref->path, dref->dir, dref->filename,
4284 dref->volume, dref->nlvl_from, dref->nlvl_to);
4286 av_log(c->fc, AV_LOG_WARNING,
4287 "Skipped opening external track: "
4288 "stream %d, alias: path='%s', dir='%s', "
4289 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4290 "Set enable_drefs to allow this.\n",
4291 st->index, dref->path, dref->dir, dref->filename,
4292 dref->volume, dref->nlvl_from, dref->nlvl_to);
4296 sc->pb_is_copied = 1;
4299 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4300 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4301 sc->height && sc->width &&
4302 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4303 st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4304 ((double)st->codecpar->width * sc->height), INT_MAX);
4307 #if FF_API_R_FRAME_RATE
4308 if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4309 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
4310 sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4314 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4315 if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4316 TAG_IS_AVCI(st->codecpar->codec_tag)) {
4317 ret = ff_generate_avci_extradata(st);
4322 switch (st->codecpar->codec_id) {
4323 #if CONFIG_H261_DECODER
4324 case AV_CODEC_ID_H261:
4326 #if CONFIG_H263_DECODER
4327 case AV_CODEC_ID_H263:
4329 #if CONFIG_MPEG4_DECODER
4330 case AV_CODEC_ID_MPEG4:
4332 st->codecpar->width = 0; /* let decoder init width/height */
4333 st->codecpar->height= 0;
4337 // If the duration of the mp3 packets is not constant, then they could need a parser
4338 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4339 && sc->stts_count > 3
4340 && sc->stts_count*10 > st->nb_frames
4341 && sc->time_scale == st->codecpar->sample_rate) {
4342 st->need_parsing = AVSTREAM_PARSE_FULL;
4344 /* Do not need those anymore. */
4345 av_freep(&sc->chunk_offsets);
4346 av_freep(&sc->sample_sizes);
4347 av_freep(&sc->keyframes);
4348 av_freep(&sc->stts_data);
4349 av_freep(&sc->stps_data);
4350 av_freep(&sc->elst_data);
4351 av_freep(&sc->rap_group);
4356 static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4359 c->itunes_metadata = 1;
4360 ret = mov_read_default(c, pb, atom);
4361 c->itunes_metadata = 0;
4365 static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4374 count = avio_rb32(pb);
4375 if (count > UINT_MAX / sizeof(*c->meta_keys) - 1) {
4376 av_log(c->fc, AV_LOG_ERROR,
4377 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
4378 return AVERROR_INVALIDDATA;
4381 c->meta_keys_count = count + 1;
4382 c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
4384 return AVERROR(ENOMEM);
4386 for (i = 1; i <= count; ++i) {
4387 uint32_t key_size = avio_rb32(pb);
4388 uint32_t type = avio_rl32(pb);
4390 av_log(c->fc, AV_LOG_ERROR,
4391 "The key# %"PRIu32" in meta has invalid size:"
4392 "%"PRIu32"\n", i, key_size);
4393 return AVERROR_INVALIDDATA;
4396 if (type != MKTAG('m','d','t','a')) {
4397 avio_skip(pb, key_size);
4399 c->meta_keys[i] = av_mallocz(key_size + 1);
4400 if (!c->meta_keys[i])
4401 return AVERROR(ENOMEM);
4402 avio_read(pb, c->meta_keys[i], key_size);
4408 static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4410 int64_t end = av_sat_add64(avio_tell(pb), atom.size);
4411 uint8_t *key = NULL, *val = NULL, *mean = NULL;
4415 MOVStreamContext *sc;
4417 if (c->fc->nb_streams < 1)
4419 st = c->fc->streams[c->fc->nb_streams-1];
4422 for (i = 0; i < 3; i++) {
4426 if (end - avio_tell(pb) <= 12)
4429 len = avio_rb32(pb);
4430 tag = avio_rl32(pb);
4431 avio_skip(pb, 4); // flags
4433 if (len < 12 || len - 12 > end - avio_tell(pb))
4437 if (tag == MKTAG('m', 'e', 'a', 'n'))
4439 else if (tag == MKTAG('n', 'a', 'm', 'e'))
4441 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
4451 *p = av_malloc(len + 1);
4453 ret = AVERROR(ENOMEM);
4456 ret = ffio_read_size(pb, *p, len);
4464 if (mean && key && val) {
4465 if (strcmp(key, "iTunSMPB") == 0) {
4466 int priming, remainder, samples;
4467 if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
4468 if(priming>0 && priming<16384)
4469 sc->start_pad = priming;
4472 if (strcmp(key, "cdec") != 0) {
4473 av_dict_set(&c->fc->metadata, key, val,
4474 AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
4478 av_log(c->fc, AV_LOG_VERBOSE,
4479 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
4482 avio_seek(pb, end, SEEK_SET);
4489 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4491 while (atom.size > 8) {
4495 tag = avio_rl32(pb);
4497 if (tag == MKTAG('h','d','l','r')) {
4498 avio_seek(pb, -8, SEEK_CUR);
4500 return mov_read_default(c, pb, atom);
4506 // return 1 when matrix is identity, 0 otherwise
4507 #define IS_MATRIX_IDENT(matrix) \
4508 ( (matrix)[0][0] == (1 << 16) && \
4509 (matrix)[1][1] == (1 << 16) && \
4510 (matrix)[2][2] == (1 << 30) && \
4511 !(matrix)[0][1] && !(matrix)[0][2] && \
4512 !(matrix)[1][0] && !(matrix)[1][2] && \
4513 !(matrix)[2][0] && !(matrix)[2][1])
4515 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4520 int display_matrix[3][3];
4521 int res_display_matrix[3][3] = { { 0 } };
4523 MOVStreamContext *sc;
4527 if (c->fc->nb_streams < 1)
4529 st = c->fc->streams[c->fc->nb_streams-1];
4532 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4533 // avoids corrupting AVStreams mapped to an earlier tkhd.
4535 return AVERROR_INVALIDDATA;
4537 version = avio_r8(pb);
4538 flags = avio_rb24(pb);
4539 st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
4545 avio_rb32(pb); /* creation time */
4546 avio_rb32(pb); /* modification time */
4548 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4549 avio_rb32(pb); /* reserved */
4551 /* highlevel (considering edits) duration in movie timebase */
4552 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4553 avio_rb32(pb); /* reserved */
4554 avio_rb32(pb); /* reserved */
4556 avio_rb16(pb); /* layer */
4557 avio_rb16(pb); /* alternate group */
4558 avio_rb16(pb); /* volume */
4559 avio_rb16(pb); /* reserved */
4561 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4562 // they're kept in fixed point format through all calculations
4563 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4564 // side data, but the scale factor is not needed to calculate aspect ratio
4565 for (i = 0; i < 3; i++) {
4566 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
4567 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
4568 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
4571 width = avio_rb32(pb); // 16.16 fixed point track width
4572 height = avio_rb32(pb); // 16.16 fixed point track height
4573 sc->width = width >> 16;
4574 sc->height = height >> 16;
4576 // apply the moov display matrix (after the tkhd one)
4577 for (i = 0; i < 3; i++) {
4578 const int sh[3] = { 16, 16, 30 };
4579 for (j = 0; j < 3; j++) {
4580 for (e = 0; e < 3; e++) {
4581 res_display_matrix[i][j] +=
4582 ((int64_t) display_matrix[i][e] *
4583 c->movie_display_matrix[e][j]) >> sh[e];
4588 // save the matrix when it is not the default identity
4589 if (!IS_MATRIX_IDENT(res_display_matrix)) {
4592 av_freep(&sc->display_matrix);
4593 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4594 if (!sc->display_matrix)
4595 return AVERROR(ENOMEM);
4597 for (i = 0; i < 3; i++)
4598 for (j = 0; j < 3; j++)
4599 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4601 #if FF_API_OLD_ROTATE_API
4602 rotate = av_display_rotation_get(sc->display_matrix);
4603 if (!isnan(rotate)) {
4604 char rotate_buf[64];
4606 if (rotate < 0) // for backward compatibility
4608 snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate);
4609 av_dict_set(&st->metadata, "rotate", rotate_buf, 0);
4614 // transform the display width/height according to the matrix
4615 // to keep the same scale, use [width height 1<<16]
4616 if (width && height && sc->display_matrix) {
4617 double disp_transform[2];
4619 for (i = 0; i < 2; i++)
4620 disp_transform[i] = hypot(sc->display_matrix[0 + i],
4621 sc->display_matrix[3 + i]);
4623 if (disp_transform[0] > 0 && disp_transform[1] > 0 &&
4624 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4625 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4626 st->sample_aspect_ratio = av_d2q(
4627 disp_transform[0] / disp_transform[1],
4633 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4635 MOVFragment *frag = &c->fragment;
4636 MOVTrackExt *trex = NULL;
4637 int flags, track_id, i;
4638 MOVFragmentStreamInfo * frag_stream_info;
4640 avio_r8(pb); /* version */
4641 flags = avio_rb24(pb);
4643 track_id = avio_rb32(pb);
4645 return AVERROR_INVALIDDATA;
4646 for (i = 0; i < c->trex_count; i++)
4647 if (c->trex_data[i].track_id == track_id) {
4648 trex = &c->trex_data[i];
4652 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4655 c->fragment.found_tfhd = 1;
4656 frag->track_id = track_id;
4657 set_frag_stream(&c->frag_index, track_id);
4659 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4660 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4661 frag->moof_offset : frag->implicit_offset;
4662 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4664 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4665 avio_rb32(pb) : trex->duration;
4666 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4667 avio_rb32(pb) : trex->size;
4668 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4669 avio_rb32(pb) : trex->flags;
4670 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4672 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4673 if (frag_stream_info)
4674 frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
4679 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4684 num = atom.size / 4;
4685 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4686 return AVERROR(ENOMEM);
4688 av_free(c->chapter_tracks);
4689 c->chapter_tracks = new_tracks;
4690 c->nb_chapter_tracks = num;
4692 for (i = 0; i < num && !pb->eof_reached; i++)
4693 c->chapter_tracks[i] = avio_rb32(pb);
4698 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4703 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4704 return AVERROR_INVALIDDATA;
4705 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4706 sizeof(*c->trex_data))) < 0) {
4711 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4713 trex = &c->trex_data[c->trex_count++];
4714 avio_r8(pb); /* version */
4715 avio_rb24(pb); /* flags */
4716 trex->track_id = avio_rb32(pb);
4717 trex->stsd_id = avio_rb32(pb);
4718 trex->duration = avio_rb32(pb);
4719 trex->size = avio_rb32(pb);
4720 trex->flags = avio_rb32(pb);
4724 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4726 MOVFragment *frag = &c->fragment;
4727 AVStream *st = NULL;
4728 MOVStreamContext *sc;
4730 MOVFragmentStreamInfo * frag_stream_info;
4731 int64_t base_media_decode_time;
4733 for (i = 0; i < c->fc->nb_streams; i++) {
4734 if (c->fc->streams[i]->id == frag->track_id) {
4735 st = c->fc->streams[i];
4740 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4744 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4746 version = avio_r8(pb);
4747 avio_rb24(pb); /* flags */
4749 base_media_decode_time = avio_rb64(pb);
4751 base_media_decode_time = avio_rb32(pb);
4754 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4755 if (frag_stream_info)
4756 frag_stream_info->tfdt_dts = base_media_decode_time;
4757 sc->track_end = base_media_decode_time;
4762 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4764 MOVFragment *frag = &c->fragment;
4765 AVStream *st = NULL;
4766 MOVStreamContext *sc;
4769 int64_t dts, pts = AV_NOPTS_VALUE;
4770 int data_offset = 0;
4771 unsigned entries, first_sample_flags = frag->flags;
4772 int flags, distance, i;
4773 int64_t prev_dts = AV_NOPTS_VALUE;
4774 int next_frag_index = -1, index_entry_pos;
4775 size_t requested_size;
4776 size_t old_ctts_allocated_size;
4777 AVIndexEntry *new_entries;
4778 MOVFragmentStreamInfo * frag_stream_info;
4780 if (!frag->found_tfhd) {
4781 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4782 return AVERROR_INVALIDDATA;
4785 for (i = 0; i < c->fc->nb_streams; i++) {
4786 if (c->fc->streams[i]->id == frag->track_id) {
4787 st = c->fc->streams[i];
4792 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4796 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4799 // Find the next frag_index index that has a valid index_entry for
4800 // the current track_id.
4802 // A valid index_entry means the trun for the fragment was read
4803 // and it's samples are in index_entries at the given position.
4804 // New index entries will be inserted before the index_entry found.
4805 index_entry_pos = st->internal->nb_index_entries;
4806 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4807 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4808 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4809 next_frag_index = i;
4810 index_entry_pos = frag_stream_info->index_entry;
4814 av_assert0(index_entry_pos <= st->internal->nb_index_entries);
4816 avio_r8(pb); /* version */
4817 flags = avio_rb24(pb);
4818 entries = avio_rb32(pb);
4819 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4821 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4822 return AVERROR_INVALIDDATA;
4823 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4824 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4826 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4827 if (frag_stream_info) {
4828 if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
4829 dts = frag_stream_info->next_trun_dts - sc->time_offset;
4830 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4831 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4832 pts = frag_stream_info->first_tfra_pts;
4833 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4834 ", using it for pts\n", pts);
4835 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4836 c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
4837 dts = frag_stream_info->first_tfra_pts;
4838 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4839 ", using it for dts\n", pts);
4840 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4841 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4842 // pts = frag_stream_info->sidx_pts;
4843 dts = frag_stream_info->sidx_pts - sc->time_offset;
4844 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4845 ", using it for pts\n", pts);
4846 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4847 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4848 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4849 ", using it for dts\n", dts);
4851 dts = sc->track_end - sc->time_offset;
4852 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4853 ", using it for dts\n", dts);
4856 dts = sc->track_end - sc->time_offset;
4857 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4858 ", using it for dts\n", dts);
4860 offset = frag->base_data_offset + data_offset;
4862 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4864 // realloc space for new index entries
4865 if((uint64_t)st->internal->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4866 entries = UINT_MAX / sizeof(AVIndexEntry) - st->internal->nb_index_entries;
4867 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4872 requested_size = (st->internal->nb_index_entries + entries) * sizeof(AVIndexEntry);
4873 new_entries = av_fast_realloc(st->internal->index_entries,
4874 &st->internal->index_entries_allocated_size,
4877 return AVERROR(ENOMEM);
4878 st->internal->index_entries= new_entries;
4880 requested_size = (st->internal->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4881 old_ctts_allocated_size = sc->ctts_allocated_size;
4882 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4885 return AVERROR(ENOMEM);
4886 sc->ctts_data = ctts_data;
4888 // In case there were samples without ctts entries, ensure they get
4889 // zero valued entries. This ensures clips which mix boxes with and
4890 // without ctts entries don't pickup uninitialized data.
4891 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4892 sc->ctts_allocated_size - old_ctts_allocated_size);
4894 if (index_entry_pos < st->internal->nb_index_entries) {
4895 // Make hole in index_entries and ctts_data for new samples
4896 memmove(st->internal->index_entries + index_entry_pos + entries,
4897 st->internal->index_entries + index_entry_pos,
4898 sizeof(*st->internal->index_entries) *
4899 (st->internal->nb_index_entries - index_entry_pos));
4900 memmove(sc->ctts_data + index_entry_pos + entries,
4901 sc->ctts_data + index_entry_pos,
4902 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4903 if (index_entry_pos < sc->current_sample) {
4904 sc->current_sample += entries;
4908 st->internal->nb_index_entries += entries;
4909 sc->ctts_count = st->internal->nb_index_entries;
4911 // Record the index_entry position in frag_index of this fragment
4912 if (frag_stream_info)
4913 frag_stream_info->index_entry = index_entry_pos;
4915 if (index_entry_pos > 0)
4916 prev_dts = st->internal->index_entries[index_entry_pos-1].timestamp;
4918 for (i = 0; i < entries && !pb->eof_reached; i++) {
4919 unsigned sample_size = frag->size;
4920 int sample_flags = i ? frag->flags : first_sample_flags;
4921 unsigned sample_duration = frag->duration;
4922 unsigned ctts_duration = 0;
4924 int index_entry_flags = 0;
4926 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4927 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4928 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4929 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4931 mov_update_dts_shift(sc, ctts_duration, c->fc);
4932 if (pts != AV_NOPTS_VALUE) {
4933 dts = pts - sc->dts_shift;
4934 if (flags & MOV_TRUN_SAMPLE_CTS) {
4935 dts -= ctts_duration;
4937 dts -= sc->time_offset;
4939 av_log(c->fc, AV_LOG_DEBUG,
4940 "pts %"PRId64" calculated dts %"PRId64
4941 " sc->dts_shift %d ctts.duration %d"
4942 " sc->time_offset %"PRId64
4943 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4945 sc->dts_shift, ctts_duration,
4946 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4947 pts = AV_NOPTS_VALUE;
4950 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4954 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4955 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4958 index_entry_flags |= AVINDEX_KEYFRAME;
4960 // Fragments can overlap in time. Discard overlapping frames after
4962 if (prev_dts >= dts)
4963 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4965 st->internal->index_entries[index_entry_pos].pos = offset;
4966 st->internal->index_entries[index_entry_pos].timestamp = dts;
4967 st->internal->index_entries[index_entry_pos].size= sample_size;
4968 st->internal->index_entries[index_entry_pos].min_distance= distance;
4969 st->internal->index_entries[index_entry_pos].flags = index_entry_flags;
4971 sc->ctts_data[index_entry_pos].count = 1;
4972 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4975 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4976 "size %u, distance %d, keyframe %d\n", st->index,
4977 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4979 dts += sample_duration;
4980 offset += sample_size;
4981 sc->data_size += sample_size;
4983 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4984 1 <= INT_MAX - sc->nb_frames_for_fps
4986 sc->duration_for_fps += sample_duration;
4987 sc->nb_frames_for_fps ++;
4990 if (frag_stream_info)
4991 frag_stream_info->next_trun_dts = dts + sc->time_offset;
4993 // EOF found before reading all entries. Fix the hole this would
4994 // leave in index_entries and ctts_data
4995 int gap = entries - i;
4996 memmove(st->internal->index_entries + index_entry_pos,
4997 st->internal->index_entries + index_entry_pos + gap,
4998 sizeof(*st->internal->index_entries) *
4999 (st->internal->nb_index_entries - (index_entry_pos + gap)));
5000 memmove(sc->ctts_data + index_entry_pos,
5001 sc->ctts_data + index_entry_pos + gap,
5002 sizeof(*sc->ctts_data) *
5003 (sc->ctts_count - (index_entry_pos + gap)));
5005 st->internal->nb_index_entries -= gap;
5006 sc->ctts_count -= gap;
5007 if (index_entry_pos < sc->current_sample) {
5008 sc->current_sample -= gap;
5013 // The end of this new fragment may overlap in time with the start
5014 // of the next fragment in index_entries. Mark the samples in the next
5015 // fragment that overlap with AVINDEX_DISCARD_FRAME
5016 prev_dts = AV_NOPTS_VALUE;
5017 if (index_entry_pos > 0)
5018 prev_dts = st->internal->index_entries[index_entry_pos-1].timestamp;
5019 for (i = index_entry_pos; i < st->internal->nb_index_entries; i++) {
5020 if (prev_dts < st->internal->index_entries[i].timestamp)
5022 st->internal->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
5025 // If a hole was created to insert the new index_entries into,
5026 // the index_entry recorded for all subsequent moof must
5027 // be incremented by the number of entries inserted.
5028 fix_frag_index_entries(&c->frag_index, next_frag_index,
5029 frag->track_id, entries);
5031 if (pb->eof_reached) {
5032 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
5036 frag->implicit_offset = offset;
5038 sc->track_end = dts + sc->time_offset;
5039 if (st->duration < sc->track_end)
5040 st->duration = sc->track_end;
5045 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5047 int64_t stream_size = avio_size(pb);
5048 int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
5049 uint8_t version, is_complete;
5050 unsigned i, j, track_id, item_count;
5051 AVStream *st = NULL;
5052 AVStream *ref_st = NULL;
5053 MOVStreamContext *sc, *ref_sc = NULL;
5054 AVRational timescale;
5056 version = avio_r8(pb);
5058 avpriv_request_sample(c->fc, "sidx version %u", version);
5062 avio_rb24(pb); // flags
5064 track_id = avio_rb32(pb); // Reference ID
5065 for (i = 0; i < c->fc->nb_streams; i++) {
5066 if (c->fc->streams[i]->id == track_id) {
5067 st = c->fc->streams[i];
5072 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5078 timescale = av_make_q(1, avio_rb32(pb));
5080 if (timescale.den <= 0) {
5081 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5082 return AVERROR_INVALIDDATA;
5086 pts = avio_rb32(pb);
5087 offset += avio_rb32(pb);
5089 pts = avio_rb64(pb);
5090 offset += avio_rb64(pb);
5093 avio_rb16(pb); // reserved
5095 item_count = avio_rb16(pb);
5097 for (i = 0; i < item_count; i++) {
5099 MOVFragmentStreamInfo * frag_stream_info;
5100 uint32_t size = avio_rb32(pb);
5101 uint32_t duration = avio_rb32(pb);
5102 if (size & 0x80000000) {
5103 avpriv_request_sample(c->fc, "sidx reference_type 1");
5104 return AVERROR_PATCHWELCOME;
5106 avio_rb32(pb); // sap_flags
5107 timestamp = av_rescale_q(pts, timescale, st->time_base);
5109 index = update_frag_index(c, offset);
5110 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5111 if (frag_stream_info)
5112 frag_stream_info->sidx_pts = timestamp;
5118 st->duration = sc->track_end = pts;
5122 // See if the remaining bytes are just an mfra which we can ignore.
5123 is_complete = offset == stream_size;
5124 if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL)) {
5126 int64_t original_pos = avio_tell(pb);
5127 if (!c->have_read_mfra_size) {
5128 if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
5130 c->mfra_size = avio_rb32(pb);
5131 c->have_read_mfra_size = 1;
5132 if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
5135 if (offset + c->mfra_size == stream_size)
5140 // Find first entry in fragment index that came from an sidx.
5141 // This will pretty much always be the first entry.
5142 for (i = 0; i < c->frag_index.nb_items; i++) {
5143 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5144 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5145 MOVFragmentStreamInfo * si;
5146 si = &item->stream_info[j];
5147 if (si->sidx_pts != AV_NOPTS_VALUE) {
5148 ref_st = c->fc->streams[j];
5149 ref_sc = ref_st->priv_data;
5154 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5155 st = c->fc->streams[i];
5157 if (!sc->has_sidx) {
5158 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5162 c->frag_index.complete = 1;
5168 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5169 /* like the files created with Adobe Premiere 5.0, for samples see */
5170 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5171 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5176 return 0; /* continue */
5177 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5178 avio_skip(pb, atom.size - 4);
5181 atom.type = avio_rl32(pb);
5183 if (atom.type != MKTAG('m','d','a','t')) {
5184 avio_skip(pb, atom.size);
5187 err = mov_read_mdat(c, pb, atom);
5191 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5196 uint8_t *moov_data; /* uncompressed data */
5197 long cmov_len, moov_len;
5200 avio_rb32(pb); /* dcom atom */
5201 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5202 return AVERROR_INVALIDDATA;
5203 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5204 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5205 return AVERROR_INVALIDDATA;
5207 avio_rb32(pb); /* cmvd atom */
5208 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5209 return AVERROR_INVALIDDATA;
5210 moov_len = avio_rb32(pb); /* uncompressed size */
5211 cmov_len = atom.size - 6 * 4;
5213 cmov_data = av_malloc(cmov_len);
5215 return AVERROR(ENOMEM);
5216 moov_data = av_malloc(moov_len);
5219 return AVERROR(ENOMEM);
5221 ret = ffio_read_size(pb, cmov_data, cmov_len);
5223 goto free_and_return;
5225 ret = AVERROR_INVALIDDATA;
5226 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5227 goto free_and_return;
5228 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5229 goto free_and_return;
5230 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5231 atom.type = MKTAG('m','o','o','v');
5232 atom.size = moov_len;
5233 ret = mov_read_default(c, &ctx, atom);
5239 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5240 return AVERROR(ENOSYS);
5244 /* edit list atom */
5245 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5247 MOVStreamContext *sc;
5248 int i, edit_count, version;
5249 int64_t elst_entry_size;
5251 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5253 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5255 version = avio_r8(pb); /* version */
5256 avio_rb24(pb); /* flags */
5257 edit_count = avio_rb32(pb); /* entries */
5260 elst_entry_size = version == 1 ? 20 : 12;
5261 if (atom.size != edit_count * elst_entry_size) {
5262 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5263 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5264 edit_count, atom.size + 8);
5265 return AVERROR_INVALIDDATA;
5267 edit_count = atom.size / elst_entry_size;
5268 if (edit_count * elst_entry_size != atom.size) {
5269 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
5277 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5278 av_free(sc->elst_data);
5280 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5282 return AVERROR(ENOMEM);
5284 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5285 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5286 MOVElst *e = &sc->elst_data[i];
5289 e->duration = avio_rb64(pb);
5290 e->time = avio_rb64(pb);
5293 e->duration = avio_rb32(pb); /* segment duration */
5294 e->time = (int32_t)avio_rb32(pb); /* media time */
5297 e->rate = avio_rb32(pb) / 65536.0;
5299 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5300 e->duration, e->time, e->rate);
5302 if (e->time < 0 && e->time != -1 &&
5303 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5304 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5305 c->fc->nb_streams-1, i, e->time);
5306 return AVERROR_INVALIDDATA;
5314 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5316 MOVStreamContext *sc;
5318 if (c->fc->nb_streams < 1)
5319 return AVERROR_INVALIDDATA;
5320 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5321 sc->timecode_track = avio_rb32(pb);
5325 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5330 if (c->fc->nb_streams < 1)
5332 st = c->fc->streams[c->fc->nb_streams - 1];
5334 if (atom.size < 4) {
5335 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5336 return AVERROR_INVALIDDATA;
5339 /* For now, propagate only the OBUs, if any. Once libavcodec is
5340 updated to handle isobmff style extradata this can be removed. */
5346 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5353 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5356 int version, color_range, color_primaries, color_trc, color_space;
5358 if (c->fc->nb_streams < 1)
5360 st = c->fc->streams[c->fc->nb_streams - 1];
5362 if (atom.size < 5) {
5363 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5364 return AVERROR_INVALIDDATA;
5367 version = avio_r8(pb);
5369 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5372 avio_skip(pb, 3); /* flags */
5374 avio_skip(pb, 2); /* profile + level */
5375 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5376 color_primaries = avio_r8(pb);
5377 color_trc = avio_r8(pb);
5378 color_space = avio_r8(pb);
5379 if (avio_rb16(pb)) /* codecIntializationDataSize */
5380 return AVERROR_INVALIDDATA;
5382 if (!av_color_primaries_name(color_primaries))
5383 color_primaries = AVCOL_PRI_UNSPECIFIED;
5384 if (!av_color_transfer_name(color_trc))
5385 color_trc = AVCOL_TRC_UNSPECIFIED;
5386 if (!av_color_space_name(color_space))
5387 color_space = AVCOL_SPC_UNSPECIFIED;
5389 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5390 st->codecpar->color_primaries = color_primaries;
5391 st->codecpar->color_trc = color_trc;
5392 st->codecpar->color_space = color_space;
5397 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5399 MOVStreamContext *sc;
5402 if (c->fc->nb_streams < 1)
5403 return AVERROR_INVALIDDATA;
5405 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5407 if (atom.size < 5) {
5408 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5409 return AVERROR_INVALIDDATA;
5412 version = avio_r8(pb);
5414 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5417 avio_skip(pb, 3); /* flags */
5419 sc->mastering = av_mastering_display_metadata_alloc();
5421 return AVERROR(ENOMEM);
5423 for (i = 0; i < 3; i++) {
5424 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5425 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5427 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5428 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5430 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5431 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5433 sc->mastering->has_primaries = 1;
5434 sc->mastering->has_luminance = 1;
5439 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5441 MOVStreamContext *sc;
5442 const int mapping[3] = {1, 2, 0};
5443 const int chroma_den = 50000;
5444 const int luma_den = 10000;
5447 if (c->fc->nb_streams < 1)
5448 return AVERROR_INVALIDDATA;
5450 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5452 if (atom.size < 24) {
5453 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5454 return AVERROR_INVALIDDATA;
5457 sc->mastering = av_mastering_display_metadata_alloc();
5459 return AVERROR(ENOMEM);
5461 for (i = 0; i < 3; i++) {
5462 const int j = mapping[i];
5463 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5464 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5466 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5467 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5469 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5470 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5472 sc->mastering->has_luminance = 1;
5473 sc->mastering->has_primaries = 1;
5478 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5480 MOVStreamContext *sc;
5483 if (c->fc->nb_streams < 1)
5484 return AVERROR_INVALIDDATA;
5486 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5488 if (atom.size < 5) {
5489 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5490 return AVERROR_INVALIDDATA;
5493 version = avio_r8(pb);
5495 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5498 avio_skip(pb, 3); /* flags */
5500 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5502 return AVERROR(ENOMEM);
5504 sc->coll->MaxCLL = avio_rb16(pb);
5505 sc->coll->MaxFALL = avio_rb16(pb);
5510 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5512 MOVStreamContext *sc;
5514 if (c->fc->nb_streams < 1)
5515 return AVERROR_INVALIDDATA;
5517 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5519 if (atom.size < 4) {
5520 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5521 return AVERROR_INVALIDDATA;
5524 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5526 return AVERROR(ENOMEM);
5528 sc->coll->MaxCLL = avio_rb16(pb);
5529 sc->coll->MaxFALL = avio_rb16(pb);
5534 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5537 MOVStreamContext *sc;
5538 enum AVStereo3DType type;
5541 if (c->fc->nb_streams < 1)
5544 st = c->fc->streams[c->fc->nb_streams - 1];
5547 if (atom.size < 5) {
5548 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5549 return AVERROR_INVALIDDATA;
5553 return AVERROR_INVALIDDATA;
5555 avio_skip(pb, 4); /* version + flags */
5560 type = AV_STEREO3D_2D;
5563 type = AV_STEREO3D_TOPBOTTOM;
5566 type = AV_STEREO3D_SIDEBYSIDE;
5569 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5573 sc->stereo3d = av_stereo3d_alloc();
5575 return AVERROR(ENOMEM);
5577 sc->stereo3d->type = type;
5581 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5584 MOVStreamContext *sc;
5585 int size, version, layout;
5586 int32_t yaw, pitch, roll;
5587 uint32_t l = 0, t = 0, r = 0, b = 0;
5588 uint32_t tag, padding = 0;
5589 enum AVSphericalProjection projection;
5591 if (c->fc->nb_streams < 1)
5594 st = c->fc->streams[c->fc->nb_streams - 1];
5597 if (atom.size < 8) {
5598 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5599 return AVERROR_INVALIDDATA;
5602 size = avio_rb32(pb);
5603 if (size <= 12 || size > atom.size)
5604 return AVERROR_INVALIDDATA;
5606 tag = avio_rl32(pb);
5607 if (tag != MKTAG('s','v','h','d')) {
5608 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5611 version = avio_r8(pb);
5613 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5617 avio_skip(pb, 3); /* flags */
5618 avio_skip(pb, size - 12); /* metadata_source */
5620 size = avio_rb32(pb);
5621 if (size > atom.size)
5622 return AVERROR_INVALIDDATA;
5624 tag = avio_rl32(pb);
5625 if (tag != MKTAG('p','r','o','j')) {
5626 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5630 size = avio_rb32(pb);
5631 if (size > atom.size)
5632 return AVERROR_INVALIDDATA;
5634 tag = avio_rl32(pb);
5635 if (tag != MKTAG('p','r','h','d')) {
5636 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5639 version = avio_r8(pb);
5641 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5645 avio_skip(pb, 3); /* flags */
5647 /* 16.16 fixed point */
5648 yaw = avio_rb32(pb);
5649 pitch = avio_rb32(pb);
5650 roll = avio_rb32(pb);
5652 size = avio_rb32(pb);
5653 if (size > atom.size)
5654 return AVERROR_INVALIDDATA;
5656 tag = avio_rl32(pb);
5657 version = avio_r8(pb);
5659 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5663 avio_skip(pb, 3); /* flags */
5665 case MKTAG('c','b','m','p'):
5666 layout = avio_rb32(pb);
5668 av_log(c->fc, AV_LOG_WARNING,
5669 "Unsupported cubemap layout %d\n", layout);
5672 projection = AV_SPHERICAL_CUBEMAP;
5673 padding = avio_rb32(pb);
5675 case MKTAG('e','q','u','i'):
5681 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5682 av_log(c->fc, AV_LOG_ERROR,
5683 "Invalid bounding rectangle coordinates "
5684 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5685 return AVERROR_INVALIDDATA;
5688 if (l || t || r || b)
5689 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5691 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5694 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5698 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5700 return AVERROR(ENOMEM);
5702 sc->spherical->projection = projection;
5704 sc->spherical->yaw = yaw;
5705 sc->spherical->pitch = pitch;
5706 sc->spherical->roll = roll;
5708 sc->spherical->padding = padding;
5710 sc->spherical->bound_left = l;
5711 sc->spherical->bound_top = t;
5712 sc->spherical->bound_right = r;
5713 sc->spherical->bound_bottom = b;
5718 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5721 uint8_t *buffer = av_malloc(len + 1);
5725 return AVERROR(ENOMEM);
5728 ret = ffio_read_size(pb, buffer, len);
5732 /* Check for mandatory keys and values, try to support XML as best-effort */
5733 if (!sc->spherical &&
5734 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5735 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5736 av_stristr(val, "true") &&
5737 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5738 av_stristr(val, "true") &&
5739 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5740 av_stristr(val, "equirectangular")) {
5741 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5745 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5747 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5748 enum AVStereo3DType mode;
5750 if (av_stristr(buffer, "left-right"))
5751 mode = AV_STEREO3D_SIDEBYSIDE;
5752 else if (av_stristr(buffer, "top-bottom"))
5753 mode = AV_STEREO3D_TOPBOTTOM;
5755 mode = AV_STEREO3D_2D;
5757 sc->stereo3d = av_stereo3d_alloc();
5761 sc->stereo3d->type = mode;
5765 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5767 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5768 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5770 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5771 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5773 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5781 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5784 MOVStreamContext *sc;
5787 static const uint8_t uuid_isml_manifest[] = {
5788 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5789 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5791 static const uint8_t uuid_xmp[] = {
5792 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5793 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5795 static const uint8_t uuid_spherical[] = {
5796 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5797 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5800 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5801 return AVERROR_INVALIDDATA;
5803 if (c->fc->nb_streams < 1)
5805 st = c->fc->streams[c->fc->nb_streams - 1];
5808 ret = ffio_read_size(pb, uuid, sizeof(uuid));
5811 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5812 uint8_t *buffer, *ptr;
5814 size_t len = atom.size - sizeof(uuid);
5817 return AVERROR_INVALIDDATA;
5819 ret = avio_skip(pb, 4); // zeroes
5822 buffer = av_mallocz(len + 1);
5824 return AVERROR(ENOMEM);
5826 ret = ffio_read_size(pb, buffer, len);
5833 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5834 ptr += sizeof("systemBitrate=\"") - 1;
5835 c->bitrates_count++;
5836 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5838 c->bitrates_count = 0;
5840 return AVERROR(ENOMEM);
5843 ret = strtol(ptr, &endptr, 10);
5844 if (ret < 0 || errno || *endptr != '"') {
5845 c->bitrates[c->bitrates_count - 1] = 0;
5847 c->bitrates[c->bitrates_count - 1] = ret;
5852 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5854 size_t len = atom.size - sizeof(uuid);
5855 if (c->export_xmp) {
5856 buffer = av_mallocz(len + 1);
5858 return AVERROR(ENOMEM);
5860 ret = ffio_read_size(pb, buffer, len);
5866 av_dict_set(&c->fc->metadata, "xmp",
5867 buffer, AV_DICT_DONT_STRDUP_VAL);
5869 // skip all uuid atom, which makes it fast for long uuid-xmp file
5870 ret = avio_skip(pb, len);
5874 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5875 size_t len = atom.size - sizeof(uuid);
5876 ret = mov_parse_uuid_spherical(sc, pb, len);
5880 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5886 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5889 uint8_t content[16];
5894 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5900 && !memcmp(content, "Anevia\x1A\x1A", 8)
5901 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5902 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5908 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5910 uint32_t format = avio_rl32(pb);
5911 MOVStreamContext *sc;
5915 if (c->fc->nb_streams < 1)
5917 st = c->fc->streams[c->fc->nb_streams - 1];
5922 case MKTAG('e','n','c','v'): // encrypted video
5923 case MKTAG('e','n','c','a'): // encrypted audio
5924 id = mov_codec_id(st, format);
5925 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5926 st->codecpar->codec_id != id) {
5927 av_log(c->fc, AV_LOG_WARNING,
5928 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5929 (char*)&format, st->codecpar->codec_id);
5933 st->codecpar->codec_id = id;
5934 sc->format = format;
5938 if (format != sc->format) {
5939 av_log(c->fc, AV_LOG_WARNING,
5940 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5941 (char*)&format, (char*)&sc->format);
5950 * Gets the current encryption info and associated current stream context. If
5951 * we are parsing a track fragment, this will return the specific encryption
5952 * info for this fragment; otherwise this will return the global encryption
5953 * info for the current stream.
5955 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5957 MOVFragmentStreamInfo *frag_stream_info;
5961 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5962 if (frag_stream_info) {
5963 for (i = 0; i < c->fc->nb_streams; i++) {
5964 if (c->fc->streams[i]->id == frag_stream_info->id) {
5965 st = c->fc->streams[i];
5969 if (i == c->fc->nb_streams)
5971 *sc = st->priv_data;
5973 if (!frag_stream_info->encryption_index) {
5974 // If this stream isn't encrypted, don't create the index.
5975 if (!(*sc)->cenc.default_encrypted_sample)
5977 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5978 if (!frag_stream_info->encryption_index)
5979 return AVERROR(ENOMEM);
5981 *encryption_index = frag_stream_info->encryption_index;
5984 // No current track fragment, using stream level encryption info.
5986 if (c->fc->nb_streams < 1)
5988 st = c->fc->streams[c->fc->nb_streams - 1];
5989 *sc = st->priv_data;
5991 if (!(*sc)->cenc.encryption_index) {
5992 // If this stream isn't encrypted, don't create the index.
5993 if (!(*sc)->cenc.default_encrypted_sample)
5995 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5996 if (!(*sc)->cenc.encryption_index)
5997 return AVERROR(ENOMEM);
6000 *encryption_index = (*sc)->cenc.encryption_index;
6005 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
6008 unsigned int subsample_count;
6009 AVSubsampleEncryptionInfo *subsamples;
6011 if (!sc->cenc.default_encrypted_sample) {
6012 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
6013 return AVERROR_INVALIDDATA;
6016 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
6018 return AVERROR(ENOMEM);
6020 if (sc->cenc.per_sample_iv_size != 0) {
6021 if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
6022 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
6023 av_encryption_info_free(*sample);
6029 if (use_subsamples) {
6030 subsample_count = avio_rb16(pb);
6031 av_free((*sample)->subsamples);
6032 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
6033 if (!(*sample)->subsamples) {
6034 av_encryption_info_free(*sample);
6036 return AVERROR(ENOMEM);
6039 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
6040 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
6041 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
6044 if (pb->eof_reached) {
6045 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
6046 av_encryption_info_free(*sample);
6048 return AVERROR_INVALIDDATA;
6050 (*sample)->subsample_count = subsample_count;
6056 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6058 AVEncryptionInfo **encrypted_samples;
6059 MOVEncryptionIndex *encryption_index;
6060 MOVStreamContext *sc;
6061 int use_subsamples, ret;
6062 unsigned int sample_count, i, alloc_size = 0;
6064 ret = get_current_encryption_info(c, &encryption_index, &sc);
6068 if (encryption_index->nb_encrypted_samples) {
6069 // This can happen if we have both saio/saiz and senc atoms.
6070 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6074 avio_r8(pb); /* version */
6075 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6077 sample_count = avio_rb32(pb);
6078 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6079 return AVERROR(ENOMEM);
6081 for (i = 0; i < sample_count; i++) {
6082 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6083 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6084 min_samples * sizeof(*encrypted_samples));
6085 if (encrypted_samples) {
6086 encryption_index->encrypted_samples = encrypted_samples;
6088 ret = mov_read_sample_encryption_info(
6089 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6091 ret = AVERROR(ENOMEM);
6093 if (pb->eof_reached) {
6094 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6095 ret = AVERROR_INVALIDDATA;
6100 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6101 av_freep(&encryption_index->encrypted_samples);
6105 encryption_index->nb_encrypted_samples = sample_count;
6110 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6112 AVEncryptionInfo **sample, **encrypted_samples;
6114 size_t sample_count, sample_info_size, i;
6116 unsigned int alloc_size = 0;
6118 if (encryption_index->nb_encrypted_samples)
6120 sample_count = encryption_index->auxiliary_info_sample_count;
6121 if (encryption_index->auxiliary_offsets_count != 1) {
6122 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6123 return AVERROR_PATCHWELCOME;
6125 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6126 return AVERROR(ENOMEM);
6128 prev_pos = avio_tell(pb);
6129 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6130 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6131 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6135 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6136 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6137 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6138 min_samples * sizeof(*encrypted_samples));
6139 if (!encrypted_samples) {
6140 ret = AVERROR(ENOMEM);
6143 encryption_index->encrypted_samples = encrypted_samples;
6145 sample = &encryption_index->encrypted_samples[i];
6146 sample_info_size = encryption_index->auxiliary_info_default_size
6147 ? encryption_index->auxiliary_info_default_size
6148 : encryption_index->auxiliary_info_sizes[i];
6150 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6154 if (pb->eof_reached) {
6155 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6156 ret = AVERROR_INVALIDDATA;
6158 encryption_index->nb_encrypted_samples = sample_count;
6162 avio_seek(pb, prev_pos, SEEK_SET);
6164 for (; i > 0; i--) {
6165 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6167 av_freep(&encryption_index->encrypted_samples);
6173 * Tries to read the given number of bytes from the stream and puts it in a
6174 * newly allocated buffer. This reads in small chunks to avoid allocating large
6175 * memory if the file contains an invalid/malicious size value.
6177 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6179 const unsigned int block_size = 1024 * 1024;
6180 uint8_t *buffer = NULL;
6181 unsigned int alloc_size = 0, offset = 0;
6182 while (offset < size) {
6183 unsigned int new_size =
6184 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6185 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6186 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6189 return AVERROR(ENOMEM);
6191 buffer = new_buffer;
6193 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6195 return AVERROR_INVALIDDATA;
6204 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6206 MOVEncryptionIndex *encryption_index;
6207 MOVStreamContext *sc;
6209 unsigned int sample_count, aux_info_type, aux_info_param;
6211 ret = get_current_encryption_info(c, &encryption_index, &sc);
6215 if (encryption_index->nb_encrypted_samples) {
6216 // This can happen if we have both saio/saiz and senc atoms.
6217 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6221 if (encryption_index->auxiliary_info_sample_count) {
6222 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6223 return AVERROR_INVALIDDATA;
6226 avio_r8(pb); /* version */
6227 if (avio_rb24(pb) & 0x01) { /* flags */
6228 aux_info_type = avio_rb32(pb);
6229 aux_info_param = avio_rb32(pb);
6230 if (sc->cenc.default_encrypted_sample) {
6231 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6232 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6235 if (aux_info_param != 0) {
6236 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6240 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6241 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6242 aux_info_type == MKBETAG('c','e','n','s') ||
6243 aux_info_type == MKBETAG('c','b','c','1') ||
6244 aux_info_type == MKBETAG('c','b','c','s')) &&
6245 aux_info_param == 0) {
6246 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6247 return AVERROR_INVALIDDATA;
6252 } else if (!sc->cenc.default_encrypted_sample) {
6253 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6257 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6258 sample_count = avio_rb32(pb);
6259 encryption_index->auxiliary_info_sample_count = sample_count;
6261 if (encryption_index->auxiliary_info_default_size == 0) {
6262 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6264 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6269 if (encryption_index->auxiliary_offsets_count) {
6270 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6276 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6278 uint64_t *auxiliary_offsets;
6279 MOVEncryptionIndex *encryption_index;
6280 MOVStreamContext *sc;
6282 unsigned int version, entry_count, aux_info_type, aux_info_param;
6283 unsigned int alloc_size = 0;
6285 ret = get_current_encryption_info(c, &encryption_index, &sc);
6289 if (encryption_index->nb_encrypted_samples) {
6290 // This can happen if we have both saio/saiz and senc atoms.
6291 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6295 if (encryption_index->auxiliary_offsets_count) {
6296 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6297 return AVERROR_INVALIDDATA;
6300 version = avio_r8(pb); /* version */
6301 if (avio_rb24(pb) & 0x01) { /* flags */
6302 aux_info_type = avio_rb32(pb);
6303 aux_info_param = avio_rb32(pb);
6304 if (sc->cenc.default_encrypted_sample) {
6305 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6306 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6309 if (aux_info_param != 0) {
6310 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6314 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6315 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6316 aux_info_type == MKBETAG('c','e','n','s') ||
6317 aux_info_type == MKBETAG('c','b','c','1') ||
6318 aux_info_type == MKBETAG('c','b','c','s')) &&
6319 aux_info_param == 0) {
6320 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6321 return AVERROR_INVALIDDATA;
6326 } else if (!sc->cenc.default_encrypted_sample) {
6327 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6331 entry_count = avio_rb32(pb);
6332 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6333 return AVERROR(ENOMEM);
6335 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6336 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6337 auxiliary_offsets = av_fast_realloc(
6338 encryption_index->auxiliary_offsets, &alloc_size,
6339 min_offsets * sizeof(*auxiliary_offsets));
6340 if (!auxiliary_offsets) {
6341 av_freep(&encryption_index->auxiliary_offsets);
6342 return AVERROR(ENOMEM);
6344 encryption_index->auxiliary_offsets = auxiliary_offsets;
6347 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6349 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6351 if (c->frag_index.current >= 0) {
6352 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6356 if (pb->eof_reached) {
6357 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6358 av_freep(&encryption_index->auxiliary_offsets);
6359 return AVERROR_INVALIDDATA;
6362 encryption_index->auxiliary_offsets_count = entry_count;
6364 if (encryption_index->auxiliary_info_sample_count) {
6365 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6371 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6373 AVEncryptionInitInfo *info, *old_init_info;
6376 uint8_t *side_data, *extra_data, *old_side_data;
6377 size_t side_data_size;
6378 buffer_size_t old_side_data_size;
6380 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6382 if (c->fc->nb_streams < 1)
6384 st = c->fc->streams[c->fc->nb_streams-1];
6386 version = avio_r8(pb); /* version */
6387 avio_rb24(pb); /* flags */
6389 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6390 /* key_id_size */ 16, /* data_size */ 0);
6392 return AVERROR(ENOMEM);
6394 if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
6395 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6400 kid_count = avio_rb32(pb);
6401 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
6402 ret = AVERROR(ENOMEM);
6406 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6407 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6408 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6409 min_kid_count * sizeof(*key_ids));
6411 ret = AVERROR(ENOMEM);
6414 info->key_ids = key_ids;
6416 info->key_ids[i] = av_mallocz(16);
6417 if (!info->key_ids[i]) {
6418 ret = AVERROR(ENOMEM);
6421 info->num_key_ids = i + 1;
6423 if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
6424 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6429 if (pb->eof_reached) {
6430 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6431 ret = AVERROR_INVALIDDATA;
6436 extra_data_size = avio_rb32(pb);
6437 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6441 av_freep(&info->data); // malloc(0) may still allocate something.
6442 info->data = extra_data;
6443 info->data_size = extra_data_size;
6445 // If there is existing initialization data, append to the list.
6446 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6447 if (old_side_data) {
6448 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6449 if (old_init_info) {
6450 // Append to the end of the list.
6451 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6457 info = old_init_info;
6459 // Assume existing side-data will be valid, so the only error we could get is OOM.
6460 ret = AVERROR(ENOMEM);
6465 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6467 ret = AVERROR(ENOMEM);
6470 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6471 side_data, side_data_size);
6476 av_encryption_init_info_free(info);
6480 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6483 MOVStreamContext *sc;
6485 if (c->fc->nb_streams < 1)
6487 st = c->fc->streams[c->fc->nb_streams-1];
6490 if (sc->pseudo_stream_id != 0) {
6491 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6492 return AVERROR_PATCHWELCOME;
6496 return AVERROR_INVALIDDATA;
6498 avio_rb32(pb); /* version and flags */
6500 if (!sc->cenc.default_encrypted_sample) {
6501 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6502 if (!sc->cenc.default_encrypted_sample) {
6503 return AVERROR(ENOMEM);
6507 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6511 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6514 MOVStreamContext *sc;
6515 unsigned int version, pattern, is_protected, iv_size;
6517 if (c->fc->nb_streams < 1)
6519 st = c->fc->streams[c->fc->nb_streams-1];
6522 if (sc->pseudo_stream_id != 0) {
6523 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6524 return AVERROR_PATCHWELCOME;
6527 if (!sc->cenc.default_encrypted_sample) {
6528 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6529 if (!sc->cenc.default_encrypted_sample) {
6530 return AVERROR(ENOMEM);
6535 return AVERROR_INVALIDDATA;
6537 version = avio_r8(pb); /* version */
6538 avio_rb24(pb); /* flags */
6540 avio_r8(pb); /* reserved */
6541 pattern = avio_r8(pb);
6544 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6545 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6548 is_protected = avio_r8(pb);
6549 if (is_protected && !sc->cenc.encryption_index) {
6550 // The whole stream should be by-default encrypted.
6551 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6552 if (!sc->cenc.encryption_index)
6553 return AVERROR(ENOMEM);
6555 sc->cenc.per_sample_iv_size = avio_r8(pb);
6556 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6557 sc->cenc.per_sample_iv_size != 16) {
6558 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6559 return AVERROR_INVALIDDATA;
6561 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6562 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6563 return AVERROR_INVALIDDATA;
6566 if (is_protected && !sc->cenc.per_sample_iv_size) {
6567 iv_size = avio_r8(pb);
6568 if (iv_size != 8 && iv_size != 16) {
6569 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6570 return AVERROR_INVALIDDATA;
6573 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6574 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6575 return AVERROR_INVALIDDATA;
6582 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6585 int last, type, size, ret;
6588 if (c->fc->nb_streams < 1)
6590 st = c->fc->streams[c->fc->nb_streams-1];
6592 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6593 return AVERROR_INVALIDDATA;
6595 /* Check FlacSpecificBox version. */
6596 if (avio_r8(pb) != 0)
6597 return AVERROR_INVALIDDATA;
6599 avio_rb24(pb); /* Flags */
6601 avio_read(pb, buf, sizeof(buf));
6602 flac_parse_block_header(buf, &last, &type, &size);
6604 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6605 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6606 return AVERROR_INVALIDDATA;
6609 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6614 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6619 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6623 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6624 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6625 return AVERROR_PATCHWELCOME;
6628 if (!sc->cenc.aes_ctr) {
6629 /* initialize the cipher */
6630 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6631 if (!sc->cenc.aes_ctr) {
6632 return AVERROR(ENOMEM);
6635 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6641 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6643 if (!sample->subsample_count) {
6644 /* decrypt the whole packet */
6645 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6649 for (i = 0; i < sample->subsample_count; i++) {
6650 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6651 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6652 return AVERROR_INVALIDDATA;
6655 /* skip the clear bytes */
6656 input += sample->subsamples[i].bytes_of_clear_data;
6657 size -= sample->subsamples[i].bytes_of_clear_data;
6659 /* decrypt the encrypted bytes */
6660 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6661 input += sample->subsamples[i].bytes_of_protected_data;
6662 size -= sample->subsamples[i].bytes_of_protected_data;
6666 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6667 return AVERROR_INVALIDDATA;
6673 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6675 MOVFragmentStreamInfo *frag_stream_info;
6676 MOVEncryptionIndex *encryption_index;
6677 AVEncryptionInfo *encrypted_sample;
6678 int encrypted_index, ret;
6680 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6681 encrypted_index = current_index;
6682 encryption_index = NULL;
6683 if (frag_stream_info) {
6684 // Note this only supports encryption info in the first sample descriptor.
6685 if (mov->fragment.stsd_id == 1) {
6686 if (frag_stream_info->encryption_index) {
6687 encrypted_index = current_index - frag_stream_info->index_entry;
6688 encryption_index = frag_stream_info->encryption_index;
6690 encryption_index = sc->cenc.encryption_index;
6694 encryption_index = sc->cenc.encryption_index;
6697 if (encryption_index) {
6698 if (encryption_index->auxiliary_info_sample_count &&
6699 !encryption_index->nb_encrypted_samples) {
6700 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6701 return AVERROR_INVALIDDATA;
6703 if (encryption_index->auxiliary_offsets_count &&
6704 !encryption_index->nb_encrypted_samples) {
6705 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6706 return AVERROR_INVALIDDATA;
6709 if (!encryption_index->nb_encrypted_samples) {
6710 // Full-sample encryption with default settings.
6711 encrypted_sample = sc->cenc.default_encrypted_sample;
6712 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6713 // Per-sample setting override.
6714 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6716 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6717 return AVERROR_INVALIDDATA;
6720 if (mov->decryption_key) {
6721 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6724 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6726 return AVERROR(ENOMEM);
6727 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6737 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6739 const int OPUS_SEEK_PREROLL_MS = 80;
6745 if (c->fc->nb_streams < 1)
6747 st = c->fc->streams[c->fc->nb_streams-1];
6749 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6750 return AVERROR_INVALIDDATA;
6752 /* Check OpusSpecificBox version. */
6753 if (avio_r8(pb) != 0) {
6754 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6755 return AVERROR_INVALIDDATA;
6758 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6759 size = atom.size + 8;
6761 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
6764 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6765 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6766 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6767 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6769 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6770 little-endian; aside from the preceeding magic and version they're
6771 otherwise currently identical. Data after output gain at offset 16
6772 doesn't need to be bytewapped. */
6773 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6774 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6775 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6776 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6778 st->codecpar->initial_padding = pre_skip;
6779 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6780 (AVRational){1, 1000},
6781 (AVRational){1, 48000});
6786 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6789 unsigned format_info;
6790 int channel_assignment, channel_assignment1, channel_assignment2;
6793 if (c->fc->nb_streams < 1)
6795 st = c->fc->streams[c->fc->nb_streams-1];
6798 return AVERROR_INVALIDDATA;
6800 format_info = avio_rb32(pb);
6802 ratebits = (format_info >> 28) & 0xF;
6803 channel_assignment1 = (format_info >> 15) & 0x1F;
6804 channel_assignment2 = format_info & 0x1FFF;
6805 if (channel_assignment2)
6806 channel_assignment = channel_assignment2;
6808 channel_assignment = channel_assignment1;
6810 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6811 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6812 st->codecpar->channels = truehd_channels(channel_assignment);
6813 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6818 static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6822 AVDOVIDecoderConfigurationRecord *dovi;
6826 if (c->fc->nb_streams < 1)
6828 st = c->fc->streams[c->fc->nb_streams-1];
6830 if ((uint64_t)atom.size > (1<<30) || atom.size < 4)
6831 return AVERROR_INVALIDDATA;
6833 dovi = av_dovi_alloc(&dovi_size);
6835 return AVERROR(ENOMEM);
6837 dovi->dv_version_major = avio_r8(pb);
6838 dovi->dv_version_minor = avio_r8(pb);
6840 buf = avio_rb16(pb);
6841 dovi->dv_profile = (buf >> 9) & 0x7f; // 7 bits
6842 dovi->dv_level = (buf >> 3) & 0x3f; // 6 bits
6843 dovi->rpu_present_flag = (buf >> 2) & 0x01; // 1 bit
6844 dovi->el_present_flag = (buf >> 1) & 0x01; // 1 bit
6845 dovi->bl_present_flag = buf & 0x01; // 1 bit
6846 if (atom.size >= 24) { // 4 + 4 + 4 * 4
6848 dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits
6850 // 0 stands for None
6851 // Dolby Vision V1.2.93 profiles and levels
6852 dovi->dv_bl_signal_compatibility_id = 0;
6855 ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF,
6856 (uint8_t *)dovi, dovi_size);
6862 av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC box, version: %d.%d, profile: %d, level: %d, "
6863 "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n",
6864 dovi->dv_version_major, dovi->dv_version_minor,
6865 dovi->dv_profile, dovi->dv_level,
6866 dovi->rpu_present_flag,
6867 dovi->el_present_flag,
6868 dovi->bl_present_flag,
6869 dovi->dv_bl_signal_compatibility_id
6875 static const MOVParseTableEntry mov_default_parse_table[] = {
6876 { MKTAG('A','C','L','R'), mov_read_aclr },
6877 { MKTAG('A','P','R','G'), mov_read_avid },
6878 { MKTAG('A','A','L','P'), mov_read_avid },
6879 { MKTAG('A','R','E','S'), mov_read_ares },
6880 { MKTAG('a','v','s','s'), mov_read_avss },
6881 { MKTAG('a','v','1','C'), mov_read_av1c },
6882 { MKTAG('c','h','p','l'), mov_read_chpl },
6883 { MKTAG('c','o','6','4'), mov_read_stco },
6884 { MKTAG('c','o','l','r'), mov_read_colr },
6885 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6886 { MKTAG('d','i','n','f'), mov_read_default },
6887 { MKTAG('D','p','x','E'), mov_read_dpxe },
6888 { MKTAG('d','r','e','f'), mov_read_dref },
6889 { MKTAG('e','d','t','s'), mov_read_default },
6890 { MKTAG('e','l','s','t'), mov_read_elst },
6891 { MKTAG('e','n','d','a'), mov_read_enda },
6892 { MKTAG('f','i','e','l'), mov_read_fiel },
6893 { MKTAG('a','d','r','m'), mov_read_adrm },
6894 { MKTAG('f','t','y','p'), mov_read_ftyp },
6895 { MKTAG('g','l','b','l'), mov_read_glbl },
6896 { MKTAG('h','d','l','r'), mov_read_hdlr },
6897 { MKTAG('i','l','s','t'), mov_read_ilst },
6898 { MKTAG('j','p','2','h'), mov_read_jp2h },
6899 { MKTAG('m','d','a','t'), mov_read_mdat },
6900 { MKTAG('m','d','h','d'), mov_read_mdhd },
6901 { MKTAG('m','d','i','a'), mov_read_default },
6902 { MKTAG('m','e','t','a'), mov_read_meta },
6903 { MKTAG('m','i','n','f'), mov_read_default },
6904 { MKTAG('m','o','o','f'), mov_read_moof },
6905 { MKTAG('m','o','o','v'), mov_read_moov },
6906 { MKTAG('m','v','e','x'), mov_read_default },
6907 { MKTAG('m','v','h','d'), mov_read_mvhd },
6908 { MKTAG('S','M','I',' '), mov_read_svq3 },
6909 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6910 { MKTAG('a','v','c','C'), mov_read_glbl },
6911 { MKTAG('p','a','s','p'), mov_read_pasp },
6912 { MKTAG('s','i','d','x'), mov_read_sidx },
6913 { MKTAG('s','t','b','l'), mov_read_default },
6914 { MKTAG('s','t','c','o'), mov_read_stco },
6915 { MKTAG('s','t','p','s'), mov_read_stps },
6916 { MKTAG('s','t','r','f'), mov_read_strf },
6917 { MKTAG('s','t','s','c'), mov_read_stsc },
6918 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6919 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6920 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6921 { MKTAG('s','t','t','s'), mov_read_stts },
6922 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6923 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
6924 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6925 { MKTAG('t','f','d','t'), mov_read_tfdt },
6926 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6927 { MKTAG('t','r','a','k'), mov_read_trak },
6928 { MKTAG('t','r','a','f'), mov_read_default },
6929 { MKTAG('t','r','e','f'), mov_read_default },
6930 { MKTAG('t','m','c','d'), mov_read_tmcd },
6931 { MKTAG('c','h','a','p'), mov_read_chap },
6932 { MKTAG('t','r','e','x'), mov_read_trex },
6933 { MKTAG('t','r','u','n'), mov_read_trun },
6934 { MKTAG('u','d','t','a'), mov_read_default },
6935 { MKTAG('w','a','v','e'), mov_read_wave },
6936 { MKTAG('e','s','d','s'), mov_read_esds },
6937 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6938 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6939 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6940 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6941 { MKTAG('w','f','e','x'), mov_read_wfex },
6942 { MKTAG('c','m','o','v'), mov_read_cmov },
6943 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6944 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6945 { MKTAG('s','b','g','p'), mov_read_sbgp },
6946 { MKTAG('h','v','c','C'), mov_read_glbl },
6947 { MKTAG('u','u','i','d'), mov_read_uuid },
6948 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6949 { MKTAG('f','r','e','e'), mov_read_free },
6950 { MKTAG('-','-','-','-'), mov_read_custom },
6951 { MKTAG('s','i','n','f'), mov_read_default },
6952 { MKTAG('f','r','m','a'), mov_read_frma },
6953 { MKTAG('s','e','n','c'), mov_read_senc },
6954 { MKTAG('s','a','i','z'), mov_read_saiz },
6955 { MKTAG('s','a','i','o'), mov_read_saio },
6956 { MKTAG('p','s','s','h'), mov_read_pssh },
6957 { MKTAG('s','c','h','m'), mov_read_schm },
6958 { MKTAG('s','c','h','i'), mov_read_default },
6959 { MKTAG('t','e','n','c'), mov_read_tenc },
6960 { MKTAG('d','f','L','a'), mov_read_dfla },
6961 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6962 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6963 { MKTAG('d','O','p','s'), mov_read_dops },
6964 { MKTAG('d','m','l','p'), mov_read_dmlp },
6965 { MKTAG('S','m','D','m'), mov_read_smdm },
6966 { MKTAG('C','o','L','L'), mov_read_coll },
6967 { MKTAG('v','p','c','C'), mov_read_vpcc },
6968 { MKTAG('m','d','c','v'), mov_read_mdcv },
6969 { MKTAG('c','l','l','i'), mov_read_clli },
6970 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
6971 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
6975 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6977 int64_t total_size = 0;
6981 if (c->atom_depth > 10) {
6982 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6983 return AVERROR_INVALIDDATA;
6988 atom.size = INT64_MAX;
6989 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6990 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
6993 if (atom.size >= 8) {
6994 a.size = avio_rb32(pb);
6995 a.type = avio_rl32(pb);
6996 if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
6997 a.type == MKTAG('h','o','o','v')) &&
6999 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
7002 type = avio_rl32(pb);
7005 avio_seek(pb, -8, SEEK_CUR);
7006 if (type == MKTAG('m','v','h','d') ||
7007 type == MKTAG('c','m','o','v')) {
7008 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
7009 a.type = MKTAG('m','o','o','v');
7012 if (atom.type != MKTAG('r','o','o','t') &&
7013 atom.type != MKTAG('m','o','o','v')) {
7014 if (a.type == MKTAG('t','r','a','k') ||
7015 a.type == MKTAG('m','d','a','t')) {
7016 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
7023 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
7024 a.size = avio_rb64(pb) - 8;
7028 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
7029 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
7031 a.size = atom.size - total_size + 8;
7036 a.size = FFMIN(a.size, atom.size - total_size);
7038 for (i = 0; mov_default_parse_table[i].type; i++)
7039 if (mov_default_parse_table[i].type == a.type) {
7040 parse = mov_default_parse_table[i].parse;
7044 // container is user data
7045 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
7046 atom.type == MKTAG('i','l','s','t')))
7047 parse = mov_read_udta_string;
7049 // Supports parsing the QuickTime Metadata Keys.
7050 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
7051 if (!parse && c->found_hdlr_mdta &&
7052 atom.type == MKTAG('m','e','t','a') &&
7053 a.type == MKTAG('k','e','y','s') &&
7054 c->meta_keys_count == 0) {
7055 parse = mov_read_keys;
7058 if (!parse) { /* skip leaf atoms data */
7059 avio_skip(pb, a.size);
7061 int64_t start_pos = avio_tell(pb);
7063 int err = parse(c, pb, a);
7068 if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
7069 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
7070 start_pos + a.size == avio_size(pb))) {
7071 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
7072 c->next_root_atom = start_pos + a.size;
7076 left = a.size - avio_tell(pb) + start_pos;
7077 if (left > 0) /* skip garbage at atom end */
7078 avio_skip(pb, left);
7079 else if (left < 0) {
7080 av_log(c->fc, AV_LOG_WARNING,
7081 "overread end of atom '%s' by %"PRId64" bytes\n",
7082 av_fourcc2str(a.type), -left);
7083 avio_seek(pb, left, SEEK_CUR);
7087 total_size += a.size;
7090 if (total_size < atom.size && atom.size < 0x7ffff)
7091 avio_skip(pb, atom.size - total_size);
7097 static int mov_probe(const AVProbeData *p)
7102 int moov_offset = -1;
7104 /* check file header */
7109 /* ignore invalid offset */
7110 if ((offset + 8) > (unsigned int)p->buf_size)
7112 size = AV_RB32(p->buf + offset);
7113 if (size == 1 && offset + 16 > (unsigned int)p->buf_size) {
7114 size = AV_RB64(p->buf+offset + 8);
7116 } else if (size == 0) {
7117 size = p->buf_size - offset;
7119 if (size < minsize) {
7123 tag = AV_RL32(p->buf + offset + 4);
7125 /* check for obvious tags */
7126 case MKTAG('m','o','o','v'):
7127 moov_offset = offset + 4;
7128 case MKTAG('m','d','a','t'):
7129 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
7130 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
7131 case MKTAG('f','t','y','p'):
7132 if (tag == MKTAG('f','t','y','p') &&
7133 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
7134 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
7136 score = FFMAX(score, 5);
7138 score = AVPROBE_SCORE_MAX;
7141 /* those are more common words, so rate then a bit less */
7142 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
7143 case MKTAG('w','i','d','e'):
7144 case MKTAG('f','r','e','e'):
7145 case MKTAG('j','u','n','k'):
7146 case MKTAG('p','i','c','t'):
7147 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
7149 case MKTAG(0x82,0x82,0x7f,0x7d):
7150 case MKTAG('s','k','i','p'):
7151 case MKTAG('u','u','i','d'):
7152 case MKTAG('p','r','f','l'):
7153 /* if we only find those cause probedata is too small at least rate them */
7154 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7159 if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
7160 /* moov atom in the header - we should make sure that this is not a
7161 * MOV-packed MPEG-PS */
7162 offset = moov_offset;
7164 while (offset < (p->buf_size - 16)) { /* Sufficient space */
7165 /* We found an actual hdlr atom */
7166 if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7167 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7168 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
7169 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7170 /* We found a media handler reference atom describing an
7171 * MPEG-PS-in-MOV, return a
7172 * low score to force expanding the probe window until
7173 * mpegps_probe finds what it needs */
7185 // must be done after parsing all trak because there's no order requirement
7186 static void mov_read_chapters(AVFormatContext *s)
7188 MOVContext *mov = s->priv_data;
7190 MOVStreamContext *sc;
7195 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7196 chapter_track = mov->chapter_tracks[j];
7198 for (i = 0; i < s->nb_streams; i++)
7199 if (s->streams[i]->id == chapter_track) {
7204 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7209 cur_pos = avio_tell(sc->pb);
7211 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7212 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7213 if (st->internal->nb_index_entries) {
7214 // Retrieve the first frame, if possible
7215 AVIndexEntry *sample = &st->internal->index_entries[0];
7216 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7217 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7221 if (av_get_packet(sc->pb, &st->attached_pic, sample->size) < 0)
7224 st->attached_pic.stream_index = st->index;
7225 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
7228 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7229 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7230 st->discard = AVDISCARD_ALL;
7231 for (i = 0; i < st->internal->nb_index_entries; i++) {
7232 AVIndexEntry *sample = &st->internal->index_entries[i];
7233 int64_t end = i+1 < st->internal->nb_index_entries ? st->internal->index_entries[i+1].timestamp : st->duration;
7238 if (end < sample->timestamp) {
7239 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7240 end = AV_NOPTS_VALUE;
7243 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7244 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7248 // the first two bytes are the length of the title
7249 len = avio_rb16(sc->pb);
7250 if (len > sample->size-2)
7252 title_len = 2*len + 1;
7253 if (!(title = av_mallocz(title_len)))
7256 // The samples could theoretically be in any encoding if there's an encd
7257 // atom following, but in practice are only utf-8 or utf-16, distinguished
7258 // instead by the presence of a BOM
7262 ch = avio_rb16(sc->pb);
7264 avio_get_str16be(sc->pb, len, title, title_len);
7265 else if (ch == 0xfffe)
7266 avio_get_str16le(sc->pb, len, title, title_len);
7269 if (len == 1 || len == 2)
7272 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7276 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7281 avio_seek(sc->pb, cur_pos, SEEK_SET);
7285 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7286 uint32_t value, int flags)
7289 char buf[AV_TIMECODE_STR_SIZE];
7290 AVRational rate = st->avg_frame_rate;
7291 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7294 av_dict_set(&st->metadata, "timecode",
7295 av_timecode_make_string(&tc, buf, value), 0);
7299 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7301 MOVStreamContext *sc = st->priv_data;
7302 char buf[AV_TIMECODE_STR_SIZE];
7303 int64_t cur_pos = avio_tell(sc->pb);
7304 int hh, mm, ss, ff, drop;
7306 if (!st->internal->nb_index_entries)
7309 avio_seek(sc->pb, st->internal->index_entries->pos, SEEK_SET);
7310 avio_skip(s->pb, 13);
7311 hh = avio_r8(s->pb);
7312 mm = avio_r8(s->pb);
7313 ss = avio_r8(s->pb);
7314 drop = avio_r8(s->pb);
7315 ff = avio_r8(s->pb);
7316 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7317 hh, mm, ss, drop ? ';' : ':', ff);
7318 av_dict_set(&st->metadata, "timecode", buf, 0);
7320 avio_seek(sc->pb, cur_pos, SEEK_SET);
7324 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7326 MOVStreamContext *sc = st->priv_data;
7328 int64_t cur_pos = avio_tell(sc->pb);
7331 if (!st->internal->nb_index_entries)
7334 avio_seek(sc->pb, st->internal->index_entries->pos, SEEK_SET);
7335 value = avio_rb32(s->pb);
7337 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7338 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7339 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7341 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7342 * not the case) and thus assume "frame number format" instead of QT one.
7343 * No sample with tmcd track can be found with a QT timecode at the moment,
7344 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7346 parse_timecode_in_framenum_format(s, st, value, flags);
7348 avio_seek(sc->pb, cur_pos, SEEK_SET);
7352 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7354 if (!index || !*index) return;
7355 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7356 av_encryption_info_free((*index)->encrypted_samples[i]);
7358 av_freep(&(*index)->encrypted_samples);
7359 av_freep(&(*index)->auxiliary_info_sizes);
7360 av_freep(&(*index)->auxiliary_offsets);
7364 static int mov_read_close(AVFormatContext *s)
7366 MOVContext *mov = s->priv_data;
7369 for (i = 0; i < s->nb_streams; i++) {
7370 AVStream *st = s->streams[i];
7371 MOVStreamContext *sc = st->priv_data;
7376 av_freep(&sc->ctts_data);
7377 for (j = 0; j < sc->drefs_count; j++) {
7378 av_freep(&sc->drefs[j].path);
7379 av_freep(&sc->drefs[j].dir);
7381 av_freep(&sc->drefs);
7383 sc->drefs_count = 0;
7385 if (!sc->pb_is_copied)
7386 ff_format_io_close(s, &sc->pb);
7389 av_freep(&sc->chunk_offsets);
7390 av_freep(&sc->stsc_data);
7391 av_freep(&sc->sample_sizes);
7392 av_freep(&sc->keyframes);
7393 av_freep(&sc->stts_data);
7394 av_freep(&sc->sdtp_data);
7395 av_freep(&sc->stps_data);
7396 av_freep(&sc->elst_data);
7397 av_freep(&sc->rap_group);
7398 av_freep(&sc->display_matrix);
7399 av_freep(&sc->index_ranges);
7402 for (j = 0; j < sc->stsd_count; j++)
7403 av_free(sc->extradata[j]);
7404 av_freep(&sc->extradata);
7405 av_freep(&sc->extradata_size);
7407 mov_free_encryption_index(&sc->cenc.encryption_index);
7408 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7409 av_aes_ctr_free(sc->cenc.aes_ctr);
7411 av_freep(&sc->stereo3d);
7412 av_freep(&sc->spherical);
7413 av_freep(&sc->mastering);
7414 av_freep(&sc->coll);
7417 av_freep(&mov->dv_demux);
7418 avformat_free_context(mov->dv_fctx);
7419 mov->dv_fctx = NULL;
7421 if (mov->meta_keys) {
7422 for (i = 1; i < mov->meta_keys_count; i++) {
7423 av_freep(&mov->meta_keys[i]);
7425 av_freep(&mov->meta_keys);
7428 av_freep(&mov->trex_data);
7429 av_freep(&mov->bitrates);
7431 for (i = 0; i < mov->frag_index.nb_items; i++) {
7432 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7433 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7434 mov_free_encryption_index(&frag[j].encryption_index);
7436 av_freep(&mov->frag_index.item[i].stream_info);
7438 av_freep(&mov->frag_index.item);
7440 av_freep(&mov->aes_decrypt);
7441 av_freep(&mov->chapter_tracks);
7446 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7450 for (i = 0; i < s->nb_streams; i++) {
7451 AVStream *st = s->streams[i];
7452 MOVStreamContext *sc = st->priv_data;
7454 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7455 sc->timecode_track == tmcd_id)
7461 /* look for a tmcd track not referenced by any video track, and export it globally */
7462 static void export_orphan_timecode(AVFormatContext *s)
7466 for (i = 0; i < s->nb_streams; i++) {
7467 AVStream *st = s->streams[i];
7469 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7470 !tmcd_is_referenced(s, i + 1)) {
7471 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7473 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7480 static int read_tfra(MOVContext *mov, AVIOContext *f)
7482 int version, fieldlength, i, j;
7483 int64_t pos = avio_tell(f);
7484 uint32_t size = avio_rb32(f);
7485 unsigned track_id, item_count;
7487 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7490 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7492 version = avio_r8(f);
7494 track_id = avio_rb32(f);
7495 fieldlength = avio_rb32(f);
7496 item_count = avio_rb32(f);
7497 for (i = 0; i < item_count; i++) {
7498 int64_t time, offset;
7500 MOVFragmentStreamInfo * frag_stream_info;
7503 return AVERROR_INVALIDDATA;
7507 time = avio_rb64(f);
7508 offset = avio_rb64(f);
7510 time = avio_rb32(f);
7511 offset = avio_rb32(f);
7514 // The first sample of each stream in a fragment is always a random
7515 // access sample. So it's entry in the tfra can be used as the
7516 // initial PTS of the fragment.
7517 index = update_frag_index(mov, offset);
7518 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7519 if (frag_stream_info &&
7520 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7521 frag_stream_info->first_tfra_pts = time;
7523 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7525 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7527 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7531 avio_seek(f, pos + size, SEEK_SET);
7535 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7537 int64_t stream_size = avio_size(f);
7538 int64_t original_pos = avio_tell(f);
7541 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7545 c->mfra_size = avio_rb32(f);
7546 c->have_read_mfra_size = 1;
7547 if (!c->mfra_size || c->mfra_size > stream_size) {
7548 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7551 if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
7555 if (avio_rb32(f) != c->mfra_size) {
7556 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7559 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7560 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7563 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7565 ret = read_tfra(c, f);
7570 c->frag_index.complete = 1;
7572 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7574 av_log(c->fc, AV_LOG_ERROR,
7575 "failed to seek back after looking for mfra\n");
7581 static int mov_read_header(AVFormatContext *s)
7583 MOVContext *mov = s->priv_data;
7584 AVIOContext *pb = s->pb;
7586 MOVAtom atom = { AV_RL32("root") };
7589 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7590 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7591 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7592 return AVERROR(EINVAL);
7596 mov->trak_index = -1;
7597 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7598 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7599 atom.size = avio_size(pb);
7601 atom.size = INT64_MAX;
7603 /* check MOV header */
7605 if (mov->moov_retry)
7606 avio_seek(pb, 0, SEEK_SET);
7607 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7608 av_log(s, AV_LOG_ERROR, "error reading header\n");
7611 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7612 if (!mov->found_moov) {
7613 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7614 err = AVERROR_INVALIDDATA;
7617 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7619 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7620 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7621 mov_read_chapters(s);
7622 for (i = 0; i < s->nb_streams; i++)
7623 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7624 mov_read_timecode_track(s, s->streams[i]);
7625 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7626 mov_read_rtmd_track(s, s->streams[i]);
7630 /* copy timecode metadata from tmcd tracks to the related video streams */
7631 for (i = 0; i < s->nb_streams; i++) {
7632 AVStream *st = s->streams[i];
7633 MOVStreamContext *sc = st->priv_data;
7634 if (sc->timecode_track > 0) {
7635 AVDictionaryEntry *tcr;
7636 int tmcd_st_id = -1;
7638 for (j = 0; j < s->nb_streams; j++)
7639 if (s->streams[j]->id == sc->timecode_track)
7642 if (tmcd_st_id < 0 || tmcd_st_id == i)
7644 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7646 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7649 export_orphan_timecode(s);
7651 for (i = 0; i < s->nb_streams; i++) {
7652 AVStream *st = s->streams[i];
7653 MOVStreamContext *sc = st->priv_data;
7654 fix_timescale(mov, sc);
7655 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
7656 st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7657 st->internal->skip_samples = sc->start_pad;
7659 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7660 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7661 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7662 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7663 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7664 st->codecpar->width = sc->width;
7665 st->codecpar->height = sc->height;
7667 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7668 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7672 if (mov->handbrake_version &&
7673 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7674 st->codecpar->codec_id == AV_CODEC_ID_MP3) {
7675 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7676 st->need_parsing = AVSTREAM_PARSE_FULL;
7680 if (mov->trex_data) {
7681 for (i = 0; i < s->nb_streams; i++) {
7682 AVStream *st = s->streams[i];
7683 MOVStreamContext *sc = st->priv_data;
7684 if (st->duration > 0) {
7685 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7686 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7687 sc->data_size, sc->time_scale);
7688 err = AVERROR_INVALIDDATA;
7691 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7696 if (mov->use_mfra_for > 0) {
7697 for (i = 0; i < s->nb_streams; i++) {
7698 AVStream *st = s->streams[i];
7699 MOVStreamContext *sc = st->priv_data;
7700 if (sc->duration_for_fps > 0) {
7701 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7702 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7703 sc->data_size, sc->time_scale);
7704 err = AVERROR_INVALIDDATA;
7707 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7708 sc->duration_for_fps;
7713 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7714 if (mov->bitrates[i]) {
7715 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7719 ff_rfps_calculate(s);
7721 for (i = 0; i < s->nb_streams; i++) {
7722 AVStream *st = s->streams[i];
7723 MOVStreamContext *sc = st->priv_data;
7725 switch (st->codecpar->codec_type) {
7726 case AVMEDIA_TYPE_AUDIO:
7727 err = ff_replaygain_export(st, s->metadata);
7731 case AVMEDIA_TYPE_VIDEO:
7732 if (sc->display_matrix) {
7733 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7734 sizeof(int32_t) * 9);
7738 sc->display_matrix = NULL;
7741 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7742 (uint8_t *)sc->stereo3d,
7743 sizeof(*sc->stereo3d));
7747 sc->stereo3d = NULL;
7749 if (sc->spherical) {
7750 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7751 (uint8_t *)sc->spherical,
7752 sc->spherical_size);
7756 sc->spherical = NULL;
7758 if (sc->mastering) {
7759 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7760 (uint8_t *)sc->mastering,
7761 sizeof(*sc->mastering));
7765 sc->mastering = NULL;
7768 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7769 (uint8_t *)sc->coll,
7779 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7781 for (i = 0; i < mov->frag_index.nb_items; i++)
7782 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7783 mov->frag_index.item[i].headers_read = 1;
7791 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7793 AVIndexEntry *sample = NULL;
7794 int64_t best_dts = INT64_MAX;
7796 for (i = 0; i < s->nb_streams; i++) {
7797 AVStream *avst = s->streams[i];
7798 MOVStreamContext *msc = avst->priv_data;
7799 if (msc->pb && msc->current_sample < avst->internal->nb_index_entries) {
7800 AVIndexEntry *current_sample = &avst->internal->index_entries[msc->current_sample];
7801 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7802 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7803 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7804 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7805 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
7806 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7807 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7808 sample = current_sample;
7817 static int should_retry(AVIOContext *pb, int error_code) {
7818 if (error_code == AVERROR_EOF || avio_feof(pb))
7824 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7827 MOVContext *mov = s->priv_data;
7829 if (index >= 0 && index < mov->frag_index.nb_items)
7830 target = mov->frag_index.item[index].moof_offset;
7831 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7832 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7833 return AVERROR_INVALIDDATA;
7836 mov->next_root_atom = 0;
7837 if (index < 0 || index >= mov->frag_index.nb_items)
7838 index = search_frag_moof_offset(&mov->frag_index, target);
7839 if (index < mov->frag_index.nb_items &&
7840 mov->frag_index.item[index].moof_offset == target) {
7841 if (index + 1 < mov->frag_index.nb_items)
7842 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7843 if (mov->frag_index.item[index].headers_read)
7845 mov->frag_index.item[index].headers_read = 1;
7848 mov->found_mdat = 0;
7850 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7853 if (avio_feof(s->pb))
7855 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7860 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7862 uint8_t *side, *extradata;
7865 /* Save the current index. */
7866 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7868 /* Notify the decoder that extradata changed. */
7869 extradata_size = sc->extradata_size[sc->last_stsd_index];
7870 extradata = sc->extradata[sc->last_stsd_index];
7871 if (extradata_size > 0 && extradata) {
7872 side = av_packet_new_side_data(pkt,
7873 AV_PKT_DATA_NEW_EXTRADATA,
7876 return AVERROR(ENOMEM);
7877 memcpy(side, extradata, extradata_size);
7883 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int size)
7888 return AVERROR_INVALIDDATA;
7889 new_size = ((size - 8) / 2) * 3;
7890 ret = av_new_packet(pkt, new_size);
7895 for (int j = 0; j < new_size; j += 3) {
7896 pkt->data[j] = 0xFC;
7897 pkt->data[j+1] = avio_r8(pb);
7898 pkt->data[j+2] = avio_r8(pb);
7904 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7906 MOVContext *mov = s->priv_data;
7907 MOVStreamContext *sc;
7908 AVIndexEntry *sample;
7909 AVStream *st = NULL;
7910 int64_t current_index;
7914 sample = mov_find_next_sample(s, &st);
7915 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7916 if (!mov->next_root_atom)
7918 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7923 /* must be done just before reading, to avoid infinite loop on sample */
7924 current_index = sc->current_index;
7925 mov_current_sample_inc(sc);
7927 if (mov->next_root_atom) {
7928 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7929 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7932 if (st->discard != AVDISCARD_ALL) {
7933 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7934 if (ret64 != sample->pos) {
7935 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7936 sc->ffindex, sample->pos);
7937 if (should_retry(sc->pb, ret64)) {
7938 mov_current_sample_dec(sc);
7940 return AVERROR_INVALIDDATA;
7943 if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
7944 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7948 if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
7949 ret = get_eia608_packet(sc->pb, pkt, sample->size);
7951 ret = av_get_packet(sc->pb, pkt, sample->size);
7953 if (should_retry(sc->pb, ret)) {
7954 mov_current_sample_dec(sc);
7958 #if CONFIG_DV_DEMUXER
7959 if (mov->dv_demux && sc->dv_audio_container) {
7960 AVBufferRef *buf = pkt->buf;
7961 ret = avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7963 av_packet_unref(pkt);
7966 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7971 if (sc->has_palette) {
7974 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7976 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7978 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7979 sc->has_palette = 0;
7982 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7983 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7984 st->need_parsing = AVSTREAM_PARSE_FULL;
7988 pkt->stream_index = sc->ffindex;
7989 pkt->dts = sample->timestamp;
7990 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7991 pkt->flags |= AV_PKT_FLAG_DISCARD;
7993 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7994 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
7995 /* update ctts context */
7997 if (sc->ctts_index < sc->ctts_count &&
7998 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
8000 sc->ctts_sample = 0;
8003 int64_t next_dts = (sc->current_sample < st->internal->nb_index_entries) ?
8004 st->internal->index_entries[sc->current_sample].timestamp : st->duration;
8006 if (next_dts >= pkt->dts)
8007 pkt->duration = next_dts - pkt->dts;
8008 pkt->pts = pkt->dts;
8010 if (st->discard == AVDISCARD_ALL)
8012 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
8013 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
8014 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
8015 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
8017 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
8018 pkt->pos = sample->pos;
8020 /* Multiple stsd handling. */
8021 if (sc->stsc_data) {
8022 /* Keep track of the stsc index for the given sample, then check
8023 * if the stsd index is different from the last used one. */
8025 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
8026 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
8028 sc->stsc_sample = 0;
8029 /* Do not check indexes after a switch. */
8030 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
8031 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
8032 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
8033 ret = mov_change_extradata(sc, pkt);
8040 aax_filter(pkt->data, pkt->size, mov);
8042 ret = cenc_filter(mov, st, sc, pkt, current_index);
8050 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
8052 MOVContext *mov = s->priv_data;
8055 if (!mov->frag_index.complete)
8058 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
8061 if (!mov->frag_index.item[index].headers_read)
8062 return mov_switch_root(s, -1, index);
8063 if (index + 1 < mov->frag_index.nb_items)
8064 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
8069 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
8071 MOVStreamContext *sc = st->priv_data;
8072 int sample, time_sample, ret;
8075 // Here we consider timestamp to be PTS, hence try to offset it so that we
8076 // can search over the DTS timeline.
8077 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
8079 ret = mov_seek_fragment(s, st, timestamp);
8083 sample = av_index_search_timestamp(st, timestamp, flags);
8084 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
8085 if (sample < 0 && st->internal->nb_index_entries && timestamp < st->internal->index_entries[0].timestamp)
8087 if (sample < 0) /* not sure what to do */
8088 return AVERROR_INVALIDDATA;
8089 mov_current_sample_set(sc, sample);
8090 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
8091 /* adjust ctts index */
8092 if (sc->ctts_data) {
8094 for (i = 0; i < sc->ctts_count; i++) {
8095 int next = time_sample + sc->ctts_data[i].count;
8096 if (next > sc->current_sample) {
8098 sc->ctts_sample = sc->current_sample - time_sample;
8105 /* adjust stsd index */
8106 if (sc->chunk_count) {
8108 for (i = 0; i < sc->stsc_count; i++) {
8109 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
8110 if (next > sc->current_sample) {
8112 sc->stsc_sample = sc->current_sample - time_sample;
8115 av_assert0(next == (int)next);
8123 static int64_t mov_get_skip_samples(AVStream *st, int sample)
8125 MOVStreamContext *sc = st->priv_data;
8126 int64_t first_ts = st->internal->index_entries[0].timestamp;
8127 int64_t ts = st->internal->index_entries[sample].timestamp;
8130 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO)
8133 /* compute skip samples according to stream start_pad, seek ts and first ts */
8134 off = av_rescale_q(ts - first_ts, st->time_base,
8135 (AVRational){1, st->codecpar->sample_rate});
8136 return FFMAX(sc->start_pad - off, 0);
8139 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
8141 MOVContext *mc = s->priv_data;
8146 if (stream_index >= s->nb_streams)
8147 return AVERROR_INVALIDDATA;
8149 st = s->streams[stream_index];
8150 sample = mov_seek_stream(s, st, sample_time, flags);
8154 if (mc->seek_individually) {
8155 /* adjust seek timestamp to found sample timestamp */
8156 int64_t seek_timestamp = st->internal->index_entries[sample].timestamp;
8157 st->internal->skip_samples = mov_get_skip_samples(st, sample);
8159 for (i = 0; i < s->nb_streams; i++) {
8163 if (stream_index == i)
8166 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
8167 sample = mov_seek_stream(s, st, timestamp, flags);
8169 st->internal->skip_samples = mov_get_skip_samples(st, sample);
8172 for (i = 0; i < s->nb_streams; i++) {
8173 MOVStreamContext *sc;
8176 mov_current_sample_set(sc, 0);
8179 MOVStreamContext *sc;
8180 AVIndexEntry *entry = mov_find_next_sample(s, &st);
8182 return AVERROR_INVALIDDATA;
8184 if (sc->ffindex == stream_index && sc->current_sample == sample)
8186 mov_current_sample_inc(sc);
8192 #define OFFSET(x) offsetof(MOVContext, x)
8193 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
8194 static const AVOption mov_options[] = {
8195 {"use_absolute_path",
8196 "allow using absolute path when opening alias, this is a possible security issue",
8197 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
8199 {"seek_streams_individually",
8200 "Seek each stream individually to the closest point",
8201 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
8203 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
8205 {"advanced_editlist",
8206 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
8207 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
8209 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8212 "use mfra for fragment timestamps",
8213 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8214 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8216 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8217 FLAGS, "use_mfra_for" },
8218 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8219 FLAGS, "use_mfra_for" },
8220 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8221 FLAGS, "use_mfra_for" },
8222 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8223 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8224 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8225 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8226 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8227 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8228 { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
8229 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8230 { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
8231 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8232 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8233 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8234 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8235 .flags = AV_OPT_FLAG_DECODING_PARAM },
8236 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8237 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8238 {.i64 = 0}, 0, 1, FLAGS },
8243 static const AVClass mov_class = {
8244 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8245 .item_name = av_default_item_name,
8246 .option = mov_options,
8247 .version = LIBAVUTIL_VERSION_INT,
8250 AVInputFormat ff_mov_demuxer = {
8251 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8252 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8253 .priv_class = &mov_class,
8254 .priv_data_size = sizeof(MOVContext),
8255 .extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
8256 .read_probe = mov_probe,
8257 .read_header = mov_read_header,
8258 .read_packet = mov_read_packet,
8259 .read_close = mov_read_close,
8260 .read_seek = mov_read_seek,
8261 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,