3 * Copyright (c) 2001 Fabrice Bellard
4 * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
6 * first version by Francois Revol <revol@free.fr>
7 * seek function by Gael Chardon <gael.dev@4now.net>
9 * This file is part of FFmpeg.
11 * FFmpeg is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * FFmpeg is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with FFmpeg; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30 #include "libavutil/attributes.h"
31 #include "libavutil/channel_layout.h"
32 #include "libavutil/internal.h"
33 #include "libavutil/intreadwrite.h"
34 #include "libavutil/intfloat.h"
35 #include "libavutil/mathematics.h"
36 #include "libavutil/time_internal.h"
37 #include "libavutil/avassert.h"
38 #include "libavutil/avstring.h"
39 #include "libavutil/dict.h"
40 #include "libavutil/display.h"
41 #include "libavutil/opt.h"
42 #include "libavutil/aes.h"
43 #include "libavutil/aes_ctr.h"
44 #include "libavutil/pixdesc.h"
45 #include "libavutil/sha.h"
46 #include "libavutil/spherical.h"
47 #include "libavutil/stereo3d.h"
48 #include "libavutil/timecode.h"
49 #include "libavutil/dovi_meta.h"
50 #include "libavcodec/ac3tab.h"
51 #include "libavcodec/flac.h"
52 #include "libavcodec/mpegaudiodecheader.h"
53 #include "libavcodec/mlp_parse.h"
56 #include "avio_internal.h"
59 #include "libavcodec/get_bits.h"
62 #include "replaygain.h"
68 #include "qtpalette.h"
70 /* those functions parse an atom */
71 /* links atom IDs to parse functions */
72 typedef struct MOVParseTableEntry {
74 int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
77 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
78 static int mov_read_mfra(MOVContext *c, AVIOContext *f);
79 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
80 int count, int duration);
82 static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb,
83 unsigned len, const char *key)
87 short current, total = 0;
88 avio_rb16(pb); // unknown
89 current = avio_rb16(pb);
91 total = avio_rb16(pb);
93 snprintf(buf, sizeof(buf), "%d", current);
95 snprintf(buf, sizeof(buf), "%d/%d", current, total);
96 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
97 av_dict_set(&c->fc->metadata, key, buf, 0);
102 static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb,
103 unsigned len, const char *key)
105 /* bypass padding bytes */
110 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
111 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
116 static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb,
117 unsigned len, const char *key)
119 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
120 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
125 static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb,
126 unsigned len, const char *key)
130 avio_r8(pb); // unknown
133 if (genre < 1 || genre > ID3v1_GENRE_MAX)
135 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
136 av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
141 static const uint32_t mac_to_unicode[128] = {
142 0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
143 0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
144 0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
145 0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
146 0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
147 0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
148 0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
149 0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
150 0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
151 0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
152 0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
153 0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
154 0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
155 0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
156 0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
157 0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
160 static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len,
161 char *dst, int dstlen)
164 char *end = dst+dstlen-1;
167 for (i = 0; i < len; i++) {
168 uint8_t t, c = avio_r8(pb);
176 PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
182 static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
185 MOVStreamContext *sc;
190 case 0xd: id = AV_CODEC_ID_MJPEG; break;
191 case 0xe: id = AV_CODEC_ID_PNG; break;
192 case 0x1b: id = AV_CODEC_ID_BMP; break;
194 av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
199 st = avformat_new_stream(c->fc, NULL);
201 return AVERROR(ENOMEM);
202 sc = av_mallocz(sizeof(*sc));
204 return AVERROR(ENOMEM);
207 ret = av_get_packet(pb, &st->attached_pic, len);
211 if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) {
212 if (AV_RB64(st->attached_pic.data) == 0x89504e470d0a1a0a) {
213 id = AV_CODEC_ID_PNG;
215 id = AV_CODEC_ID_MJPEG;
219 st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
221 st->attached_pic.stream_index = st->index;
222 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
224 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
225 st->codecpar->codec_id = id;
231 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
233 char language[4] = { 0 };
234 char buf[200], place[100];
235 uint16_t langcode = 0;
236 double longitude, latitude, altitude;
237 const char *key = "location";
239 if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
240 av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
241 return AVERROR_INVALIDDATA;
244 avio_skip(pb, 4); // version+flags
245 langcode = avio_rb16(pb);
246 ff_mov_lang_to_iso639(langcode, language);
249 len -= avio_get_str(pb, len, place, sizeof(place));
251 av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
252 return AVERROR_INVALIDDATA;
254 avio_skip(pb, 1); // role
258 av_log(c->fc, AV_LOG_ERROR,
259 "loci too short (%u bytes left, need at least %d)\n", len, 12);
260 return AVERROR_INVALIDDATA;
262 longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
263 latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
264 altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
266 // Try to output in the same format as the ?xyz field
267 snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
269 av_strlcatf(buf, sizeof(buf), "%+f", altitude);
270 av_strlcatf(buf, sizeof(buf), "/%s", place);
272 if (*language && strcmp(language, "und")) {
274 snprintf(key2, sizeof(key2), "%s-%s", key, language);
275 av_dict_set(&c->fc->metadata, key2, buf, 0);
277 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
278 return av_dict_set(&c->fc->metadata, key, buf, 0);
281 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
287 if (c->ignore_chapters)
290 n_hmmt = avio_rb32(pb);
291 if (n_hmmt > len / 4)
292 return AVERROR_INVALIDDATA;
293 for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
294 int moment_time = avio_rb32(pb);
295 avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
300 static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
302 char tmp_key[AV_FOURCC_MAX_STRING_SIZE] = {0};
303 char key2[32], language[4] = {0};
305 const char *key = NULL;
306 uint16_t langcode = 0;
307 uint32_t data_type = 0, str_size, str_size_alloc;
308 int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
313 case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
314 case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
315 case MKTAG( 'X','M','P','_'):
316 if (c->export_xmp) { key = "xmp"; raw = 1; } break;
317 case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
318 case MKTAG( 'a','k','I','D'): key = "account_type";
319 parse = mov_metadata_int8_no_padding; break;
320 case MKTAG( 'a','p','I','D'): key = "account_id"; break;
321 case MKTAG( 'c','a','t','g'): key = "category"; break;
322 case MKTAG( 'c','p','i','l'): key = "compilation";
323 parse = mov_metadata_int8_no_padding; break;
324 case MKTAG( 'c','p','r','t'): key = "copyright"; break;
325 case MKTAG( 'd','e','s','c'): key = "description"; break;
326 case MKTAG( 'd','i','s','k'): key = "disc";
327 parse = mov_metadata_track_or_disc_number; break;
328 case MKTAG( 'e','g','i','d'): key = "episode_uid";
329 parse = mov_metadata_int8_no_padding; break;
330 case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
331 case MKTAG( 'g','n','r','e'): key = "genre";
332 parse = mov_metadata_gnre; break;
333 case MKTAG( 'h','d','v','d'): key = "hd_video";
334 parse = mov_metadata_int8_no_padding; break;
335 case MKTAG( 'H','M','M','T'):
336 return mov_metadata_hmmt(c, pb, atom.size);
337 case MKTAG( 'k','e','y','w'): key = "keywords"; break;
338 case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
339 case MKTAG( 'l','o','c','i'):
340 return mov_metadata_loci(c, pb, atom.size);
341 case MKTAG( 'm','a','n','u'): key = "make"; break;
342 case MKTAG( 'm','o','d','l'): key = "model"; break;
343 case MKTAG( 'p','c','s','t'): key = "podcast";
344 parse = mov_metadata_int8_no_padding; break;
345 case MKTAG( 'p','g','a','p'): key = "gapless_playback";
346 parse = mov_metadata_int8_no_padding; break;
347 case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
348 case MKTAG( 'r','t','n','g'): key = "rating";
349 parse = mov_metadata_int8_no_padding; break;
350 case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
351 case MKTAG( 's','o','a','l'): key = "sort_album"; break;
352 case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
353 case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
354 case MKTAG( 's','o','n','m'): key = "sort_name"; break;
355 case MKTAG( 's','o','s','n'): key = "sort_show"; break;
356 case MKTAG( 's','t','i','k'): key = "media_type";
357 parse = mov_metadata_int8_no_padding; break;
358 case MKTAG( 't','r','k','n'): key = "track";
359 parse = mov_metadata_track_or_disc_number; break;
360 case MKTAG( 't','v','e','n'): key = "episode_id"; break;
361 case MKTAG( 't','v','e','s'): key = "episode_sort";
362 parse = mov_metadata_int8_bypass_padding; break;
363 case MKTAG( 't','v','n','n'): key = "network"; break;
364 case MKTAG( 't','v','s','h'): key = "show"; break;
365 case MKTAG( 't','v','s','n'): key = "season_number";
366 parse = mov_metadata_int8_bypass_padding; break;
367 case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
368 case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
369 case MKTAG(0xa9,'a','l','b'): key = "album"; break;
370 case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
371 case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
372 case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
373 case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
374 case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
375 case MKTAG(0xa9,'d','a','y'): key = "date"; break;
376 case MKTAG(0xa9,'d','i','r'): key = "director"; break;
377 case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
378 case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
379 case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
380 case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
381 case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
382 case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
383 case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
384 case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
385 case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
386 case MKTAG(0xa9,'m','a','k'): key = "make"; break;
387 case MKTAG(0xa9,'m','o','d'): key = "model"; break;
388 case MKTAG(0xa9,'n','a','m'): key = "title"; break;
389 case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
390 case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
391 case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
392 case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
393 case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
394 case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
395 case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
396 case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
397 case MKTAG(0xa9,'t','r','k'): key = "track"; break;
398 case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
399 case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
400 case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
401 case MKTAG(0xa9,'x','y','z'): key = "location"; break;
404 if (c->itunes_metadata && atom.size > 8) {
405 int data_size = avio_rb32(pb);
406 int tag = avio_rl32(pb);
407 if (tag == MKTAG('d','a','t','a') && data_size <= atom.size && data_size >= 16) {
408 data_type = avio_rb32(pb); // type
409 avio_rb32(pb); // unknown
410 str_size = data_size - 16;
413 if (atom.type == MKTAG('c', 'o', 'v', 'r')) {
414 int ret = mov_read_covr(c, pb, data_type, str_size);
416 av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
419 atom.size -= str_size;
423 } else if (!key && c->found_hdlr_mdta && c->meta_keys) {
424 uint32_t index = AV_RB32(&atom.type);
425 if (index < c->meta_keys_count && index > 0) {
426 key = c->meta_keys[index];
428 av_log(c->fc, AV_LOG_WARNING,
429 "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
430 index, c->meta_keys_count);
434 } else if (atom.size > 4 && key && !c->itunes_metadata && !raw) {
435 str_size = avio_rb16(pb); // string length
436 if (str_size > atom.size) {
438 avio_seek(pb, -2, SEEK_CUR);
439 av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
442 langcode = avio_rb16(pb);
443 ff_mov_lang_to_iso639(langcode, language);
446 str_size = atom.size;
448 if (c->export_all && !key) {
449 key = av_fourcc_make_string(tmp_key, atom.type);
454 if (atom.size < 0 || str_size >= INT_MAX/2)
455 return AVERROR_INVALIDDATA;
457 // Allocates enough space if data_type is a int32 or float32 number, otherwise
458 // worst-case requirement for output string in case of utf8 coded input
459 num = (data_type >= 21 && data_type <= 23);
460 str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
461 str = av_mallocz(str_size_alloc);
463 return AVERROR(ENOMEM);
466 parse(c, pb, str_size, key);
468 if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
469 mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
470 } else if (data_type == 21) { // BE signed integer, variable size
473 val = (int8_t)avio_r8(pb);
474 else if (str_size == 2)
475 val = (int16_t)avio_rb16(pb);
476 else if (str_size == 3)
477 val = ((int32_t)(avio_rb24(pb)<<8))>>8;
478 else if (str_size == 4)
479 val = (int32_t)avio_rb32(pb);
480 if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
481 av_log(c->fc, AV_LOG_ERROR,
482 "Failed to store the number (%d) in string.\n", val);
484 return AVERROR_INVALIDDATA;
486 } else if (data_type == 22) { // BE unsigned integer, variable size
487 unsigned int val = 0;
490 else if (str_size == 2)
492 else if (str_size == 3)
494 else if (str_size == 4)
496 if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
497 av_log(c->fc, AV_LOG_ERROR,
498 "Failed to store the number (%u) in string.\n", val);
500 return AVERROR_INVALIDDATA;
502 } else if (data_type == 23 && str_size >= 4) { // BE float32
503 float val = av_int2float(avio_rb32(pb));
504 if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
505 av_log(c->fc, AV_LOG_ERROR,
506 "Failed to store the float32 number (%f) in string.\n", val);
508 return AVERROR_INVALIDDATA;
511 int ret = ffio_read_size(pb, str, str_size);
518 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
519 av_dict_set(&c->fc->metadata, key, str, 0);
520 if (*language && strcmp(language, "und")) {
521 snprintf(key2, sizeof(key2), "%s-%s", key, language);
522 av_dict_set(&c->fc->metadata, key2, str, 0);
524 if (!strcmp(key, "encoder")) {
525 int major, minor, micro;
526 if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, µ) == 3) {
527 c->handbrake_version = 1000000*major + 1000*minor + micro;
536 static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
539 int i, nb_chapters, str_len, version;
543 if (c->ignore_chapters)
546 if ((atom.size -= 5) < 0)
549 version = avio_r8(pb);
552 avio_rb32(pb); // ???
553 nb_chapters = avio_r8(pb);
555 for (i = 0; i < nb_chapters; i++) {
559 start = avio_rb64(pb);
560 str_len = avio_r8(pb);
562 if ((atom.size -= 9+str_len) < 0)
565 ret = ffio_read_size(pb, str, str_len);
569 avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
574 #define MIN_DATA_ENTRY_BOX_SIZE 12
575 static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
578 MOVStreamContext *sc;
581 if (c->fc->nb_streams < 1)
583 st = c->fc->streams[c->fc->nb_streams-1];
586 avio_rb32(pb); // version + flags
587 entries = avio_rb32(pb);
589 entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
590 entries >= UINT_MAX / sizeof(*sc->drefs))
591 return AVERROR_INVALIDDATA;
593 for (i = 0; i < sc->drefs_count; i++) {
594 MOVDref *dref = &sc->drefs[i];
595 av_freep(&dref->path);
596 av_freep(&dref->dir);
600 sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
602 return AVERROR(ENOMEM);
603 sc->drefs_count = entries;
605 for (i = 0; i < entries; i++) {
606 MOVDref *dref = &sc->drefs[i];
607 uint32_t size = avio_rb32(pb);
608 int64_t next = avio_tell(pb) + size - 4;
611 return AVERROR_INVALIDDATA;
613 dref->type = avio_rl32(pb);
614 avio_rb32(pb); // version + flags
616 if (dref->type == MKTAG('a','l','i','s') && size > 150) {
617 /* macintosh alias record */
618 uint16_t volume_len, len;
624 volume_len = avio_r8(pb);
625 volume_len = FFMIN(volume_len, 27);
626 ret = ffio_read_size(pb, dref->volume, 27);
629 dref->volume[volume_len] = 0;
630 av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
635 len = FFMIN(len, 63);
636 ret = ffio_read_size(pb, dref->filename, 63);
639 dref->filename[len] = 0;
640 av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
644 /* read next level up_from_alias/down_to_target */
645 dref->nlvl_from = avio_rb16(pb);
646 dref->nlvl_to = avio_rb16(pb);
647 av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
648 dref->nlvl_from, dref->nlvl_to);
652 for (type = 0; type != -1 && avio_tell(pb) < next; ) {
655 type = avio_rb16(pb);
657 av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
660 if (type == 2) { // absolute path
662 dref->path = av_mallocz(len+1);
664 return AVERROR(ENOMEM);
666 ret = ffio_read_size(pb, dref->path, len);
668 av_freep(&dref->path);
671 if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
673 memmove(dref->path, dref->path+volume_len, len);
676 // trim string of any ending zeros
677 for (j = len - 1; j >= 0; j--) {
678 if (dref->path[j] == 0)
683 for (j = 0; j < len; j++)
684 if (dref->path[j] == ':' || dref->path[j] == 0)
686 av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
687 } else if (type == 0) { // directory name
689 dref->dir = av_malloc(len+1);
691 return AVERROR(ENOMEM);
693 ret = ffio_read_size(pb, dref->dir, len);
695 av_freep(&dref->dir);
699 for (j = 0; j < len; j++)
700 if (dref->dir[j] == ':')
702 av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
707 av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
712 avio_seek(pb, next, SEEK_SET);
717 static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
726 avio_r8(pb); /* version */
727 avio_rb24(pb); /* flags */
730 ctype = avio_rl32(pb);
731 type = avio_rl32(pb); /* component subtype */
733 av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
734 av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
736 if (c->trak_index < 0) { // meta not inside a trak
737 if (type == MKTAG('m','d','t','a')) {
738 c->found_hdlr_mdta = 1;
743 st = c->fc->streams[c->fc->nb_streams-1];
745 if (type == MKTAG('v','i','d','e'))
746 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
747 else if (type == MKTAG('s','o','u','n'))
748 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
749 else if (type == MKTAG('m','1','a',' '))
750 st->codecpar->codec_id = AV_CODEC_ID_MP2;
751 else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
752 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
754 avio_rb32(pb); /* component manufacture */
755 avio_rb32(pb); /* component flags */
756 avio_rb32(pb); /* component flags mask */
758 title_size = atom.size - 24;
759 if (title_size > 0) {
760 if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
761 return AVERROR_INVALIDDATA;
762 title_str = av_malloc(title_size + 1); /* Add null terminator */
764 return AVERROR(ENOMEM);
766 ret = ffio_read_size(pb, title_str, title_size);
768 av_freep(&title_str);
771 title_str[title_size] = 0;
773 int off = (!c->isom && title_str[0] == title_size - 1);
774 // flag added so as to not set stream handler name if already set from mdia->hdlr
775 av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
777 av_freep(&title_str);
783 static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
785 return ff_mov_read_esds(c->fc, pb);
788 static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
791 enum AVAudioServiceType *ast;
792 int ac3info, acmod, lfeon, bsmod;
794 if (c->fc->nb_streams < 1)
796 st = c->fc->streams[c->fc->nb_streams-1];
798 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
801 return AVERROR(ENOMEM);
803 ac3info = avio_rb24(pb);
804 bsmod = (ac3info >> 14) & 0x7;
805 acmod = (ac3info >> 11) & 0x7;
806 lfeon = (ac3info >> 10) & 0x1;
807 st->codecpar->channels = ((int[]){2,1,2,3,3,4,4,5})[acmod] + lfeon;
808 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
810 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
812 if (st->codecpar->channels > 1 && bsmod == 0x7)
813 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
815 #if FF_API_LAVF_AVCTX
816 FF_DISABLE_DEPRECATION_WARNINGS
817 st->codec->audio_service_type = *ast;
818 FF_ENABLE_DEPRECATION_WARNINGS
824 static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
827 enum AVAudioServiceType *ast;
828 int eac3info, acmod, lfeon, bsmod;
830 if (c->fc->nb_streams < 1)
832 st = c->fc->streams[c->fc->nb_streams-1];
834 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
837 return AVERROR(ENOMEM);
839 /* No need to parse fields for additional independent substreams and its
840 * associated dependent substreams since libavcodec's E-AC-3 decoder
841 * does not support them yet. */
842 avio_rb16(pb); /* data_rate and num_ind_sub */
843 eac3info = avio_rb24(pb);
844 bsmod = (eac3info >> 12) & 0x1f;
845 acmod = (eac3info >> 9) & 0x7;
846 lfeon = (eac3info >> 8) & 0x1;
847 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
849 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
850 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
852 if (st->codecpar->channels > 1 && bsmod == 0x7)
853 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
855 #if FF_API_LAVF_AVCTX
856 FF_DISABLE_DEPRECATION_WARNINGS
857 st->codec->audio_service_type = *ast;
858 FF_ENABLE_DEPRECATION_WARNINGS
864 static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
867 uint8_t buf[DDTS_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
869 uint32_t frame_duration_code = 0;
870 uint32_t channel_layout_code = 0;
874 if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
877 init_get_bits(&gb, buf, 8 * DDTS_SIZE);
879 if (c->fc->nb_streams < 1) {
882 st = c->fc->streams[c->fc->nb_streams-1];
884 st->codecpar->sample_rate = get_bits_long(&gb, 32);
885 if (st->codecpar->sample_rate <= 0) {
886 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
887 return AVERROR_INVALIDDATA;
889 skip_bits_long(&gb, 32); /* max bitrate */
890 st->codecpar->bit_rate = get_bits_long(&gb, 32);
891 st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
892 frame_duration_code = get_bits(&gb, 2);
893 skip_bits(&gb, 30); /* various fields */
894 channel_layout_code = get_bits(&gb, 16);
896 st->codecpar->frame_size =
897 (frame_duration_code == 0) ? 512 :
898 (frame_duration_code == 1) ? 1024 :
899 (frame_duration_code == 2) ? 2048 :
900 (frame_duration_code == 3) ? 4096 : 0;
902 if (channel_layout_code > 0xff) {
903 av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout\n");
905 st->codecpar->channel_layout =
906 ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
907 ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
908 ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
909 ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
910 ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
911 ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0);
913 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
918 static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
922 if (c->fc->nb_streams < 1)
924 st = c->fc->streams[c->fc->nb_streams-1];
929 /* skip version and flags */
932 ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
937 static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
942 if (c->fc->nb_streams < 1)
944 st = c->fc->streams[c->fc->nb_streams-1];
946 if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
947 av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
952 static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
954 const int num = avio_rb32(pb);
955 const int den = avio_rb32(pb);
958 if (c->fc->nb_streams < 1)
960 st = c->fc->streams[c->fc->nb_streams-1];
962 if ((st->sample_aspect_ratio.den != 1 || st->sample_aspect_ratio.num) && // default
963 (den != st->sample_aspect_ratio.den || num != st->sample_aspect_ratio.num)) {
964 av_log(c->fc, AV_LOG_WARNING,
965 "sample aspect ratio already set to %d:%d, ignoring 'pasp' atom (%d:%d)\n",
966 st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
968 } else if (den != 0) {
969 av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den,
975 /* this atom contains actual media data */
976 static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
978 if (atom.size == 0) /* wrong one (MP4) */
981 return 0; /* now go for moov */
984 #define DRM_BLOB_SIZE 56
986 static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
988 uint8_t intermediate_key[20];
989 uint8_t intermediate_iv[20];
992 uint8_t file_checksum[20];
993 uint8_t calculated_checksum[20];
997 uint8_t *activation_bytes = c->activation_bytes;
998 uint8_t *fixed_key = c->audible_fixed_key;
1002 sha = av_sha_alloc();
1004 return AVERROR(ENOMEM);
1005 av_free(c->aes_decrypt);
1006 c->aes_decrypt = av_aes_alloc();
1007 if (!c->aes_decrypt) {
1008 ret = AVERROR(ENOMEM);
1012 /* drm blob processing */
1013 avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1014 avio_read(pb, input, DRM_BLOB_SIZE);
1015 avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1016 avio_read(pb, file_checksum, 20);
1018 av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == "); // required by external tools
1019 for (i = 0; i < 20; i++)
1020 av_log(c->fc, AV_LOG_INFO, "%02x", file_checksum[i]);
1021 av_log(c->fc, AV_LOG_INFO, "\n");
1023 /* verify activation data */
1024 if (!activation_bytes) {
1025 av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1026 ret = 0; /* allow ffprobe to continue working on .aax files */
1029 if (c->activation_bytes_size != 4) {
1030 av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1031 ret = AVERROR(EINVAL);
1035 /* verify fixed key */
1036 if (c->audible_fixed_key_size != 16) {
1037 av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1038 ret = AVERROR(EINVAL);
1042 /* AAX (and AAX+) key derivation */
1043 av_sha_init(sha, 160);
1044 av_sha_update(sha, fixed_key, 16);
1045 av_sha_update(sha, activation_bytes, 4);
1046 av_sha_final(sha, intermediate_key);
1047 av_sha_init(sha, 160);
1048 av_sha_update(sha, fixed_key, 16);
1049 av_sha_update(sha, intermediate_key, 20);
1050 av_sha_update(sha, activation_bytes, 4);
1051 av_sha_final(sha, intermediate_iv);
1052 av_sha_init(sha, 160);
1053 av_sha_update(sha, intermediate_key, 16);
1054 av_sha_update(sha, intermediate_iv, 16);
1055 av_sha_final(sha, calculated_checksum);
1056 if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1057 av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1058 ret = AVERROR_INVALIDDATA;
1061 av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1062 av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1063 for (i = 0; i < 4; i++) {
1064 // file data (in output) is stored in big-endian mode
1065 if (activation_bytes[i] != output[3 - i]) { // critical error
1066 av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1067 ret = AVERROR_INVALIDDATA;
1071 memcpy(c->file_key, output + 8, 16);
1072 memcpy(input, output + 26, 16);
1073 av_sha_init(sha, 160);
1074 av_sha_update(sha, input, 16);
1075 av_sha_update(sha, c->file_key, 16);
1076 av_sha_update(sha, fixed_key, 16);
1077 av_sha_final(sha, c->file_iv);
1085 static int mov_aaxc_crypto(MOVContext *c)
1087 if (c->audible_key_size != 16) {
1088 av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
1089 return AVERROR(EINVAL);
1092 if (c->audible_iv_size != 16) {
1093 av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
1094 return AVERROR(EINVAL);
1097 c->aes_decrypt = av_aes_alloc();
1098 if (!c->aes_decrypt) {
1099 return AVERROR(ENOMEM);
1102 memcpy(c->file_key, c->audible_key, 16);
1103 memcpy(c->file_iv, c->audible_iv, 16);
1109 // Audible AAX (and AAX+) bytestream decryption
1110 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1113 unsigned char iv[16];
1115 memcpy(iv, c->file_iv, 16); // iv is overwritten
1116 blocks = size >> 4; // trailing bytes are not encrypted!
1117 av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1118 av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1123 /* read major brand, minor version and compatible brands and store them as metadata */
1124 static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1127 int comp_brand_size;
1128 char* comp_brands_str;
1129 uint8_t type[5] = {0};
1130 int ret = ffio_read_size(pb, type, 4);
1134 if (strcmp(type, "qt "))
1136 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1137 av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1138 minor_ver = avio_rb32(pb); /* minor version */
1139 av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1141 comp_brand_size = atom.size - 8;
1142 if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1143 return AVERROR_INVALIDDATA;
1144 comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1145 if (!comp_brands_str)
1146 return AVERROR(ENOMEM);
1148 ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1150 av_freep(&comp_brands_str);
1153 comp_brands_str[comp_brand_size] = 0;
1154 av_dict_set(&c->fc->metadata, "compatible_brands",
1155 comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1157 // Logic for handling Audible's .aaxc files
1158 if (!strcmp(type, "aaxc")) {
1165 /* this atom should contain all header atoms */
1166 static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1170 if (c->found_moov) {
1171 av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1172 avio_skip(pb, atom.size);
1176 if ((ret = mov_read_default(c, pb, atom)) < 0)
1178 /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1179 /* so we don't parse the whole file if over a network */
1181 return 0; /* now go for mdat */
1184 static MOVFragmentStreamInfo * get_frag_stream_info(
1185 MOVFragmentIndex *frag_index,
1190 MOVFragmentIndexItem * item;
1192 if (index < 0 || index >= frag_index->nb_items)
1194 item = &frag_index->item[index];
1195 for (i = 0; i < item->nb_stream_info; i++)
1196 if (item->stream_info[i].id == id)
1197 return &item->stream_info[i];
1199 // This shouldn't happen
1203 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1206 MOVFragmentIndexItem * item;
1208 if (frag_index->current < 0 ||
1209 frag_index->current >= frag_index->nb_items)
1212 item = &frag_index->item[frag_index->current];
1213 for (i = 0; i < item->nb_stream_info; i++)
1214 if (item->stream_info[i].id == id) {
1219 // id not found. This shouldn't happen.
1223 static MOVFragmentStreamInfo * get_current_frag_stream_info(
1224 MOVFragmentIndex *frag_index)
1226 MOVFragmentIndexItem *item;
1227 if (frag_index->current < 0 ||
1228 frag_index->current >= frag_index->nb_items)
1231 item = &frag_index->item[frag_index->current];
1232 if (item->current >= 0 && item->current < item->nb_stream_info)
1233 return &item->stream_info[item->current];
1235 // This shouldn't happen
1239 static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
1242 int64_t moof_offset;
1244 // Optimize for appending new entries
1245 if (!frag_index->nb_items ||
1246 frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1247 return frag_index->nb_items;
1250 b = frag_index->nb_items;
1254 moof_offset = frag_index->item[m].moof_offset;
1255 if (moof_offset >= offset)
1257 if (moof_offset <= offset)
1263 static int64_t get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
1265 av_assert0(frag_stream_info);
1266 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1267 return frag_stream_info->sidx_pts;
1268 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1269 return frag_stream_info->first_tfra_pts;
1270 return frag_stream_info->tfdt_dts;
1273 static int64_t get_frag_time(MOVFragmentIndex *frag_index,
1274 int index, int track_id)
1276 MOVFragmentStreamInfo * frag_stream_info;
1280 if (track_id >= 0) {
1281 frag_stream_info = get_frag_stream_info(frag_index, index, track_id);
1282 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1283 return frag_stream_info->sidx_pts;
1284 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1285 return frag_stream_info->first_tfra_pts;
1286 return frag_stream_info->sidx_pts;
1289 for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1290 frag_stream_info = &frag_index->item[index].stream_info[i];
1291 timestamp = get_stream_info_time(frag_stream_info);
1292 if (timestamp != AV_NOPTS_VALUE)
1295 return AV_NOPTS_VALUE;
1298 static int search_frag_timestamp(MOVFragmentIndex *frag_index,
1299 AVStream *st, int64_t timestamp)
1306 // If the stream is referenced by any sidx, limit the search
1307 // to fragments that referenced this stream in the sidx
1308 MOVStreamContext *sc = st->priv_data;
1314 b = frag_index->nb_items;
1317 m0 = m = (a + b) >> 1;
1320 (frag_time = get_frag_time(frag_index, m, id)) == AV_NOPTS_VALUE)
1323 if (m < b && frag_time <= timestamp)
1332 static int update_frag_index(MOVContext *c, int64_t offset)
1335 MOVFragmentIndexItem * item;
1336 MOVFragmentStreamInfo * frag_stream_info;
1338 // If moof_offset already exists in frag_index, return index to it
1339 index = search_frag_moof_offset(&c->frag_index, offset);
1340 if (index < c->frag_index.nb_items &&
1341 c->frag_index.item[index].moof_offset == offset)
1344 // offset is not yet in frag index.
1345 // Insert new item at index (sorted by moof offset)
1346 item = av_fast_realloc(c->frag_index.item,
1347 &c->frag_index.allocated_size,
1348 (c->frag_index.nb_items + 1) *
1349 sizeof(*c->frag_index.item));
1352 c->frag_index.item = item;
1354 frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1355 sizeof(*item->stream_info));
1356 if (!frag_stream_info)
1359 for (i = 0; i < c->fc->nb_streams; i++) {
1360 // Avoid building frag index if streams lack track id.
1361 if (c->fc->streams[i]->id < 0) {
1362 av_free(frag_stream_info);
1363 return AVERROR_INVALIDDATA;
1366 frag_stream_info[i].id = c->fc->streams[i]->id;
1367 frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1368 frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1369 frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1370 frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1371 frag_stream_info[i].index_entry = -1;
1372 frag_stream_info[i].encryption_index = NULL;
1375 if (index < c->frag_index.nb_items)
1376 memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1377 (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1379 item = &c->frag_index.item[index];
1380 item->headers_read = 0;
1382 item->nb_stream_info = c->fc->nb_streams;
1383 item->moof_offset = offset;
1384 item->stream_info = frag_stream_info;
1385 c->frag_index.nb_items++;
1390 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1391 int id, int entries)
1394 MOVFragmentStreamInfo * frag_stream_info;
1398 for (i = index; i < frag_index->nb_items; i++) {
1399 frag_stream_info = get_frag_stream_info(frag_index, i, id);
1400 if (frag_stream_info && frag_stream_info->index_entry >= 0)
1401 frag_stream_info->index_entry += entries;
1405 static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1407 // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1408 c->fragment.found_tfhd = 0;
1410 if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1411 c->has_looked_for_mfra = 1;
1412 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1414 av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1416 if ((ret = mov_read_mfra(c, pb)) < 0) {
1417 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1418 "read the mfra (may be a live ismv)\n");
1421 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1422 "seekable, can not look for mfra\n");
1425 c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1426 av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1427 c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1428 return mov_read_default(c, pb, atom);
1431 static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time, void *logctx)
1434 if (time >= 2082844800)
1435 time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1437 if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1438 av_log(logctx, AV_LOG_DEBUG, "creation_time is not representable\n");
1442 avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1446 static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1449 MOVStreamContext *sc;
1451 char language[4] = {0};
1453 int64_t creation_time;
1455 if (c->fc->nb_streams < 1)
1457 st = c->fc->streams[c->fc->nb_streams-1];
1460 if (sc->time_scale) {
1461 av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1462 return AVERROR_INVALIDDATA;
1465 version = avio_r8(pb);
1467 avpriv_request_sample(c->fc, "Version %d", version);
1468 return AVERROR_PATCHWELCOME;
1470 avio_rb24(pb); /* flags */
1472 creation_time = avio_rb64(pb);
1475 creation_time = avio_rb32(pb);
1476 avio_rb32(pb); /* modification time */
1478 mov_metadata_creation_time(&st->metadata, creation_time, c->fc);
1480 sc->time_scale = avio_rb32(pb);
1481 if (sc->time_scale <= 0) {
1482 av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1485 st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1487 lang = avio_rb16(pb); /* language */
1488 if (ff_mov_lang_to_iso639(lang, language))
1489 av_dict_set(&st->metadata, "language", language, 0);
1490 avio_rb16(pb); /* quality */
1495 static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1498 int64_t creation_time;
1499 int version = avio_r8(pb); /* version */
1500 avio_rb24(pb); /* flags */
1503 creation_time = avio_rb64(pb);
1506 creation_time = avio_rb32(pb);
1507 avio_rb32(pb); /* modification time */
1509 mov_metadata_creation_time(&c->fc->metadata, creation_time, c->fc);
1510 c->time_scale = avio_rb32(pb); /* time scale */
1511 if (c->time_scale <= 0) {
1512 av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1515 av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1517 c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1518 // set the AVFormatContext duration because the duration of individual tracks
1519 // may be inaccurate
1521 c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale);
1522 avio_rb32(pb); /* preferred scale */
1524 avio_rb16(pb); /* preferred volume */
1526 avio_skip(pb, 10); /* reserved */
1528 /* movie display matrix, store it in main context and use it later on */
1529 for (i = 0; i < 3; i++) {
1530 c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1531 c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1532 c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1535 avio_rb32(pb); /* preview time */
1536 avio_rb32(pb); /* preview duration */
1537 avio_rb32(pb); /* poster time */
1538 avio_rb32(pb); /* selection time */
1539 avio_rb32(pb); /* selection duration */
1540 avio_rb32(pb); /* current time */
1541 avio_rb32(pb); /* next track ID */
1546 static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1551 if (c->fc->nb_streams < 1)
1553 st = c->fc->streams[c->fc->nb_streams-1];
1555 little_endian = avio_rb16(pb) & 0xFF;
1556 av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1557 if (little_endian == 1) {
1558 switch (st->codecpar->codec_id) {
1559 case AV_CODEC_ID_PCM_S24BE:
1560 st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE;
1562 case AV_CODEC_ID_PCM_S32BE:
1563 st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE;
1565 case AV_CODEC_ID_PCM_F32BE:
1566 st->codecpar->codec_id = AV_CODEC_ID_PCM_F32LE;
1568 case AV_CODEC_ID_PCM_F64BE:
1569 st->codecpar->codec_id = AV_CODEC_ID_PCM_F64LE;
1578 static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1581 uint8_t *icc_profile;
1582 char color_parameter_type[5] = { 0 };
1583 uint16_t color_primaries, color_trc, color_matrix;
1586 if (c->fc->nb_streams < 1)
1588 st = c->fc->streams[c->fc->nb_streams - 1];
1590 ret = ffio_read_size(pb, color_parameter_type, 4);
1593 if (strncmp(color_parameter_type, "nclx", 4) &&
1594 strncmp(color_parameter_type, "nclc", 4) &&
1595 strncmp(color_parameter_type, "prof", 4)) {
1596 av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
1597 color_parameter_type);
1601 if (!strncmp(color_parameter_type, "prof", 4)) {
1602 icc_profile = av_stream_new_side_data(st, AV_PKT_DATA_ICC_PROFILE, atom.size - 4);
1604 return AVERROR(ENOMEM);
1605 ret = ffio_read_size(pb, icc_profile, atom.size - 4);
1609 color_primaries = avio_rb16(pb);
1610 color_trc = avio_rb16(pb);
1611 color_matrix = avio_rb16(pb);
1613 av_log(c->fc, AV_LOG_TRACE,
1614 "%s: pri %d trc %d matrix %d",
1615 color_parameter_type, color_primaries, color_trc, color_matrix);
1617 if (!strncmp(color_parameter_type, "nclx", 4)) {
1618 uint8_t color_range = avio_r8(pb) >> 7;
1619 av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
1621 st->codecpar->color_range = AVCOL_RANGE_JPEG;
1623 st->codecpar->color_range = AVCOL_RANGE_MPEG;
1626 if (!av_color_primaries_name(color_primaries))
1627 color_primaries = AVCOL_PRI_UNSPECIFIED;
1628 if (!av_color_transfer_name(color_trc))
1629 color_trc = AVCOL_TRC_UNSPECIFIED;
1630 if (!av_color_space_name(color_matrix))
1631 color_matrix = AVCOL_SPC_UNSPECIFIED;
1633 st->codecpar->color_primaries = color_primaries;
1634 st->codecpar->color_trc = color_trc;
1635 st->codecpar->color_space = color_matrix;
1636 av_log(c->fc, AV_LOG_TRACE, "\n");
1641 static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1644 unsigned mov_field_order;
1645 enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
1647 if (c->fc->nb_streams < 1) // will happen with jp2 files
1649 st = c->fc->streams[c->fc->nb_streams-1];
1651 return AVERROR_INVALIDDATA;
1652 mov_field_order = avio_rb16(pb);
1653 if ((mov_field_order & 0xFF00) == 0x0100)
1654 decoded_field_order = AV_FIELD_PROGRESSIVE;
1655 else if ((mov_field_order & 0xFF00) == 0x0200) {
1656 switch (mov_field_order & 0xFF) {
1657 case 0x01: decoded_field_order = AV_FIELD_TT;
1659 case 0x06: decoded_field_order = AV_FIELD_BB;
1661 case 0x09: decoded_field_order = AV_FIELD_TB;
1663 case 0x0E: decoded_field_order = AV_FIELD_BT;
1667 if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
1668 av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
1670 st->codecpar->field_order = decoded_field_order;
1675 static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
1678 uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
1679 if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
1680 return AVERROR_INVALIDDATA;
1681 if ((err = av_reallocp(&par->extradata, size)) < 0) {
1682 par->extradata_size = 0;
1685 par->extradata_size = size - AV_INPUT_BUFFER_PADDING_SIZE;
1689 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
1690 static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1691 AVCodecParameters *par, uint8_t *buf)
1693 int64_t result = atom.size;
1696 AV_WB32(buf , atom.size + 8);
1697 AV_WL32(buf + 4, atom.type);
1698 err = ffio_read_size(pb, buf + 8, atom.size);
1700 par->extradata_size -= atom.size;
1702 } else if (err < atom.size) {
1703 av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
1704 par->extradata_size -= atom.size - err;
1707 memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1711 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
1712 static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1713 enum AVCodecID codec_id)
1716 uint64_t original_size;
1719 if (c->fc->nb_streams < 1) // will happen with jp2 files
1721 st = c->fc->streams[c->fc->nb_streams-1];
1723 if (st->codecpar->codec_id != codec_id)
1724 return 0; /* unexpected codec_id - don't mess with extradata */
1726 original_size = st->codecpar->extradata_size;
1727 err = mov_realloc_extradata(st->codecpar, atom);
1731 err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
1734 return 0; // Note: this is the original behavior to ignore truncation.
1737 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
1738 static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1740 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
1743 static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1745 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS);
1748 static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1750 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
1753 static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1755 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
1758 static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1760 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
1762 ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
1766 static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1768 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
1770 if (!ret && c->fc->nb_streams >= 1) {
1771 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1772 if (par->extradata_size >= 40) {
1773 par->height = AV_RB16(&par->extradata[36]);
1774 par->width = AV_RB16(&par->extradata[38]);
1780 static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1782 if (c->fc->nb_streams >= 1) {
1783 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1784 if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
1785 par->codec_id == AV_CODEC_ID_H264 &&
1789 cid = avio_rb16(pb);
1790 /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
1791 if (cid == 0xd4d || cid == 0xd4e)
1794 } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
1795 par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
1796 par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
1800 num = avio_rb32(pb);
1801 den = avio_rb32(pb);
1802 if (num <= 0 || den <= 0)
1804 switch (avio_rb32(pb)) {
1806 if (den >= INT_MAX / 2)
1810 c->fc->streams[c->fc->nb_streams-1]->internal->display_aspect_ratio.num = num;
1811 c->fc->streams[c->fc->nb_streams-1]->internal->display_aspect_ratio.den = den;
1818 return mov_read_avid(c, pb, atom);
1821 static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1825 uint64_t original_size;
1826 if (c->fc->nb_streams >= 1) {
1827 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1828 if (par->codec_id == AV_CODEC_ID_H264)
1830 if (atom.size == 16) {
1831 original_size = par->extradata_size;
1832 ret = mov_realloc_extradata(par, atom);
1834 length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
1835 if (length == atom.size) {
1836 const uint8_t range_value = par->extradata[original_size + 19];
1837 switch (range_value) {
1839 par->color_range = AVCOL_RANGE_MPEG;
1842 par->color_range = AVCOL_RANGE_JPEG;
1845 av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
1848 ff_dlog(c->fc, "color_range: %d\n", par->color_range);
1850 /* For some reason the whole atom was not added to the extradata */
1851 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
1854 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
1857 av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
1864 static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1866 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
1869 static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1874 if (c->fc->nb_streams < 1)
1876 st = c->fc->streams[c->fc->nb_streams-1];
1878 if ((uint64_t)atom.size > (1<<30))
1879 return AVERROR_INVALIDDATA;
1881 if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
1882 st->codecpar->codec_id == AV_CODEC_ID_QDMC ||
1883 st->codecpar->codec_id == AV_CODEC_ID_SPEEX) {
1884 // pass all frma atom to codec, needed at least for QDMC and QDM2
1885 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1888 } else if (atom.size > 8) { /* to read frma, esds atoms */
1889 if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
1891 ret = ffio_ensure_seekback(pb, 8);
1894 buffer = avio_rb64(pb);
1896 if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
1897 && buffer >> 32 <= atom.size
1898 && buffer >> 32 >= 8) {
1901 } else if (!st->codecpar->extradata_size) {
1902 #define ALAC_EXTRADATA_SIZE 36
1903 st->codecpar->extradata = av_mallocz(ALAC_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
1904 if (!st->codecpar->extradata)
1905 return AVERROR(ENOMEM);
1906 st->codecpar->extradata_size = ALAC_EXTRADATA_SIZE;
1907 AV_WB32(st->codecpar->extradata , ALAC_EXTRADATA_SIZE);
1908 AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
1909 AV_WB64(st->codecpar->extradata + 12, buffer);
1910 avio_read(pb, st->codecpar->extradata + 20, 16);
1911 avio_skip(pb, atom.size - 24);
1915 if ((ret = mov_read_default(c, pb, atom)) < 0)
1918 avio_skip(pb, atom.size);
1923 * This function reads atom content and puts data in extradata without tag
1924 * nor size unlike mov_read_extradata.
1926 static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1931 if (c->fc->nb_streams < 1)
1933 st = c->fc->streams[c->fc->nb_streams-1];
1935 if ((uint64_t)atom.size > (1<<30))
1936 return AVERROR_INVALIDDATA;
1938 if (atom.size >= 10) {
1939 // Broken files created by legacy versions of libavformat will
1940 // wrap a whole fiel atom inside of a glbl atom.
1941 unsigned size = avio_rb32(pb);
1942 unsigned type = avio_rl32(pb);
1943 avio_seek(pb, -8, SEEK_CUR);
1944 if (type == MKTAG('f','i','e','l') && size == atom.size)
1945 return mov_read_default(c, pb, atom);
1947 if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
1948 av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
1951 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1954 if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
1955 /* HEVC-based Dolby Vision derived from hvc1.
1956 Happens to match with an identifier
1957 previously utilized for DV. Thus, if we have
1958 the hvcC extradata box available as specified,
1959 set codec to HEVC */
1960 st->codecpar->codec_id = AV_CODEC_ID_HEVC;
1965 static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1968 uint8_t profile_level;
1971 if (c->fc->nb_streams < 1)
1973 st = c->fc->streams[c->fc->nb_streams-1];
1975 if (atom.size >= (1<<28) || atom.size < 7)
1976 return AVERROR_INVALIDDATA;
1978 profile_level = avio_r8(pb);
1979 if ((profile_level & 0xf0) != 0xc0)
1982 avio_seek(pb, 6, SEEK_CUR);
1983 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
1991 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
1992 * but can have extradata appended at the end after the 40 bytes belonging
1995 static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2000 if (c->fc->nb_streams < 1)
2002 if (atom.size <= 40)
2004 st = c->fc->streams[c->fc->nb_streams-1];
2006 if ((uint64_t)atom.size > (1<<30))
2007 return AVERROR_INVALIDDATA;
2010 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2017 static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2020 MOVStreamContext *sc;
2021 unsigned int i, entries;
2023 if (c->trak_index < 0) {
2024 av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2027 if (c->fc->nb_streams < 1)
2029 st = c->fc->streams[c->fc->nb_streams-1];
2032 avio_r8(pb); /* version */
2033 avio_rb24(pb); /* flags */
2035 entries = avio_rb32(pb);
2040 if (sc->chunk_offsets) {
2041 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STCO atom\n");
2044 av_free(sc->chunk_offsets);
2045 sc->chunk_count = 0;
2046 sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2047 if (!sc->chunk_offsets)
2048 return AVERROR(ENOMEM);
2049 sc->chunk_count = entries;
2051 if (atom.type == MKTAG('s','t','c','o'))
2052 for (i = 0; i < entries && !pb->eof_reached; i++)
2053 sc->chunk_offsets[i] = avio_rb32(pb);
2054 else if (atom.type == MKTAG('c','o','6','4'))
2055 for (i = 0; i < entries && !pb->eof_reached; i++)
2056 sc->chunk_offsets[i] = avio_rb64(pb);
2058 return AVERROR_INVALIDDATA;
2060 sc->chunk_count = i;
2062 if (pb->eof_reached) {
2063 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2070 static int mov_codec_id(AVStream *st, uint32_t format)
2072 int id = ff_codec_get_id(ff_codec_movaudio_tags, format);
2075 ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2076 (format & 0xFFFF) == 'T' + ('S' << 8)))
2077 id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format) & 0xFFFF);
2079 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2080 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2081 } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2082 /* skip old ASF MPEG-4 tag */
2083 format && format != MKTAG('m','p','4','s')) {
2084 id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2086 id = ff_codec_get_id(ff_codec_bmp_tags, format);
2088 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
2089 else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2090 (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE &&
2091 st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2092 id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
2094 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
2096 id = ff_codec_get_id(ff_codec_movdata_tags, format);
2100 st->codecpar->codec_tag = format;
2105 static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
2106 AVStream *st, MOVStreamContext *sc)
2108 uint8_t codec_name[32] = { 0 };
2113 /* The first 16 bytes of the video sample description are already
2114 * read in ff_mov_read_stsd_entries() */
2115 stsd_start = avio_tell(pb) - 16;
2117 avio_rb16(pb); /* version */
2118 avio_rb16(pb); /* revision level */
2119 id = avio_rl32(pb); /* vendor */
2120 av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2121 avio_rb32(pb); /* temporal quality */
2122 avio_rb32(pb); /* spatial quality */
2124 st->codecpar->width = avio_rb16(pb); /* width */
2125 st->codecpar->height = avio_rb16(pb); /* height */
2127 avio_rb32(pb); /* horiz resolution */
2128 avio_rb32(pb); /* vert resolution */
2129 avio_rb32(pb); /* data size, always 0 */
2130 avio_rb16(pb); /* frames per samples */
2132 len = avio_r8(pb); /* codec name, pascal string */
2135 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2137 avio_skip(pb, 31 - len);
2140 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2142 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2143 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2144 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2145 st->codecpar->width &= ~1;
2146 st->codecpar->height &= ~1;
2148 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2149 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2150 !strncmp(codec_name, "Sorenson H263", 13))
2151 st->codecpar->codec_id = AV_CODEC_ID_FLV1;
2153 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2155 avio_seek(pb, stsd_start, SEEK_SET);
2157 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2158 st->codecpar->bits_per_coded_sample &= 0x1F;
2159 sc->has_palette = 1;
2163 static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
2164 AVStream *st, MOVStreamContext *sc)
2166 int bits_per_sample, flags;
2167 uint16_t version = avio_rb16(pb);
2169 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2171 avio_rb16(pb); /* revision level */
2172 id = avio_rl32(pb); /* vendor */
2173 av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2175 st->codecpar->channels = avio_rb16(pb); /* channel count */
2176 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2177 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", st->codecpar->channels);
2179 sc->audio_cid = avio_rb16(pb);
2180 avio_rb16(pb); /* packet size = 0 */
2182 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2184 // Read QT version 1 fields. In version 0 these do not exist.
2185 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2187 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2188 (sc->stsd_version == 0 && version > 0)) {
2190 sc->samples_per_frame = avio_rb32(pb);
2191 avio_rb32(pb); /* bytes per packet */
2192 sc->bytes_per_frame = avio_rb32(pb);
2193 avio_rb32(pb); /* bytes per sample */
2194 } else if (version == 2) {
2195 avio_rb32(pb); /* sizeof struct only */
2196 st->codecpar->sample_rate = av_int2double(avio_rb64(pb));
2197 st->codecpar->channels = avio_rb32(pb);
2198 avio_rb32(pb); /* always 0x7F000000 */
2199 st->codecpar->bits_per_coded_sample = avio_rb32(pb);
2201 flags = avio_rb32(pb); /* lpcm format specific flag */
2202 sc->bytes_per_frame = avio_rb32(pb);
2203 sc->samples_per_frame = avio_rb32(pb);
2204 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2205 st->codecpar->codec_id =
2206 ff_mov_get_lpcm_codec_id(st->codecpar->bits_per_coded_sample,
2209 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2210 /* can't correctly handle variable sized packet as audio unit */
2211 switch (st->codecpar->codec_id) {
2212 case AV_CODEC_ID_MP2:
2213 case AV_CODEC_ID_MP3:
2214 st->need_parsing = AVSTREAM_PARSE_FULL;
2220 if (sc->format == 0) {
2221 if (st->codecpar->bits_per_coded_sample == 8)
2222 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2223 else if (st->codecpar->bits_per_coded_sample == 16)
2224 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2227 switch (st->codecpar->codec_id) {
2228 case AV_CODEC_ID_PCM_S8:
2229 case AV_CODEC_ID_PCM_U8:
2230 if (st->codecpar->bits_per_coded_sample == 16)
2231 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16BE;
2233 case AV_CODEC_ID_PCM_S16LE:
2234 case AV_CODEC_ID_PCM_S16BE:
2235 if (st->codecpar->bits_per_coded_sample == 8)
2236 st->codecpar->codec_id = AV_CODEC_ID_PCM_S8;
2237 else if (st->codecpar->bits_per_coded_sample == 24)
2238 st->codecpar->codec_id =
2239 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2240 AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
2241 else if (st->codecpar->bits_per_coded_sample == 32)
2242 st->codecpar->codec_id =
2243 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2244 AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
2246 /* set values for old format before stsd version 1 appeared */
2247 case AV_CODEC_ID_MACE3:
2248 sc->samples_per_frame = 6;
2249 sc->bytes_per_frame = 2 * st->codecpar->channels;
2251 case AV_CODEC_ID_MACE6:
2252 sc->samples_per_frame = 6;
2253 sc->bytes_per_frame = 1 * st->codecpar->channels;
2255 case AV_CODEC_ID_ADPCM_IMA_QT:
2256 sc->samples_per_frame = 64;
2257 sc->bytes_per_frame = 34 * st->codecpar->channels;
2259 case AV_CODEC_ID_GSM:
2260 sc->samples_per_frame = 160;
2261 sc->bytes_per_frame = 33;
2267 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2268 if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->channels <= INT_MAX) {
2269 st->codecpar->bits_per_coded_sample = bits_per_sample;
2270 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->channels;
2274 static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
2275 AVStream *st, MOVStreamContext *sc,
2278 // ttxt stsd contains display flags, justification, background
2279 // color, fonts, and default styles, so fake an atom to read it
2280 MOVAtom fake_atom = { .size = size };
2281 // mp4s contains a regular esds atom
2282 if (st->codecpar->codec_tag != AV_RL32("mp4s"))
2283 mov_read_glbl(c, pb, fake_atom);
2284 st->codecpar->width = sc->width;
2285 st->codecpar->height = sc->height;
2288 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2293 y = (ycbcr >> 16) & 0xFF;
2294 cr = (ycbcr >> 8) & 0xFF;
2297 b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
2298 g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
2299 r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
2301 return (r << 16) | (g << 8) | b;
2304 static int mov_rewrite_dvd_sub_extradata(AVStream *st)
2306 char buf[256] = {0};
2307 uint8_t *src = st->codecpar->extradata;
2310 if (st->codecpar->extradata_size != 64)
2313 if (st->codecpar->width > 0 && st->codecpar->height > 0)
2314 snprintf(buf, sizeof(buf), "size: %dx%d\n",
2315 st->codecpar->width, st->codecpar->height);
2316 av_strlcat(buf, "palette: ", sizeof(buf));
2318 for (i = 0; i < 16; i++) {
2319 uint32_t yuv = AV_RB32(src + i * 4);
2320 uint32_t rgba = yuv_to_rgba(yuv);
2322 av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2325 if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2328 ret = ff_alloc_extradata(st->codecpar, strlen(buf));
2331 memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2336 static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
2337 AVStream *st, MOVStreamContext *sc,
2342 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2343 if ((int)size != size)
2344 return AVERROR(ENOMEM);
2346 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2350 MOVStreamContext *tmcd_ctx = st->priv_data;
2352 val = AV_RB32(st->codecpar->extradata + 4);
2353 tmcd_ctx->tmcd_flags = val;
2354 st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2355 st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2356 #if FF_API_LAVF_AVCTX
2357 FF_DISABLE_DEPRECATION_WARNINGS
2358 st->codec->time_base = av_inv_q(st->avg_frame_rate);
2359 FF_ENABLE_DEPRECATION_WARNINGS
2362 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2363 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2364 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2365 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2366 if (str_size > 0 && size >= (int)str_size + 30 &&
2367 st->codecpar->extradata[30] /* Don't add empty string */) {
2368 char *reel_name = av_malloc(str_size + 1);
2370 return AVERROR(ENOMEM);
2371 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2372 reel_name[str_size] = 0; /* Add null terminator */
2373 av_dict_set(&st->metadata, "reel_name", reel_name,
2374 AV_DICT_DONT_STRDUP_VAL);
2380 /* other codec type, just skip (rtp, mp4s ...) */
2381 avio_skip(pb, size);
2386 static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
2387 AVStream *st, MOVStreamContext *sc)
2389 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2390 !st->codecpar->sample_rate && sc->time_scale > 1)
2391 st->codecpar->sample_rate = sc->time_scale;
2393 /* special codec parameters handling */
2394 switch (st->codecpar->codec_id) {
2395 #if CONFIG_DV_DEMUXER
2396 case AV_CODEC_ID_DVAUDIO:
2397 c->dv_fctx = avformat_alloc_context();
2399 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2400 return AVERROR(ENOMEM);
2402 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2404 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2405 return AVERROR(ENOMEM);
2407 sc->dv_audio_container = 1;
2408 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
2411 /* no ifdef since parameters are always those */
2412 case AV_CODEC_ID_QCELP:
2413 st->codecpar->channels = 1;
2414 // force sample rate for qcelp when not stored in mov
2415 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2416 st->codecpar->sample_rate = 8000;
2417 // FIXME: Why is the following needed for some files?
2418 sc->samples_per_frame = 160;
2419 if (!sc->bytes_per_frame)
2420 sc->bytes_per_frame = 35;
2422 case AV_CODEC_ID_AMR_NB:
2423 st->codecpar->channels = 1;
2424 /* force sample rate for amr, stsd in 3gp does not store sample rate */
2425 st->codecpar->sample_rate = 8000;
2427 case AV_CODEC_ID_AMR_WB:
2428 st->codecpar->channels = 1;
2429 st->codecpar->sample_rate = 16000;
2431 case AV_CODEC_ID_MP2:
2432 case AV_CODEC_ID_MP3:
2433 /* force type after stsd for m1a hdlr */
2434 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2436 case AV_CODEC_ID_GSM:
2437 case AV_CODEC_ID_ADPCM_MS:
2438 case AV_CODEC_ID_ADPCM_IMA_WAV:
2439 case AV_CODEC_ID_ILBC:
2440 case AV_CODEC_ID_MACE3:
2441 case AV_CODEC_ID_MACE6:
2442 case AV_CODEC_ID_QDM2:
2443 st->codecpar->block_align = sc->bytes_per_frame;
2445 case AV_CODEC_ID_ALAC:
2446 if (st->codecpar->extradata_size == 36) {
2447 st->codecpar->channels = AV_RB8 (st->codecpar->extradata + 21);
2448 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2451 case AV_CODEC_ID_AC3:
2452 case AV_CODEC_ID_EAC3:
2453 case AV_CODEC_ID_MPEG1VIDEO:
2454 case AV_CODEC_ID_VC1:
2455 case AV_CODEC_ID_VP8:
2456 case AV_CODEC_ID_VP9:
2457 st->need_parsing = AVSTREAM_PARSE_FULL;
2459 case AV_CODEC_ID_AV1:
2460 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2468 static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
2469 int codec_tag, int format,
2472 int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2475 (codec_tag != format &&
2476 // AVID 1:1 samples with differing data format and codec tag exist
2477 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
2478 // prores is allowed to have differing data format and codec tag
2479 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
2481 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
2482 (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id
2483 : codec_tag != MKTAG('j','p','e','g')))) {
2484 /* Multiple fourcc, we skip JPEG. This is not correct, we should
2485 * export it as a separate AVStream but this needs a few changes
2486 * in the MOV demuxer, patch welcome. */
2488 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
2489 avio_skip(pb, size);
2496 int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
2499 MOVStreamContext *sc;
2500 int pseudo_stream_id;
2502 av_assert0 (c->fc->nb_streams >= 1);
2503 st = c->fc->streams[c->fc->nb_streams-1];
2506 for (pseudo_stream_id = 0;
2507 pseudo_stream_id < entries && !pb->eof_reached;
2508 pseudo_stream_id++) {
2509 //Parsing Sample description table
2511 int ret, dref_id = 1;
2512 MOVAtom a = { AV_RL32("stsd") };
2513 int64_t start_pos = avio_tell(pb);
2514 int64_t size = avio_rb32(pb); /* size */
2515 uint32_t format = avio_rl32(pb); /* data format */
2518 avio_rb32(pb); /* reserved */
2519 avio_rb16(pb); /* reserved */
2520 dref_id = avio_rb16(pb);
2521 } else if (size <= 7) {
2522 av_log(c->fc, AV_LOG_ERROR,
2523 "invalid size %"PRId64" in stsd\n", size);
2524 return AVERROR_INVALIDDATA;
2527 if (mov_skip_multiple_stsd(c, pb, st->codecpar->codec_tag, format,
2528 size - (avio_tell(pb) - start_pos))) {
2533 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
2534 sc->dref_id= dref_id;
2535 sc->format = format;
2537 id = mov_codec_id(st, format);
2539 av_log(c->fc, AV_LOG_TRACE,
2540 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
2541 av_fourcc2str(format), st->codecpar->codec_type);
2543 st->codecpar->codec_id = id;
2544 if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) {
2545 mov_parse_stsd_video(c, pb, st, sc);
2546 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
2547 mov_parse_stsd_audio(c, pb, st, sc);
2548 if (st->codecpar->sample_rate < 0) {
2549 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
2550 return AVERROR_INVALIDDATA;
2552 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
2553 mov_parse_stsd_subtitle(c, pb, st, sc,
2554 size - (avio_tell(pb) - start_pos));
2556 ret = mov_parse_stsd_data(c, pb, st, sc,
2557 size - (avio_tell(pb) - start_pos));
2561 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
2562 a.size = size - (avio_tell(pb) - start_pos);
2564 if ((ret = mov_read_default(c, pb, a)) < 0)
2566 } else if (a.size > 0)
2567 avio_skip(pb, a.size);
2569 if (sc->extradata && st->codecpar->extradata) {
2570 int extra_size = st->codecpar->extradata_size;
2572 /* Move the current stream extradata to the stream context one. */
2573 sc->extradata_size[pseudo_stream_id] = extra_size;
2574 sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
2575 st->codecpar->extradata = NULL;
2576 st->codecpar->extradata_size = 0;
2581 if (pb->eof_reached) {
2582 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
2589 static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2592 MOVStreamContext *sc;
2595 if (c->fc->nb_streams < 1)
2597 st = c->fc->streams[c->fc->nb_streams - 1];
2600 sc->stsd_version = avio_r8(pb);
2601 avio_rb24(pb); /* flags */
2602 entries = avio_rb32(pb);
2604 /* Each entry contains a size (4 bytes) and format (4 bytes). */
2605 if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
2606 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
2607 return AVERROR_INVALIDDATA;
2610 if (sc->extradata) {
2611 av_log(c->fc, AV_LOG_ERROR,
2612 "Duplicate stsd found in this track.\n");
2613 return AVERROR_INVALIDDATA;
2616 /* Prepare space for hosting multiple extradata. */
2617 sc->extradata = av_mallocz_array(entries, sizeof(*sc->extradata));
2619 return AVERROR(ENOMEM);
2621 sc->extradata_size = av_mallocz_array(entries, sizeof(*sc->extradata_size));
2622 if (!sc->extradata_size) {
2623 ret = AVERROR(ENOMEM);
2627 ret = ff_mov_read_stsd_entries(c, pb, entries);
2631 /* Restore back the primary extradata. */
2632 av_freep(&st->codecpar->extradata);
2633 st->codecpar->extradata_size = sc->extradata_size[0];
2634 if (sc->extradata_size[0]) {
2635 st->codecpar->extradata = av_mallocz(sc->extradata_size[0] + AV_INPUT_BUFFER_PADDING_SIZE);
2636 if (!st->codecpar->extradata)
2637 return AVERROR(ENOMEM);
2638 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
2641 return mov_finalize_stsd_codec(c, pb, st, sc);
2643 if (sc->extradata) {
2645 for (j = 0; j < sc->stsd_count; j++)
2646 av_freep(&sc->extradata[j]);
2649 av_freep(&sc->extradata);
2650 av_freep(&sc->extradata_size);
2654 static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2657 MOVStreamContext *sc;
2658 unsigned int i, entries;
2660 if (c->fc->nb_streams < 1)
2662 st = c->fc->streams[c->fc->nb_streams-1];
2665 avio_r8(pb); /* version */
2666 avio_rb24(pb); /* flags */
2668 entries = avio_rb32(pb);
2669 if ((uint64_t)entries * 12 + 4 > atom.size)
2670 return AVERROR_INVALIDDATA;
2672 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
2676 if (sc->stsc_data) {
2677 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n");
2680 av_free(sc->stsc_data);
2682 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
2684 return AVERROR(ENOMEM);
2686 for (i = 0; i < entries && !pb->eof_reached; i++) {
2687 sc->stsc_data[i].first = avio_rb32(pb);
2688 sc->stsc_data[i].count = avio_rb32(pb);
2689 sc->stsc_data[i].id = avio_rb32(pb);
2693 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
2694 int64_t first_min = i + 1;
2695 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
2696 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
2697 sc->stsc_data[i].first < first_min ||
2698 sc->stsc_data[i].count < 1 ||
2699 sc->stsc_data[i].id < 1) {
2700 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);
2701 if (i+1 >= sc->stsc_count) {
2702 if (sc->stsc_data[i].count == 0 && i > 0) {
2706 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
2707 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
2708 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
2709 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
2710 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
2713 av_assert0(sc->stsc_data[i+1].first >= 2);
2714 // We replace this entry by the next valid
2715 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
2716 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
2717 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
2721 if (pb->eof_reached) {
2722 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
2729 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
2731 return index < count - 1;
2734 /* Compute the samples value for the stsc entry at the given index. */
2735 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
2739 if (mov_stsc_index_valid(index, sc->stsc_count))
2740 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
2742 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
2743 av_assert0(sc->stsc_data[index].first <= sc->chunk_count);
2744 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
2747 return sc->stsc_data[index].count * (int64_t)chunk_count;
2750 static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2753 MOVStreamContext *sc;
2754 unsigned i, entries;
2756 if (c->fc->nb_streams < 1)
2758 st = c->fc->streams[c->fc->nb_streams-1];
2761 avio_rb32(pb); // version + flags
2763 entries = avio_rb32(pb);
2765 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
2766 av_free(sc->stps_data);
2768 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
2770 return AVERROR(ENOMEM);
2772 for (i = 0; i < entries && !pb->eof_reached; i++) {
2773 sc->stps_data[i] = avio_rb32(pb);
2778 if (pb->eof_reached) {
2779 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
2786 static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2789 MOVStreamContext *sc;
2790 unsigned int i, entries;
2792 if (c->fc->nb_streams < 1)
2794 st = c->fc->streams[c->fc->nb_streams-1];
2797 avio_r8(pb); /* version */
2798 avio_rb24(pb); /* flags */
2800 entries = avio_rb32(pb);
2802 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
2805 sc->keyframe_absent = 1;
2806 if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
2807 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2811 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
2812 if (entries >= UINT_MAX / sizeof(int))
2813 return AVERROR_INVALIDDATA;
2814 av_freep(&sc->keyframes);
2815 sc->keyframe_count = 0;
2816 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
2818 return AVERROR(ENOMEM);
2820 for (i = 0; i < entries && !pb->eof_reached; i++) {
2821 sc->keyframes[i] = avio_rb32(pb);
2824 sc->keyframe_count = i;
2826 if (pb->eof_reached) {
2827 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
2834 static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2837 MOVStreamContext *sc;
2838 unsigned int i, entries, sample_size, field_size, num_bytes;
2843 if (c->fc->nb_streams < 1)
2845 st = c->fc->streams[c->fc->nb_streams-1];
2848 avio_r8(pb); /* version */
2849 avio_rb24(pb); /* flags */
2851 if (atom.type == MKTAG('s','t','s','z')) {
2852 sample_size = avio_rb32(pb);
2853 if (!sc->sample_size) /* do not overwrite value computed in stsd */
2854 sc->sample_size = sample_size;
2855 sc->stsz_sample_size = sample_size;
2859 avio_rb24(pb); /* reserved */
2860 field_size = avio_r8(pb);
2862 entries = avio_rb32(pb);
2864 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
2866 sc->sample_count = entries;
2870 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
2871 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
2872 return AVERROR_INVALIDDATA;
2877 if (entries >= (UINT_MAX - 4) / field_size)
2878 return AVERROR_INVALIDDATA;
2879 if (sc->sample_sizes)
2880 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
2881 av_free(sc->sample_sizes);
2882 sc->sample_count = 0;
2883 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
2884 if (!sc->sample_sizes)
2885 return AVERROR(ENOMEM);
2887 num_bytes = (entries*field_size+4)>>3;
2889 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
2891 av_freep(&sc->sample_sizes);
2892 return AVERROR(ENOMEM);
2895 ret = ffio_read_size(pb, buf, num_bytes);
2897 av_freep(&sc->sample_sizes);
2899 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
2903 init_get_bits(&gb, buf, 8*num_bytes);
2905 for (i = 0; i < entries && !pb->eof_reached; i++) {
2906 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
2907 if (sc->sample_sizes[i] < 0) {
2909 av_log(c->fc, AV_LOG_ERROR, "Invalid sample size %d\n", sc->sample_sizes[i]);
2910 return AVERROR_INVALIDDATA;
2912 sc->data_size += sc->sample_sizes[i];
2915 sc->sample_count = i;
2919 if (pb->eof_reached) {
2920 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSZ atom\n");
2927 static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2930 MOVStreamContext *sc;
2931 unsigned int i, entries, alloc_size = 0;
2932 int64_t duration = 0;
2933 int64_t total_sample_count = 0;
2935 if (c->fc->nb_streams < 1)
2937 st = c->fc->streams[c->fc->nb_streams-1];
2940 avio_r8(pb); /* version */
2941 avio_rb24(pb); /* flags */
2942 entries = avio_rb32(pb);
2944 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
2945 c->fc->nb_streams-1, entries);
2948 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
2949 av_freep(&sc->stts_data);
2951 if (entries >= INT_MAX / sizeof(*sc->stts_data))
2952 return AVERROR(ENOMEM);
2954 for (i = 0; i < entries && !pb->eof_reached; i++) {
2955 int sample_duration;
2956 unsigned int sample_count;
2957 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
2958 MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
2959 min_entries * sizeof(*sc->stts_data));
2961 av_freep(&sc->stts_data);
2963 return AVERROR(ENOMEM);
2965 sc->stts_count = min_entries;
2966 sc->stts_data = stts_data;
2968 sample_count = avio_rb32(pb);
2969 sample_duration = avio_rb32(pb);
2971 sc->stts_data[i].count= sample_count;
2972 sc->stts_data[i].duration= sample_duration;
2974 av_log(c->fc, AV_LOG_TRACE, "sample_count=%d, sample_duration=%d\n",
2975 sample_count, sample_duration);
2977 duration+=(int64_t)sample_duration*(uint64_t)sample_count;
2978 total_sample_count+=sample_count;
2984 duration <= INT64_MAX - sc->duration_for_fps &&
2985 total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
2986 sc->duration_for_fps += duration;
2987 sc->nb_frames_for_fps += total_sample_count;
2990 if (pb->eof_reached) {
2991 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
2995 st->nb_frames= total_sample_count;
2997 st->duration= FFMIN(st->duration, duration);
2998 sc->track_end = duration;
3002 static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3005 MOVStreamContext *sc;
3008 if (c->fc->nb_streams < 1)
3010 st = c->fc->streams[c->fc->nb_streams - 1];
3013 avio_r8(pb); /* version */
3014 avio_rb24(pb); /* flags */
3015 entries = atom.size - 4;
3017 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3018 c->fc->nb_streams - 1, entries);
3021 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3022 av_freep(&sc->sdtp_data);
3025 sc->sdtp_data = av_malloc(entries);
3027 return AVERROR(ENOMEM);
3029 for (i = 0; i < entries && !pb->eof_reached; i++)
3030 sc->sdtp_data[i] = avio_r8(pb);
3036 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3039 if (duration == INT_MIN) {
3040 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3043 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3047 static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3050 MOVStreamContext *sc;
3051 unsigned int i, entries, ctts_count = 0;
3053 if (c->fc->nb_streams < 1)
3055 st = c->fc->streams[c->fc->nb_streams-1];
3058 avio_r8(pb); /* version */
3059 avio_rb24(pb); /* flags */
3060 entries = avio_rb32(pb);
3062 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3066 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3067 return AVERROR_INVALIDDATA;
3068 av_freep(&sc->ctts_data);
3069 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3071 return AVERROR(ENOMEM);
3073 for (i = 0; i < entries && !pb->eof_reached; i++) {
3074 int count = avio_rb32(pb);
3075 int duration = avio_rb32(pb);
3078 av_log(c->fc, AV_LOG_TRACE,
3079 "ignoring CTTS entry with count=%d duration=%d\n",
3084 add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3087 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3090 if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3091 av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3092 av_freep(&sc->ctts_data);
3098 mov_update_dts_shift(sc, duration, c->fc);
3101 sc->ctts_count = ctts_count;
3103 if (pb->eof_reached) {
3104 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3108 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3113 static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3116 MOVStreamContext *sc;
3117 unsigned int i, entries;
3119 uint32_t grouping_type;
3121 if (c->fc->nb_streams < 1)
3123 st = c->fc->streams[c->fc->nb_streams-1];
3126 version = avio_r8(pb); /* version */
3127 avio_rb24(pb); /* flags */
3128 grouping_type = avio_rl32(pb);
3129 if (grouping_type != MKTAG( 'r','a','p',' '))
3130 return 0; /* only support 'rap ' grouping */
3132 avio_rb32(pb); /* grouping_type_parameter */
3134 entries = avio_rb32(pb);
3138 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP atom\n");
3139 av_free(sc->rap_group);
3140 sc->rap_group_count = 0;
3141 sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group));
3143 return AVERROR(ENOMEM);
3145 for (i = 0; i < entries && !pb->eof_reached; i++) {
3146 sc->rap_group[i].count = avio_rb32(pb); /* sample_count */
3147 sc->rap_group[i].index = avio_rb32(pb); /* group_description_index */
3150 sc->rap_group_count = i;
3152 if (pb->eof_reached) {
3153 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3161 * Get ith edit list entry (media time, duration).
3163 static int get_edit_list_entry(MOVContext *mov,
3164 const MOVStreamContext *msc,
3165 unsigned int edit_list_index,
3166 int64_t *edit_list_media_time,
3167 int64_t *edit_list_duration,
3168 int64_t global_timescale)
3170 if (edit_list_index == msc->elst_count) {
3173 *edit_list_media_time = msc->elst_data[edit_list_index].time;
3174 *edit_list_duration = msc->elst_data[edit_list_index].duration;
3176 /* duration is in global timescale units;convert to msc timescale */
3177 if (global_timescale == 0) {
3178 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3181 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3187 * Find the closest previous frame to the timestamp_pts, in e_old index
3188 * entries. Searching for just any frame / just key frames can be controlled by
3189 * last argument 'flag'.
3190 * Note that if ctts_data is not NULL, we will always search for a key frame
3191 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3192 * return the first frame of the video.
3194 * Here the timestamp_pts is considered to be a presentation timestamp and
3195 * the timestamp of index entries are considered to be decoding timestamps.
3197 * Returns 0 if successful in finding a frame, else returns -1.
3198 * Places the found index corresponding output arg.
3200 * If ctts_old is not NULL, then refines the searched entry by searching
3201 * backwards from the found timestamp, to find the frame with correct PTS.
3203 * Places the found ctts_index and ctts_sample in corresponding output args.
3205 static int find_prev_closest_index(AVStream *st,
3206 AVIndexEntry *e_old,
3210 int64_t timestamp_pts,
3213 int64_t* ctts_index,
3214 int64_t* ctts_sample)
3216 MOVStreamContext *msc = st->priv_data;
3217 AVIndexEntry *e_keep = st->internal->index_entries;
3218 int nb_keep = st->internal->nb_index_entries;
3220 int64_t index_ctts_count;
3224 // If dts_shift > 0, then all the index timestamps will have to be offset by
3225 // at least dts_shift amount to obtain PTS.
3226 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3227 if (msc->dts_shift > 0) {
3228 timestamp_pts -= msc->dts_shift;
3231 st->internal->index_entries = e_old;
3232 st->internal->nb_index_entries = nb_old;
3233 *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3235 // Keep going backwards in the index entries until the timestamp is the same.
3237 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3239 if ((flag & AVSEEK_FLAG_ANY) ||
3240 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3246 // If we have CTTS then refine the search, by searching backwards over PTS
3247 // computed by adding corresponding CTTS durations to index timestamps.
3248 if (ctts_data && *index >= 0) {
3249 av_assert0(ctts_index);
3250 av_assert0(ctts_sample);
3251 // Find out the ctts_index for the found frame.
3254 for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3255 if (*ctts_index < ctts_count) {
3257 if (ctts_data[*ctts_index].count == *ctts_sample) {
3264 while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3265 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3266 // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3267 // compensated by dts_shift above.
3268 if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3269 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3274 if (*ctts_sample == 0) {
3276 if (*ctts_index >= 0)
3277 *ctts_sample = ctts_data[*ctts_index].count - 1;
3284 /* restore AVStream state*/
3285 st->internal->index_entries = e_keep;
3286 st->internal->nb_index_entries = nb_keep;
3287 return *index >= 0 ? 0 : -1;
3291 * Add index entry with the given values, to the end of st->internal->index_entries.
3292 * Returns the new size st->internal->index_entries if successful, else returns -1.
3294 * This function is similar to ff_add_index_entry in libavformat/utils.c
3295 * except that here we are always unconditionally adding an index entry to
3296 * the end, instead of searching the entries list and skipping the add if
3297 * there is an existing entry with the same timestamp.
3298 * This is needed because the mov_fix_index calls this func with the same
3299 * unincremented timestamp for successive discarded frames.
3301 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3302 int size, int distance, int flags)
3304 AVIndexEntry *entries, *ie;
3306 const size_t min_size_needed = (st->internal->nb_index_entries + 1) * sizeof(AVIndexEntry);
3308 // Double the allocation each time, to lower memory fragmentation.
3309 // Another difference from ff_add_index_entry function.
3310 const size_t requested_size =
3311 min_size_needed > st->internal->index_entries_allocated_size ?
3312 FFMAX(min_size_needed, 2 * st->internal->index_entries_allocated_size) :
3315 if (st->internal->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
3318 entries = av_fast_realloc(st->internal->index_entries,
3319 &st->internal->index_entries_allocated_size,
3324 st->internal->index_entries= entries;
3326 index= st->internal->nb_index_entries++;
3327 ie= &entries[index];
3330 ie->timestamp = timestamp;
3331 ie->min_distance= distance;
3338 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3339 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3341 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3342 int64_t* frame_duration_buffer,
3343 int frame_duration_buffer_size) {
3345 av_assert0(end_index >= 0 && end_index <= st->internal->nb_index_entries);
3346 for (i = 0; i < frame_duration_buffer_size; i++) {
3347 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3348 st->internal->index_entries[end_index - 1 - i].timestamp = end_ts;
3353 * Append a new ctts entry to ctts_data.
3354 * Returns the new ctts_count if successful, else returns -1.
3356 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3357 int count, int duration)
3359 MOVStts *ctts_buf_new;
3360 const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVStts);
3361 const size_t requested_size =
3362 min_size_needed > *allocated_size ?
3363 FFMAX(min_size_needed, 2 * (*allocated_size)) :
3366 if ((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
3369 ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3374 *ctts_data = ctts_buf_new;
3376 ctts_buf_new[*ctts_count].count = count;
3377 ctts_buf_new[*ctts_count].duration = duration;
3379 *ctts_count = (*ctts_count) + 1;
3383 #define MAX_REORDER_DELAY 16
3384 static void mov_estimate_video_delay(MOVContext *c, AVStream* st)
3386 MOVStreamContext *msc = st->priv_data;
3389 int ctts_sample = 0;
3390 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3392 int j, r, num_swaps;
3394 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3395 pts_buf[j] = INT64_MIN;
3397 if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3398 st->codecpar->codec_id == AV_CODEC_ID_H264) {
3399 st->codecpar->video_delay = 0;
3400 for (ind = 0; ind < st->internal->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3401 // Point j to the last elem of the buffer and insert the current pts there.
3403 buf_start = (buf_start + 1);
3404 if (buf_start == MAX_REORDER_DELAY + 1)
3407 pts_buf[j] = st->internal->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3409 // The timestamps that are already in the sorted buffer, and are greater than the
3410 // current pts, are exactly the timestamps that need to be buffered to output PTS
3411 // in correct sorted order.
3412 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3413 // can be computed as the maximum no. of swaps any particular timestamp needs to
3414 // go through, to keep this buffer in sorted order.
3416 while (j != buf_start) {
3418 if (r < 0) r = MAX_REORDER_DELAY;
3419 if (pts_buf[j] < pts_buf[r]) {
3420 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3427 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3430 if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3435 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3436 st->codecpar->video_delay, st->index);
3440 static void mov_current_sample_inc(MOVStreamContext *sc)
3442 sc->current_sample++;
3443 sc->current_index++;
3444 if (sc->index_ranges &&
3445 sc->current_index >= sc->current_index_range->end &&
3446 sc->current_index_range->end) {
3447 sc->current_index_range++;
3448 sc->current_index = sc->current_index_range->start;
3452 static void mov_current_sample_dec(MOVStreamContext *sc)
3454 sc->current_sample--;
3455 sc->current_index--;
3456 if (sc->index_ranges &&
3457 sc->current_index < sc->current_index_range->start &&
3458 sc->current_index_range > sc->index_ranges) {
3459 sc->current_index_range--;
3460 sc->current_index = sc->current_index_range->end - 1;
3464 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3468 sc->current_sample = current_sample;
3469 sc->current_index = current_sample;
3470 if (!sc->index_ranges) {
3474 for (sc->current_index_range = sc->index_ranges;
3475 sc->current_index_range->end;
3476 sc->current_index_range++) {
3477 range_size = sc->current_index_range->end - sc->current_index_range->start;
3478 if (range_size > current_sample) {
3479 sc->current_index = sc->current_index_range->start + current_sample;
3482 current_sample -= range_size;
3487 * Fix st->internal->index_entries, so that it contains only the entries (and the entries
3488 * which are needed to decode them) that fall in the edit list time ranges.
3489 * Also fixes the timestamps of the index entries to match the timeline
3490 * specified the edit lists.
3492 static void mov_fix_index(MOVContext *mov, AVStream *st)
3494 MOVStreamContext *msc = st->priv_data;
3495 AVIndexEntry *e_old = st->internal->index_entries;
3496 int nb_old = st->internal->nb_index_entries;
3497 const AVIndexEntry *e_old_end = e_old + nb_old;
3498 const AVIndexEntry *current = NULL;
3499 MOVStts *ctts_data_old = msc->ctts_data;
3500 int64_t ctts_index_old = 0;
3501 int64_t ctts_sample_old = 0;
3502 int64_t ctts_count_old = msc->ctts_count;
3503 int64_t edit_list_media_time = 0;
3504 int64_t edit_list_duration = 0;
3505 int64_t frame_duration = 0;
3506 int64_t edit_list_dts_counter = 0;
3507 int64_t edit_list_dts_entry_end = 0;
3508 int64_t edit_list_start_ctts_sample = 0;
3510 int64_t curr_ctts = 0;
3511 int64_t empty_edits_sum_duration = 0;
3512 int64_t edit_list_index = 0;
3515 int64_t start_dts = 0;
3516 int64_t edit_list_start_encountered = 0;
3517 int64_t search_timestamp = 0;
3518 int64_t* frame_duration_buffer = NULL;
3519 int num_discarded_begin = 0;
3520 int first_non_zero_audio_edit = -1;
3521 int packet_skip_samples = 0;
3522 MOVIndexRange *current_index_range;
3524 int found_keyframe_after_edit = 0;
3525 int found_non_empty_edit = 0;
3527 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
3531 // allocate the index ranges array
3532 msc->index_ranges = av_malloc((msc->elst_count + 1) * sizeof(msc->index_ranges[0]));
3533 if (!msc->index_ranges) {
3534 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
3537 msc->current_index_range = msc->index_ranges;
3538 current_index_range = msc->index_ranges - 1;
3540 // Clean AVStream from traces of old index
3541 st->internal->index_entries = NULL;
3542 st->internal->index_entries_allocated_size = 0;
3543 st->internal->nb_index_entries = 0;
3545 // Clean ctts fields of MOVStreamContext
3546 msc->ctts_data = NULL;
3547 msc->ctts_count = 0;
3548 msc->ctts_index = 0;
3549 msc->ctts_sample = 0;
3550 msc->ctts_allocated_size = 0;
3552 // Reinitialize min_corrected_pts so that it can be computed again.
3553 msc->min_corrected_pts = -1;
3555 // If the dts_shift is positive (in case of negative ctts values in mov),
3556 // then negate the DTS by dts_shift
3557 if (msc->dts_shift > 0) {
3558 edit_list_dts_entry_end -= msc->dts_shift;
3559 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
3562 start_dts = edit_list_dts_entry_end;
3564 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
3565 &edit_list_duration, mov->time_scale)) {
3566 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
3567 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
3569 edit_list_dts_counter = edit_list_dts_entry_end;
3570 edit_list_dts_entry_end += edit_list_duration;
3571 num_discarded_begin = 0;
3572 if (!found_non_empty_edit && edit_list_media_time == -1) {
3573 empty_edits_sum_duration += edit_list_duration;
3576 found_non_empty_edit = 1;
3578 // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
3579 // according to the edit list below.
3580 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3581 if (first_non_zero_audio_edit < 0) {
3582 first_non_zero_audio_edit = 1;
3584 first_non_zero_audio_edit = 0;
3587 if (first_non_zero_audio_edit > 0)
3588 st->internal->skip_samples = msc->start_pad = 0;
3591 // While reordering frame index according to edit list we must handle properly
3592 // the scenario when edit list entry starts from none key frame.
3593 // We find closest previous key frame and preserve it and consequent frames in index.
3594 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
3595 search_timestamp = edit_list_media_time;
3596 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3597 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
3598 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
3599 // edit_list_media_time to cover the decoder delay.
3600 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
3603 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
3604 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3605 av_log(mov->fc, AV_LOG_WARNING,
3606 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
3607 st->index, edit_list_index, search_timestamp);
3608 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
3609 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3610 av_log(mov->fc, AV_LOG_WARNING,
3611 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
3612 st->index, edit_list_index, search_timestamp);
3615 ctts_sample_old = 0;
3618 current = e_old + index;
3619 edit_list_start_ctts_sample = ctts_sample_old;
3621 // Iterate over index and arrange it according to edit list
3622 edit_list_start_encountered = 0;
3623 found_keyframe_after_edit = 0;
3624 for (; current < e_old_end; current++, index++) {
3625 // check if frame outside edit list mark it for discard
3626 frame_duration = (current + 1 < e_old_end) ?
3627 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
3629 flags = current->flags;
3631 // frames (pts) before or after edit list
3632 curr_cts = current->timestamp + msc->dts_shift;
3635 if (ctts_data_old && ctts_index_old < ctts_count_old) {
3636 curr_ctts = ctts_data_old[ctts_index_old].duration;
3637 av_log(mov->fc, AV_LOG_DEBUG, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
3638 curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
3639 curr_cts += curr_ctts;
3641 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
3642 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3643 &msc->ctts_allocated_size,
3644 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3645 ctts_data_old[ctts_index_old].duration) == -1) {
3646 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3648 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3649 ctts_data_old[ctts_index_old].duration);
3653 ctts_sample_old = 0;
3654 edit_list_start_ctts_sample = 0;
3658 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
3659 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
3660 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
3661 first_non_zero_audio_edit > 0) {
3662 packet_skip_samples = edit_list_media_time - curr_cts;
3663 st->internal->skip_samples += packet_skip_samples;
3665 // Shift the index entry timestamp by packet_skip_samples to be correct.
3666 edit_list_dts_counter -= packet_skip_samples;
3667 if (edit_list_start_encountered == 0) {
3668 edit_list_start_encountered = 1;
3669 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
3670 // discarded packets.
3671 if (frame_duration_buffer) {
3672 fix_index_entry_timestamps(st, st->internal->nb_index_entries, edit_list_dts_counter,
3673 frame_duration_buffer, num_discarded_begin);
3674 av_freep(&frame_duration_buffer);
3678 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
3680 flags |= AVINDEX_DISCARD_FRAME;
3681 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
3683 if (edit_list_start_encountered == 0) {
3684 num_discarded_begin++;
3685 frame_duration_buffer = av_realloc(frame_duration_buffer,
3686 num_discarded_begin * sizeof(int64_t));
3687 if (!frame_duration_buffer) {
3688 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
3691 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
3693 // Increment skip_samples for the first non-zero audio edit list
3694 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3695 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
3696 st->internal->skip_samples += frame_duration;
3701 if (msc->min_corrected_pts < 0) {
3702 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
3704 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
3706 if (edit_list_start_encountered == 0) {
3707 edit_list_start_encountered = 1;
3708 // Make timestamps strictly monotonically increasing by rewriting timestamps for
3709 // discarded packets.
3710 if (frame_duration_buffer) {
3711 fix_index_entry_timestamps(st, st->internal->nb_index_entries, edit_list_dts_counter,
3712 frame_duration_buffer, num_discarded_begin);
3713 av_freep(&frame_duration_buffer);
3718 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
3719 current->min_distance, flags) == -1) {
3720 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
3724 // Update the index ranges array
3725 if (current_index_range < msc->index_ranges || index != current_index_range->end) {
3726 current_index_range++;
3727 current_index_range->start = index;
3729 current_index_range->end = index + 1;
3731 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
3732 if (edit_list_start_encountered > 0) {
3733 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
3736 // Break when found first key frame after edit entry completion
3737 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
3738 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
3739 if (ctts_data_old) {
3740 // If we have CTTS and this is the first keyframe after edit elist,
3741 // wait for one more, because there might be trailing B-frames after this I-frame
3742 // that do belong to the edit.
3743 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
3744 found_keyframe_after_edit = 1;
3747 if (ctts_sample_old != 0) {
3748 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3749 &msc->ctts_allocated_size,
3750 ctts_sample_old - edit_list_start_ctts_sample,
3751 ctts_data_old[ctts_index_old].duration) == -1) {
3752 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3753 ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
3754 ctts_data_old[ctts_index_old].duration);
3763 // If there are empty edits, then msc->min_corrected_pts might be positive
3764 // intentionally. So we subtract the sum duration of emtpy edits here.
3765 msc->min_corrected_pts -= empty_edits_sum_duration;
3767 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
3768 // dts by that amount to make the first pts zero.
3769 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
3770 if (msc->min_corrected_pts > 0) {
3771 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
3772 for (i = 0; i < st->internal->nb_index_entries; ++i) {
3773 st->internal->index_entries[i].timestamp -= msc->min_corrected_pts;
3777 // Start time should be equal to zero or the duration of any empty edits.
3778 st->start_time = empty_edits_sum_duration;
3780 // Update av stream length, if it ends up shorter than the track's media duration
3781 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
3782 msc->start_pad = st->internal->skip_samples;
3784 // Free the old index and the old CTTS structures
3786 av_free(ctts_data_old);
3787 av_freep(&frame_duration_buffer);
3789 // Null terminate the index ranges array
3790 current_index_range++;
3791 current_index_range->start = 0;
3792 current_index_range->end = 0;
3793 msc->current_index = msc->index_ranges[0].start;
3796 static void mov_build_index(MOVContext *mov, AVStream *st)
3798 MOVStreamContext *sc = st->priv_data;
3799 int64_t current_offset;
3800 int64_t current_dts = 0;
3801 unsigned int stts_index = 0;
3802 unsigned int stsc_index = 0;
3803 unsigned int stss_index = 0;
3804 unsigned int stps_index = 0;
3806 uint64_t stream_size = 0;
3807 MOVStts *ctts_data_old = sc->ctts_data;
3808 unsigned int ctts_count_old = sc->ctts_count;
3810 if (sc->elst_count) {
3811 int i, edit_start_index = 0, multiple_edits = 0;
3812 int64_t empty_duration = 0; // empty duration of the first edit list entry
3813 int64_t start_time = 0; // start time of the media
3815 for (i = 0; i < sc->elst_count; i++) {
3816 const MOVElst *e = &sc->elst_data[i];
3817 if (i == 0 && e->time == -1) {
3818 /* if empty, the first entry is the start time of the stream
3819 * relative to the presentation itself */
3820 empty_duration = e->duration;
3821 edit_start_index = 1;
3822 } else if (i == edit_start_index && e->time >= 0) {
3823 start_time = e->time;
3829 if (multiple_edits && !mov->advanced_editlist)
3830 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
3831 "Use -advanced_editlist to correctly decode otherwise "
3832 "a/v desync might occur\n");
3834 /* adjust first dts according to edit list */
3835 if ((empty_duration || start_time) && mov->time_scale > 0) {
3837 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
3838 sc->time_offset = start_time - empty_duration;
3839 sc->min_corrected_pts = start_time;
3840 if (!mov->advanced_editlist)
3841 current_dts = -sc->time_offset;
3844 if (!multiple_edits && !mov->advanced_editlist &&
3845 st->codecpar->codec_id == AV_CODEC_ID_AAC && start_time > 0)
3846 sc->start_pad = start_time;
3849 /* only use old uncompressed audio chunk demuxing when stts specifies it */
3850 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3851 sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
3852 unsigned int current_sample = 0;
3853 unsigned int stts_sample = 0;
3854 unsigned int sample_size;
3855 unsigned int distance = 0;
3856 unsigned int rap_group_index = 0;
3857 unsigned int rap_group_sample = 0;
3858 int64_t last_dts = 0;
3859 int64_t dts_correction = 0;
3860 int rap_group_present = sc->rap_group_count && sc->rap_group;
3861 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
3863 current_dts -= sc->dts_shift;
3864 last_dts = current_dts;
3866 if (!sc->sample_count || st->internal->nb_index_entries)
3868 if (sc->sample_count >= UINT_MAX / sizeof(*st->internal->index_entries) - st->internal->nb_index_entries)
3870 if (av_reallocp_array(&st->internal->index_entries,
3871 st->internal->nb_index_entries + sc->sample_count,
3872 sizeof(*st->internal->index_entries)) < 0) {
3873 st->internal->nb_index_entries = 0;
3876 st->internal->index_entries_allocated_size = (st->internal->nb_index_entries + sc->sample_count) * sizeof(*st->internal->index_entries);
3878 if (ctts_data_old) {
3879 // Expand ctts entries such that we have a 1-1 mapping with samples
3880 if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
3883 sc->ctts_allocated_size = 0;
3884 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size,
3885 sc->sample_count * sizeof(*sc->ctts_data));
3886 if (!sc->ctts_data) {
3887 av_free(ctts_data_old);
3891 memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
3893 for (i = 0; i < ctts_count_old &&
3894 sc->ctts_count < sc->sample_count; i++)
3895 for (j = 0; j < ctts_data_old[i].count &&
3896 sc->ctts_count < sc->sample_count; j++)
3897 add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
3898 &sc->ctts_allocated_size, 1,
3899 ctts_data_old[i].duration);
3900 av_free(ctts_data_old);
3903 for (i = 0; i < sc->chunk_count; i++) {
3904 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
3905 current_offset = sc->chunk_offsets[i];
3906 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3907 i + 1 == sc->stsc_data[stsc_index + 1].first)
3910 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
3911 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
3912 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
3913 sc->stsz_sample_size = sc->sample_size;
3915 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
3916 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
3917 sc->stsz_sample_size = sc->sample_size;
3920 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
3922 if (current_sample >= sc->sample_count) {
3923 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
3927 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
3929 if (stss_index + 1 < sc->keyframe_count)
3931 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
3933 if (stps_index + 1 < sc->stps_count)
3936 if (rap_group_present && rap_group_index < sc->rap_group_count) {
3937 if (sc->rap_group[rap_group_index].index > 0)
3939 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
3940 rap_group_sample = 0;
3944 if (sc->keyframe_absent
3946 && !rap_group_present
3947 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
3951 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
3952 if (sc->pseudo_stream_id == -1 ||
3953 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
3955 if (sample_size > 0x3FFFFFFF) {
3956 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
3959 e = &st->internal->index_entries[st->internal->nb_index_entries++];
3960 e->pos = current_offset;
3961 e->timestamp = current_dts;
3962 e->size = sample_size;
3963 e->min_distance = distance;
3964 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
3965 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
3966 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
3967 current_offset, current_dts, sample_size, distance, keyframe);
3968 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->internal->nb_index_entries < 100)
3969 ff_rfps_add_frame(mov->fc, st, current_dts);
3972 current_offset += sample_size;
3973 stream_size += sample_size;
3975 /* A negative sample duration is invalid based on the spec,
3976 * but some samples need it to correct the DTS. */
3977 if (sc->stts_data[stts_index].duration < 0) {
3978 av_log(mov->fc, AV_LOG_WARNING,
3979 "Invalid SampleDelta %d in STTS, at %d st:%d\n",
3980 sc->stts_data[stts_index].duration, stts_index,
3982 dts_correction += sc->stts_data[stts_index].duration - 1;
3983 sc->stts_data[stts_index].duration = 1;
3985 current_dts += sc->stts_data[stts_index].duration;
3986 if (!dts_correction || current_dts + dts_correction > last_dts) {
3987 current_dts += dts_correction;
3990 /* Avoid creating non-monotonous DTS */
3991 dts_correction += current_dts - last_dts - 1;
3992 current_dts = last_dts + 1;
3994 last_dts = current_dts;
3998 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
4004 if (st->duration > 0)
4005 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
4007 unsigned chunk_samples, total = 0;
4009 if (!sc->chunk_count)
4012 // compute total chunk count
4013 for (i = 0; i < sc->stsc_count; i++) {
4014 unsigned count, chunk_count;
4016 chunk_samples = sc->stsc_data[i].count;
4017 if (i != sc->stsc_count - 1 &&
4018 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
4019 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
4023 if (sc->samples_per_frame >= 160) { // gsm
4024 count = chunk_samples / sc->samples_per_frame;
4025 } else if (sc->samples_per_frame > 1) {
4026 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4027 count = (chunk_samples+samples-1) / samples;
4029 count = (chunk_samples+1023) / 1024;
4032 if (mov_stsc_index_valid(i, sc->stsc_count))
4033 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4035 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4036 total += chunk_count * count;
4039 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4040 if (total >= UINT_MAX / sizeof(*st->internal->index_entries) - st->internal->nb_index_entries)
4042 if (av_reallocp_array(&st->internal->index_entries,
4043 st->internal->nb_index_entries + total,
4044 sizeof(*st->internal->index_entries)) < 0) {
4045 st->internal->nb_index_entries = 0;
4048 st->internal->index_entries_allocated_size = (st->internal->nb_index_entries + total) * sizeof(*st->internal->index_entries);
4051 for (i = 0; i < sc->chunk_count; i++) {
4052 current_offset = sc->chunk_offsets[i];
4053 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4054 i + 1 == sc->stsc_data[stsc_index + 1].first)
4056 chunk_samples = sc->stsc_data[stsc_index].count;
4058 while (chunk_samples > 0) {
4060 unsigned size, samples;
4062 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4063 avpriv_request_sample(mov->fc,
4064 "Zero bytes per frame, but %d samples per frame",
4065 sc->samples_per_frame);
4069 if (sc->samples_per_frame >= 160) { // gsm
4070 samples = sc->samples_per_frame;
4071 size = sc->bytes_per_frame;
4073 if (sc->samples_per_frame > 1) {
4074 samples = FFMIN((1024 / sc->samples_per_frame)*
4075 sc->samples_per_frame, chunk_samples);
4076 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
4078 samples = FFMIN(1024, chunk_samples);
4079 size = samples * sc->sample_size;
4083 if (st->internal->nb_index_entries >= total) {
4084 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4087 if (size > 0x3FFFFFFF) {
4088 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4091 e = &st->internal->index_entries[st->internal->nb_index_entries++];
4092 e->pos = current_offset;
4093 e->timestamp = current_dts;
4095 e->min_distance = 0;
4096 e->flags = AVINDEX_KEYFRAME;
4097 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4098 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4101 current_offset += size;
4102 current_dts += samples;
4103 chunk_samples -= samples;
4108 if (!mov->ignore_editlist && mov->advanced_editlist) {
4109 // Fix index according to edit lists.
4110 mov_fix_index(mov, st);
4113 // Update start time of the stream.
4114 if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->internal->nb_index_entries > 0) {
4115 st->start_time = st->internal->index_entries[0].timestamp + sc->dts_shift;
4116 if (sc->ctts_data) {
4117 st->start_time += sc->ctts_data[0].duration;
4121 mov_estimate_video_delay(mov, st);
4124 static int test_same_origin(const char *src, const char *ref) {
4134 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4135 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4137 if (strlen(src) == 0) {
4139 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4140 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4141 strlen(src_host) + 1 >= sizeof(src_host) ||
4142 strlen(ref_host) + 1 >= sizeof(ref_host)) {
4144 } else if (strcmp(src_proto, ref_proto) ||
4145 strcmp(src_auth, ref_auth) ||
4146 strcmp(src_host, ref_host) ||
4147 src_port != ref_port) {
4153 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4155 /* try relative path, we do not try the absolute because it can leak information about our
4156 system to an attacker */
4157 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4158 char filename[1025];
4159 const char *src_path;
4162 /* find a source dir */
4163 src_path = strrchr(src, '/');
4169 /* find a next level down to target */
4170 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4171 if (ref->path[l] == '/') {
4172 if (i == ref->nlvl_to - 1)
4178 /* compose filename if next level down to target was found */
4179 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4180 memcpy(filename, src, src_path - src);
4181 filename[src_path - src] = 0;
4183 for (i = 1; i < ref->nlvl_from; i++)
4184 av_strlcat(filename, "../", sizeof(filename));
4186 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4187 if (!c->use_absolute_path) {
4188 int same_origin = test_same_origin(src, filename);
4191 av_log(c->fc, AV_LOG_ERROR,
4192 "Reference with mismatching origin, %s not tried for security reasons, "
4193 "set demuxer option use_absolute_path to allow it anyway\n",
4195 return AVERROR(ENOENT);
4198 if (strstr(ref->path + l + 1, "..") ||
4199 strstr(ref->path + l + 1, ":") ||
4200 (ref->nlvl_from > 1 && same_origin < 0) ||
4201 (filename[0] == '/' && src_path == src))
4202 return AVERROR(ENOENT);
4205 if (strlen(filename) + 1 == sizeof(filename))
4206 return AVERROR(ENOENT);
4207 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4210 } else if (c->use_absolute_path) {
4211 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4212 "this is a possible security issue\n");
4213 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4216 av_log(c->fc, AV_LOG_ERROR,
4217 "Absolute path %s not tried for security reasons, "
4218 "set demuxer option use_absolute_path to allow absolute paths\n",
4222 return AVERROR(ENOENT);
4225 static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
4227 if (sc->time_scale <= 0) {
4228 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4229 sc->time_scale = c->time_scale;
4230 if (sc->time_scale <= 0)
4235 static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4238 MOVStreamContext *sc;
4241 st = avformat_new_stream(c->fc, NULL);
4242 if (!st) return AVERROR(ENOMEM);
4244 sc = av_mallocz(sizeof(MOVStreamContext));
4245 if (!sc) return AVERROR(ENOMEM);
4248 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
4249 sc->ffindex = st->index;
4250 c->trak_index = st->index;
4252 if ((ret = mov_read_default(c, pb, atom)) < 0)
4257 // Here stsc refers to a chunk not described in stco. This is technically invalid,
4258 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4259 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4261 av_freep(&sc->stsc_data);
4265 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4266 (!sc->sample_size && !sc->sample_count))) ||
4267 (!sc->chunk_count && sc->sample_count)) {
4268 av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4272 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4273 av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4275 return AVERROR_INVALIDDATA;
4278 fix_timescale(c, sc);
4280 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4282 mov_build_index(c, st);
4284 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4285 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4286 if (c->enable_drefs) {
4287 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4288 av_log(c->fc, AV_LOG_ERROR,
4289 "stream %d, error opening alias: path='%s', dir='%s', "
4290 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4291 st->index, dref->path, dref->dir, dref->filename,
4292 dref->volume, dref->nlvl_from, dref->nlvl_to);
4294 av_log(c->fc, AV_LOG_WARNING,
4295 "Skipped opening external track: "
4296 "stream %d, alias: path='%s', dir='%s', "
4297 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4298 "Set enable_drefs to allow this.\n",
4299 st->index, dref->path, dref->dir, dref->filename,
4300 dref->volume, dref->nlvl_from, dref->nlvl_to);
4304 sc->pb_is_copied = 1;
4307 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4308 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4309 sc->height && sc->width &&
4310 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4311 st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4312 ((double)st->codecpar->width * sc->height), INT_MAX);
4315 #if FF_API_R_FRAME_RATE
4316 if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4317 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
4318 sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4322 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4323 if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4324 TAG_IS_AVCI(st->codecpar->codec_tag)) {
4325 ret = ff_generate_avci_extradata(st);
4330 switch (st->codecpar->codec_id) {
4331 #if CONFIG_H261_DECODER
4332 case AV_CODEC_ID_H261:
4334 #if CONFIG_H263_DECODER
4335 case AV_CODEC_ID_H263:
4337 #if CONFIG_MPEG4_DECODER
4338 case AV_CODEC_ID_MPEG4:
4340 st->codecpar->width = 0; /* let decoder init width/height */
4341 st->codecpar->height= 0;
4345 // If the duration of the mp3 packets is not constant, then they could need a parser
4346 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4347 && sc->stts_count > 3
4348 && sc->stts_count*10 > st->nb_frames
4349 && sc->time_scale == st->codecpar->sample_rate) {
4350 st->need_parsing = AVSTREAM_PARSE_FULL;
4352 /* Do not need those anymore. */
4353 av_freep(&sc->chunk_offsets);
4354 av_freep(&sc->sample_sizes);
4355 av_freep(&sc->keyframes);
4356 av_freep(&sc->stts_data);
4357 av_freep(&sc->stps_data);
4358 av_freep(&sc->elst_data);
4359 av_freep(&sc->rap_group);
4364 static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4367 c->itunes_metadata = 1;
4368 ret = mov_read_default(c, pb, atom);
4369 c->itunes_metadata = 0;
4373 static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4382 count = avio_rb32(pb);
4383 if (count > UINT_MAX / sizeof(*c->meta_keys) - 1) {
4384 av_log(c->fc, AV_LOG_ERROR,
4385 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
4386 return AVERROR_INVALIDDATA;
4389 c->meta_keys_count = count + 1;
4390 c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
4392 return AVERROR(ENOMEM);
4394 for (i = 1; i <= count; ++i) {
4395 uint32_t key_size = avio_rb32(pb);
4396 uint32_t type = avio_rl32(pb);
4398 av_log(c->fc, AV_LOG_ERROR,
4399 "The key# %"PRIu32" in meta has invalid size:"
4400 "%"PRIu32"\n", i, key_size);
4401 return AVERROR_INVALIDDATA;
4404 if (type != MKTAG('m','d','t','a')) {
4405 avio_skip(pb, key_size);
4407 c->meta_keys[i] = av_mallocz(key_size + 1);
4408 if (!c->meta_keys[i])
4409 return AVERROR(ENOMEM);
4410 avio_read(pb, c->meta_keys[i], key_size);
4416 static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4418 int64_t end = av_sat_add64(avio_tell(pb), atom.size);
4419 uint8_t *key = NULL, *val = NULL, *mean = NULL;
4423 MOVStreamContext *sc;
4425 if (c->fc->nb_streams < 1)
4427 st = c->fc->streams[c->fc->nb_streams-1];
4430 for (i = 0; i < 3; i++) {
4434 if (end - avio_tell(pb) <= 12)
4437 len = avio_rb32(pb);
4438 tag = avio_rl32(pb);
4439 avio_skip(pb, 4); // flags
4441 if (len < 12 || len - 12 > end - avio_tell(pb))
4445 if (tag == MKTAG('m', 'e', 'a', 'n'))
4447 else if (tag == MKTAG('n', 'a', 'm', 'e'))
4449 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
4459 *p = av_malloc(len + 1);
4461 ret = AVERROR(ENOMEM);
4464 ret = ffio_read_size(pb, *p, len);
4472 if (mean && key && val) {
4473 if (strcmp(key, "iTunSMPB") == 0) {
4474 int priming, remainder, samples;
4475 if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
4476 if(priming>0 && priming<16384)
4477 sc->start_pad = priming;
4480 if (strcmp(key, "cdec") != 0) {
4481 av_dict_set(&c->fc->metadata, key, val,
4482 AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
4486 av_log(c->fc, AV_LOG_VERBOSE,
4487 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
4490 avio_seek(pb, end, SEEK_SET);
4497 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4499 while (atom.size > 8) {
4503 tag = avio_rl32(pb);
4505 if (tag == MKTAG('h','d','l','r')) {
4506 avio_seek(pb, -8, SEEK_CUR);
4508 return mov_read_default(c, pb, atom);
4514 // return 1 when matrix is identity, 0 otherwise
4515 #define IS_MATRIX_IDENT(matrix) \
4516 ( (matrix)[0][0] == (1 << 16) && \
4517 (matrix)[1][1] == (1 << 16) && \
4518 (matrix)[2][2] == (1 << 30) && \
4519 !(matrix)[0][1] && !(matrix)[0][2] && \
4520 !(matrix)[1][0] && !(matrix)[1][2] && \
4521 !(matrix)[2][0] && !(matrix)[2][1])
4523 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4528 int display_matrix[3][3];
4529 int res_display_matrix[3][3] = { { 0 } };
4531 MOVStreamContext *sc;
4535 if (c->fc->nb_streams < 1)
4537 st = c->fc->streams[c->fc->nb_streams-1];
4540 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4541 // avoids corrupting AVStreams mapped to an earlier tkhd.
4543 return AVERROR_INVALIDDATA;
4545 version = avio_r8(pb);
4546 flags = avio_rb24(pb);
4547 st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
4553 avio_rb32(pb); /* creation time */
4554 avio_rb32(pb); /* modification time */
4556 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4557 avio_rb32(pb); /* reserved */
4559 /* highlevel (considering edits) duration in movie timebase */
4560 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4561 avio_rb32(pb); /* reserved */
4562 avio_rb32(pb); /* reserved */
4564 avio_rb16(pb); /* layer */
4565 avio_rb16(pb); /* alternate group */
4566 avio_rb16(pb); /* volume */
4567 avio_rb16(pb); /* reserved */
4569 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4570 // they're kept in fixed point format through all calculations
4571 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4572 // side data, but the scale factor is not needed to calculate aspect ratio
4573 for (i = 0; i < 3; i++) {
4574 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
4575 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
4576 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
4579 width = avio_rb32(pb); // 16.16 fixed point track width
4580 height = avio_rb32(pb); // 16.16 fixed point track height
4581 sc->width = width >> 16;
4582 sc->height = height >> 16;
4584 // apply the moov display matrix (after the tkhd one)
4585 for (i = 0; i < 3; i++) {
4586 const int sh[3] = { 16, 16, 30 };
4587 for (j = 0; j < 3; j++) {
4588 for (e = 0; e < 3; e++) {
4589 res_display_matrix[i][j] +=
4590 ((int64_t) display_matrix[i][e] *
4591 c->movie_display_matrix[e][j]) >> sh[e];
4596 // save the matrix when it is not the default identity
4597 if (!IS_MATRIX_IDENT(res_display_matrix)) {
4600 av_freep(&sc->display_matrix);
4601 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4602 if (!sc->display_matrix)
4603 return AVERROR(ENOMEM);
4605 for (i = 0; i < 3; i++)
4606 for (j = 0; j < 3; j++)
4607 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4609 #if FF_API_OLD_ROTATE_API
4610 rotate = av_display_rotation_get(sc->display_matrix);
4611 if (!isnan(rotate)) {
4612 char rotate_buf[64];
4614 if (rotate < 0) // for backward compatibility
4616 snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate);
4617 av_dict_set(&st->metadata, "rotate", rotate_buf, 0);
4622 // transform the display width/height according to the matrix
4623 // to keep the same scale, use [width height 1<<16]
4624 if (width && height && sc->display_matrix) {
4625 double disp_transform[2];
4627 for (i = 0; i < 2; i++)
4628 disp_transform[i] = hypot(sc->display_matrix[0 + i],
4629 sc->display_matrix[3 + i]);
4631 if (disp_transform[0] > 0 && disp_transform[1] > 0 &&
4632 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4633 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4634 st->sample_aspect_ratio = av_d2q(
4635 disp_transform[0] / disp_transform[1],
4641 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4643 MOVFragment *frag = &c->fragment;
4644 MOVTrackExt *trex = NULL;
4645 int flags, track_id, i;
4646 MOVFragmentStreamInfo * frag_stream_info;
4648 avio_r8(pb); /* version */
4649 flags = avio_rb24(pb);
4651 track_id = avio_rb32(pb);
4653 return AVERROR_INVALIDDATA;
4654 for (i = 0; i < c->trex_count; i++)
4655 if (c->trex_data[i].track_id == track_id) {
4656 trex = &c->trex_data[i];
4660 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4663 c->fragment.found_tfhd = 1;
4664 frag->track_id = track_id;
4665 set_frag_stream(&c->frag_index, track_id);
4667 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4668 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4669 frag->moof_offset : frag->implicit_offset;
4670 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4672 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4673 avio_rb32(pb) : trex->duration;
4674 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4675 avio_rb32(pb) : trex->size;
4676 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4677 avio_rb32(pb) : trex->flags;
4678 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4680 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4681 if (frag_stream_info)
4682 frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
4687 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4692 num = atom.size / 4;
4693 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4694 return AVERROR(ENOMEM);
4696 av_free(c->chapter_tracks);
4697 c->chapter_tracks = new_tracks;
4698 c->nb_chapter_tracks = num;
4700 for (i = 0; i < num && !pb->eof_reached; i++)
4701 c->chapter_tracks[i] = avio_rb32(pb);
4706 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4711 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4712 return AVERROR_INVALIDDATA;
4713 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4714 sizeof(*c->trex_data))) < 0) {
4719 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4721 trex = &c->trex_data[c->trex_count++];
4722 avio_r8(pb); /* version */
4723 avio_rb24(pb); /* flags */
4724 trex->track_id = avio_rb32(pb);
4725 trex->stsd_id = avio_rb32(pb);
4726 trex->duration = avio_rb32(pb);
4727 trex->size = avio_rb32(pb);
4728 trex->flags = avio_rb32(pb);
4732 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4734 MOVFragment *frag = &c->fragment;
4735 AVStream *st = NULL;
4736 MOVStreamContext *sc;
4738 MOVFragmentStreamInfo * frag_stream_info;
4739 int64_t base_media_decode_time;
4741 for (i = 0; i < c->fc->nb_streams; i++) {
4742 if (c->fc->streams[i]->id == frag->track_id) {
4743 st = c->fc->streams[i];
4748 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4752 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4754 version = avio_r8(pb);
4755 avio_rb24(pb); /* flags */
4757 base_media_decode_time = avio_rb64(pb);
4759 base_media_decode_time = avio_rb32(pb);
4762 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4763 if (frag_stream_info)
4764 frag_stream_info->tfdt_dts = base_media_decode_time;
4765 sc->track_end = base_media_decode_time;
4770 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4772 MOVFragment *frag = &c->fragment;
4773 AVStream *st = NULL;
4774 MOVStreamContext *sc;
4777 int64_t dts, pts = AV_NOPTS_VALUE;
4778 int data_offset = 0;
4779 unsigned entries, first_sample_flags = frag->flags;
4780 int flags, distance, i;
4781 int64_t prev_dts = AV_NOPTS_VALUE;
4782 int next_frag_index = -1, index_entry_pos;
4783 size_t requested_size;
4784 size_t old_ctts_allocated_size;
4785 AVIndexEntry *new_entries;
4786 MOVFragmentStreamInfo * frag_stream_info;
4788 if (!frag->found_tfhd) {
4789 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4790 return AVERROR_INVALIDDATA;
4793 for (i = 0; i < c->fc->nb_streams; i++) {
4794 if (c->fc->streams[i]->id == frag->track_id) {
4795 st = c->fc->streams[i];
4800 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4804 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4807 // Find the next frag_index index that has a valid index_entry for
4808 // the current track_id.
4810 // A valid index_entry means the trun for the fragment was read
4811 // and it's samples are in index_entries at the given position.
4812 // New index entries will be inserted before the index_entry found.
4813 index_entry_pos = st->internal->nb_index_entries;
4814 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4815 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4816 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4817 next_frag_index = i;
4818 index_entry_pos = frag_stream_info->index_entry;
4822 av_assert0(index_entry_pos <= st->internal->nb_index_entries);
4824 avio_r8(pb); /* version */
4825 flags = avio_rb24(pb);
4826 entries = avio_rb32(pb);
4827 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4829 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4830 return AVERROR_INVALIDDATA;
4831 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4832 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4834 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4835 if (frag_stream_info) {
4836 if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
4837 dts = frag_stream_info->next_trun_dts - sc->time_offset;
4838 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4839 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4840 pts = frag_stream_info->first_tfra_pts;
4841 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4842 ", using it for pts\n", pts);
4843 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4844 c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
4845 dts = frag_stream_info->first_tfra_pts;
4846 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4847 ", using it for dts\n", pts);
4848 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4849 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4850 // pts = frag_stream_info->sidx_pts;
4851 dts = frag_stream_info->sidx_pts - sc->time_offset;
4852 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4853 ", using it for pts\n", pts);
4854 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4855 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4856 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4857 ", using it for dts\n", dts);
4859 dts = sc->track_end - sc->time_offset;
4860 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4861 ", using it for dts\n", dts);
4864 dts = sc->track_end - sc->time_offset;
4865 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4866 ", using it for dts\n", dts);
4868 offset = frag->base_data_offset + data_offset;
4870 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4872 // realloc space for new index entries
4873 if((uint64_t)st->internal->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4874 entries = UINT_MAX / sizeof(AVIndexEntry) - st->internal->nb_index_entries;
4875 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4880 requested_size = (st->internal->nb_index_entries + entries) * sizeof(AVIndexEntry);
4881 new_entries = av_fast_realloc(st->internal->index_entries,
4882 &st->internal->index_entries_allocated_size,
4885 return AVERROR(ENOMEM);
4886 st->internal->index_entries= new_entries;
4888 requested_size = (st->internal->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4889 old_ctts_allocated_size = sc->ctts_allocated_size;
4890 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4893 return AVERROR(ENOMEM);
4894 sc->ctts_data = ctts_data;
4896 // In case there were samples without ctts entries, ensure they get
4897 // zero valued entries. This ensures clips which mix boxes with and
4898 // without ctts entries don't pickup uninitialized data.
4899 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4900 sc->ctts_allocated_size - old_ctts_allocated_size);
4902 if (index_entry_pos < st->internal->nb_index_entries) {
4903 // Make hole in index_entries and ctts_data for new samples
4904 memmove(st->internal->index_entries + index_entry_pos + entries,
4905 st->internal->index_entries + index_entry_pos,
4906 sizeof(*st->internal->index_entries) *
4907 (st->internal->nb_index_entries - index_entry_pos));
4908 memmove(sc->ctts_data + index_entry_pos + entries,
4909 sc->ctts_data + index_entry_pos,
4910 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4911 if (index_entry_pos < sc->current_sample) {
4912 sc->current_sample += entries;
4916 st->internal->nb_index_entries += entries;
4917 sc->ctts_count = st->internal->nb_index_entries;
4919 // Record the index_entry position in frag_index of this fragment
4920 if (frag_stream_info)
4921 frag_stream_info->index_entry = index_entry_pos;
4923 if (index_entry_pos > 0)
4924 prev_dts = st->internal->index_entries[index_entry_pos-1].timestamp;
4926 for (i = 0; i < entries && !pb->eof_reached; i++) {
4927 unsigned sample_size = frag->size;
4928 int sample_flags = i ? frag->flags : first_sample_flags;
4929 unsigned sample_duration = frag->duration;
4930 unsigned ctts_duration = 0;
4932 int index_entry_flags = 0;
4934 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4935 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4936 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4937 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4939 mov_update_dts_shift(sc, ctts_duration, c->fc);
4940 if (pts != AV_NOPTS_VALUE) {
4941 dts = pts - sc->dts_shift;
4942 if (flags & MOV_TRUN_SAMPLE_CTS) {
4943 dts -= ctts_duration;
4945 dts -= sc->time_offset;
4947 av_log(c->fc, AV_LOG_DEBUG,
4948 "pts %"PRId64" calculated dts %"PRId64
4949 " sc->dts_shift %d ctts.duration %d"
4950 " sc->time_offset %"PRId64
4951 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4953 sc->dts_shift, ctts_duration,
4954 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4955 pts = AV_NOPTS_VALUE;
4958 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4962 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4963 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4966 index_entry_flags |= AVINDEX_KEYFRAME;
4968 // Fragments can overlap in time. Discard overlapping frames after
4970 if (prev_dts >= dts)
4971 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4973 st->internal->index_entries[index_entry_pos].pos = offset;
4974 st->internal->index_entries[index_entry_pos].timestamp = dts;
4975 st->internal->index_entries[index_entry_pos].size= sample_size;
4976 st->internal->index_entries[index_entry_pos].min_distance= distance;
4977 st->internal->index_entries[index_entry_pos].flags = index_entry_flags;
4979 sc->ctts_data[index_entry_pos].count = 1;
4980 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4983 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4984 "size %u, distance %d, keyframe %d\n", st->index,
4985 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4987 dts += sample_duration;
4988 offset += sample_size;
4989 sc->data_size += sample_size;
4991 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4992 1 <= INT_MAX - sc->nb_frames_for_fps
4994 sc->duration_for_fps += sample_duration;
4995 sc->nb_frames_for_fps ++;
4998 if (frag_stream_info)
4999 frag_stream_info->next_trun_dts = dts + sc->time_offset;
5001 // EOF found before reading all entries. Fix the hole this would
5002 // leave in index_entries and ctts_data
5003 int gap = entries - i;
5004 memmove(st->internal->index_entries + index_entry_pos,
5005 st->internal->index_entries + index_entry_pos + gap,
5006 sizeof(*st->internal->index_entries) *
5007 (st->internal->nb_index_entries - (index_entry_pos + gap)));
5008 memmove(sc->ctts_data + index_entry_pos,
5009 sc->ctts_data + index_entry_pos + gap,
5010 sizeof(*sc->ctts_data) *
5011 (sc->ctts_count - (index_entry_pos + gap)));
5013 st->internal->nb_index_entries -= gap;
5014 sc->ctts_count -= gap;
5015 if (index_entry_pos < sc->current_sample) {
5016 sc->current_sample -= gap;
5021 // The end of this new fragment may overlap in time with the start
5022 // of the next fragment in index_entries. Mark the samples in the next
5023 // fragment that overlap with AVINDEX_DISCARD_FRAME
5024 prev_dts = AV_NOPTS_VALUE;
5025 if (index_entry_pos > 0)
5026 prev_dts = st->internal->index_entries[index_entry_pos-1].timestamp;
5027 for (i = index_entry_pos; i < st->internal->nb_index_entries; i++) {
5028 if (prev_dts < st->internal->index_entries[i].timestamp)
5030 st->internal->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
5033 // If a hole was created to insert the new index_entries into,
5034 // the index_entry recorded for all subsequent moof must
5035 // be incremented by the number of entries inserted.
5036 fix_frag_index_entries(&c->frag_index, next_frag_index,
5037 frag->track_id, entries);
5039 if (pb->eof_reached) {
5040 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
5044 frag->implicit_offset = offset;
5046 sc->track_end = dts + sc->time_offset;
5047 if (st->duration < sc->track_end)
5048 st->duration = sc->track_end;
5053 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5055 int64_t stream_size = avio_size(pb);
5056 int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
5057 uint8_t version, is_complete;
5059 unsigned i, j, track_id, item_count;
5060 AVStream *st = NULL;
5061 AVStream *ref_st = NULL;
5062 MOVStreamContext *sc, *ref_sc = NULL;
5063 AVRational timescale;
5065 version = avio_r8(pb);
5067 avpriv_request_sample(c->fc, "sidx version %u", version);
5071 avio_rb24(pb); // flags
5073 track_id = avio_rb32(pb); // Reference ID
5074 for (i = 0; i < c->fc->nb_streams; i++) {
5075 if (c->fc->streams[i]->id == track_id) {
5076 st = c->fc->streams[i];
5081 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5087 timescale = av_make_q(1, avio_rb32(pb));
5089 if (timescale.den <= 0) {
5090 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5091 return AVERROR_INVALIDDATA;
5095 pts = avio_rb32(pb);
5096 offadd= avio_rb32(pb);
5098 pts = avio_rb64(pb);
5099 offadd= avio_rb64(pb);
5101 if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
5102 return AVERROR_INVALIDDATA;
5104 offset += (uint64_t)offadd;
5106 avio_rb16(pb); // reserved
5108 item_count = avio_rb16(pb);
5110 for (i = 0; i < item_count; i++) {
5112 MOVFragmentStreamInfo * frag_stream_info;
5113 uint32_t size = avio_rb32(pb);
5114 uint32_t duration = avio_rb32(pb);
5115 if (size & 0x80000000) {
5116 avpriv_request_sample(c->fc, "sidx reference_type 1");
5117 return AVERROR_PATCHWELCOME;
5119 avio_rb32(pb); // sap_flags
5120 timestamp = av_rescale_q(pts, timescale, st->time_base);
5122 index = update_frag_index(c, offset);
5123 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5124 if (frag_stream_info)
5125 frag_stream_info->sidx_pts = timestamp;
5127 if (av_sat_add64(offset, size) != offset + size)
5128 return AVERROR_INVALIDDATA;
5133 st->duration = sc->track_end = pts;
5137 // See if the remaining bytes are just an mfra which we can ignore.
5138 is_complete = offset == stream_size;
5139 if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL)) {
5141 int64_t original_pos = avio_tell(pb);
5142 if (!c->have_read_mfra_size) {
5143 if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
5145 c->mfra_size = avio_rb32(pb);
5146 c->have_read_mfra_size = 1;
5147 if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
5150 if (offset + c->mfra_size == stream_size)
5155 // Find first entry in fragment index that came from an sidx.
5156 // This will pretty much always be the first entry.
5157 for (i = 0; i < c->frag_index.nb_items; i++) {
5158 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5159 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5160 MOVFragmentStreamInfo * si;
5161 si = &item->stream_info[j];
5162 if (si->sidx_pts != AV_NOPTS_VALUE) {
5163 ref_st = c->fc->streams[j];
5164 ref_sc = ref_st->priv_data;
5169 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5170 st = c->fc->streams[i];
5172 if (!sc->has_sidx) {
5173 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5177 c->frag_index.complete = 1;
5183 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5184 /* like the files created with Adobe Premiere 5.0, for samples see */
5185 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5186 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5191 return 0; /* continue */
5192 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5193 avio_skip(pb, atom.size - 4);
5196 atom.type = avio_rl32(pb);
5198 if (atom.type != MKTAG('m','d','a','t')) {
5199 avio_skip(pb, atom.size);
5202 err = mov_read_mdat(c, pb, atom);
5206 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5211 uint8_t *moov_data; /* uncompressed data */
5212 long cmov_len, moov_len;
5215 avio_rb32(pb); /* dcom atom */
5216 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5217 return AVERROR_INVALIDDATA;
5218 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5219 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5220 return AVERROR_INVALIDDATA;
5222 avio_rb32(pb); /* cmvd atom */
5223 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5224 return AVERROR_INVALIDDATA;
5225 moov_len = avio_rb32(pb); /* uncompressed size */
5226 cmov_len = atom.size - 6 * 4;
5228 cmov_data = av_malloc(cmov_len);
5230 return AVERROR(ENOMEM);
5231 moov_data = av_malloc(moov_len);
5234 return AVERROR(ENOMEM);
5236 ret = ffio_read_size(pb, cmov_data, cmov_len);
5238 goto free_and_return;
5240 ret = AVERROR_INVALIDDATA;
5241 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5242 goto free_and_return;
5243 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5244 goto free_and_return;
5245 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5246 atom.type = MKTAG('m','o','o','v');
5247 atom.size = moov_len;
5248 ret = mov_read_default(c, &ctx, atom);
5254 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5255 return AVERROR(ENOSYS);
5259 /* edit list atom */
5260 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5262 MOVStreamContext *sc;
5263 int i, edit_count, version;
5264 int64_t elst_entry_size;
5266 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5268 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5270 version = avio_r8(pb); /* version */
5271 avio_rb24(pb); /* flags */
5272 edit_count = avio_rb32(pb); /* entries */
5275 elst_entry_size = version == 1 ? 20 : 12;
5276 if (atom.size != edit_count * elst_entry_size) {
5277 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5278 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5279 edit_count, atom.size + 8);
5280 return AVERROR_INVALIDDATA;
5282 edit_count = atom.size / elst_entry_size;
5283 if (edit_count * elst_entry_size != atom.size) {
5284 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
5292 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5293 av_free(sc->elst_data);
5295 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5297 return AVERROR(ENOMEM);
5299 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5300 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5301 MOVElst *e = &sc->elst_data[i];
5304 e->duration = avio_rb64(pb);
5305 e->time = avio_rb64(pb);
5308 e->duration = avio_rb32(pb); /* segment duration */
5309 e->time = (int32_t)avio_rb32(pb); /* media time */
5312 e->rate = avio_rb32(pb) / 65536.0;
5314 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5315 e->duration, e->time, e->rate);
5317 if (e->time < 0 && e->time != -1 &&
5318 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5319 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5320 c->fc->nb_streams-1, i, e->time);
5321 return AVERROR_INVALIDDATA;
5329 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5331 MOVStreamContext *sc;
5333 if (c->fc->nb_streams < 1)
5334 return AVERROR_INVALIDDATA;
5335 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5336 sc->timecode_track = avio_rb32(pb);
5340 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5345 if (c->fc->nb_streams < 1)
5347 st = c->fc->streams[c->fc->nb_streams - 1];
5349 if (atom.size < 4) {
5350 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5351 return AVERROR_INVALIDDATA;
5354 /* For now, propagate only the OBUs, if any. Once libavcodec is
5355 updated to handle isobmff style extradata this can be removed. */
5361 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5368 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5371 int version, color_range, color_primaries, color_trc, color_space;
5373 if (c->fc->nb_streams < 1)
5375 st = c->fc->streams[c->fc->nb_streams - 1];
5377 if (atom.size < 5) {
5378 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5379 return AVERROR_INVALIDDATA;
5382 version = avio_r8(pb);
5384 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5387 avio_skip(pb, 3); /* flags */
5389 avio_skip(pb, 2); /* profile + level */
5390 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5391 color_primaries = avio_r8(pb);
5392 color_trc = avio_r8(pb);
5393 color_space = avio_r8(pb);
5394 if (avio_rb16(pb)) /* codecIntializationDataSize */
5395 return AVERROR_INVALIDDATA;
5397 if (!av_color_primaries_name(color_primaries))
5398 color_primaries = AVCOL_PRI_UNSPECIFIED;
5399 if (!av_color_transfer_name(color_trc))
5400 color_trc = AVCOL_TRC_UNSPECIFIED;
5401 if (!av_color_space_name(color_space))
5402 color_space = AVCOL_SPC_UNSPECIFIED;
5404 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5405 st->codecpar->color_primaries = color_primaries;
5406 st->codecpar->color_trc = color_trc;
5407 st->codecpar->color_space = color_space;
5412 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5414 MOVStreamContext *sc;
5417 if (c->fc->nb_streams < 1)
5418 return AVERROR_INVALIDDATA;
5420 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5422 if (atom.size < 5) {
5423 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5424 return AVERROR_INVALIDDATA;
5427 version = avio_r8(pb);
5429 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5432 avio_skip(pb, 3); /* flags */
5434 sc->mastering = av_mastering_display_metadata_alloc();
5436 return AVERROR(ENOMEM);
5438 for (i = 0; i < 3; i++) {
5439 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5440 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5442 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5443 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5445 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5446 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5448 sc->mastering->has_primaries = 1;
5449 sc->mastering->has_luminance = 1;
5454 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5456 MOVStreamContext *sc;
5457 const int mapping[3] = {1, 2, 0};
5458 const int chroma_den = 50000;
5459 const int luma_den = 10000;
5462 if (c->fc->nb_streams < 1)
5463 return AVERROR_INVALIDDATA;
5465 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5467 if (atom.size < 24) {
5468 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5469 return AVERROR_INVALIDDATA;
5472 sc->mastering = av_mastering_display_metadata_alloc();
5474 return AVERROR(ENOMEM);
5476 for (i = 0; i < 3; i++) {
5477 const int j = mapping[i];
5478 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5479 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5481 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5482 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5484 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5485 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5487 sc->mastering->has_luminance = 1;
5488 sc->mastering->has_primaries = 1;
5493 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5495 MOVStreamContext *sc;
5498 if (c->fc->nb_streams < 1)
5499 return AVERROR_INVALIDDATA;
5501 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5503 if (atom.size < 5) {
5504 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5505 return AVERROR_INVALIDDATA;
5508 version = avio_r8(pb);
5510 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5513 avio_skip(pb, 3); /* flags */
5515 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5517 return AVERROR(ENOMEM);
5519 sc->coll->MaxCLL = avio_rb16(pb);
5520 sc->coll->MaxFALL = avio_rb16(pb);
5525 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5527 MOVStreamContext *sc;
5529 if (c->fc->nb_streams < 1)
5530 return AVERROR_INVALIDDATA;
5532 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5534 if (atom.size < 4) {
5535 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5536 return AVERROR_INVALIDDATA;
5539 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5541 return AVERROR(ENOMEM);
5543 sc->coll->MaxCLL = avio_rb16(pb);
5544 sc->coll->MaxFALL = avio_rb16(pb);
5549 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5552 MOVStreamContext *sc;
5553 enum AVStereo3DType type;
5556 if (c->fc->nb_streams < 1)
5559 st = c->fc->streams[c->fc->nb_streams - 1];
5562 if (atom.size < 5) {
5563 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5564 return AVERROR_INVALIDDATA;
5568 return AVERROR_INVALIDDATA;
5570 avio_skip(pb, 4); /* version + flags */
5575 type = AV_STEREO3D_2D;
5578 type = AV_STEREO3D_TOPBOTTOM;
5581 type = AV_STEREO3D_SIDEBYSIDE;
5584 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5588 sc->stereo3d = av_stereo3d_alloc();
5590 return AVERROR(ENOMEM);
5592 sc->stereo3d->type = type;
5596 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5599 MOVStreamContext *sc;
5600 int size, version, layout;
5601 int32_t yaw, pitch, roll;
5602 uint32_t l = 0, t = 0, r = 0, b = 0;
5603 uint32_t tag, padding = 0;
5604 enum AVSphericalProjection projection;
5606 if (c->fc->nb_streams < 1)
5609 st = c->fc->streams[c->fc->nb_streams - 1];
5612 if (atom.size < 8) {
5613 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5614 return AVERROR_INVALIDDATA;
5617 size = avio_rb32(pb);
5618 if (size <= 12 || size > atom.size)
5619 return AVERROR_INVALIDDATA;
5621 tag = avio_rl32(pb);
5622 if (tag != MKTAG('s','v','h','d')) {
5623 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5626 version = avio_r8(pb);
5628 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5632 avio_skip(pb, 3); /* flags */
5633 avio_skip(pb, size - 12); /* metadata_source */
5635 size = avio_rb32(pb);
5636 if (size > atom.size)
5637 return AVERROR_INVALIDDATA;
5639 tag = avio_rl32(pb);
5640 if (tag != MKTAG('p','r','o','j')) {
5641 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5645 size = avio_rb32(pb);
5646 if (size > atom.size)
5647 return AVERROR_INVALIDDATA;
5649 tag = avio_rl32(pb);
5650 if (tag != MKTAG('p','r','h','d')) {
5651 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5654 version = avio_r8(pb);
5656 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5660 avio_skip(pb, 3); /* flags */
5662 /* 16.16 fixed point */
5663 yaw = avio_rb32(pb);
5664 pitch = avio_rb32(pb);
5665 roll = avio_rb32(pb);
5667 size = avio_rb32(pb);
5668 if (size > atom.size)
5669 return AVERROR_INVALIDDATA;
5671 tag = avio_rl32(pb);
5672 version = avio_r8(pb);
5674 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5678 avio_skip(pb, 3); /* flags */
5680 case MKTAG('c','b','m','p'):
5681 layout = avio_rb32(pb);
5683 av_log(c->fc, AV_LOG_WARNING,
5684 "Unsupported cubemap layout %d\n", layout);
5687 projection = AV_SPHERICAL_CUBEMAP;
5688 padding = avio_rb32(pb);
5690 case MKTAG('e','q','u','i'):
5696 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5697 av_log(c->fc, AV_LOG_ERROR,
5698 "Invalid bounding rectangle coordinates "
5699 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5700 return AVERROR_INVALIDDATA;
5703 if (l || t || r || b)
5704 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5706 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5709 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5713 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5715 return AVERROR(ENOMEM);
5717 sc->spherical->projection = projection;
5719 sc->spherical->yaw = yaw;
5720 sc->spherical->pitch = pitch;
5721 sc->spherical->roll = roll;
5723 sc->spherical->padding = padding;
5725 sc->spherical->bound_left = l;
5726 sc->spherical->bound_top = t;
5727 sc->spherical->bound_right = r;
5728 sc->spherical->bound_bottom = b;
5733 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5736 uint8_t *buffer = av_malloc(len + 1);
5740 return AVERROR(ENOMEM);
5743 ret = ffio_read_size(pb, buffer, len);
5747 /* Check for mandatory keys and values, try to support XML as best-effort */
5748 if (!sc->spherical &&
5749 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5750 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5751 av_stristr(val, "true") &&
5752 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5753 av_stristr(val, "true") &&
5754 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5755 av_stristr(val, "equirectangular")) {
5756 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5760 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5762 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5763 enum AVStereo3DType mode;
5765 if (av_stristr(buffer, "left-right"))
5766 mode = AV_STEREO3D_SIDEBYSIDE;
5767 else if (av_stristr(buffer, "top-bottom"))
5768 mode = AV_STEREO3D_TOPBOTTOM;
5770 mode = AV_STEREO3D_2D;
5772 sc->stereo3d = av_stereo3d_alloc();
5776 sc->stereo3d->type = mode;
5780 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5782 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5783 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5785 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5786 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5788 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5796 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5799 MOVStreamContext *sc;
5802 static const uint8_t uuid_isml_manifest[] = {
5803 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5804 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5806 static const uint8_t uuid_xmp[] = {
5807 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5808 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5810 static const uint8_t uuid_spherical[] = {
5811 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5812 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5815 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5816 return AVERROR_INVALIDDATA;
5818 if (c->fc->nb_streams < 1)
5820 st = c->fc->streams[c->fc->nb_streams - 1];
5823 ret = ffio_read_size(pb, uuid, sizeof(uuid));
5826 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5827 uint8_t *buffer, *ptr;
5829 size_t len = atom.size - sizeof(uuid);
5832 return AVERROR_INVALIDDATA;
5834 ret = avio_skip(pb, 4); // zeroes
5837 buffer = av_mallocz(len + 1);
5839 return AVERROR(ENOMEM);
5841 ret = ffio_read_size(pb, buffer, len);
5848 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5849 ptr += sizeof("systemBitrate=\"") - 1;
5850 c->bitrates_count++;
5851 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5853 c->bitrates_count = 0;
5855 return AVERROR(ENOMEM);
5858 ret = strtol(ptr, &endptr, 10);
5859 if (ret < 0 || errno || *endptr != '"') {
5860 c->bitrates[c->bitrates_count - 1] = 0;
5862 c->bitrates[c->bitrates_count - 1] = ret;
5867 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5869 size_t len = atom.size - sizeof(uuid);
5870 if (c->export_xmp) {
5871 buffer = av_mallocz(len + 1);
5873 return AVERROR(ENOMEM);
5875 ret = ffio_read_size(pb, buffer, len);
5881 av_dict_set(&c->fc->metadata, "xmp",
5882 buffer, AV_DICT_DONT_STRDUP_VAL);
5884 // skip all uuid atom, which makes it fast for long uuid-xmp file
5885 ret = avio_skip(pb, len);
5889 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5890 size_t len = atom.size - sizeof(uuid);
5891 ret = mov_parse_uuid_spherical(sc, pb, len);
5895 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5901 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5904 uint8_t content[16];
5909 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5915 && !memcmp(content, "Anevia\x1A\x1A", 8)
5916 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5917 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5923 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5925 uint32_t format = avio_rl32(pb);
5926 MOVStreamContext *sc;
5930 if (c->fc->nb_streams < 1)
5932 st = c->fc->streams[c->fc->nb_streams - 1];
5937 case MKTAG('e','n','c','v'): // encrypted video
5938 case MKTAG('e','n','c','a'): // encrypted audio
5939 id = mov_codec_id(st, format);
5940 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5941 st->codecpar->codec_id != id) {
5942 av_log(c->fc, AV_LOG_WARNING,
5943 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5944 (char*)&format, st->codecpar->codec_id);
5948 st->codecpar->codec_id = id;
5949 sc->format = format;
5953 if (format != sc->format) {
5954 av_log(c->fc, AV_LOG_WARNING,
5955 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5956 (char*)&format, (char*)&sc->format);
5965 * Gets the current encryption info and associated current stream context. If
5966 * we are parsing a track fragment, this will return the specific encryption
5967 * info for this fragment; otherwise this will return the global encryption
5968 * info for the current stream.
5970 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5972 MOVFragmentStreamInfo *frag_stream_info;
5976 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5977 if (frag_stream_info) {
5978 for (i = 0; i < c->fc->nb_streams; i++) {
5979 if (c->fc->streams[i]->id == frag_stream_info->id) {
5980 st = c->fc->streams[i];
5984 if (i == c->fc->nb_streams)
5986 *sc = st->priv_data;
5988 if (!frag_stream_info->encryption_index) {
5989 // If this stream isn't encrypted, don't create the index.
5990 if (!(*sc)->cenc.default_encrypted_sample)
5992 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5993 if (!frag_stream_info->encryption_index)
5994 return AVERROR(ENOMEM);
5996 *encryption_index = frag_stream_info->encryption_index;
5999 // No current track fragment, using stream level encryption info.
6001 if (c->fc->nb_streams < 1)
6003 st = c->fc->streams[c->fc->nb_streams - 1];
6004 *sc = st->priv_data;
6006 if (!(*sc)->cenc.encryption_index) {
6007 // If this stream isn't encrypted, don't create the index.
6008 if (!(*sc)->cenc.default_encrypted_sample)
6010 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
6011 if (!(*sc)->cenc.encryption_index)
6012 return AVERROR(ENOMEM);
6015 *encryption_index = (*sc)->cenc.encryption_index;
6020 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
6023 unsigned int subsample_count;
6024 AVSubsampleEncryptionInfo *subsamples;
6026 if (!sc->cenc.default_encrypted_sample) {
6027 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
6028 return AVERROR_INVALIDDATA;
6031 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
6033 return AVERROR(ENOMEM);
6035 if (sc->cenc.per_sample_iv_size != 0) {
6036 if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
6037 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
6038 av_encryption_info_free(*sample);
6044 if (use_subsamples) {
6045 subsample_count = avio_rb16(pb);
6046 av_free((*sample)->subsamples);
6047 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
6048 if (!(*sample)->subsamples) {
6049 av_encryption_info_free(*sample);
6051 return AVERROR(ENOMEM);
6054 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
6055 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
6056 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
6059 if (pb->eof_reached) {
6060 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
6061 av_encryption_info_free(*sample);
6063 return AVERROR_INVALIDDATA;
6065 (*sample)->subsample_count = subsample_count;
6071 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6073 AVEncryptionInfo **encrypted_samples;
6074 MOVEncryptionIndex *encryption_index;
6075 MOVStreamContext *sc;
6076 int use_subsamples, ret;
6077 unsigned int sample_count, i, alloc_size = 0;
6079 ret = get_current_encryption_info(c, &encryption_index, &sc);
6083 if (encryption_index->nb_encrypted_samples) {
6084 // This can happen if we have both saio/saiz and senc atoms.
6085 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6089 avio_r8(pb); /* version */
6090 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6092 sample_count = avio_rb32(pb);
6093 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6094 return AVERROR(ENOMEM);
6096 for (i = 0; i < sample_count; i++) {
6097 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6098 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6099 min_samples * sizeof(*encrypted_samples));
6100 if (encrypted_samples) {
6101 encryption_index->encrypted_samples = encrypted_samples;
6103 ret = mov_read_sample_encryption_info(
6104 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6106 ret = AVERROR(ENOMEM);
6108 if (pb->eof_reached) {
6109 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6110 ret = AVERROR_INVALIDDATA;
6115 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6116 av_freep(&encryption_index->encrypted_samples);
6120 encryption_index->nb_encrypted_samples = sample_count;
6125 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6127 AVEncryptionInfo **sample, **encrypted_samples;
6129 size_t sample_count, sample_info_size, i;
6131 unsigned int alloc_size = 0;
6133 if (encryption_index->nb_encrypted_samples)
6135 sample_count = encryption_index->auxiliary_info_sample_count;
6136 if (encryption_index->auxiliary_offsets_count != 1) {
6137 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6138 return AVERROR_PATCHWELCOME;
6140 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6141 return AVERROR(ENOMEM);
6143 prev_pos = avio_tell(pb);
6144 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6145 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6146 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6150 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6151 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6152 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6153 min_samples * sizeof(*encrypted_samples));
6154 if (!encrypted_samples) {
6155 ret = AVERROR(ENOMEM);
6158 encryption_index->encrypted_samples = encrypted_samples;
6160 sample = &encryption_index->encrypted_samples[i];
6161 sample_info_size = encryption_index->auxiliary_info_default_size
6162 ? encryption_index->auxiliary_info_default_size
6163 : encryption_index->auxiliary_info_sizes[i];
6165 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6169 if (pb->eof_reached) {
6170 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6171 ret = AVERROR_INVALIDDATA;
6173 encryption_index->nb_encrypted_samples = sample_count;
6177 avio_seek(pb, prev_pos, SEEK_SET);
6179 for (; i > 0; i--) {
6180 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6182 av_freep(&encryption_index->encrypted_samples);
6188 * Tries to read the given number of bytes from the stream and puts it in a
6189 * newly allocated buffer. This reads in small chunks to avoid allocating large
6190 * memory if the file contains an invalid/malicious size value.
6192 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6194 const unsigned int block_size = 1024 * 1024;
6195 uint8_t *buffer = NULL;
6196 unsigned int alloc_size = 0, offset = 0;
6197 while (offset < size) {
6198 unsigned int new_size =
6199 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6200 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6201 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6204 return AVERROR(ENOMEM);
6206 buffer = new_buffer;
6208 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6210 return AVERROR_INVALIDDATA;
6219 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6221 MOVEncryptionIndex *encryption_index;
6222 MOVStreamContext *sc;
6224 unsigned int sample_count, aux_info_type, aux_info_param;
6226 ret = get_current_encryption_info(c, &encryption_index, &sc);
6230 if (encryption_index->nb_encrypted_samples) {
6231 // This can happen if we have both saio/saiz and senc atoms.
6232 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6236 if (encryption_index->auxiliary_info_sample_count) {
6237 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6238 return AVERROR_INVALIDDATA;
6241 avio_r8(pb); /* version */
6242 if (avio_rb24(pb) & 0x01) { /* flags */
6243 aux_info_type = avio_rb32(pb);
6244 aux_info_param = avio_rb32(pb);
6245 if (sc->cenc.default_encrypted_sample) {
6246 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6247 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6250 if (aux_info_param != 0) {
6251 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6255 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6256 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6257 aux_info_type == MKBETAG('c','e','n','s') ||
6258 aux_info_type == MKBETAG('c','b','c','1') ||
6259 aux_info_type == MKBETAG('c','b','c','s')) &&
6260 aux_info_param == 0) {
6261 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6262 return AVERROR_INVALIDDATA;
6267 } else if (!sc->cenc.default_encrypted_sample) {
6268 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6272 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6273 sample_count = avio_rb32(pb);
6274 encryption_index->auxiliary_info_sample_count = sample_count;
6276 if (encryption_index->auxiliary_info_default_size == 0) {
6277 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6279 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6284 if (encryption_index->auxiliary_offsets_count) {
6285 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6291 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6293 uint64_t *auxiliary_offsets;
6294 MOVEncryptionIndex *encryption_index;
6295 MOVStreamContext *sc;
6297 unsigned int version, entry_count, aux_info_type, aux_info_param;
6298 unsigned int alloc_size = 0;
6300 ret = get_current_encryption_info(c, &encryption_index, &sc);
6304 if (encryption_index->nb_encrypted_samples) {
6305 // This can happen if we have both saio/saiz and senc atoms.
6306 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6310 if (encryption_index->auxiliary_offsets_count) {
6311 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6312 return AVERROR_INVALIDDATA;
6315 version = avio_r8(pb); /* version */
6316 if (avio_rb24(pb) & 0x01) { /* flags */
6317 aux_info_type = avio_rb32(pb);
6318 aux_info_param = avio_rb32(pb);
6319 if (sc->cenc.default_encrypted_sample) {
6320 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6321 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6324 if (aux_info_param != 0) {
6325 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6329 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6330 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6331 aux_info_type == MKBETAG('c','e','n','s') ||
6332 aux_info_type == MKBETAG('c','b','c','1') ||
6333 aux_info_type == MKBETAG('c','b','c','s')) &&
6334 aux_info_param == 0) {
6335 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6336 return AVERROR_INVALIDDATA;
6341 } else if (!sc->cenc.default_encrypted_sample) {
6342 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6346 entry_count = avio_rb32(pb);
6347 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6348 return AVERROR(ENOMEM);
6350 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6351 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6352 auxiliary_offsets = av_fast_realloc(
6353 encryption_index->auxiliary_offsets, &alloc_size,
6354 min_offsets * sizeof(*auxiliary_offsets));
6355 if (!auxiliary_offsets) {
6356 av_freep(&encryption_index->auxiliary_offsets);
6357 return AVERROR(ENOMEM);
6359 encryption_index->auxiliary_offsets = auxiliary_offsets;
6362 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6364 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6366 if (c->frag_index.current >= 0) {
6367 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6371 if (pb->eof_reached) {
6372 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6373 av_freep(&encryption_index->auxiliary_offsets);
6374 return AVERROR_INVALIDDATA;
6377 encryption_index->auxiliary_offsets_count = entry_count;
6379 if (encryption_index->auxiliary_info_sample_count) {
6380 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6386 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6388 AVEncryptionInitInfo *info, *old_init_info;
6391 uint8_t *side_data, *extra_data, *old_side_data;
6392 size_t side_data_size;
6393 buffer_size_t old_side_data_size;
6395 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6397 if (c->fc->nb_streams < 1)
6399 st = c->fc->streams[c->fc->nb_streams-1];
6401 version = avio_r8(pb); /* version */
6402 avio_rb24(pb); /* flags */
6404 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6405 /* key_id_size */ 16, /* data_size */ 0);
6407 return AVERROR(ENOMEM);
6409 if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
6410 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6415 kid_count = avio_rb32(pb);
6416 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
6417 ret = AVERROR(ENOMEM);
6421 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6422 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6423 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6424 min_kid_count * sizeof(*key_ids));
6426 ret = AVERROR(ENOMEM);
6429 info->key_ids = key_ids;
6431 info->key_ids[i] = av_mallocz(16);
6432 if (!info->key_ids[i]) {
6433 ret = AVERROR(ENOMEM);
6436 info->num_key_ids = i + 1;
6438 if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
6439 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6444 if (pb->eof_reached) {
6445 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6446 ret = AVERROR_INVALIDDATA;
6451 extra_data_size = avio_rb32(pb);
6452 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6456 av_freep(&info->data); // malloc(0) may still allocate something.
6457 info->data = extra_data;
6458 info->data_size = extra_data_size;
6460 // If there is existing initialization data, append to the list.
6461 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6462 if (old_side_data) {
6463 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6464 if (old_init_info) {
6465 // Append to the end of the list.
6466 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6472 info = old_init_info;
6474 // Assume existing side-data will be valid, so the only error we could get is OOM.
6475 ret = AVERROR(ENOMEM);
6480 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6482 ret = AVERROR(ENOMEM);
6485 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6486 side_data, side_data_size);
6491 av_encryption_init_info_free(info);
6495 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6498 MOVStreamContext *sc;
6500 if (c->fc->nb_streams < 1)
6502 st = c->fc->streams[c->fc->nb_streams-1];
6505 if (sc->pseudo_stream_id != 0) {
6506 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6507 return AVERROR_PATCHWELCOME;
6511 return AVERROR_INVALIDDATA;
6513 avio_rb32(pb); /* version and flags */
6515 if (!sc->cenc.default_encrypted_sample) {
6516 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6517 if (!sc->cenc.default_encrypted_sample) {
6518 return AVERROR(ENOMEM);
6522 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6526 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6529 MOVStreamContext *sc;
6530 unsigned int version, pattern, is_protected, iv_size;
6532 if (c->fc->nb_streams < 1)
6534 st = c->fc->streams[c->fc->nb_streams-1];
6537 if (sc->pseudo_stream_id != 0) {
6538 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6539 return AVERROR_PATCHWELCOME;
6542 if (!sc->cenc.default_encrypted_sample) {
6543 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6544 if (!sc->cenc.default_encrypted_sample) {
6545 return AVERROR(ENOMEM);
6550 return AVERROR_INVALIDDATA;
6552 version = avio_r8(pb); /* version */
6553 avio_rb24(pb); /* flags */
6555 avio_r8(pb); /* reserved */
6556 pattern = avio_r8(pb);
6559 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6560 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6563 is_protected = avio_r8(pb);
6564 if (is_protected && !sc->cenc.encryption_index) {
6565 // The whole stream should be by-default encrypted.
6566 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6567 if (!sc->cenc.encryption_index)
6568 return AVERROR(ENOMEM);
6570 sc->cenc.per_sample_iv_size = avio_r8(pb);
6571 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6572 sc->cenc.per_sample_iv_size != 16) {
6573 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6574 return AVERROR_INVALIDDATA;
6576 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6577 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6578 return AVERROR_INVALIDDATA;
6581 if (is_protected && !sc->cenc.per_sample_iv_size) {
6582 iv_size = avio_r8(pb);
6583 if (iv_size != 8 && iv_size != 16) {
6584 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6585 return AVERROR_INVALIDDATA;
6588 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6589 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6590 return AVERROR_INVALIDDATA;
6597 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6600 int last, type, size, ret;
6603 if (c->fc->nb_streams < 1)
6605 st = c->fc->streams[c->fc->nb_streams-1];
6607 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6608 return AVERROR_INVALIDDATA;
6610 /* Check FlacSpecificBox version. */
6611 if (avio_r8(pb) != 0)
6612 return AVERROR_INVALIDDATA;
6614 avio_rb24(pb); /* Flags */
6616 avio_read(pb, buf, sizeof(buf));
6617 flac_parse_block_header(buf, &last, &type, &size);
6619 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6620 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6621 return AVERROR_INVALIDDATA;
6624 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6629 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6634 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6638 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6639 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6640 return AVERROR_PATCHWELCOME;
6643 if (!sc->cenc.aes_ctr) {
6644 /* initialize the cipher */
6645 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6646 if (!sc->cenc.aes_ctr) {
6647 return AVERROR(ENOMEM);
6650 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6656 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6658 if (!sample->subsample_count) {
6659 /* decrypt the whole packet */
6660 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6664 for (i = 0; i < sample->subsample_count; i++) {
6665 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6666 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6667 return AVERROR_INVALIDDATA;
6670 /* skip the clear bytes */
6671 input += sample->subsamples[i].bytes_of_clear_data;
6672 size -= sample->subsamples[i].bytes_of_clear_data;
6674 /* decrypt the encrypted bytes */
6675 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6676 input += sample->subsamples[i].bytes_of_protected_data;
6677 size -= sample->subsamples[i].bytes_of_protected_data;
6681 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6682 return AVERROR_INVALIDDATA;
6688 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6690 MOVFragmentStreamInfo *frag_stream_info;
6691 MOVEncryptionIndex *encryption_index;
6692 AVEncryptionInfo *encrypted_sample;
6693 int encrypted_index, ret;
6695 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6696 encrypted_index = current_index;
6697 encryption_index = NULL;
6698 if (frag_stream_info) {
6699 // Note this only supports encryption info in the first sample descriptor.
6700 if (mov->fragment.stsd_id == 1) {
6701 if (frag_stream_info->encryption_index) {
6702 encrypted_index = current_index - frag_stream_info->index_entry;
6703 encryption_index = frag_stream_info->encryption_index;
6705 encryption_index = sc->cenc.encryption_index;
6709 encryption_index = sc->cenc.encryption_index;
6712 if (encryption_index) {
6713 if (encryption_index->auxiliary_info_sample_count &&
6714 !encryption_index->nb_encrypted_samples) {
6715 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6716 return AVERROR_INVALIDDATA;
6718 if (encryption_index->auxiliary_offsets_count &&
6719 !encryption_index->nb_encrypted_samples) {
6720 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6721 return AVERROR_INVALIDDATA;
6724 if (!encryption_index->nb_encrypted_samples) {
6725 // Full-sample encryption with default settings.
6726 encrypted_sample = sc->cenc.default_encrypted_sample;
6727 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6728 // Per-sample setting override.
6729 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6731 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6732 return AVERROR_INVALIDDATA;
6735 if (mov->decryption_key) {
6736 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6739 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6741 return AVERROR(ENOMEM);
6742 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6752 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6754 const int OPUS_SEEK_PREROLL_MS = 80;
6760 if (c->fc->nb_streams < 1)
6762 st = c->fc->streams[c->fc->nb_streams-1];
6764 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6765 return AVERROR_INVALIDDATA;
6767 /* Check OpusSpecificBox version. */
6768 if (avio_r8(pb) != 0) {
6769 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6770 return AVERROR_INVALIDDATA;
6773 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6774 size = atom.size + 8;
6776 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
6779 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6780 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6781 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6782 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6784 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6785 little-endian; aside from the preceeding magic and version they're
6786 otherwise currently identical. Data after output gain at offset 16
6787 doesn't need to be bytewapped. */
6788 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6789 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6790 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6791 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6793 st->codecpar->initial_padding = pre_skip;
6794 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6795 (AVRational){1, 1000},
6796 (AVRational){1, 48000});
6801 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6804 unsigned format_info;
6805 int channel_assignment, channel_assignment1, channel_assignment2;
6808 if (c->fc->nb_streams < 1)
6810 st = c->fc->streams[c->fc->nb_streams-1];
6813 return AVERROR_INVALIDDATA;
6815 format_info = avio_rb32(pb);
6817 ratebits = (format_info >> 28) & 0xF;
6818 channel_assignment1 = (format_info >> 15) & 0x1F;
6819 channel_assignment2 = format_info & 0x1FFF;
6820 if (channel_assignment2)
6821 channel_assignment = channel_assignment2;
6823 channel_assignment = channel_assignment1;
6825 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6826 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6827 st->codecpar->channels = truehd_channels(channel_assignment);
6828 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6833 static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6837 AVDOVIDecoderConfigurationRecord *dovi;
6841 if (c->fc->nb_streams < 1)
6843 st = c->fc->streams[c->fc->nb_streams-1];
6845 if ((uint64_t)atom.size > (1<<30) || atom.size < 4)
6846 return AVERROR_INVALIDDATA;
6848 dovi = av_dovi_alloc(&dovi_size);
6850 return AVERROR(ENOMEM);
6852 dovi->dv_version_major = avio_r8(pb);
6853 dovi->dv_version_minor = avio_r8(pb);
6855 buf = avio_rb16(pb);
6856 dovi->dv_profile = (buf >> 9) & 0x7f; // 7 bits
6857 dovi->dv_level = (buf >> 3) & 0x3f; // 6 bits
6858 dovi->rpu_present_flag = (buf >> 2) & 0x01; // 1 bit
6859 dovi->el_present_flag = (buf >> 1) & 0x01; // 1 bit
6860 dovi->bl_present_flag = buf & 0x01; // 1 bit
6861 if (atom.size >= 24) { // 4 + 4 + 4 * 4
6863 dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits
6865 // 0 stands for None
6866 // Dolby Vision V1.2.93 profiles and levels
6867 dovi->dv_bl_signal_compatibility_id = 0;
6870 ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF,
6871 (uint8_t *)dovi, dovi_size);
6877 av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC box, version: %d.%d, profile: %d, level: %d, "
6878 "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n",
6879 dovi->dv_version_major, dovi->dv_version_minor,
6880 dovi->dv_profile, dovi->dv_level,
6881 dovi->rpu_present_flag,
6882 dovi->el_present_flag,
6883 dovi->bl_present_flag,
6884 dovi->dv_bl_signal_compatibility_id
6890 static const MOVParseTableEntry mov_default_parse_table[] = {
6891 { MKTAG('A','C','L','R'), mov_read_aclr },
6892 { MKTAG('A','P','R','G'), mov_read_avid },
6893 { MKTAG('A','A','L','P'), mov_read_avid },
6894 { MKTAG('A','R','E','S'), mov_read_ares },
6895 { MKTAG('a','v','s','s'), mov_read_avss },
6896 { MKTAG('a','v','1','C'), mov_read_av1c },
6897 { MKTAG('c','h','p','l'), mov_read_chpl },
6898 { MKTAG('c','o','6','4'), mov_read_stco },
6899 { MKTAG('c','o','l','r'), mov_read_colr },
6900 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6901 { MKTAG('d','i','n','f'), mov_read_default },
6902 { MKTAG('D','p','x','E'), mov_read_dpxe },
6903 { MKTAG('d','r','e','f'), mov_read_dref },
6904 { MKTAG('e','d','t','s'), mov_read_default },
6905 { MKTAG('e','l','s','t'), mov_read_elst },
6906 { MKTAG('e','n','d','a'), mov_read_enda },
6907 { MKTAG('f','i','e','l'), mov_read_fiel },
6908 { MKTAG('a','d','r','m'), mov_read_adrm },
6909 { MKTAG('f','t','y','p'), mov_read_ftyp },
6910 { MKTAG('g','l','b','l'), mov_read_glbl },
6911 { MKTAG('h','d','l','r'), mov_read_hdlr },
6912 { MKTAG('i','l','s','t'), mov_read_ilst },
6913 { MKTAG('j','p','2','h'), mov_read_jp2h },
6914 { MKTAG('m','d','a','t'), mov_read_mdat },
6915 { MKTAG('m','d','h','d'), mov_read_mdhd },
6916 { MKTAG('m','d','i','a'), mov_read_default },
6917 { MKTAG('m','e','t','a'), mov_read_meta },
6918 { MKTAG('m','i','n','f'), mov_read_default },
6919 { MKTAG('m','o','o','f'), mov_read_moof },
6920 { MKTAG('m','o','o','v'), mov_read_moov },
6921 { MKTAG('m','v','e','x'), mov_read_default },
6922 { MKTAG('m','v','h','d'), mov_read_mvhd },
6923 { MKTAG('S','M','I',' '), mov_read_svq3 },
6924 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6925 { MKTAG('a','v','c','C'), mov_read_glbl },
6926 { MKTAG('p','a','s','p'), mov_read_pasp },
6927 { MKTAG('s','i','d','x'), mov_read_sidx },
6928 { MKTAG('s','t','b','l'), mov_read_default },
6929 { MKTAG('s','t','c','o'), mov_read_stco },
6930 { MKTAG('s','t','p','s'), mov_read_stps },
6931 { MKTAG('s','t','r','f'), mov_read_strf },
6932 { MKTAG('s','t','s','c'), mov_read_stsc },
6933 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6934 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6935 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6936 { MKTAG('s','t','t','s'), mov_read_stts },
6937 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6938 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
6939 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6940 { MKTAG('t','f','d','t'), mov_read_tfdt },
6941 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6942 { MKTAG('t','r','a','k'), mov_read_trak },
6943 { MKTAG('t','r','a','f'), mov_read_default },
6944 { MKTAG('t','r','e','f'), mov_read_default },
6945 { MKTAG('t','m','c','d'), mov_read_tmcd },
6946 { MKTAG('c','h','a','p'), mov_read_chap },
6947 { MKTAG('t','r','e','x'), mov_read_trex },
6948 { MKTAG('t','r','u','n'), mov_read_trun },
6949 { MKTAG('u','d','t','a'), mov_read_default },
6950 { MKTAG('w','a','v','e'), mov_read_wave },
6951 { MKTAG('e','s','d','s'), mov_read_esds },
6952 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6953 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6954 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6955 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6956 { MKTAG('w','f','e','x'), mov_read_wfex },
6957 { MKTAG('c','m','o','v'), mov_read_cmov },
6958 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6959 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6960 { MKTAG('s','b','g','p'), mov_read_sbgp },
6961 { MKTAG('h','v','c','C'), mov_read_glbl },
6962 { MKTAG('u','u','i','d'), mov_read_uuid },
6963 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6964 { MKTAG('f','r','e','e'), mov_read_free },
6965 { MKTAG('-','-','-','-'), mov_read_custom },
6966 { MKTAG('s','i','n','f'), mov_read_default },
6967 { MKTAG('f','r','m','a'), mov_read_frma },
6968 { MKTAG('s','e','n','c'), mov_read_senc },
6969 { MKTAG('s','a','i','z'), mov_read_saiz },
6970 { MKTAG('s','a','i','o'), mov_read_saio },
6971 { MKTAG('p','s','s','h'), mov_read_pssh },
6972 { MKTAG('s','c','h','m'), mov_read_schm },
6973 { MKTAG('s','c','h','i'), mov_read_default },
6974 { MKTAG('t','e','n','c'), mov_read_tenc },
6975 { MKTAG('d','f','L','a'), mov_read_dfla },
6976 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6977 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6978 { MKTAG('d','O','p','s'), mov_read_dops },
6979 { MKTAG('d','m','l','p'), mov_read_dmlp },
6980 { MKTAG('S','m','D','m'), mov_read_smdm },
6981 { MKTAG('C','o','L','L'), mov_read_coll },
6982 { MKTAG('v','p','c','C'), mov_read_vpcc },
6983 { MKTAG('m','d','c','v'), mov_read_mdcv },
6984 { MKTAG('c','l','l','i'), mov_read_clli },
6985 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
6986 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
6990 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6992 int64_t total_size = 0;
6996 if (c->atom_depth > 10) {
6997 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6998 return AVERROR_INVALIDDATA;
7003 atom.size = INT64_MAX;
7004 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
7005 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
7008 if (atom.size >= 8) {
7009 a.size = avio_rb32(pb);
7010 a.type = avio_rl32(pb);
7011 if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
7012 a.type == MKTAG('h','o','o','v')) &&
7014 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
7017 type = avio_rl32(pb);
7020 avio_seek(pb, -8, SEEK_CUR);
7021 if (type == MKTAG('m','v','h','d') ||
7022 type == MKTAG('c','m','o','v')) {
7023 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
7024 a.type = MKTAG('m','o','o','v');
7027 if (atom.type != MKTAG('r','o','o','t') &&
7028 atom.type != MKTAG('m','o','o','v')) {
7029 if (a.type == MKTAG('t','r','a','k') ||
7030 a.type == MKTAG('m','d','a','t')) {
7031 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
7038 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
7039 a.size = avio_rb64(pb) - 8;
7043 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
7044 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
7046 a.size = atom.size - total_size + 8;
7051 a.size = FFMIN(a.size, atom.size - total_size);
7053 for (i = 0; mov_default_parse_table[i].type; i++)
7054 if (mov_default_parse_table[i].type == a.type) {
7055 parse = mov_default_parse_table[i].parse;
7059 // container is user data
7060 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
7061 atom.type == MKTAG('i','l','s','t')))
7062 parse = mov_read_udta_string;
7064 // Supports parsing the QuickTime Metadata Keys.
7065 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
7066 if (!parse && c->found_hdlr_mdta &&
7067 atom.type == MKTAG('m','e','t','a') &&
7068 a.type == MKTAG('k','e','y','s') &&
7069 c->meta_keys_count == 0) {
7070 parse = mov_read_keys;
7073 if (!parse) { /* skip leaf atoms data */
7074 avio_skip(pb, a.size);
7076 int64_t start_pos = avio_tell(pb);
7078 int err = parse(c, pb, a);
7083 if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
7084 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
7085 start_pos + a.size == avio_size(pb))) {
7086 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
7087 c->next_root_atom = start_pos + a.size;
7091 left = a.size - avio_tell(pb) + start_pos;
7092 if (left > 0) /* skip garbage at atom end */
7093 avio_skip(pb, left);
7094 else if (left < 0) {
7095 av_log(c->fc, AV_LOG_WARNING,
7096 "overread end of atom '%s' by %"PRId64" bytes\n",
7097 av_fourcc2str(a.type), -left);
7098 avio_seek(pb, left, SEEK_CUR);
7102 total_size += a.size;
7105 if (total_size < atom.size && atom.size < 0x7ffff)
7106 avio_skip(pb, atom.size - total_size);
7112 static int mov_probe(const AVProbeData *p)
7117 int moov_offset = -1;
7119 /* check file header */
7124 /* ignore invalid offset */
7125 if ((offset + 8) > (unsigned int)p->buf_size)
7127 size = AV_RB32(p->buf + offset);
7128 if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
7129 size = AV_RB64(p->buf+offset + 8);
7131 } else if (size == 0) {
7132 size = p->buf_size - offset;
7134 if (size < minsize) {
7138 tag = AV_RL32(p->buf + offset + 4);
7140 /* check for obvious tags */
7141 case MKTAG('m','o','o','v'):
7142 moov_offset = offset + 4;
7143 case MKTAG('m','d','a','t'):
7144 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
7145 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
7146 case MKTAG('f','t','y','p'):
7147 if (tag == MKTAG('f','t','y','p') &&
7148 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
7149 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
7151 score = FFMAX(score, 5);
7153 score = AVPROBE_SCORE_MAX;
7156 /* those are more common words, so rate then a bit less */
7157 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
7158 case MKTAG('w','i','d','e'):
7159 case MKTAG('f','r','e','e'):
7160 case MKTAG('j','u','n','k'):
7161 case MKTAG('p','i','c','t'):
7162 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
7164 case MKTAG(0x82,0x82,0x7f,0x7d):
7165 case MKTAG('s','k','i','p'):
7166 case MKTAG('u','u','i','d'):
7167 case MKTAG('p','r','f','l'):
7168 /* if we only find those cause probedata is too small at least rate them */
7169 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7174 if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
7175 /* moov atom in the header - we should make sure that this is not a
7176 * MOV-packed MPEG-PS */
7177 offset = moov_offset;
7179 while (offset < (p->buf_size - 16)) { /* Sufficient space */
7180 /* We found an actual hdlr atom */
7181 if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7182 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7183 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
7184 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7185 /* We found a media handler reference atom describing an
7186 * MPEG-PS-in-MOV, return a
7187 * low score to force expanding the probe window until
7188 * mpegps_probe finds what it needs */
7200 // must be done after parsing all trak because there's no order requirement
7201 static void mov_read_chapters(AVFormatContext *s)
7203 MOVContext *mov = s->priv_data;
7205 MOVStreamContext *sc;
7210 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7211 chapter_track = mov->chapter_tracks[j];
7213 for (i = 0; i < s->nb_streams; i++)
7214 if (s->streams[i]->id == chapter_track) {
7219 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7224 cur_pos = avio_tell(sc->pb);
7226 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7227 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7228 if (st->internal->nb_index_entries) {
7229 // Retrieve the first frame, if possible
7230 AVIndexEntry *sample = &st->internal->index_entries[0];
7231 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7232 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7236 if (av_get_packet(sc->pb, &st->attached_pic, sample->size) < 0)
7239 st->attached_pic.stream_index = st->index;
7240 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
7243 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7244 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7245 st->discard = AVDISCARD_ALL;
7246 for (i = 0; i < st->internal->nb_index_entries; i++) {
7247 AVIndexEntry *sample = &st->internal->index_entries[i];
7248 int64_t end = i+1 < st->internal->nb_index_entries ? st->internal->index_entries[i+1].timestamp : st->duration;
7253 if (end < sample->timestamp) {
7254 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7255 end = AV_NOPTS_VALUE;
7258 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7259 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7263 // the first two bytes are the length of the title
7264 len = avio_rb16(sc->pb);
7265 if (len > sample->size-2)
7267 title_len = 2*len + 1;
7268 if (!(title = av_mallocz(title_len)))
7271 // The samples could theoretically be in any encoding if there's an encd
7272 // atom following, but in practice are only utf-8 or utf-16, distinguished
7273 // instead by the presence of a BOM
7277 ch = avio_rb16(sc->pb);
7279 avio_get_str16be(sc->pb, len, title, title_len);
7280 else if (ch == 0xfffe)
7281 avio_get_str16le(sc->pb, len, title, title_len);
7284 if (len == 1 || len == 2)
7287 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7291 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7296 avio_seek(sc->pb, cur_pos, SEEK_SET);
7300 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7301 uint32_t value, int flags)
7304 char buf[AV_TIMECODE_STR_SIZE];
7305 AVRational rate = st->avg_frame_rate;
7306 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7309 av_dict_set(&st->metadata, "timecode",
7310 av_timecode_make_string(&tc, buf, value), 0);
7314 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7316 MOVStreamContext *sc = st->priv_data;
7317 char buf[AV_TIMECODE_STR_SIZE];
7318 int64_t cur_pos = avio_tell(sc->pb);
7319 int hh, mm, ss, ff, drop;
7321 if (!st->internal->nb_index_entries)
7324 avio_seek(sc->pb, st->internal->index_entries->pos, SEEK_SET);
7325 avio_skip(s->pb, 13);
7326 hh = avio_r8(s->pb);
7327 mm = avio_r8(s->pb);
7328 ss = avio_r8(s->pb);
7329 drop = avio_r8(s->pb);
7330 ff = avio_r8(s->pb);
7331 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7332 hh, mm, ss, drop ? ';' : ':', ff);
7333 av_dict_set(&st->metadata, "timecode", buf, 0);
7335 avio_seek(sc->pb, cur_pos, SEEK_SET);
7339 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7341 MOVStreamContext *sc = st->priv_data;
7343 int64_t cur_pos = avio_tell(sc->pb);
7346 if (!st->internal->nb_index_entries)
7349 avio_seek(sc->pb, st->internal->index_entries->pos, SEEK_SET);
7350 value = avio_rb32(s->pb);
7352 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7353 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7354 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7356 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7357 * not the case) and thus assume "frame number format" instead of QT one.
7358 * No sample with tmcd track can be found with a QT timecode at the moment,
7359 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7361 parse_timecode_in_framenum_format(s, st, value, flags);
7363 avio_seek(sc->pb, cur_pos, SEEK_SET);
7367 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7369 if (!index || !*index) return;
7370 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7371 av_encryption_info_free((*index)->encrypted_samples[i]);
7373 av_freep(&(*index)->encrypted_samples);
7374 av_freep(&(*index)->auxiliary_info_sizes);
7375 av_freep(&(*index)->auxiliary_offsets);
7379 static int mov_read_close(AVFormatContext *s)
7381 MOVContext *mov = s->priv_data;
7384 for (i = 0; i < s->nb_streams; i++) {
7385 AVStream *st = s->streams[i];
7386 MOVStreamContext *sc = st->priv_data;
7391 av_freep(&sc->ctts_data);
7392 for (j = 0; j < sc->drefs_count; j++) {
7393 av_freep(&sc->drefs[j].path);
7394 av_freep(&sc->drefs[j].dir);
7396 av_freep(&sc->drefs);
7398 sc->drefs_count = 0;
7400 if (!sc->pb_is_copied)
7401 ff_format_io_close(s, &sc->pb);
7404 av_freep(&sc->chunk_offsets);
7405 av_freep(&sc->stsc_data);
7406 av_freep(&sc->sample_sizes);
7407 av_freep(&sc->keyframes);
7408 av_freep(&sc->stts_data);
7409 av_freep(&sc->sdtp_data);
7410 av_freep(&sc->stps_data);
7411 av_freep(&sc->elst_data);
7412 av_freep(&sc->rap_group);
7413 av_freep(&sc->display_matrix);
7414 av_freep(&sc->index_ranges);
7417 for (j = 0; j < sc->stsd_count; j++)
7418 av_free(sc->extradata[j]);
7419 av_freep(&sc->extradata);
7420 av_freep(&sc->extradata_size);
7422 mov_free_encryption_index(&sc->cenc.encryption_index);
7423 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7424 av_aes_ctr_free(sc->cenc.aes_ctr);
7426 av_freep(&sc->stereo3d);
7427 av_freep(&sc->spherical);
7428 av_freep(&sc->mastering);
7429 av_freep(&sc->coll);
7432 av_freep(&mov->dv_demux);
7433 avformat_free_context(mov->dv_fctx);
7434 mov->dv_fctx = NULL;
7436 if (mov->meta_keys) {
7437 for (i = 1; i < mov->meta_keys_count; i++) {
7438 av_freep(&mov->meta_keys[i]);
7440 av_freep(&mov->meta_keys);
7443 av_freep(&mov->trex_data);
7444 av_freep(&mov->bitrates);
7446 for (i = 0; i < mov->frag_index.nb_items; i++) {
7447 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7448 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7449 mov_free_encryption_index(&frag[j].encryption_index);
7451 av_freep(&mov->frag_index.item[i].stream_info);
7453 av_freep(&mov->frag_index.item);
7455 av_freep(&mov->aes_decrypt);
7456 av_freep(&mov->chapter_tracks);
7461 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7465 for (i = 0; i < s->nb_streams; i++) {
7466 AVStream *st = s->streams[i];
7467 MOVStreamContext *sc = st->priv_data;
7469 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7470 sc->timecode_track == tmcd_id)
7476 /* look for a tmcd track not referenced by any video track, and export it globally */
7477 static void export_orphan_timecode(AVFormatContext *s)
7481 for (i = 0; i < s->nb_streams; i++) {
7482 AVStream *st = s->streams[i];
7484 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7485 !tmcd_is_referenced(s, i + 1)) {
7486 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7488 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7495 static int read_tfra(MOVContext *mov, AVIOContext *f)
7497 int version, fieldlength, i, j;
7498 int64_t pos = avio_tell(f);
7499 uint32_t size = avio_rb32(f);
7500 unsigned track_id, item_count;
7502 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7505 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7507 version = avio_r8(f);
7509 track_id = avio_rb32(f);
7510 fieldlength = avio_rb32(f);
7511 item_count = avio_rb32(f);
7512 for (i = 0; i < item_count; i++) {
7513 int64_t time, offset;
7515 MOVFragmentStreamInfo * frag_stream_info;
7518 return AVERROR_INVALIDDATA;
7522 time = avio_rb64(f);
7523 offset = avio_rb64(f);
7525 time = avio_rb32(f);
7526 offset = avio_rb32(f);
7529 // The first sample of each stream in a fragment is always a random
7530 // access sample. So it's entry in the tfra can be used as the
7531 // initial PTS of the fragment.
7532 index = update_frag_index(mov, offset);
7533 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7534 if (frag_stream_info &&
7535 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7536 frag_stream_info->first_tfra_pts = time;
7538 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7540 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7542 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7546 avio_seek(f, pos + size, SEEK_SET);
7550 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7552 int64_t stream_size = avio_size(f);
7553 int64_t original_pos = avio_tell(f);
7556 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7560 c->mfra_size = avio_rb32(f);
7561 c->have_read_mfra_size = 1;
7562 if (!c->mfra_size || c->mfra_size > stream_size) {
7563 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7566 if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
7570 if (avio_rb32(f) != c->mfra_size) {
7571 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7574 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7575 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7578 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7580 ret = read_tfra(c, f);
7585 c->frag_index.complete = 1;
7587 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7589 av_log(c->fc, AV_LOG_ERROR,
7590 "failed to seek back after looking for mfra\n");
7596 static int mov_read_header(AVFormatContext *s)
7598 MOVContext *mov = s->priv_data;
7599 AVIOContext *pb = s->pb;
7601 MOVAtom atom = { AV_RL32("root") };
7604 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7605 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7606 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7607 return AVERROR(EINVAL);
7611 mov->trak_index = -1;
7612 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7613 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7614 atom.size = avio_size(pb);
7616 atom.size = INT64_MAX;
7618 /* check MOV header */
7620 if (mov->moov_retry)
7621 avio_seek(pb, 0, SEEK_SET);
7622 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7623 av_log(s, AV_LOG_ERROR, "error reading header\n");
7626 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7627 if (!mov->found_moov) {
7628 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7629 err = AVERROR_INVALIDDATA;
7632 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7634 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7635 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7636 mov_read_chapters(s);
7637 for (i = 0; i < s->nb_streams; i++)
7638 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7639 mov_read_timecode_track(s, s->streams[i]);
7640 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7641 mov_read_rtmd_track(s, s->streams[i]);
7645 /* copy timecode metadata from tmcd tracks to the related video streams */
7646 for (i = 0; i < s->nb_streams; i++) {
7647 AVStream *st = s->streams[i];
7648 MOVStreamContext *sc = st->priv_data;
7649 if (sc->timecode_track > 0) {
7650 AVDictionaryEntry *tcr;
7651 int tmcd_st_id = -1;
7653 for (j = 0; j < s->nb_streams; j++)
7654 if (s->streams[j]->id == sc->timecode_track)
7657 if (tmcd_st_id < 0 || tmcd_st_id == i)
7659 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7661 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7664 export_orphan_timecode(s);
7666 for (i = 0; i < s->nb_streams; i++) {
7667 AVStream *st = s->streams[i];
7668 MOVStreamContext *sc = st->priv_data;
7669 fix_timescale(mov, sc);
7670 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
7671 st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7672 st->internal->skip_samples = sc->start_pad;
7674 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7675 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7676 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7677 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7678 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7679 st->codecpar->width = sc->width;
7680 st->codecpar->height = sc->height;
7682 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7683 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7687 if (mov->handbrake_version &&
7688 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7689 st->codecpar->codec_id == AV_CODEC_ID_MP3) {
7690 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7691 st->need_parsing = AVSTREAM_PARSE_FULL;
7695 if (mov->trex_data) {
7696 for (i = 0; i < s->nb_streams; i++) {
7697 AVStream *st = s->streams[i];
7698 MOVStreamContext *sc = st->priv_data;
7699 if (st->duration > 0) {
7700 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7701 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7702 sc->data_size, sc->time_scale);
7703 err = AVERROR_INVALIDDATA;
7706 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7711 if (mov->use_mfra_for > 0) {
7712 for (i = 0; i < s->nb_streams; i++) {
7713 AVStream *st = s->streams[i];
7714 MOVStreamContext *sc = st->priv_data;
7715 if (sc->duration_for_fps > 0) {
7716 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7717 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7718 sc->data_size, sc->time_scale);
7719 err = AVERROR_INVALIDDATA;
7722 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7723 sc->duration_for_fps;
7728 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7729 if (mov->bitrates[i]) {
7730 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7734 ff_rfps_calculate(s);
7736 for (i = 0; i < s->nb_streams; i++) {
7737 AVStream *st = s->streams[i];
7738 MOVStreamContext *sc = st->priv_data;
7740 switch (st->codecpar->codec_type) {
7741 case AVMEDIA_TYPE_AUDIO:
7742 err = ff_replaygain_export(st, s->metadata);
7746 case AVMEDIA_TYPE_VIDEO:
7747 if (sc->display_matrix) {
7748 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7749 sizeof(int32_t) * 9);
7753 sc->display_matrix = NULL;
7756 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7757 (uint8_t *)sc->stereo3d,
7758 sizeof(*sc->stereo3d));
7762 sc->stereo3d = NULL;
7764 if (sc->spherical) {
7765 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7766 (uint8_t *)sc->spherical,
7767 sc->spherical_size);
7771 sc->spherical = NULL;
7773 if (sc->mastering) {
7774 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7775 (uint8_t *)sc->mastering,
7776 sizeof(*sc->mastering));
7780 sc->mastering = NULL;
7783 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7784 (uint8_t *)sc->coll,
7794 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7796 for (i = 0; i < mov->frag_index.nb_items; i++)
7797 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7798 mov->frag_index.item[i].headers_read = 1;
7806 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7808 AVIndexEntry *sample = NULL;
7809 int64_t best_dts = INT64_MAX;
7811 for (i = 0; i < s->nb_streams; i++) {
7812 AVStream *avst = s->streams[i];
7813 MOVStreamContext *msc = avst->priv_data;
7814 if (msc->pb && msc->current_sample < avst->internal->nb_index_entries) {
7815 AVIndexEntry *current_sample = &avst->internal->index_entries[msc->current_sample];
7816 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7817 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7818 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7819 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7820 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
7821 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7822 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7823 sample = current_sample;
7832 static int should_retry(AVIOContext *pb, int error_code) {
7833 if (error_code == AVERROR_EOF || avio_feof(pb))
7839 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7842 MOVContext *mov = s->priv_data;
7844 if (index >= 0 && index < mov->frag_index.nb_items)
7845 target = mov->frag_index.item[index].moof_offset;
7846 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7847 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7848 return AVERROR_INVALIDDATA;
7851 mov->next_root_atom = 0;
7852 if (index < 0 || index >= mov->frag_index.nb_items)
7853 index = search_frag_moof_offset(&mov->frag_index, target);
7854 if (index < mov->frag_index.nb_items &&
7855 mov->frag_index.item[index].moof_offset == target) {
7856 if (index + 1 < mov->frag_index.nb_items)
7857 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7858 if (mov->frag_index.item[index].headers_read)
7860 mov->frag_index.item[index].headers_read = 1;
7863 mov->found_mdat = 0;
7865 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7868 if (avio_feof(s->pb))
7870 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7875 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7877 uint8_t *side, *extradata;
7880 /* Save the current index. */
7881 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7883 /* Notify the decoder that extradata changed. */
7884 extradata_size = sc->extradata_size[sc->last_stsd_index];
7885 extradata = sc->extradata[sc->last_stsd_index];
7886 if (extradata_size > 0 && extradata) {
7887 side = av_packet_new_side_data(pkt,
7888 AV_PKT_DATA_NEW_EXTRADATA,
7891 return AVERROR(ENOMEM);
7892 memcpy(side, extradata, extradata_size);
7898 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int size)
7903 return AVERROR_INVALIDDATA;
7904 new_size = ((size - 8) / 2) * 3;
7905 ret = av_new_packet(pkt, new_size);
7910 for (int j = 0; j < new_size; j += 3) {
7911 pkt->data[j] = 0xFC;
7912 pkt->data[j+1] = avio_r8(pb);
7913 pkt->data[j+2] = avio_r8(pb);
7919 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7921 MOVContext *mov = s->priv_data;
7922 MOVStreamContext *sc;
7923 AVIndexEntry *sample;
7924 AVStream *st = NULL;
7925 int64_t current_index;
7929 sample = mov_find_next_sample(s, &st);
7930 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7931 if (!mov->next_root_atom)
7933 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7938 /* must be done just before reading, to avoid infinite loop on sample */
7939 current_index = sc->current_index;
7940 mov_current_sample_inc(sc);
7942 if (mov->next_root_atom) {
7943 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7944 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7947 if (st->discard != AVDISCARD_ALL) {
7948 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7949 if (ret64 != sample->pos) {
7950 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7951 sc->ffindex, sample->pos);
7952 if (should_retry(sc->pb, ret64)) {
7953 mov_current_sample_dec(sc);
7954 } else if (ret64 < 0) {
7957 return AVERROR_INVALIDDATA;
7960 if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
7961 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7965 if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
7966 ret = get_eia608_packet(sc->pb, pkt, sample->size);
7968 ret = av_get_packet(sc->pb, pkt, sample->size);
7970 if (should_retry(sc->pb, ret)) {
7971 mov_current_sample_dec(sc);
7975 #if CONFIG_DV_DEMUXER
7976 if (mov->dv_demux && sc->dv_audio_container) {
7977 AVBufferRef *buf = pkt->buf;
7978 ret = avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7980 av_packet_unref(pkt);
7983 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7988 if (sc->has_palette) {
7991 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7993 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7995 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7996 sc->has_palette = 0;
7999 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
8000 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
8001 st->need_parsing = AVSTREAM_PARSE_FULL;
8005 pkt->stream_index = sc->ffindex;
8006 pkt->dts = sample->timestamp;
8007 if (sample->flags & AVINDEX_DISCARD_FRAME) {
8008 pkt->flags |= AV_PKT_FLAG_DISCARD;
8010 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
8011 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
8012 /* update ctts context */
8014 if (sc->ctts_index < sc->ctts_count &&
8015 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
8017 sc->ctts_sample = 0;
8020 int64_t next_dts = (sc->current_sample < st->internal->nb_index_entries) ?
8021 st->internal->index_entries[sc->current_sample].timestamp : st->duration;
8023 if (next_dts >= pkt->dts)
8024 pkt->duration = next_dts - pkt->dts;
8025 pkt->pts = pkt->dts;
8027 if (st->discard == AVDISCARD_ALL)
8029 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
8030 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
8031 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
8032 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
8034 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
8035 pkt->pos = sample->pos;
8037 /* Multiple stsd handling. */
8038 if (sc->stsc_data) {
8039 /* Keep track of the stsc index for the given sample, then check
8040 * if the stsd index is different from the last used one. */
8042 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
8043 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
8045 sc->stsc_sample = 0;
8046 /* Do not check indexes after a switch. */
8047 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
8048 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
8049 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
8050 ret = mov_change_extradata(sc, pkt);
8057 aax_filter(pkt->data, pkt->size, mov);
8059 ret = cenc_filter(mov, st, sc, pkt, current_index);
8067 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
8069 MOVContext *mov = s->priv_data;
8072 if (!mov->frag_index.complete)
8075 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
8078 if (!mov->frag_index.item[index].headers_read)
8079 return mov_switch_root(s, -1, index);
8080 if (index + 1 < mov->frag_index.nb_items)
8081 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
8086 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
8088 MOVStreamContext *sc = st->priv_data;
8089 int sample, time_sample, ret;
8092 // Here we consider timestamp to be PTS, hence try to offset it so that we
8093 // can search over the DTS timeline.
8094 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
8096 ret = mov_seek_fragment(s, st, timestamp);
8100 sample = av_index_search_timestamp(st, timestamp, flags);
8101 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
8102 if (sample < 0 && st->internal->nb_index_entries && timestamp < st->internal->index_entries[0].timestamp)
8104 if (sample < 0) /* not sure what to do */
8105 return AVERROR_INVALIDDATA;
8106 mov_current_sample_set(sc, sample);
8107 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
8108 /* adjust ctts index */
8109 if (sc->ctts_data) {
8111 for (i = 0; i < sc->ctts_count; i++) {
8112 int next = time_sample + sc->ctts_data[i].count;
8113 if (next > sc->current_sample) {
8115 sc->ctts_sample = sc->current_sample - time_sample;
8122 /* adjust stsd index */
8123 if (sc->chunk_count) {
8125 for (i = 0; i < sc->stsc_count; i++) {
8126 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
8127 if (next > sc->current_sample) {
8129 sc->stsc_sample = sc->current_sample - time_sample;
8132 av_assert0(next == (int)next);
8140 static int64_t mov_get_skip_samples(AVStream *st, int sample)
8142 MOVStreamContext *sc = st->priv_data;
8143 int64_t first_ts = st->internal->index_entries[0].timestamp;
8144 int64_t ts = st->internal->index_entries[sample].timestamp;
8147 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO)
8150 /* compute skip samples according to stream start_pad, seek ts and first ts */
8151 off = av_rescale_q(ts - first_ts, st->time_base,
8152 (AVRational){1, st->codecpar->sample_rate});
8153 return FFMAX(sc->start_pad - off, 0);
8156 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
8158 MOVContext *mc = s->priv_data;
8163 if (stream_index >= s->nb_streams)
8164 return AVERROR_INVALIDDATA;
8166 st = s->streams[stream_index];
8167 sample = mov_seek_stream(s, st, sample_time, flags);
8171 if (mc->seek_individually) {
8172 /* adjust seek timestamp to found sample timestamp */
8173 int64_t seek_timestamp = st->internal->index_entries[sample].timestamp;
8174 st->internal->skip_samples = mov_get_skip_samples(st, sample);
8176 for (i = 0; i < s->nb_streams; i++) {
8180 if (stream_index == i)
8183 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
8184 sample = mov_seek_stream(s, st, timestamp, flags);
8186 st->internal->skip_samples = mov_get_skip_samples(st, sample);
8189 for (i = 0; i < s->nb_streams; i++) {
8190 MOVStreamContext *sc;
8193 mov_current_sample_set(sc, 0);
8196 MOVStreamContext *sc;
8197 AVIndexEntry *entry = mov_find_next_sample(s, &st);
8199 return AVERROR_INVALIDDATA;
8201 if (sc->ffindex == stream_index && sc->current_sample == sample)
8203 mov_current_sample_inc(sc);
8209 #define OFFSET(x) offsetof(MOVContext, x)
8210 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
8211 static const AVOption mov_options[] = {
8212 {"use_absolute_path",
8213 "allow using absolute path when opening alias, this is a possible security issue",
8214 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
8216 {"seek_streams_individually",
8217 "Seek each stream individually to the closest point",
8218 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
8220 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
8222 {"advanced_editlist",
8223 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
8224 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
8226 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8229 "use mfra for fragment timestamps",
8230 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8231 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8233 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8234 FLAGS, "use_mfra_for" },
8235 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8236 FLAGS, "use_mfra_for" },
8237 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8238 FLAGS, "use_mfra_for" },
8239 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8240 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8241 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8242 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8243 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8244 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8245 { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
8246 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8247 { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
8248 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8249 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8250 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8251 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8252 .flags = AV_OPT_FLAG_DECODING_PARAM },
8253 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8254 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8255 {.i64 = 0}, 0, 1, FLAGS },
8260 static const AVClass mov_class = {
8261 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8262 .item_name = av_default_item_name,
8263 .option = mov_options,
8264 .version = LIBAVUTIL_VERSION_INT,
8267 AVInputFormat ff_mov_demuxer = {
8268 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8269 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8270 .priv_class = &mov_class,
8271 .priv_data_size = sizeof(MOVContext),
8272 .extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
8273 .read_probe = mov_probe,
8274 .read_header = mov_read_header,
8275 .read_packet = mov_read_packet,
8276 .read_close = mov_read_close,
8277 .read_seek = mov_read_seek,
8278 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,