3 * Copyright (c) 2001 Fabrice Bellard
4 * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
6 * first version by Francois Revol <revol@free.fr>
7 * seek function by Gael Chardon <gael.dev@4now.net>
9 * This file is part of FFmpeg.
11 * FFmpeg is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * FFmpeg is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with FFmpeg; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30 #include "libavutil/attributes.h"
31 #include "libavutil/channel_layout.h"
32 #include "libavutil/internal.h"
33 #include "libavutil/intreadwrite.h"
34 #include "libavutil/intfloat.h"
35 #include "libavutil/mathematics.h"
36 #include "libavutil/time_internal.h"
37 #include "libavutil/avassert.h"
38 #include "libavutil/avstring.h"
39 #include "libavutil/dict.h"
40 #include "libavutil/display.h"
41 #include "libavutil/opt.h"
42 #include "libavutil/aes.h"
43 #include "libavutil/aes_ctr.h"
44 #include "libavutil/pixdesc.h"
45 #include "libavutil/sha.h"
46 #include "libavutil/spherical.h"
47 #include "libavutil/stereo3d.h"
48 #include "libavutil/timecode.h"
49 #include "libavutil/dovi_meta.h"
50 #include "libavcodec/ac3tab.h"
51 #include "libavcodec/flac.h"
52 #include "libavcodec/mpegaudiodecheader.h"
53 #include "libavcodec/mlp_parse.h"
56 #include "avio_internal.h"
59 #include "libavcodec/get_bits.h"
62 #include "replaygain.h"
68 #include "qtpalette.h"
70 /* those functions parse an atom */
71 /* links atom IDs to parse functions */
72 typedef struct MOVParseTableEntry {
74 int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
77 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
78 static int mov_read_mfra(MOVContext *c, AVIOContext *f);
79 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
80 int count, int duration);
82 static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb,
83 unsigned len, const char *key)
87 short current, total = 0;
88 avio_rb16(pb); // unknown
89 current = avio_rb16(pb);
91 total = avio_rb16(pb);
93 snprintf(buf, sizeof(buf), "%d", current);
95 snprintf(buf, sizeof(buf), "%d/%d", current, total);
96 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
97 av_dict_set(&c->fc->metadata, key, buf, 0);
102 static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb,
103 unsigned len, const char *key)
105 /* bypass padding bytes */
110 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
111 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
116 static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb,
117 unsigned len, const char *key)
119 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
120 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
125 static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb,
126 unsigned len, const char *key)
130 avio_r8(pb); // unknown
133 if (genre < 1 || genre > ID3v1_GENRE_MAX)
135 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
136 av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
141 static const uint32_t mac_to_unicode[128] = {
142 0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
143 0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
144 0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
145 0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
146 0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
147 0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
148 0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
149 0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
150 0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
151 0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
152 0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
153 0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
154 0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
155 0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
156 0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
157 0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
160 static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len,
161 char *dst, int dstlen)
164 char *end = dst+dstlen-1;
167 for (i = 0; i < len; i++) {
168 uint8_t t, c = avio_r8(pb);
176 PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
182 static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
185 MOVStreamContext *sc;
190 case 0xd: id = AV_CODEC_ID_MJPEG; break;
191 case 0xe: id = AV_CODEC_ID_PNG; break;
192 case 0x1b: id = AV_CODEC_ID_BMP; break;
194 av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
199 st = avformat_new_stream(c->fc, NULL);
201 return AVERROR(ENOMEM);
202 sc = av_mallocz(sizeof(*sc));
204 return AVERROR(ENOMEM);
207 ret = av_get_packet(pb, &st->attached_pic, len);
211 if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) {
212 if (AV_RB64(st->attached_pic.data) == 0x89504e470d0a1a0a) {
213 id = AV_CODEC_ID_PNG;
215 id = AV_CODEC_ID_MJPEG;
219 st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
221 st->attached_pic.stream_index = st->index;
222 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
224 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
225 st->codecpar->codec_id = id;
231 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
233 char language[4] = { 0 };
234 char buf[200], place[100];
235 uint16_t langcode = 0;
236 double longitude, latitude, altitude;
237 const char *key = "location";
239 if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
240 av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
241 return AVERROR_INVALIDDATA;
244 avio_skip(pb, 4); // version+flags
245 langcode = avio_rb16(pb);
246 ff_mov_lang_to_iso639(langcode, language);
249 len -= avio_get_str(pb, len, place, sizeof(place));
251 av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
252 return AVERROR_INVALIDDATA;
254 avio_skip(pb, 1); // role
258 av_log(c->fc, AV_LOG_ERROR,
259 "loci too short (%u bytes left, need at least %d)\n", len, 12);
260 return AVERROR_INVALIDDATA;
262 longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
263 latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
264 altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
266 // Try to output in the same format as the ?xyz field
267 snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
269 av_strlcatf(buf, sizeof(buf), "%+f", altitude);
270 av_strlcatf(buf, sizeof(buf), "/%s", place);
272 if (*language && strcmp(language, "und")) {
274 snprintf(key2, sizeof(key2), "%s-%s", key, language);
275 av_dict_set(&c->fc->metadata, key2, buf, 0);
277 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
278 return av_dict_set(&c->fc->metadata, key, buf, 0);
281 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
287 if (c->ignore_chapters)
290 n_hmmt = avio_rb32(pb);
291 if (n_hmmt > len / 4)
292 return AVERROR_INVALIDDATA;
293 for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
294 int moment_time = avio_rb32(pb);
295 avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
300 static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
302 char tmp_key[AV_FOURCC_MAX_STRING_SIZE] = {0};
303 char key2[32], language[4] = {0};
305 const char *key = NULL;
306 uint16_t langcode = 0;
307 uint32_t data_type = 0, str_size, str_size_alloc;
308 int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
313 case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
314 case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
315 case MKTAG( 'X','M','P','_'):
316 if (c->export_xmp) { key = "xmp"; raw = 1; } break;
317 case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
318 case MKTAG( 'a','k','I','D'): key = "account_type";
319 parse = mov_metadata_int8_no_padding; break;
320 case MKTAG( 'a','p','I','D'): key = "account_id"; break;
321 case MKTAG( 'c','a','t','g'): key = "category"; break;
322 case MKTAG( 'c','p','i','l'): key = "compilation";
323 parse = mov_metadata_int8_no_padding; break;
324 case MKTAG( 'c','p','r','t'): key = "copyright"; break;
325 case MKTAG( 'd','e','s','c'): key = "description"; break;
326 case MKTAG( 'd','i','s','k'): key = "disc";
327 parse = mov_metadata_track_or_disc_number; break;
328 case MKTAG( 'e','g','i','d'): key = "episode_uid";
329 parse = mov_metadata_int8_no_padding; break;
330 case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
331 case MKTAG( 'g','n','r','e'): key = "genre";
332 parse = mov_metadata_gnre; break;
333 case MKTAG( 'h','d','v','d'): key = "hd_video";
334 parse = mov_metadata_int8_no_padding; break;
335 case MKTAG( 'H','M','M','T'):
336 return mov_metadata_hmmt(c, pb, atom.size);
337 case MKTAG( 'k','e','y','w'): key = "keywords"; break;
338 case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
339 case MKTAG( 'l','o','c','i'):
340 return mov_metadata_loci(c, pb, atom.size);
341 case MKTAG( 'm','a','n','u'): key = "make"; break;
342 case MKTAG( 'm','o','d','l'): key = "model"; break;
343 case MKTAG( 'p','c','s','t'): key = "podcast";
344 parse = mov_metadata_int8_no_padding; break;
345 case MKTAG( 'p','g','a','p'): key = "gapless_playback";
346 parse = mov_metadata_int8_no_padding; break;
347 case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
348 case MKTAG( 'r','t','n','g'): key = "rating";
349 parse = mov_metadata_int8_no_padding; break;
350 case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
351 case MKTAG( 's','o','a','l'): key = "sort_album"; break;
352 case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
353 case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
354 case MKTAG( 's','o','n','m'): key = "sort_name"; break;
355 case MKTAG( 's','o','s','n'): key = "sort_show"; break;
356 case MKTAG( 's','t','i','k'): key = "media_type";
357 parse = mov_metadata_int8_no_padding; break;
358 case MKTAG( 't','r','k','n'): key = "track";
359 parse = mov_metadata_track_or_disc_number; break;
360 case MKTAG( 't','v','e','n'): key = "episode_id"; break;
361 case MKTAG( 't','v','e','s'): key = "episode_sort";
362 parse = mov_metadata_int8_bypass_padding; break;
363 case MKTAG( 't','v','n','n'): key = "network"; break;
364 case MKTAG( 't','v','s','h'): key = "show"; break;
365 case MKTAG( 't','v','s','n'): key = "season_number";
366 parse = mov_metadata_int8_bypass_padding; break;
367 case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
368 case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
369 case MKTAG(0xa9,'a','l','b'): key = "album"; break;
370 case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
371 case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
372 case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
373 case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
374 case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
375 case MKTAG(0xa9,'d','a','y'): key = "date"; break;
376 case MKTAG(0xa9,'d','i','r'): key = "director"; break;
377 case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
378 case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
379 case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
380 case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
381 case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
382 case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
383 case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
384 case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
385 case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
386 case MKTAG(0xa9,'m','a','k'): key = "make"; break;
387 case MKTAG(0xa9,'m','o','d'): key = "model"; break;
388 case MKTAG(0xa9,'n','a','m'): key = "title"; break;
389 case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
390 case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
391 case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
392 case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
393 case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
394 case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
395 case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
396 case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
397 case MKTAG(0xa9,'t','r','k'): key = "track"; break;
398 case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
399 case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
400 case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
401 case MKTAG(0xa9,'x','y','z'): key = "location"; break;
404 if (c->itunes_metadata && atom.size > 8) {
405 int data_size = avio_rb32(pb);
406 int tag = avio_rl32(pb);
407 if (tag == MKTAG('d','a','t','a') && data_size <= atom.size && data_size >= 16) {
408 data_type = avio_rb32(pb); // type
409 avio_rb32(pb); // unknown
410 str_size = data_size - 16;
413 if (atom.type == MKTAG('c', 'o', 'v', 'r')) {
414 int ret = mov_read_covr(c, pb, data_type, str_size);
416 av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
419 atom.size -= str_size;
423 } else if (!key && c->found_hdlr_mdta && c->meta_keys) {
424 uint32_t index = AV_RB32(&atom.type);
425 if (index < c->meta_keys_count && index > 0) {
426 key = c->meta_keys[index];
428 av_log(c->fc, AV_LOG_WARNING,
429 "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
430 index, c->meta_keys_count);
434 } else if (atom.size > 4 && key && !c->itunes_metadata && !raw) {
435 str_size = avio_rb16(pb); // string length
436 if (str_size > atom.size) {
438 avio_seek(pb, -2, SEEK_CUR);
439 av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
442 langcode = avio_rb16(pb);
443 ff_mov_lang_to_iso639(langcode, language);
446 str_size = atom.size;
448 if (c->export_all && !key) {
449 key = av_fourcc_make_string(tmp_key, atom.type);
454 if (atom.size < 0 || str_size >= INT_MAX/2)
455 return AVERROR_INVALIDDATA;
457 // Allocates enough space if data_type is a int32 or float32 number, otherwise
458 // worst-case requirement for output string in case of utf8 coded input
459 num = (data_type >= 21 && data_type <= 23);
460 str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
461 str = av_mallocz(str_size_alloc);
463 return AVERROR(ENOMEM);
466 parse(c, pb, str_size, key);
468 if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
469 mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
470 } else if (data_type == 21) { // BE signed integer, variable size
473 val = (int8_t)avio_r8(pb);
474 else if (str_size == 2)
475 val = (int16_t)avio_rb16(pb);
476 else if (str_size == 3)
477 val = ((int32_t)(avio_rb24(pb)<<8))>>8;
478 else if (str_size == 4)
479 val = (int32_t)avio_rb32(pb);
480 if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
481 av_log(c->fc, AV_LOG_ERROR,
482 "Failed to store the number (%d) in string.\n", val);
484 return AVERROR_INVALIDDATA;
486 } else if (data_type == 22) { // BE unsigned integer, variable size
487 unsigned int val = 0;
490 else if (str_size == 2)
492 else if (str_size == 3)
494 else if (str_size == 4)
496 if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
497 av_log(c->fc, AV_LOG_ERROR,
498 "Failed to store the number (%u) in string.\n", val);
500 return AVERROR_INVALIDDATA;
502 } else if (data_type == 23 && str_size >= 4) { // BE float32
503 float val = av_int2float(avio_rb32(pb));
504 if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
505 av_log(c->fc, AV_LOG_ERROR,
506 "Failed to store the float32 number (%f) in string.\n", val);
508 return AVERROR_INVALIDDATA;
511 int ret = ffio_read_size(pb, str, str_size);
518 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
519 av_dict_set(&c->fc->metadata, key, str, 0);
520 if (*language && strcmp(language, "und")) {
521 snprintf(key2, sizeof(key2), "%s-%s", key, language);
522 av_dict_set(&c->fc->metadata, key2, str, 0);
524 if (!strcmp(key, "encoder")) {
525 int major, minor, micro;
526 if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, µ) == 3) {
527 c->handbrake_version = 1000000*major + 1000*minor + micro;
536 static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
539 int i, nb_chapters, str_len, version;
543 if (c->ignore_chapters)
546 if ((atom.size -= 5) < 0)
549 version = avio_r8(pb);
552 avio_rb32(pb); // ???
553 nb_chapters = avio_r8(pb);
555 for (i = 0; i < nb_chapters; i++) {
559 start = avio_rb64(pb);
560 str_len = avio_r8(pb);
562 if ((atom.size -= 9+str_len) < 0)
565 ret = ffio_read_size(pb, str, str_len);
569 avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
574 #define MIN_DATA_ENTRY_BOX_SIZE 12
575 static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
578 MOVStreamContext *sc;
581 if (c->fc->nb_streams < 1)
583 st = c->fc->streams[c->fc->nb_streams-1];
586 avio_rb32(pb); // version + flags
587 entries = avio_rb32(pb);
589 entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
590 entries >= UINT_MAX / sizeof(*sc->drefs))
591 return AVERROR_INVALIDDATA;
593 for (i = 0; i < sc->drefs_count; i++) {
594 MOVDref *dref = &sc->drefs[i];
595 av_freep(&dref->path);
596 av_freep(&dref->dir);
600 sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
602 return AVERROR(ENOMEM);
603 sc->drefs_count = entries;
605 for (i = 0; i < entries; i++) {
606 MOVDref *dref = &sc->drefs[i];
607 uint32_t size = avio_rb32(pb);
608 int64_t next = avio_tell(pb) + size - 4;
611 return AVERROR_INVALIDDATA;
613 dref->type = avio_rl32(pb);
614 avio_rb32(pb); // version + flags
616 if (dref->type == MKTAG('a','l','i','s') && size > 150) {
617 /* macintosh alias record */
618 uint16_t volume_len, len;
624 volume_len = avio_r8(pb);
625 volume_len = FFMIN(volume_len, 27);
626 ret = ffio_read_size(pb, dref->volume, 27);
629 dref->volume[volume_len] = 0;
630 av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
635 len = FFMIN(len, 63);
636 ret = ffio_read_size(pb, dref->filename, 63);
639 dref->filename[len] = 0;
640 av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
644 /* read next level up_from_alias/down_to_target */
645 dref->nlvl_from = avio_rb16(pb);
646 dref->nlvl_to = avio_rb16(pb);
647 av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
648 dref->nlvl_from, dref->nlvl_to);
652 for (type = 0; type != -1 && avio_tell(pb) < next; ) {
655 type = avio_rb16(pb);
657 av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
660 if (type == 2) { // absolute path
662 dref->path = av_mallocz(len+1);
664 return AVERROR(ENOMEM);
666 ret = ffio_read_size(pb, dref->path, len);
668 av_freep(&dref->path);
671 if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
673 memmove(dref->path, dref->path+volume_len, len);
676 // trim string of any ending zeros
677 for (j = len - 1; j >= 0; j--) {
678 if (dref->path[j] == 0)
683 for (j = 0; j < len; j++)
684 if (dref->path[j] == ':' || dref->path[j] == 0)
686 av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
687 } else if (type == 0) { // directory name
689 dref->dir = av_malloc(len+1);
691 return AVERROR(ENOMEM);
693 ret = ffio_read_size(pb, dref->dir, len);
695 av_freep(&dref->dir);
699 for (j = 0; j < len; j++)
700 if (dref->dir[j] == ':')
702 av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
707 av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
712 avio_seek(pb, next, SEEK_SET);
717 static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
726 avio_r8(pb); /* version */
727 avio_rb24(pb); /* flags */
730 ctype = avio_rl32(pb);
731 type = avio_rl32(pb); /* component subtype */
733 av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
734 av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
736 if (c->trak_index < 0) { // meta not inside a trak
737 if (type == MKTAG('m','d','t','a')) {
738 c->found_hdlr_mdta = 1;
743 st = c->fc->streams[c->fc->nb_streams-1];
745 if (type == MKTAG('v','i','d','e'))
746 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
747 else if (type == MKTAG('s','o','u','n'))
748 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
749 else if (type == MKTAG('m','1','a',' '))
750 st->codecpar->codec_id = AV_CODEC_ID_MP2;
751 else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
752 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
754 avio_rb32(pb); /* component manufacture */
755 avio_rb32(pb); /* component flags */
756 avio_rb32(pb); /* component flags mask */
758 title_size = atom.size - 24;
759 if (title_size > 0) {
760 if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
761 return AVERROR_INVALIDDATA;
762 title_str = av_malloc(title_size + 1); /* Add null terminator */
764 return AVERROR(ENOMEM);
766 ret = ffio_read_size(pb, title_str, title_size);
768 av_freep(&title_str);
771 title_str[title_size] = 0;
773 int off = (!c->isom && title_str[0] == title_size - 1);
774 // flag added so as to not set stream handler name if already set from mdia->hdlr
775 av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
777 av_freep(&title_str);
783 static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
785 return ff_mov_read_esds(c->fc, pb);
788 static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
791 enum AVAudioServiceType *ast;
792 int ac3info, acmod, lfeon, bsmod;
794 if (c->fc->nb_streams < 1)
796 st = c->fc->streams[c->fc->nb_streams-1];
798 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
801 return AVERROR(ENOMEM);
803 ac3info = avio_rb24(pb);
804 bsmod = (ac3info >> 14) & 0x7;
805 acmod = (ac3info >> 11) & 0x7;
806 lfeon = (ac3info >> 10) & 0x1;
807 st->codecpar->channels = ((int[]){2,1,2,3,3,4,4,5})[acmod] + lfeon;
808 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
810 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
812 if (st->codecpar->channels > 1 && bsmod == 0x7)
813 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
815 #if FF_API_LAVF_AVCTX
816 FF_DISABLE_DEPRECATION_WARNINGS
817 st->codec->audio_service_type = *ast;
818 FF_ENABLE_DEPRECATION_WARNINGS
824 static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
827 enum AVAudioServiceType *ast;
828 int eac3info, acmod, lfeon, bsmod;
830 if (c->fc->nb_streams < 1)
832 st = c->fc->streams[c->fc->nb_streams-1];
834 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
837 return AVERROR(ENOMEM);
839 /* No need to parse fields for additional independent substreams and its
840 * associated dependent substreams since libavcodec's E-AC-3 decoder
841 * does not support them yet. */
842 avio_rb16(pb); /* data_rate and num_ind_sub */
843 eac3info = avio_rb24(pb);
844 bsmod = (eac3info >> 12) & 0x1f;
845 acmod = (eac3info >> 9) & 0x7;
846 lfeon = (eac3info >> 8) & 0x1;
847 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
849 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
850 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
852 if (st->codecpar->channels > 1 && bsmod == 0x7)
853 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
855 #if FF_API_LAVF_AVCTX
856 FF_DISABLE_DEPRECATION_WARNINGS
857 st->codec->audio_service_type = *ast;
858 FF_ENABLE_DEPRECATION_WARNINGS
864 static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
867 uint8_t buf[DDTS_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
869 uint32_t frame_duration_code = 0;
870 uint32_t channel_layout_code = 0;
874 if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
877 init_get_bits(&gb, buf, 8 * DDTS_SIZE);
879 if (c->fc->nb_streams < 1) {
882 st = c->fc->streams[c->fc->nb_streams-1];
884 st->codecpar->sample_rate = get_bits_long(&gb, 32);
885 if (st->codecpar->sample_rate <= 0) {
886 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
887 return AVERROR_INVALIDDATA;
889 skip_bits_long(&gb, 32); /* max bitrate */
890 st->codecpar->bit_rate = get_bits_long(&gb, 32);
891 st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
892 frame_duration_code = get_bits(&gb, 2);
893 skip_bits(&gb, 30); /* various fields */
894 channel_layout_code = get_bits(&gb, 16);
896 st->codecpar->frame_size =
897 (frame_duration_code == 0) ? 512 :
898 (frame_duration_code == 1) ? 1024 :
899 (frame_duration_code == 2) ? 2048 :
900 (frame_duration_code == 3) ? 4096 : 0;
902 if (channel_layout_code > 0xff) {
903 av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout\n");
905 st->codecpar->channel_layout =
906 ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
907 ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
908 ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
909 ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
910 ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
911 ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0);
913 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
918 static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
922 if (c->fc->nb_streams < 1)
924 st = c->fc->streams[c->fc->nb_streams-1];
929 /* skip version and flags */
932 ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
937 static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
942 if (c->fc->nb_streams < 1)
944 st = c->fc->streams[c->fc->nb_streams-1];
946 if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
947 av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
952 static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
954 const int num = avio_rb32(pb);
955 const int den = avio_rb32(pb);
958 if (c->fc->nb_streams < 1)
960 st = c->fc->streams[c->fc->nb_streams-1];
962 if ((st->sample_aspect_ratio.den != 1 || st->sample_aspect_ratio.num) && // default
963 (den != st->sample_aspect_ratio.den || num != st->sample_aspect_ratio.num)) {
964 av_log(c->fc, AV_LOG_WARNING,
965 "sample aspect ratio already set to %d:%d, ignoring 'pasp' atom (%d:%d)\n",
966 st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
968 } else if (den != 0) {
969 av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den,
975 /* this atom contains actual media data */
976 static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
978 if (atom.size == 0) /* wrong one (MP4) */
981 return 0; /* now go for moov */
984 #define DRM_BLOB_SIZE 56
986 static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
988 uint8_t intermediate_key[20];
989 uint8_t intermediate_iv[20];
992 uint8_t file_checksum[20];
993 uint8_t calculated_checksum[20];
997 uint8_t *activation_bytes = c->activation_bytes;
998 uint8_t *fixed_key = c->audible_fixed_key;
1002 sha = av_sha_alloc();
1004 return AVERROR(ENOMEM);
1005 av_free(c->aes_decrypt);
1006 c->aes_decrypt = av_aes_alloc();
1007 if (!c->aes_decrypt) {
1008 ret = AVERROR(ENOMEM);
1012 /* drm blob processing */
1013 avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1014 avio_read(pb, input, DRM_BLOB_SIZE);
1015 avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1016 avio_read(pb, file_checksum, 20);
1018 av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == "); // required by external tools
1019 for (i = 0; i < 20; i++)
1020 av_log(c->fc, AV_LOG_INFO, "%02x", file_checksum[i]);
1021 av_log(c->fc, AV_LOG_INFO, "\n");
1023 /* verify activation data */
1024 if (!activation_bytes) {
1025 av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1026 ret = 0; /* allow ffprobe to continue working on .aax files */
1029 if (c->activation_bytes_size != 4) {
1030 av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1031 ret = AVERROR(EINVAL);
1035 /* verify fixed key */
1036 if (c->audible_fixed_key_size != 16) {
1037 av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1038 ret = AVERROR(EINVAL);
1042 /* AAX (and AAX+) key derivation */
1043 av_sha_init(sha, 160);
1044 av_sha_update(sha, fixed_key, 16);
1045 av_sha_update(sha, activation_bytes, 4);
1046 av_sha_final(sha, intermediate_key);
1047 av_sha_init(sha, 160);
1048 av_sha_update(sha, fixed_key, 16);
1049 av_sha_update(sha, intermediate_key, 20);
1050 av_sha_update(sha, activation_bytes, 4);
1051 av_sha_final(sha, intermediate_iv);
1052 av_sha_init(sha, 160);
1053 av_sha_update(sha, intermediate_key, 16);
1054 av_sha_update(sha, intermediate_iv, 16);
1055 av_sha_final(sha, calculated_checksum);
1056 if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1057 av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1058 ret = AVERROR_INVALIDDATA;
1061 av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1062 av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1063 for (i = 0; i < 4; i++) {
1064 // file data (in output) is stored in big-endian mode
1065 if (activation_bytes[i] != output[3 - i]) { // critical error
1066 av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1067 ret = AVERROR_INVALIDDATA;
1071 memcpy(c->file_key, output + 8, 16);
1072 memcpy(input, output + 26, 16);
1073 av_sha_init(sha, 160);
1074 av_sha_update(sha, input, 16);
1075 av_sha_update(sha, c->file_key, 16);
1076 av_sha_update(sha, fixed_key, 16);
1077 av_sha_final(sha, c->file_iv);
1085 static int mov_aaxc_crypto(MOVContext *c)
1087 if (c->audible_key_size != 16) {
1088 av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
1089 return AVERROR(EINVAL);
1092 if (c->audible_iv_size != 16) {
1093 av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
1094 return AVERROR(EINVAL);
1097 c->aes_decrypt = av_aes_alloc();
1098 if (!c->aes_decrypt) {
1099 return AVERROR(ENOMEM);
1102 memcpy(c->file_key, c->audible_key, 16);
1103 memcpy(c->file_iv, c->audible_iv, 16);
1109 // Audible AAX (and AAX+) bytestream decryption
1110 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1113 unsigned char iv[16];
1115 memcpy(iv, c->file_iv, 16); // iv is overwritten
1116 blocks = size >> 4; // trailing bytes are not encrypted!
1117 av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1118 av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1123 /* read major brand, minor version and compatible brands and store them as metadata */
1124 static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1127 int comp_brand_size;
1128 char* comp_brands_str;
1129 uint8_t type[5] = {0};
1130 int ret = ffio_read_size(pb, type, 4);
1134 if (strcmp(type, "qt "))
1136 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1137 av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1138 minor_ver = avio_rb32(pb); /* minor version */
1139 av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1141 comp_brand_size = atom.size - 8;
1142 if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1143 return AVERROR_INVALIDDATA;
1144 comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1145 if (!comp_brands_str)
1146 return AVERROR(ENOMEM);
1148 ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1150 av_freep(&comp_brands_str);
1153 comp_brands_str[comp_brand_size] = 0;
1154 av_dict_set(&c->fc->metadata, "compatible_brands",
1155 comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1157 // Logic for handling Audible's .aaxc files
1158 if (!strcmp(type, "aaxc")) {
1165 /* this atom should contain all header atoms */
1166 static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1170 if (c->found_moov) {
1171 av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1172 avio_skip(pb, atom.size);
1176 if ((ret = mov_read_default(c, pb, atom)) < 0)
1178 /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1179 /* so we don't parse the whole file if over a network */
1181 return 0; /* now go for mdat */
1184 static MOVFragmentStreamInfo * get_frag_stream_info(
1185 MOVFragmentIndex *frag_index,
1190 MOVFragmentIndexItem * item;
1192 if (index < 0 || index >= frag_index->nb_items)
1194 item = &frag_index->item[index];
1195 for (i = 0; i < item->nb_stream_info; i++)
1196 if (item->stream_info[i].id == id)
1197 return &item->stream_info[i];
1199 // This shouldn't happen
1203 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1206 MOVFragmentIndexItem * item;
1208 if (frag_index->current < 0 ||
1209 frag_index->current >= frag_index->nb_items)
1212 item = &frag_index->item[frag_index->current];
1213 for (i = 0; i < item->nb_stream_info; i++)
1214 if (item->stream_info[i].id == id) {
1219 // id not found. This shouldn't happen.
1223 static MOVFragmentStreamInfo * get_current_frag_stream_info(
1224 MOVFragmentIndex *frag_index)
1226 MOVFragmentIndexItem *item;
1227 if (frag_index->current < 0 ||
1228 frag_index->current >= frag_index->nb_items)
1231 item = &frag_index->item[frag_index->current];
1232 if (item->current >= 0 && item->current < item->nb_stream_info)
1233 return &item->stream_info[item->current];
1235 // This shouldn't happen
1239 static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
1242 int64_t moof_offset;
1244 // Optimize for appending new entries
1245 if (!frag_index->nb_items ||
1246 frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1247 return frag_index->nb_items;
1250 b = frag_index->nb_items;
1254 moof_offset = frag_index->item[m].moof_offset;
1255 if (moof_offset >= offset)
1257 if (moof_offset <= offset)
1263 static int64_t get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
1265 av_assert0(frag_stream_info);
1266 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1267 return frag_stream_info->sidx_pts;
1268 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1269 return frag_stream_info->first_tfra_pts;
1270 return frag_stream_info->tfdt_dts;
1273 static int64_t get_frag_time(MOVFragmentIndex *frag_index,
1274 int index, int track_id)
1276 MOVFragmentStreamInfo * frag_stream_info;
1280 if (track_id >= 0) {
1281 frag_stream_info = get_frag_stream_info(frag_index, index, track_id);
1282 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1283 return frag_stream_info->sidx_pts;
1284 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1285 return frag_stream_info->first_tfra_pts;
1286 return frag_stream_info->sidx_pts;
1289 for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1290 frag_stream_info = &frag_index->item[index].stream_info[i];
1291 timestamp = get_stream_info_time(frag_stream_info);
1292 if (timestamp != AV_NOPTS_VALUE)
1295 return AV_NOPTS_VALUE;
1298 static int search_frag_timestamp(MOVFragmentIndex *frag_index,
1299 AVStream *st, int64_t timestamp)
1306 // If the stream is referenced by any sidx, limit the search
1307 // to fragments that referenced this stream in the sidx
1308 MOVStreamContext *sc = st->priv_data;
1314 b = frag_index->nb_items;
1317 m0 = m = (a + b) >> 1;
1320 (frag_time = get_frag_time(frag_index, m, id)) == AV_NOPTS_VALUE)
1323 if (m < b && frag_time <= timestamp)
1332 static int update_frag_index(MOVContext *c, int64_t offset)
1335 MOVFragmentIndexItem * item;
1336 MOVFragmentStreamInfo * frag_stream_info;
1338 // If moof_offset already exists in frag_index, return index to it
1339 index = search_frag_moof_offset(&c->frag_index, offset);
1340 if (index < c->frag_index.nb_items &&
1341 c->frag_index.item[index].moof_offset == offset)
1344 // offset is not yet in frag index.
1345 // Insert new item at index (sorted by moof offset)
1346 item = av_fast_realloc(c->frag_index.item,
1347 &c->frag_index.allocated_size,
1348 (c->frag_index.nb_items + 1) *
1349 sizeof(*c->frag_index.item));
1352 c->frag_index.item = item;
1354 frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1355 sizeof(*item->stream_info));
1356 if (!frag_stream_info)
1359 for (i = 0; i < c->fc->nb_streams; i++) {
1360 // Avoid building frag index if streams lack track id.
1361 if (c->fc->streams[i]->id < 0) {
1362 av_free(frag_stream_info);
1363 return AVERROR_INVALIDDATA;
1366 frag_stream_info[i].id = c->fc->streams[i]->id;
1367 frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1368 frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1369 frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1370 frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1371 frag_stream_info[i].index_entry = -1;
1372 frag_stream_info[i].encryption_index = NULL;
1375 if (index < c->frag_index.nb_items)
1376 memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1377 (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1379 item = &c->frag_index.item[index];
1380 item->headers_read = 0;
1382 item->nb_stream_info = c->fc->nb_streams;
1383 item->moof_offset = offset;
1384 item->stream_info = frag_stream_info;
1385 c->frag_index.nb_items++;
1390 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1391 int id, int entries)
1394 MOVFragmentStreamInfo * frag_stream_info;
1398 for (i = index; i < frag_index->nb_items; i++) {
1399 frag_stream_info = get_frag_stream_info(frag_index, i, id);
1400 if (frag_stream_info && frag_stream_info->index_entry >= 0)
1401 frag_stream_info->index_entry += entries;
1405 static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1407 // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1408 c->fragment.found_tfhd = 0;
1410 if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1411 c->has_looked_for_mfra = 1;
1412 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1414 av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1416 if ((ret = mov_read_mfra(c, pb)) < 0) {
1417 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1418 "read the mfra (may be a live ismv)\n");
1421 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1422 "seekable, can not look for mfra\n");
1425 c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1426 av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1427 c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1428 return mov_read_default(c, pb, atom);
1431 static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time, void *logctx)
1434 if (time >= 2082844800)
1435 time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1437 if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1438 av_log(logctx, AV_LOG_DEBUG, "creation_time is not representable\n");
1442 avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1446 static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1449 MOVStreamContext *sc;
1451 char language[4] = {0};
1453 int64_t creation_time;
1455 if (c->fc->nb_streams < 1)
1457 st = c->fc->streams[c->fc->nb_streams-1];
1460 if (sc->time_scale) {
1461 av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1462 return AVERROR_INVALIDDATA;
1465 version = avio_r8(pb);
1467 avpriv_request_sample(c->fc, "Version %d", version);
1468 return AVERROR_PATCHWELCOME;
1470 avio_rb24(pb); /* flags */
1472 creation_time = avio_rb64(pb);
1475 creation_time = avio_rb32(pb);
1476 avio_rb32(pb); /* modification time */
1478 mov_metadata_creation_time(&st->metadata, creation_time, c->fc);
1480 sc->time_scale = avio_rb32(pb);
1481 if (sc->time_scale <= 0) {
1482 av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1485 st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1487 lang = avio_rb16(pb); /* language */
1488 if (ff_mov_lang_to_iso639(lang, language))
1489 av_dict_set(&st->metadata, "language", language, 0);
1490 avio_rb16(pb); /* quality */
1495 static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1498 int64_t creation_time;
1499 int version = avio_r8(pb); /* version */
1500 avio_rb24(pb); /* flags */
1503 creation_time = avio_rb64(pb);
1506 creation_time = avio_rb32(pb);
1507 avio_rb32(pb); /* modification time */
1509 mov_metadata_creation_time(&c->fc->metadata, creation_time, c->fc);
1510 c->time_scale = avio_rb32(pb); /* time scale */
1511 if (c->time_scale <= 0) {
1512 av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1515 av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1517 c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1518 // set the AVFormatContext duration because the duration of individual tracks
1519 // may be inaccurate
1521 c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale);
1522 avio_rb32(pb); /* preferred scale */
1524 avio_rb16(pb); /* preferred volume */
1526 avio_skip(pb, 10); /* reserved */
1528 /* movie display matrix, store it in main context and use it later on */
1529 for (i = 0; i < 3; i++) {
1530 c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1531 c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1532 c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1535 avio_rb32(pb); /* preview time */
1536 avio_rb32(pb); /* preview duration */
1537 avio_rb32(pb); /* poster time */
1538 avio_rb32(pb); /* selection time */
1539 avio_rb32(pb); /* selection duration */
1540 avio_rb32(pb); /* current time */
1541 avio_rb32(pb); /* next track ID */
1546 static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1551 if (c->fc->nb_streams < 1)
1553 st = c->fc->streams[c->fc->nb_streams-1];
1555 little_endian = avio_rb16(pb) & 0xFF;
1556 av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1557 if (little_endian == 1) {
1558 switch (st->codecpar->codec_id) {
1559 case AV_CODEC_ID_PCM_S24BE:
1560 st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE;
1562 case AV_CODEC_ID_PCM_S32BE:
1563 st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE;
1565 case AV_CODEC_ID_PCM_F32BE:
1566 st->codecpar->codec_id = AV_CODEC_ID_PCM_F32LE;
1568 case AV_CODEC_ID_PCM_F64BE:
1569 st->codecpar->codec_id = AV_CODEC_ID_PCM_F64LE;
1578 static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1581 uint8_t *icc_profile;
1582 char color_parameter_type[5] = { 0 };
1583 uint16_t color_primaries, color_trc, color_matrix;
1586 if (c->fc->nb_streams < 1)
1588 st = c->fc->streams[c->fc->nb_streams - 1];
1590 ret = ffio_read_size(pb, color_parameter_type, 4);
1593 if (strncmp(color_parameter_type, "nclx", 4) &&
1594 strncmp(color_parameter_type, "nclc", 4) &&
1595 strncmp(color_parameter_type, "prof", 4)) {
1596 av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
1597 color_parameter_type);
1601 if (!strncmp(color_parameter_type, "prof", 4)) {
1602 icc_profile = av_stream_new_side_data(st, AV_PKT_DATA_ICC_PROFILE, atom.size - 4);
1604 return AVERROR(ENOMEM);
1605 ret = ffio_read_size(pb, icc_profile, atom.size - 4);
1609 color_primaries = avio_rb16(pb);
1610 color_trc = avio_rb16(pb);
1611 color_matrix = avio_rb16(pb);
1613 av_log(c->fc, AV_LOG_TRACE,
1614 "%s: pri %d trc %d matrix %d",
1615 color_parameter_type, color_primaries, color_trc, color_matrix);
1617 if (!strncmp(color_parameter_type, "nclx", 4)) {
1618 uint8_t color_range = avio_r8(pb) >> 7;
1619 av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
1621 st->codecpar->color_range = AVCOL_RANGE_JPEG;
1623 st->codecpar->color_range = AVCOL_RANGE_MPEG;
1626 if (!av_color_primaries_name(color_primaries))
1627 color_primaries = AVCOL_PRI_UNSPECIFIED;
1628 if (!av_color_transfer_name(color_trc))
1629 color_trc = AVCOL_TRC_UNSPECIFIED;
1630 if (!av_color_space_name(color_matrix))
1631 color_matrix = AVCOL_SPC_UNSPECIFIED;
1633 st->codecpar->color_primaries = color_primaries;
1634 st->codecpar->color_trc = color_trc;
1635 st->codecpar->color_space = color_matrix;
1636 av_log(c->fc, AV_LOG_TRACE, "\n");
1641 static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1644 unsigned mov_field_order;
1645 enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
1647 if (c->fc->nb_streams < 1) // will happen with jp2 files
1649 st = c->fc->streams[c->fc->nb_streams-1];
1651 return AVERROR_INVALIDDATA;
1652 mov_field_order = avio_rb16(pb);
1653 if ((mov_field_order & 0xFF00) == 0x0100)
1654 decoded_field_order = AV_FIELD_PROGRESSIVE;
1655 else if ((mov_field_order & 0xFF00) == 0x0200) {
1656 switch (mov_field_order & 0xFF) {
1657 case 0x01: decoded_field_order = AV_FIELD_TT;
1659 case 0x06: decoded_field_order = AV_FIELD_BB;
1661 case 0x09: decoded_field_order = AV_FIELD_TB;
1663 case 0x0E: decoded_field_order = AV_FIELD_BT;
1667 if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
1668 av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
1670 st->codecpar->field_order = decoded_field_order;
1675 static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
1678 uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
1679 if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
1680 return AVERROR_INVALIDDATA;
1681 if ((err = av_reallocp(&par->extradata, size)) < 0) {
1682 par->extradata_size = 0;
1685 par->extradata_size = size - AV_INPUT_BUFFER_PADDING_SIZE;
1689 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
1690 static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1691 AVCodecParameters *par, uint8_t *buf)
1693 int64_t result = atom.size;
1696 AV_WB32(buf , atom.size + 8);
1697 AV_WL32(buf + 4, atom.type);
1698 err = ffio_read_size(pb, buf + 8, atom.size);
1700 par->extradata_size -= atom.size;
1702 } else if (err < atom.size) {
1703 av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
1704 par->extradata_size -= atom.size - err;
1707 memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1711 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
1712 static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1713 enum AVCodecID codec_id)
1716 uint64_t original_size;
1719 if (c->fc->nb_streams < 1) // will happen with jp2 files
1721 st = c->fc->streams[c->fc->nb_streams-1];
1723 if (st->codecpar->codec_id != codec_id)
1724 return 0; /* unexpected codec_id - don't mess with extradata */
1726 original_size = st->codecpar->extradata_size;
1727 err = mov_realloc_extradata(st->codecpar, atom);
1731 err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
1734 return 0; // Note: this is the original behavior to ignore truncation.
1737 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
1738 static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1740 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
1743 static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1745 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS);
1748 static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1750 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
1753 static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1755 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
1758 static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1760 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
1762 ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
1766 static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1768 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
1770 if (!ret && c->fc->nb_streams >= 1) {
1771 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1772 if (par->extradata_size >= 40) {
1773 par->height = AV_RB16(&par->extradata[36]);
1774 par->width = AV_RB16(&par->extradata[38]);
1780 static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1782 if (c->fc->nb_streams >= 1) {
1783 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1784 if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
1785 par->codec_id == AV_CODEC_ID_H264 &&
1789 cid = avio_rb16(pb);
1790 /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
1791 if (cid == 0xd4d || cid == 0xd4e)
1794 } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
1795 par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
1796 par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
1800 num = avio_rb32(pb);
1801 den = avio_rb32(pb);
1802 if (num <= 0 || den <= 0)
1804 switch (avio_rb32(pb)) {
1806 if (den >= INT_MAX / 2)
1810 c->fc->streams[c->fc->nb_streams-1]->internal->display_aspect_ratio.num = num;
1811 c->fc->streams[c->fc->nb_streams-1]->internal->display_aspect_ratio.den = den;
1818 return mov_read_avid(c, pb, atom);
1821 static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1825 uint64_t original_size;
1826 if (c->fc->nb_streams >= 1) {
1827 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1828 if (par->codec_id == AV_CODEC_ID_H264)
1830 if (atom.size == 16) {
1831 original_size = par->extradata_size;
1832 ret = mov_realloc_extradata(par, atom);
1834 length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
1835 if (length == atom.size) {
1836 const uint8_t range_value = par->extradata[original_size + 19];
1837 switch (range_value) {
1839 par->color_range = AVCOL_RANGE_MPEG;
1842 par->color_range = AVCOL_RANGE_JPEG;
1845 av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
1848 ff_dlog(c->fc, "color_range: %d\n", par->color_range);
1850 /* For some reason the whole atom was not added to the extradata */
1851 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
1854 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
1857 av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
1864 static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1866 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
1869 static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1874 if (c->fc->nb_streams < 1)
1876 st = c->fc->streams[c->fc->nb_streams-1];
1878 if ((uint64_t)atom.size > (1<<30))
1879 return AVERROR_INVALIDDATA;
1881 if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
1882 st->codecpar->codec_id == AV_CODEC_ID_QDMC ||
1883 st->codecpar->codec_id == AV_CODEC_ID_SPEEX) {
1884 // pass all frma atom to codec, needed at least for QDMC and QDM2
1885 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1888 } else if (atom.size > 8) { /* to read frma, esds atoms */
1889 if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
1891 ret = ffio_ensure_seekback(pb, 8);
1894 buffer = avio_rb64(pb);
1896 if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
1897 && buffer >> 32 <= atom.size
1898 && buffer >> 32 >= 8) {
1901 } else if (!st->codecpar->extradata_size) {
1902 #define ALAC_EXTRADATA_SIZE 36
1903 st->codecpar->extradata = av_mallocz(ALAC_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
1904 if (!st->codecpar->extradata)
1905 return AVERROR(ENOMEM);
1906 st->codecpar->extradata_size = ALAC_EXTRADATA_SIZE;
1907 AV_WB32(st->codecpar->extradata , ALAC_EXTRADATA_SIZE);
1908 AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
1909 AV_WB64(st->codecpar->extradata + 12, buffer);
1910 avio_read(pb, st->codecpar->extradata + 20, 16);
1911 avio_skip(pb, atom.size - 24);
1915 if ((ret = mov_read_default(c, pb, atom)) < 0)
1918 avio_skip(pb, atom.size);
1923 * This function reads atom content and puts data in extradata without tag
1924 * nor size unlike mov_read_extradata.
1926 static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1931 if (c->fc->nb_streams < 1)
1933 st = c->fc->streams[c->fc->nb_streams-1];
1935 if ((uint64_t)atom.size > (1<<30))
1936 return AVERROR_INVALIDDATA;
1938 if (atom.size >= 10) {
1939 // Broken files created by legacy versions of libavformat will
1940 // wrap a whole fiel atom inside of a glbl atom.
1941 unsigned size = avio_rb32(pb);
1942 unsigned type = avio_rl32(pb);
1943 avio_seek(pb, -8, SEEK_CUR);
1944 if (type == MKTAG('f','i','e','l') && size == atom.size)
1945 return mov_read_default(c, pb, atom);
1947 if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
1948 av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
1951 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1954 if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
1955 /* HEVC-based Dolby Vision derived from hvc1.
1956 Happens to match with an identifier
1957 previously utilized for DV. Thus, if we have
1958 the hvcC extradata box available as specified,
1959 set codec to HEVC */
1960 st->codecpar->codec_id = AV_CODEC_ID_HEVC;
1965 static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1968 uint8_t profile_level;
1971 if (c->fc->nb_streams < 1)
1973 st = c->fc->streams[c->fc->nb_streams-1];
1975 if (atom.size >= (1<<28) || atom.size < 7)
1976 return AVERROR_INVALIDDATA;
1978 profile_level = avio_r8(pb);
1979 if ((profile_level & 0xf0) != 0xc0)
1982 avio_seek(pb, 6, SEEK_CUR);
1983 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
1991 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
1992 * but can have extradata appended at the end after the 40 bytes belonging
1995 static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2000 if (c->fc->nb_streams < 1)
2002 if (atom.size <= 40)
2004 st = c->fc->streams[c->fc->nb_streams-1];
2006 if ((uint64_t)atom.size > (1<<30))
2007 return AVERROR_INVALIDDATA;
2010 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2017 static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2020 MOVStreamContext *sc;
2021 unsigned int i, entries;
2023 if (c->trak_index < 0) {
2024 av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2027 if (c->fc->nb_streams < 1)
2029 st = c->fc->streams[c->fc->nb_streams-1];
2032 avio_r8(pb); /* version */
2033 avio_rb24(pb); /* flags */
2035 entries = avio_rb32(pb);
2040 if (sc->chunk_offsets)
2041 av_log(c->fc, AV_LOG_WARNING, "Duplicated STCO atom\n");
2042 av_free(sc->chunk_offsets);
2043 sc->chunk_count = 0;
2044 sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2045 if (!sc->chunk_offsets)
2046 return AVERROR(ENOMEM);
2047 sc->chunk_count = entries;
2049 if (atom.type == MKTAG('s','t','c','o'))
2050 for (i = 0; i < entries && !pb->eof_reached; i++)
2051 sc->chunk_offsets[i] = avio_rb32(pb);
2052 else if (atom.type == MKTAG('c','o','6','4'))
2053 for (i = 0; i < entries && !pb->eof_reached; i++)
2054 sc->chunk_offsets[i] = avio_rb64(pb);
2056 return AVERROR_INVALIDDATA;
2058 sc->chunk_count = i;
2060 if (pb->eof_reached) {
2061 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2068 static int mov_codec_id(AVStream *st, uint32_t format)
2070 int id = ff_codec_get_id(ff_codec_movaudio_tags, format);
2073 ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2074 (format & 0xFFFF) == 'T' + ('S' << 8)))
2075 id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format) & 0xFFFF);
2077 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2078 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2079 } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2080 /* skip old ASF MPEG-4 tag */
2081 format && format != MKTAG('m','p','4','s')) {
2082 id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2084 id = ff_codec_get_id(ff_codec_bmp_tags, format);
2086 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
2087 else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2088 (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE &&
2089 st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2090 id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
2092 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
2094 id = ff_codec_get_id(ff_codec_movdata_tags, format);
2098 st->codecpar->codec_tag = format;
2103 static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
2104 AVStream *st, MOVStreamContext *sc)
2106 uint8_t codec_name[32] = { 0 };
2111 /* The first 16 bytes of the video sample description are already
2112 * read in ff_mov_read_stsd_entries() */
2113 stsd_start = avio_tell(pb) - 16;
2115 avio_rb16(pb); /* version */
2116 avio_rb16(pb); /* revision level */
2117 id = avio_rl32(pb); /* vendor */
2118 av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2119 avio_rb32(pb); /* temporal quality */
2120 avio_rb32(pb); /* spatial quality */
2122 st->codecpar->width = avio_rb16(pb); /* width */
2123 st->codecpar->height = avio_rb16(pb); /* height */
2125 avio_rb32(pb); /* horiz resolution */
2126 avio_rb32(pb); /* vert resolution */
2127 avio_rb32(pb); /* data size, always 0 */
2128 avio_rb16(pb); /* frames per samples */
2130 len = avio_r8(pb); /* codec name, pascal string */
2133 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2135 avio_skip(pb, 31 - len);
2138 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2140 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2141 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2142 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2143 st->codecpar->width &= ~1;
2144 st->codecpar->height &= ~1;
2146 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2147 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2148 !strncmp(codec_name, "Sorenson H263", 13))
2149 st->codecpar->codec_id = AV_CODEC_ID_FLV1;
2151 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2153 avio_seek(pb, stsd_start, SEEK_SET);
2155 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2156 st->codecpar->bits_per_coded_sample &= 0x1F;
2157 sc->has_palette = 1;
2161 static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
2162 AVStream *st, MOVStreamContext *sc)
2164 int bits_per_sample, flags;
2165 uint16_t version = avio_rb16(pb);
2167 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2169 avio_rb16(pb); /* revision level */
2170 id = avio_rl32(pb); /* vendor */
2171 av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2173 st->codecpar->channels = avio_rb16(pb); /* channel count */
2174 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2175 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", st->codecpar->channels);
2177 sc->audio_cid = avio_rb16(pb);
2178 avio_rb16(pb); /* packet size = 0 */
2180 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2182 // Read QT version 1 fields. In version 0 these do not exist.
2183 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2185 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2186 (sc->stsd_version == 0 && version > 0)) {
2188 sc->samples_per_frame = avio_rb32(pb);
2189 avio_rb32(pb); /* bytes per packet */
2190 sc->bytes_per_frame = avio_rb32(pb);
2191 avio_rb32(pb); /* bytes per sample */
2192 } else if (version == 2) {
2193 avio_rb32(pb); /* sizeof struct only */
2194 st->codecpar->sample_rate = av_int2double(avio_rb64(pb));
2195 st->codecpar->channels = avio_rb32(pb);
2196 avio_rb32(pb); /* always 0x7F000000 */
2197 st->codecpar->bits_per_coded_sample = avio_rb32(pb);
2199 flags = avio_rb32(pb); /* lpcm format specific flag */
2200 sc->bytes_per_frame = avio_rb32(pb);
2201 sc->samples_per_frame = avio_rb32(pb);
2202 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2203 st->codecpar->codec_id =
2204 ff_mov_get_lpcm_codec_id(st->codecpar->bits_per_coded_sample,
2207 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2208 /* can't correctly handle variable sized packet as audio unit */
2209 switch (st->codecpar->codec_id) {
2210 case AV_CODEC_ID_MP2:
2211 case AV_CODEC_ID_MP3:
2212 st->need_parsing = AVSTREAM_PARSE_FULL;
2218 if (sc->format == 0) {
2219 if (st->codecpar->bits_per_coded_sample == 8)
2220 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2221 else if (st->codecpar->bits_per_coded_sample == 16)
2222 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2225 switch (st->codecpar->codec_id) {
2226 case AV_CODEC_ID_PCM_S8:
2227 case AV_CODEC_ID_PCM_U8:
2228 if (st->codecpar->bits_per_coded_sample == 16)
2229 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16BE;
2231 case AV_CODEC_ID_PCM_S16LE:
2232 case AV_CODEC_ID_PCM_S16BE:
2233 if (st->codecpar->bits_per_coded_sample == 8)
2234 st->codecpar->codec_id = AV_CODEC_ID_PCM_S8;
2235 else if (st->codecpar->bits_per_coded_sample == 24)
2236 st->codecpar->codec_id =
2237 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2238 AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
2239 else if (st->codecpar->bits_per_coded_sample == 32)
2240 st->codecpar->codec_id =
2241 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2242 AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
2244 /* set values for old format before stsd version 1 appeared */
2245 case AV_CODEC_ID_MACE3:
2246 sc->samples_per_frame = 6;
2247 sc->bytes_per_frame = 2 * st->codecpar->channels;
2249 case AV_CODEC_ID_MACE6:
2250 sc->samples_per_frame = 6;
2251 sc->bytes_per_frame = 1 * st->codecpar->channels;
2253 case AV_CODEC_ID_ADPCM_IMA_QT:
2254 sc->samples_per_frame = 64;
2255 sc->bytes_per_frame = 34 * st->codecpar->channels;
2257 case AV_CODEC_ID_GSM:
2258 sc->samples_per_frame = 160;
2259 sc->bytes_per_frame = 33;
2265 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2266 if (bits_per_sample) {
2267 st->codecpar->bits_per_coded_sample = bits_per_sample;
2268 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->channels;
2272 static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
2273 AVStream *st, MOVStreamContext *sc,
2276 // ttxt stsd contains display flags, justification, background
2277 // color, fonts, and default styles, so fake an atom to read it
2278 MOVAtom fake_atom = { .size = size };
2279 // mp4s contains a regular esds atom
2280 if (st->codecpar->codec_tag != AV_RL32("mp4s"))
2281 mov_read_glbl(c, pb, fake_atom);
2282 st->codecpar->width = sc->width;
2283 st->codecpar->height = sc->height;
2286 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2291 y = (ycbcr >> 16) & 0xFF;
2292 cr = (ycbcr >> 8) & 0xFF;
2295 b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
2296 g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
2297 r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
2299 return (r << 16) | (g << 8) | b;
2302 static int mov_rewrite_dvd_sub_extradata(AVStream *st)
2304 char buf[256] = {0};
2305 uint8_t *src = st->codecpar->extradata;
2308 if (st->codecpar->extradata_size != 64)
2311 if (st->codecpar->width > 0 && st->codecpar->height > 0)
2312 snprintf(buf, sizeof(buf), "size: %dx%d\n",
2313 st->codecpar->width, st->codecpar->height);
2314 av_strlcat(buf, "palette: ", sizeof(buf));
2316 for (i = 0; i < 16; i++) {
2317 uint32_t yuv = AV_RB32(src + i * 4);
2318 uint32_t rgba = yuv_to_rgba(yuv);
2320 av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2323 if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2326 ret = ff_alloc_extradata(st->codecpar, strlen(buf));
2329 memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2334 static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
2335 AVStream *st, MOVStreamContext *sc,
2340 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2341 if ((int)size != size)
2342 return AVERROR(ENOMEM);
2344 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2348 MOVStreamContext *tmcd_ctx = st->priv_data;
2350 val = AV_RB32(st->codecpar->extradata + 4);
2351 tmcd_ctx->tmcd_flags = val;
2352 st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2353 st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2354 #if FF_API_LAVF_AVCTX
2355 FF_DISABLE_DEPRECATION_WARNINGS
2356 st->codec->time_base = av_inv_q(st->avg_frame_rate);
2357 FF_ENABLE_DEPRECATION_WARNINGS
2360 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2361 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2362 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2363 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2364 if (str_size > 0 && size >= (int)str_size + 30 &&
2365 st->codecpar->extradata[30] /* Don't add empty string */) {
2366 char *reel_name = av_malloc(str_size + 1);
2368 return AVERROR(ENOMEM);
2369 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2370 reel_name[str_size] = 0; /* Add null terminator */
2371 av_dict_set(&st->metadata, "reel_name", reel_name,
2372 AV_DICT_DONT_STRDUP_VAL);
2378 /* other codec type, just skip (rtp, mp4s ...) */
2379 avio_skip(pb, size);
2384 static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
2385 AVStream *st, MOVStreamContext *sc)
2387 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2388 !st->codecpar->sample_rate && sc->time_scale > 1)
2389 st->codecpar->sample_rate = sc->time_scale;
2391 /* special codec parameters handling */
2392 switch (st->codecpar->codec_id) {
2393 #if CONFIG_DV_DEMUXER
2394 case AV_CODEC_ID_DVAUDIO:
2395 c->dv_fctx = avformat_alloc_context();
2397 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2398 return AVERROR(ENOMEM);
2400 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2402 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2403 return AVERROR(ENOMEM);
2405 sc->dv_audio_container = 1;
2406 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
2409 /* no ifdef since parameters are always those */
2410 case AV_CODEC_ID_QCELP:
2411 st->codecpar->channels = 1;
2412 // force sample rate for qcelp when not stored in mov
2413 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2414 st->codecpar->sample_rate = 8000;
2415 // FIXME: Why is the following needed for some files?
2416 sc->samples_per_frame = 160;
2417 if (!sc->bytes_per_frame)
2418 sc->bytes_per_frame = 35;
2420 case AV_CODEC_ID_AMR_NB:
2421 st->codecpar->channels = 1;
2422 /* force sample rate for amr, stsd in 3gp does not store sample rate */
2423 st->codecpar->sample_rate = 8000;
2425 case AV_CODEC_ID_AMR_WB:
2426 st->codecpar->channels = 1;
2427 st->codecpar->sample_rate = 16000;
2429 case AV_CODEC_ID_MP2:
2430 case AV_CODEC_ID_MP3:
2431 /* force type after stsd for m1a hdlr */
2432 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2434 case AV_CODEC_ID_GSM:
2435 case AV_CODEC_ID_ADPCM_MS:
2436 case AV_CODEC_ID_ADPCM_IMA_WAV:
2437 case AV_CODEC_ID_ILBC:
2438 case AV_CODEC_ID_MACE3:
2439 case AV_CODEC_ID_MACE6:
2440 case AV_CODEC_ID_QDM2:
2441 st->codecpar->block_align = sc->bytes_per_frame;
2443 case AV_CODEC_ID_ALAC:
2444 if (st->codecpar->extradata_size == 36) {
2445 st->codecpar->channels = AV_RB8 (st->codecpar->extradata + 21);
2446 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2449 case AV_CODEC_ID_AC3:
2450 case AV_CODEC_ID_EAC3:
2451 case AV_CODEC_ID_MPEG1VIDEO:
2452 case AV_CODEC_ID_VC1:
2453 case AV_CODEC_ID_VP8:
2454 case AV_CODEC_ID_VP9:
2455 st->need_parsing = AVSTREAM_PARSE_FULL;
2457 case AV_CODEC_ID_AV1:
2458 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2466 static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
2467 int codec_tag, int format,
2470 int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2473 (codec_tag != format &&
2474 // AVID 1:1 samples with differing data format and codec tag exist
2475 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
2476 // prores is allowed to have differing data format and codec tag
2477 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
2479 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
2480 (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id
2481 : codec_tag != MKTAG('j','p','e','g')))) {
2482 /* Multiple fourcc, we skip JPEG. This is not correct, we should
2483 * export it as a separate AVStream but this needs a few changes
2484 * in the MOV demuxer, patch welcome. */
2486 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
2487 avio_skip(pb, size);
2494 int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
2497 MOVStreamContext *sc;
2498 int pseudo_stream_id;
2500 av_assert0 (c->fc->nb_streams >= 1);
2501 st = c->fc->streams[c->fc->nb_streams-1];
2504 for (pseudo_stream_id = 0;
2505 pseudo_stream_id < entries && !pb->eof_reached;
2506 pseudo_stream_id++) {
2507 //Parsing Sample description table
2509 int ret, dref_id = 1;
2510 MOVAtom a = { AV_RL32("stsd") };
2511 int64_t start_pos = avio_tell(pb);
2512 int64_t size = avio_rb32(pb); /* size */
2513 uint32_t format = avio_rl32(pb); /* data format */
2516 avio_rb32(pb); /* reserved */
2517 avio_rb16(pb); /* reserved */
2518 dref_id = avio_rb16(pb);
2519 } else if (size <= 7) {
2520 av_log(c->fc, AV_LOG_ERROR,
2521 "invalid size %"PRId64" in stsd\n", size);
2522 return AVERROR_INVALIDDATA;
2525 if (mov_skip_multiple_stsd(c, pb, st->codecpar->codec_tag, format,
2526 size - (avio_tell(pb) - start_pos))) {
2531 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
2532 sc->dref_id= dref_id;
2533 sc->format = format;
2535 id = mov_codec_id(st, format);
2537 av_log(c->fc, AV_LOG_TRACE,
2538 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
2539 av_fourcc2str(format), st->codecpar->codec_type);
2541 st->codecpar->codec_id = id;
2542 if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) {
2543 mov_parse_stsd_video(c, pb, st, sc);
2544 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
2545 mov_parse_stsd_audio(c, pb, st, sc);
2546 if (st->codecpar->sample_rate < 0) {
2547 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
2548 return AVERROR_INVALIDDATA;
2550 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
2551 mov_parse_stsd_subtitle(c, pb, st, sc,
2552 size - (avio_tell(pb) - start_pos));
2554 ret = mov_parse_stsd_data(c, pb, st, sc,
2555 size - (avio_tell(pb) - start_pos));
2559 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
2560 a.size = size - (avio_tell(pb) - start_pos);
2562 if ((ret = mov_read_default(c, pb, a)) < 0)
2564 } else if (a.size > 0)
2565 avio_skip(pb, a.size);
2567 if (sc->extradata && st->codecpar->extradata) {
2568 int extra_size = st->codecpar->extradata_size;
2570 /* Move the current stream extradata to the stream context one. */
2571 sc->extradata_size[pseudo_stream_id] = extra_size;
2572 sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
2573 st->codecpar->extradata = NULL;
2574 st->codecpar->extradata_size = 0;
2579 if (pb->eof_reached) {
2580 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
2587 static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2590 MOVStreamContext *sc;
2593 if (c->fc->nb_streams < 1)
2595 st = c->fc->streams[c->fc->nb_streams - 1];
2598 sc->stsd_version = avio_r8(pb);
2599 avio_rb24(pb); /* flags */
2600 entries = avio_rb32(pb);
2602 /* Each entry contains a size (4 bytes) and format (4 bytes). */
2603 if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
2604 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
2605 return AVERROR_INVALIDDATA;
2608 if (sc->extradata) {
2609 av_log(c->fc, AV_LOG_ERROR,
2610 "Duplicate stsd found in this track.\n");
2611 return AVERROR_INVALIDDATA;
2614 /* Prepare space for hosting multiple extradata. */
2615 sc->extradata = av_mallocz_array(entries, sizeof(*sc->extradata));
2617 return AVERROR(ENOMEM);
2619 sc->extradata_size = av_mallocz_array(entries, sizeof(*sc->extradata_size));
2620 if (!sc->extradata_size) {
2621 ret = AVERROR(ENOMEM);
2625 ret = ff_mov_read_stsd_entries(c, pb, entries);
2629 /* Restore back the primary extradata. */
2630 av_freep(&st->codecpar->extradata);
2631 st->codecpar->extradata_size = sc->extradata_size[0];
2632 if (sc->extradata_size[0]) {
2633 st->codecpar->extradata = av_mallocz(sc->extradata_size[0] + AV_INPUT_BUFFER_PADDING_SIZE);
2634 if (!st->codecpar->extradata)
2635 return AVERROR(ENOMEM);
2636 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
2639 return mov_finalize_stsd_codec(c, pb, st, sc);
2641 if (sc->extradata) {
2643 for (j = 0; j < sc->stsd_count; j++)
2644 av_freep(&sc->extradata[j]);
2647 av_freep(&sc->extradata);
2648 av_freep(&sc->extradata_size);
2652 static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2655 MOVStreamContext *sc;
2656 unsigned int i, entries;
2658 if (c->fc->nb_streams < 1)
2660 st = c->fc->streams[c->fc->nb_streams-1];
2663 avio_r8(pb); /* version */
2664 avio_rb24(pb); /* flags */
2666 entries = avio_rb32(pb);
2667 if ((uint64_t)entries * 12 + 4 > atom.size)
2668 return AVERROR_INVALIDDATA;
2670 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
2675 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSC atom\n");
2676 av_free(sc->stsc_data);
2678 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
2680 return AVERROR(ENOMEM);
2682 for (i = 0; i < entries && !pb->eof_reached; i++) {
2683 sc->stsc_data[i].first = avio_rb32(pb);
2684 sc->stsc_data[i].count = avio_rb32(pb);
2685 sc->stsc_data[i].id = avio_rb32(pb);
2689 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
2690 int64_t first_min = i + 1;
2691 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
2692 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
2693 sc->stsc_data[i].first < first_min ||
2694 sc->stsc_data[i].count < 1 ||
2695 sc->stsc_data[i].id < 1) {
2696 av_log(c->fc, AV_LOG_WARNING, "STSC entry %d is invalid (first=%d count=%d id=%d)\n", i, sc->stsc_data[i].first, sc->stsc_data[i].count, sc->stsc_data[i].id);
2697 if (i+1 >= sc->stsc_count) {
2698 if (sc->stsc_data[i].count == 0 && i > 0) {
2702 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
2703 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
2704 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
2705 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
2706 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
2709 av_assert0(sc->stsc_data[i+1].first >= 2);
2710 // We replace this entry by the next valid
2711 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
2712 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
2713 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
2717 if (pb->eof_reached) {
2718 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
2725 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
2727 return index < count - 1;
2730 /* Compute the samples value for the stsc entry at the given index. */
2731 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
2735 if (mov_stsc_index_valid(index, sc->stsc_count))
2736 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
2738 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
2739 av_assert0(sc->stsc_data[index].first <= sc->chunk_count);
2740 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
2743 return sc->stsc_data[index].count * (int64_t)chunk_count;
2746 static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2749 MOVStreamContext *sc;
2750 unsigned i, entries;
2752 if (c->fc->nb_streams < 1)
2754 st = c->fc->streams[c->fc->nb_streams-1];
2757 avio_rb32(pb); // version + flags
2759 entries = avio_rb32(pb);
2761 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
2762 av_free(sc->stps_data);
2764 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
2766 return AVERROR(ENOMEM);
2768 for (i = 0; i < entries && !pb->eof_reached; i++) {
2769 sc->stps_data[i] = avio_rb32(pb);
2774 if (pb->eof_reached) {
2775 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
2782 static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2785 MOVStreamContext *sc;
2786 unsigned int i, entries;
2788 if (c->fc->nb_streams < 1)
2790 st = c->fc->streams[c->fc->nb_streams-1];
2793 avio_r8(pb); /* version */
2794 avio_rb24(pb); /* flags */
2796 entries = avio_rb32(pb);
2798 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
2801 sc->keyframe_absent = 1;
2802 if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
2803 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2807 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
2808 if (entries >= UINT_MAX / sizeof(int))
2809 return AVERROR_INVALIDDATA;
2810 av_freep(&sc->keyframes);
2811 sc->keyframe_count = 0;
2812 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
2814 return AVERROR(ENOMEM);
2816 for (i = 0; i < entries && !pb->eof_reached; i++) {
2817 sc->keyframes[i] = avio_rb32(pb);
2820 sc->keyframe_count = i;
2822 if (pb->eof_reached) {
2823 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
2830 static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2833 MOVStreamContext *sc;
2834 unsigned int i, entries, sample_size, field_size, num_bytes;
2839 if (c->fc->nb_streams < 1)
2841 st = c->fc->streams[c->fc->nb_streams-1];
2844 avio_r8(pb); /* version */
2845 avio_rb24(pb); /* flags */
2847 if (atom.type == MKTAG('s','t','s','z')) {
2848 sample_size = avio_rb32(pb);
2849 if (!sc->sample_size) /* do not overwrite value computed in stsd */
2850 sc->sample_size = sample_size;
2851 sc->stsz_sample_size = sample_size;
2855 avio_rb24(pb); /* reserved */
2856 field_size = avio_r8(pb);
2858 entries = avio_rb32(pb);
2860 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
2862 sc->sample_count = entries;
2866 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
2867 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
2868 return AVERROR_INVALIDDATA;
2873 if (entries >= (UINT_MAX - 4) / field_size)
2874 return AVERROR_INVALIDDATA;
2875 if (sc->sample_sizes)
2876 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
2877 av_free(sc->sample_sizes);
2878 sc->sample_count = 0;
2879 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
2880 if (!sc->sample_sizes)
2881 return AVERROR(ENOMEM);
2883 num_bytes = (entries*field_size+4)>>3;
2885 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
2887 av_freep(&sc->sample_sizes);
2888 return AVERROR(ENOMEM);
2891 ret = ffio_read_size(pb, buf, num_bytes);
2893 av_freep(&sc->sample_sizes);
2895 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
2899 init_get_bits(&gb, buf, 8*num_bytes);
2901 for (i = 0; i < entries && !pb->eof_reached; i++) {
2902 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
2903 if (sc->sample_sizes[i] < 0) {
2905 av_log(c->fc, AV_LOG_ERROR, "Invalid sample size %d\n", sc->sample_sizes[i]);
2906 return AVERROR_INVALIDDATA;
2908 sc->data_size += sc->sample_sizes[i];
2911 sc->sample_count = i;
2915 if (pb->eof_reached) {
2916 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSZ atom\n");
2923 static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2926 MOVStreamContext *sc;
2927 unsigned int i, entries, alloc_size = 0;
2928 int64_t duration = 0;
2929 int64_t total_sample_count = 0;
2931 if (c->fc->nb_streams < 1)
2933 st = c->fc->streams[c->fc->nb_streams-1];
2936 avio_r8(pb); /* version */
2937 avio_rb24(pb); /* flags */
2938 entries = avio_rb32(pb);
2940 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
2941 c->fc->nb_streams-1, entries);
2944 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
2945 av_freep(&sc->stts_data);
2947 if (entries >= INT_MAX / sizeof(*sc->stts_data))
2948 return AVERROR(ENOMEM);
2950 for (i = 0; i < entries && !pb->eof_reached; i++) {
2951 int sample_duration;
2952 unsigned int sample_count;
2953 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
2954 MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
2955 min_entries * sizeof(*sc->stts_data));
2957 av_freep(&sc->stts_data);
2959 return AVERROR(ENOMEM);
2961 sc->stts_count = min_entries;
2962 sc->stts_data = stts_data;
2964 sample_count = avio_rb32(pb);
2965 sample_duration = avio_rb32(pb);
2967 sc->stts_data[i].count= sample_count;
2968 sc->stts_data[i].duration= sample_duration;
2970 av_log(c->fc, AV_LOG_TRACE, "sample_count=%d, sample_duration=%d\n",
2971 sample_count, sample_duration);
2973 duration+=(int64_t)sample_duration*(uint64_t)sample_count;
2974 total_sample_count+=sample_count;
2980 duration <= INT64_MAX - sc->duration_for_fps &&
2981 total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
2982 sc->duration_for_fps += duration;
2983 sc->nb_frames_for_fps += total_sample_count;
2986 if (pb->eof_reached) {
2987 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
2991 st->nb_frames= total_sample_count;
2993 st->duration= FFMIN(st->duration, duration);
2994 sc->track_end = duration;
2998 static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3001 MOVStreamContext *sc;
3004 if (c->fc->nb_streams < 1)
3006 st = c->fc->streams[c->fc->nb_streams - 1];
3009 avio_r8(pb); /* version */
3010 avio_rb24(pb); /* flags */
3011 entries = atom.size - 4;
3013 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3014 c->fc->nb_streams - 1, entries);
3017 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3018 av_freep(&sc->sdtp_data);
3021 sc->sdtp_data = av_mallocz(entries);
3023 return AVERROR(ENOMEM);
3025 for (i = 0; i < entries && !pb->eof_reached; i++)
3026 sc->sdtp_data[i] = avio_r8(pb);
3032 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3035 if (duration == INT_MIN) {
3036 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3039 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3043 static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3046 MOVStreamContext *sc;
3047 unsigned int i, entries, ctts_count = 0;
3049 if (c->fc->nb_streams < 1)
3051 st = c->fc->streams[c->fc->nb_streams-1];
3054 avio_r8(pb); /* version */
3055 avio_rb24(pb); /* flags */
3056 entries = avio_rb32(pb);
3058 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3062 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3063 return AVERROR_INVALIDDATA;
3064 av_freep(&sc->ctts_data);
3065 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3067 return AVERROR(ENOMEM);
3069 for (i = 0; i < entries && !pb->eof_reached; i++) {
3070 int count = avio_rb32(pb);
3071 int duration = avio_rb32(pb);
3074 av_log(c->fc, AV_LOG_TRACE,
3075 "ignoring CTTS entry with count=%d duration=%d\n",
3080 add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3083 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3086 if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3087 av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3088 av_freep(&sc->ctts_data);
3094 mov_update_dts_shift(sc, duration, c->fc);
3097 sc->ctts_count = ctts_count;
3099 if (pb->eof_reached) {
3100 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3104 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3109 static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3112 MOVStreamContext *sc;
3113 unsigned int i, entries;
3115 uint32_t grouping_type;
3117 if (c->fc->nb_streams < 1)
3119 st = c->fc->streams[c->fc->nb_streams-1];
3122 version = avio_r8(pb); /* version */
3123 avio_rb24(pb); /* flags */
3124 grouping_type = avio_rl32(pb);
3125 if (grouping_type != MKTAG( 'r','a','p',' '))
3126 return 0; /* only support 'rap ' grouping */
3128 avio_rb32(pb); /* grouping_type_parameter */
3130 entries = avio_rb32(pb);
3134 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP atom\n");
3135 av_free(sc->rap_group);
3136 sc->rap_group_count = 0;
3137 sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group));
3139 return AVERROR(ENOMEM);
3141 for (i = 0; i < entries && !pb->eof_reached; i++) {
3142 sc->rap_group[i].count = avio_rb32(pb); /* sample_count */
3143 sc->rap_group[i].index = avio_rb32(pb); /* group_description_index */
3146 sc->rap_group_count = i;
3148 if (pb->eof_reached) {
3149 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3157 * Get ith edit list entry (media time, duration).
3159 static int get_edit_list_entry(MOVContext *mov,
3160 const MOVStreamContext *msc,
3161 unsigned int edit_list_index,
3162 int64_t *edit_list_media_time,
3163 int64_t *edit_list_duration,
3164 int64_t global_timescale)
3166 if (edit_list_index == msc->elst_count) {
3169 *edit_list_media_time = msc->elst_data[edit_list_index].time;
3170 *edit_list_duration = msc->elst_data[edit_list_index].duration;
3172 /* duration is in global timescale units;convert to msc timescale */
3173 if (global_timescale == 0) {
3174 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3177 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3183 * Find the closest previous frame to the timestamp_pts, in e_old index
3184 * entries. Searching for just any frame / just key frames can be controlled by
3185 * last argument 'flag'.
3186 * Note that if ctts_data is not NULL, we will always search for a key frame
3187 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3188 * return the first frame of the video.
3190 * Here the timestamp_pts is considered to be a presentation timestamp and
3191 * the timestamp of index entries are considered to be decoding timestamps.
3193 * Returns 0 if successful in finding a frame, else returns -1.
3194 * Places the found index corresponding output arg.
3196 * If ctts_old is not NULL, then refines the searched entry by searching
3197 * backwards from the found timestamp, to find the frame with correct PTS.
3199 * Places the found ctts_index and ctts_sample in corresponding output args.
3201 static int find_prev_closest_index(AVStream *st,
3202 AVIndexEntry *e_old,
3206 int64_t timestamp_pts,
3209 int64_t* ctts_index,
3210 int64_t* ctts_sample)
3212 MOVStreamContext *msc = st->priv_data;
3213 AVIndexEntry *e_keep = st->internal->index_entries;
3214 int nb_keep = st->internal->nb_index_entries;
3216 int64_t index_ctts_count;
3220 // If dts_shift > 0, then all the index timestamps will have to be offset by
3221 // at least dts_shift amount to obtain PTS.
3222 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3223 if (msc->dts_shift > 0) {
3224 timestamp_pts -= msc->dts_shift;
3227 st->internal->index_entries = e_old;
3228 st->internal->nb_index_entries = nb_old;
3229 *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3231 // Keep going backwards in the index entries until the timestamp is the same.
3233 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3235 if ((flag & AVSEEK_FLAG_ANY) ||
3236 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3242 // If we have CTTS then refine the search, by searching backwards over PTS
3243 // computed by adding corresponding CTTS durations to index timestamps.
3244 if (ctts_data && *index >= 0) {
3245 av_assert0(ctts_index);
3246 av_assert0(ctts_sample);
3247 // Find out the ctts_index for the found frame.
3250 for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3251 if (*ctts_index < ctts_count) {
3253 if (ctts_data[*ctts_index].count == *ctts_sample) {
3260 while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3261 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3262 // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3263 // compensated by dts_shift above.
3264 if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3265 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3270 if (*ctts_sample == 0) {
3272 if (*ctts_index >= 0)
3273 *ctts_sample = ctts_data[*ctts_index].count - 1;
3280 /* restore AVStream state*/
3281 st->internal->index_entries = e_keep;
3282 st->internal->nb_index_entries = nb_keep;
3283 return *index >= 0 ? 0 : -1;
3287 * Add index entry with the given values, to the end of st->internal->index_entries.
3288 * Returns the new size st->internal->index_entries if successful, else returns -1.
3290 * This function is similar to ff_add_index_entry in libavformat/utils.c
3291 * except that here we are always unconditionally adding an index entry to
3292 * the end, instead of searching the entries list and skipping the add if
3293 * there is an existing entry with the same timestamp.
3294 * This is needed because the mov_fix_index calls this func with the same
3295 * unincremented timestamp for successive discarded frames.
3297 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3298 int size, int distance, int flags)
3300 AVIndexEntry *entries, *ie;
3302 const size_t min_size_needed = (st->internal->nb_index_entries + 1) * sizeof(AVIndexEntry);
3304 // Double the allocation each time, to lower memory fragmentation.
3305 // Another difference from ff_add_index_entry function.
3306 const size_t requested_size =
3307 min_size_needed > st->internal->index_entries_allocated_size ?
3308 FFMAX(min_size_needed, 2 * st->internal->index_entries_allocated_size) :
3311 if (st->internal->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
3314 entries = av_fast_realloc(st->internal->index_entries,
3315 &st->internal->index_entries_allocated_size,
3320 st->internal->index_entries= entries;
3322 index= st->internal->nb_index_entries++;
3323 ie= &entries[index];
3326 ie->timestamp = timestamp;
3327 ie->min_distance= distance;
3334 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3335 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3337 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3338 int64_t* frame_duration_buffer,
3339 int frame_duration_buffer_size) {
3341 av_assert0(end_index >= 0 && end_index <= st->internal->nb_index_entries);
3342 for (i = 0; i < frame_duration_buffer_size; i++) {
3343 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3344 st->internal->index_entries[end_index - 1 - i].timestamp = end_ts;
3349 * Append a new ctts entry to ctts_data.
3350 * Returns the new ctts_count if successful, else returns -1.
3352 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3353 int count, int duration)
3355 MOVStts *ctts_buf_new;
3356 const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVStts);
3357 const size_t requested_size =
3358 min_size_needed > *allocated_size ?
3359 FFMAX(min_size_needed, 2 * (*allocated_size)) :
3362 if ((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
3365 ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3370 *ctts_data = ctts_buf_new;
3372 ctts_buf_new[*ctts_count].count = count;
3373 ctts_buf_new[*ctts_count].duration = duration;
3375 *ctts_count = (*ctts_count) + 1;
3379 #define MAX_REORDER_DELAY 16
3380 static void mov_estimate_video_delay(MOVContext *c, AVStream* st)
3382 MOVStreamContext *msc = st->priv_data;
3385 int ctts_sample = 0;
3386 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3388 int j, r, num_swaps;
3390 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3391 pts_buf[j] = INT64_MIN;
3393 if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3394 st->codecpar->codec_id == AV_CODEC_ID_H264) {
3395 st->codecpar->video_delay = 0;
3396 for (ind = 0; ind < st->internal->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3397 // Point j to the last elem of the buffer and insert the current pts there.
3399 buf_start = (buf_start + 1);
3400 if (buf_start == MAX_REORDER_DELAY + 1)
3403 pts_buf[j] = st->internal->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3405 // The timestamps that are already in the sorted buffer, and are greater than the
3406 // current pts, are exactly the timestamps that need to be buffered to output PTS
3407 // in correct sorted order.
3408 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3409 // can be computed as the maximum no. of swaps any particular timestamp needs to
3410 // go through, to keep this buffer in sorted order.
3412 while (j != buf_start) {
3414 if (r < 0) r = MAX_REORDER_DELAY;
3415 if (pts_buf[j] < pts_buf[r]) {
3416 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3423 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3426 if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3431 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3432 st->codecpar->video_delay, st->index);
3436 static void mov_current_sample_inc(MOVStreamContext *sc)
3438 sc->current_sample++;
3439 sc->current_index++;
3440 if (sc->index_ranges &&
3441 sc->current_index >= sc->current_index_range->end &&
3442 sc->current_index_range->end) {
3443 sc->current_index_range++;
3444 sc->current_index = sc->current_index_range->start;
3448 static void mov_current_sample_dec(MOVStreamContext *sc)
3450 sc->current_sample--;
3451 sc->current_index--;
3452 if (sc->index_ranges &&
3453 sc->current_index < sc->current_index_range->start &&
3454 sc->current_index_range > sc->index_ranges) {
3455 sc->current_index_range--;
3456 sc->current_index = sc->current_index_range->end - 1;
3460 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3464 sc->current_sample = current_sample;
3465 sc->current_index = current_sample;
3466 if (!sc->index_ranges) {
3470 for (sc->current_index_range = sc->index_ranges;
3471 sc->current_index_range->end;
3472 sc->current_index_range++) {
3473 range_size = sc->current_index_range->end - sc->current_index_range->start;
3474 if (range_size > current_sample) {
3475 sc->current_index = sc->current_index_range->start + current_sample;
3478 current_sample -= range_size;
3483 * Fix st->internal->index_entries, so that it contains only the entries (and the entries
3484 * which are needed to decode them) that fall in the edit list time ranges.
3485 * Also fixes the timestamps of the index entries to match the timeline
3486 * specified the edit lists.
3488 static void mov_fix_index(MOVContext *mov, AVStream *st)
3490 MOVStreamContext *msc = st->priv_data;
3491 AVIndexEntry *e_old = st->internal->index_entries;
3492 int nb_old = st->internal->nb_index_entries;
3493 const AVIndexEntry *e_old_end = e_old + nb_old;
3494 const AVIndexEntry *current = NULL;
3495 MOVStts *ctts_data_old = msc->ctts_data;
3496 int64_t ctts_index_old = 0;
3497 int64_t ctts_sample_old = 0;
3498 int64_t ctts_count_old = msc->ctts_count;
3499 int64_t edit_list_media_time = 0;
3500 int64_t edit_list_duration = 0;
3501 int64_t frame_duration = 0;
3502 int64_t edit_list_dts_counter = 0;
3503 int64_t edit_list_dts_entry_end = 0;
3504 int64_t edit_list_start_ctts_sample = 0;
3506 int64_t curr_ctts = 0;
3507 int64_t empty_edits_sum_duration = 0;
3508 int64_t edit_list_index = 0;
3511 int64_t start_dts = 0;
3512 int64_t edit_list_start_encountered = 0;
3513 int64_t search_timestamp = 0;
3514 int64_t* frame_duration_buffer = NULL;
3515 int num_discarded_begin = 0;
3516 int first_non_zero_audio_edit = -1;
3517 int packet_skip_samples = 0;
3518 MOVIndexRange *current_index_range;
3520 int found_keyframe_after_edit = 0;
3521 int found_non_empty_edit = 0;
3523 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
3527 // allocate the index ranges array
3528 msc->index_ranges = av_malloc((msc->elst_count + 1) * sizeof(msc->index_ranges[0]));
3529 if (!msc->index_ranges) {
3530 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
3533 msc->current_index_range = msc->index_ranges;
3534 current_index_range = msc->index_ranges - 1;
3536 // Clean AVStream from traces of old index
3537 st->internal->index_entries = NULL;
3538 st->internal->index_entries_allocated_size = 0;
3539 st->internal->nb_index_entries = 0;
3541 // Clean ctts fields of MOVStreamContext
3542 msc->ctts_data = NULL;
3543 msc->ctts_count = 0;
3544 msc->ctts_index = 0;
3545 msc->ctts_sample = 0;
3546 msc->ctts_allocated_size = 0;
3548 // Reinitialize min_corrected_pts so that it can be computed again.
3549 msc->min_corrected_pts = -1;
3551 // If the dts_shift is positive (in case of negative ctts values in mov),
3552 // then negate the DTS by dts_shift
3553 if (msc->dts_shift > 0) {
3554 edit_list_dts_entry_end -= msc->dts_shift;
3555 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
3558 start_dts = edit_list_dts_entry_end;
3560 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
3561 &edit_list_duration, mov->time_scale)) {
3562 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
3563 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
3565 edit_list_dts_counter = edit_list_dts_entry_end;
3566 edit_list_dts_entry_end += edit_list_duration;
3567 num_discarded_begin = 0;
3568 if (!found_non_empty_edit && edit_list_media_time == -1) {
3569 empty_edits_sum_duration += edit_list_duration;
3572 found_non_empty_edit = 1;
3574 // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
3575 // according to the edit list below.
3576 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3577 if (first_non_zero_audio_edit < 0) {
3578 first_non_zero_audio_edit = 1;
3580 first_non_zero_audio_edit = 0;
3583 if (first_non_zero_audio_edit > 0)
3584 st->internal->skip_samples = msc->start_pad = 0;
3587 // While reordering frame index according to edit list we must handle properly
3588 // the scenario when edit list entry starts from none key frame.
3589 // We find closest previous key frame and preserve it and consequent frames in index.
3590 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
3591 search_timestamp = edit_list_media_time;
3592 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3593 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
3594 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
3595 // edit_list_media_time to cover the decoder delay.
3596 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
3599 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
3600 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3601 av_log(mov->fc, AV_LOG_WARNING,
3602 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
3603 st->index, edit_list_index, search_timestamp);
3604 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
3605 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3606 av_log(mov->fc, AV_LOG_WARNING,
3607 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
3608 st->index, edit_list_index, search_timestamp);
3611 ctts_sample_old = 0;
3614 current = e_old + index;
3615 edit_list_start_ctts_sample = ctts_sample_old;
3617 // Iterate over index and arrange it according to edit list
3618 edit_list_start_encountered = 0;
3619 found_keyframe_after_edit = 0;
3620 for (; current < e_old_end; current++, index++) {
3621 // check if frame outside edit list mark it for discard
3622 frame_duration = (current + 1 < e_old_end) ?
3623 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
3625 flags = current->flags;
3627 // frames (pts) before or after edit list
3628 curr_cts = current->timestamp + msc->dts_shift;
3631 if (ctts_data_old && ctts_index_old < ctts_count_old) {
3632 curr_ctts = ctts_data_old[ctts_index_old].duration;
3633 av_log(mov->fc, AV_LOG_DEBUG, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
3634 curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
3635 curr_cts += curr_ctts;
3637 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
3638 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3639 &msc->ctts_allocated_size,
3640 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3641 ctts_data_old[ctts_index_old].duration) == -1) {
3642 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3644 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3645 ctts_data_old[ctts_index_old].duration);
3649 ctts_sample_old = 0;
3650 edit_list_start_ctts_sample = 0;
3654 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
3655 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
3656 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
3657 first_non_zero_audio_edit > 0) {
3658 packet_skip_samples = edit_list_media_time - curr_cts;
3659 st->internal->skip_samples += packet_skip_samples;
3661 // Shift the index entry timestamp by packet_skip_samples to be correct.
3662 edit_list_dts_counter -= packet_skip_samples;
3663 if (edit_list_start_encountered == 0) {
3664 edit_list_start_encountered = 1;
3665 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
3666 // discarded packets.
3667 if (frame_duration_buffer) {
3668 fix_index_entry_timestamps(st, st->internal->nb_index_entries, edit_list_dts_counter,
3669 frame_duration_buffer, num_discarded_begin);
3670 av_freep(&frame_duration_buffer);
3674 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
3676 flags |= AVINDEX_DISCARD_FRAME;
3677 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
3679 if (edit_list_start_encountered == 0) {
3680 num_discarded_begin++;
3681 frame_duration_buffer = av_realloc(frame_duration_buffer,
3682 num_discarded_begin * sizeof(int64_t));
3683 if (!frame_duration_buffer) {
3684 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
3687 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
3689 // Increment skip_samples for the first non-zero audio edit list
3690 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3691 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
3692 st->internal->skip_samples += frame_duration;
3697 if (msc->min_corrected_pts < 0) {
3698 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
3700 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
3702 if (edit_list_start_encountered == 0) {
3703 edit_list_start_encountered = 1;
3704 // Make timestamps strictly monotonically increasing by rewriting timestamps for
3705 // discarded packets.
3706 if (frame_duration_buffer) {
3707 fix_index_entry_timestamps(st, st->internal->nb_index_entries, edit_list_dts_counter,
3708 frame_duration_buffer, num_discarded_begin);
3709 av_freep(&frame_duration_buffer);
3714 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
3715 current->min_distance, flags) == -1) {
3716 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
3720 // Update the index ranges array
3721 if (current_index_range < msc->index_ranges || index != current_index_range->end) {
3722 current_index_range++;
3723 current_index_range->start = index;
3725 current_index_range->end = index + 1;
3727 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
3728 if (edit_list_start_encountered > 0) {
3729 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
3732 // Break when found first key frame after edit entry completion
3733 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
3734 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
3735 if (ctts_data_old) {
3736 // If we have CTTS and this is the first keyframe after edit elist,
3737 // wait for one more, because there might be trailing B-frames after this I-frame
3738 // that do belong to the edit.
3739 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
3740 found_keyframe_after_edit = 1;
3743 if (ctts_sample_old != 0) {
3744 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3745 &msc->ctts_allocated_size,
3746 ctts_sample_old - edit_list_start_ctts_sample,
3747 ctts_data_old[ctts_index_old].duration) == -1) {
3748 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3749 ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
3750 ctts_data_old[ctts_index_old].duration);
3759 // If there are empty edits, then msc->min_corrected_pts might be positive
3760 // intentionally. So we subtract the sum duration of emtpy edits here.
3761 msc->min_corrected_pts -= empty_edits_sum_duration;
3763 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
3764 // dts by that amount to make the first pts zero.
3765 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
3766 if (msc->min_corrected_pts > 0) {
3767 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
3768 for (i = 0; i < st->internal->nb_index_entries; ++i) {
3769 st->internal->index_entries[i].timestamp -= msc->min_corrected_pts;
3773 // Start time should be equal to zero or the duration of any empty edits.
3774 st->start_time = empty_edits_sum_duration;
3776 // Update av stream length, if it ends up shorter than the track's media duration
3777 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
3778 msc->start_pad = st->internal->skip_samples;
3780 // Free the old index and the old CTTS structures
3782 av_free(ctts_data_old);
3783 av_freep(&frame_duration_buffer);
3785 // Null terminate the index ranges array
3786 current_index_range++;
3787 current_index_range->start = 0;
3788 current_index_range->end = 0;
3789 msc->current_index = msc->index_ranges[0].start;
3792 static void mov_build_index(MOVContext *mov, AVStream *st)
3794 MOVStreamContext *sc = st->priv_data;
3795 int64_t current_offset;
3796 int64_t current_dts = 0;
3797 unsigned int stts_index = 0;
3798 unsigned int stsc_index = 0;
3799 unsigned int stss_index = 0;
3800 unsigned int stps_index = 0;
3802 uint64_t stream_size = 0;
3803 MOVStts *ctts_data_old = sc->ctts_data;
3804 unsigned int ctts_count_old = sc->ctts_count;
3806 if (sc->elst_count) {
3807 int i, edit_start_index = 0, multiple_edits = 0;
3808 int64_t empty_duration = 0; // empty duration of the first edit list entry
3809 int64_t start_time = 0; // start time of the media
3811 for (i = 0; i < sc->elst_count; i++) {
3812 const MOVElst *e = &sc->elst_data[i];
3813 if (i == 0 && e->time == -1) {
3814 /* if empty, the first entry is the start time of the stream
3815 * relative to the presentation itself */
3816 empty_duration = e->duration;
3817 edit_start_index = 1;
3818 } else if (i == edit_start_index && e->time >= 0) {
3819 start_time = e->time;
3825 if (multiple_edits && !mov->advanced_editlist)
3826 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
3827 "Use -advanced_editlist to correctly decode otherwise "
3828 "a/v desync might occur\n");
3830 /* adjust first dts according to edit list */
3831 if ((empty_duration || start_time) && mov->time_scale > 0) {
3833 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
3834 sc->time_offset = start_time - empty_duration;
3835 sc->min_corrected_pts = start_time;
3836 if (!mov->advanced_editlist)
3837 current_dts = -sc->time_offset;
3840 if (!multiple_edits && !mov->advanced_editlist &&
3841 st->codecpar->codec_id == AV_CODEC_ID_AAC && start_time > 0)
3842 sc->start_pad = start_time;
3845 /* only use old uncompressed audio chunk demuxing when stts specifies it */
3846 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3847 sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
3848 unsigned int current_sample = 0;
3849 unsigned int stts_sample = 0;
3850 unsigned int sample_size;
3851 unsigned int distance = 0;
3852 unsigned int rap_group_index = 0;
3853 unsigned int rap_group_sample = 0;
3854 int64_t last_dts = 0;
3855 int64_t dts_correction = 0;
3856 int rap_group_present = sc->rap_group_count && sc->rap_group;
3857 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
3859 current_dts -= sc->dts_shift;
3860 last_dts = current_dts;
3862 if (!sc->sample_count || st->internal->nb_index_entries)
3864 if (sc->sample_count >= UINT_MAX / sizeof(*st->internal->index_entries) - st->internal->nb_index_entries)
3866 if (av_reallocp_array(&st->internal->index_entries,
3867 st->internal->nb_index_entries + sc->sample_count,
3868 sizeof(*st->internal->index_entries)) < 0) {
3869 st->internal->nb_index_entries = 0;
3872 st->internal->index_entries_allocated_size = (st->internal->nb_index_entries + sc->sample_count) * sizeof(*st->internal->index_entries);
3874 if (ctts_data_old) {
3875 // Expand ctts entries such that we have a 1-1 mapping with samples
3876 if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
3879 sc->ctts_allocated_size = 0;
3880 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size,
3881 sc->sample_count * sizeof(*sc->ctts_data));
3882 if (!sc->ctts_data) {
3883 av_free(ctts_data_old);
3887 memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
3889 for (i = 0; i < ctts_count_old &&
3890 sc->ctts_count < sc->sample_count; i++)
3891 for (j = 0; j < ctts_data_old[i].count &&
3892 sc->ctts_count < sc->sample_count; j++)
3893 add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
3894 &sc->ctts_allocated_size, 1,
3895 ctts_data_old[i].duration);
3896 av_free(ctts_data_old);
3899 for (i = 0; i < sc->chunk_count; i++) {
3900 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
3901 current_offset = sc->chunk_offsets[i];
3902 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3903 i + 1 == sc->stsc_data[stsc_index + 1].first)
3906 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
3907 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
3908 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
3909 sc->stsz_sample_size = sc->sample_size;
3911 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
3912 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
3913 sc->stsz_sample_size = sc->sample_size;
3916 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
3918 if (current_sample >= sc->sample_count) {
3919 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
3923 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
3925 if (stss_index + 1 < sc->keyframe_count)
3927 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
3929 if (stps_index + 1 < sc->stps_count)
3932 if (rap_group_present && rap_group_index < sc->rap_group_count) {
3933 if (sc->rap_group[rap_group_index].index > 0)
3935 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
3936 rap_group_sample = 0;
3940 if (sc->keyframe_absent
3942 && !rap_group_present
3943 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
3947 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
3948 if (sc->pseudo_stream_id == -1 ||
3949 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
3951 if (sample_size > 0x3FFFFFFF) {
3952 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
3955 e = &st->internal->index_entries[st->internal->nb_index_entries++];
3956 e->pos = current_offset;
3957 e->timestamp = current_dts;
3958 e->size = sample_size;
3959 e->min_distance = distance;
3960 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
3961 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
3962 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
3963 current_offset, current_dts, sample_size, distance, keyframe);
3964 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->internal->nb_index_entries < 100)
3965 ff_rfps_add_frame(mov->fc, st, current_dts);
3968 current_offset += sample_size;
3969 stream_size += sample_size;
3971 /* A negative sample duration is invalid based on the spec,
3972 * but some samples need it to correct the DTS. */
3973 if (sc->stts_data[stts_index].duration < 0) {
3974 av_log(mov->fc, AV_LOG_WARNING,
3975 "Invalid SampleDelta %d in STTS, at %d st:%d\n",
3976 sc->stts_data[stts_index].duration, stts_index,
3978 dts_correction += sc->stts_data[stts_index].duration - 1;
3979 sc->stts_data[stts_index].duration = 1;
3981 current_dts += sc->stts_data[stts_index].duration;
3982 if (!dts_correction || current_dts + dts_correction > last_dts) {
3983 current_dts += dts_correction;
3986 /* Avoid creating non-monotonous DTS */
3987 dts_correction += current_dts - last_dts - 1;
3988 current_dts = last_dts + 1;
3990 last_dts = current_dts;
3994 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
4000 if (st->duration > 0)
4001 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
4003 unsigned chunk_samples, total = 0;
4005 if (!sc->chunk_count)
4008 // compute total chunk count
4009 for (i = 0; i < sc->stsc_count; i++) {
4010 unsigned count, chunk_count;
4012 chunk_samples = sc->stsc_data[i].count;
4013 if (i != sc->stsc_count - 1 &&
4014 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
4015 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
4019 if (sc->samples_per_frame >= 160) { // gsm
4020 count = chunk_samples / sc->samples_per_frame;
4021 } else if (sc->samples_per_frame > 1) {
4022 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4023 count = (chunk_samples+samples-1) / samples;
4025 count = (chunk_samples+1023) / 1024;
4028 if (mov_stsc_index_valid(i, sc->stsc_count))
4029 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4031 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4032 total += chunk_count * count;
4035 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4036 if (total >= UINT_MAX / sizeof(*st->internal->index_entries) - st->internal->nb_index_entries)
4038 if (av_reallocp_array(&st->internal->index_entries,
4039 st->internal->nb_index_entries + total,
4040 sizeof(*st->internal->index_entries)) < 0) {
4041 st->internal->nb_index_entries = 0;
4044 st->internal->index_entries_allocated_size = (st->internal->nb_index_entries + total) * sizeof(*st->internal->index_entries);
4047 for (i = 0; i < sc->chunk_count; i++) {
4048 current_offset = sc->chunk_offsets[i];
4049 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4050 i + 1 == sc->stsc_data[stsc_index + 1].first)
4052 chunk_samples = sc->stsc_data[stsc_index].count;
4054 while (chunk_samples > 0) {
4056 unsigned size, samples;
4058 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4059 avpriv_request_sample(mov->fc,
4060 "Zero bytes per frame, but %d samples per frame",
4061 sc->samples_per_frame);
4065 if (sc->samples_per_frame >= 160) { // gsm
4066 samples = sc->samples_per_frame;
4067 size = sc->bytes_per_frame;
4069 if (sc->samples_per_frame > 1) {
4070 samples = FFMIN((1024 / sc->samples_per_frame)*
4071 sc->samples_per_frame, chunk_samples);
4072 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
4074 samples = FFMIN(1024, chunk_samples);
4075 size = samples * sc->sample_size;
4079 if (st->internal->nb_index_entries >= total) {
4080 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4083 if (size > 0x3FFFFFFF) {
4084 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4087 e = &st->internal->index_entries[st->internal->nb_index_entries++];
4088 e->pos = current_offset;
4089 e->timestamp = current_dts;
4091 e->min_distance = 0;
4092 e->flags = AVINDEX_KEYFRAME;
4093 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4094 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4097 current_offset += size;
4098 current_dts += samples;
4099 chunk_samples -= samples;
4104 if (!mov->ignore_editlist && mov->advanced_editlist) {
4105 // Fix index according to edit lists.
4106 mov_fix_index(mov, st);
4109 // Update start time of the stream.
4110 if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->internal->nb_index_entries > 0) {
4111 st->start_time = st->internal->index_entries[0].timestamp + sc->dts_shift;
4112 if (sc->ctts_data) {
4113 st->start_time += sc->ctts_data[0].duration;
4117 mov_estimate_video_delay(mov, st);
4120 static int test_same_origin(const char *src, const char *ref) {
4130 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4131 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4133 if (strlen(src) == 0) {
4135 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4136 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4137 strlen(src_host) + 1 >= sizeof(src_host) ||
4138 strlen(ref_host) + 1 >= sizeof(ref_host)) {
4140 } else if (strcmp(src_proto, ref_proto) ||
4141 strcmp(src_auth, ref_auth) ||
4142 strcmp(src_host, ref_host) ||
4143 src_port != ref_port) {
4149 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4151 /* try relative path, we do not try the absolute because it can leak information about our
4152 system to an attacker */
4153 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4154 char filename[1025];
4155 const char *src_path;
4158 /* find a source dir */
4159 src_path = strrchr(src, '/');
4165 /* find a next level down to target */
4166 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4167 if (ref->path[l] == '/') {
4168 if (i == ref->nlvl_to - 1)
4174 /* compose filename if next level down to target was found */
4175 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4176 memcpy(filename, src, src_path - src);
4177 filename[src_path - src] = 0;
4179 for (i = 1; i < ref->nlvl_from; i++)
4180 av_strlcat(filename, "../", sizeof(filename));
4182 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4183 if (!c->use_absolute_path) {
4184 int same_origin = test_same_origin(src, filename);
4187 av_log(c->fc, AV_LOG_ERROR,
4188 "Reference with mismatching origin, %s not tried for security reasons, "
4189 "set demuxer option use_absolute_path to allow it anyway\n",
4191 return AVERROR(ENOENT);
4194 if (strstr(ref->path + l + 1, "..") ||
4195 strstr(ref->path + l + 1, ":") ||
4196 (ref->nlvl_from > 1 && same_origin < 0) ||
4197 (filename[0] == '/' && src_path == src))
4198 return AVERROR(ENOENT);
4201 if (strlen(filename) + 1 == sizeof(filename))
4202 return AVERROR(ENOENT);
4203 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4206 } else if (c->use_absolute_path) {
4207 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4208 "this is a possible security issue\n");
4209 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4212 av_log(c->fc, AV_LOG_ERROR,
4213 "Absolute path %s not tried for security reasons, "
4214 "set demuxer option use_absolute_path to allow absolute paths\n",
4218 return AVERROR(ENOENT);
4221 static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
4223 if (sc->time_scale <= 0) {
4224 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4225 sc->time_scale = c->time_scale;
4226 if (sc->time_scale <= 0)
4231 static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4234 MOVStreamContext *sc;
4237 st = avformat_new_stream(c->fc, NULL);
4238 if (!st) return AVERROR(ENOMEM);
4240 sc = av_mallocz(sizeof(MOVStreamContext));
4241 if (!sc) return AVERROR(ENOMEM);
4244 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
4245 sc->ffindex = st->index;
4246 c->trak_index = st->index;
4248 if ((ret = mov_read_default(c, pb, atom)) < 0)
4253 // Here stsc refers to a chunk not described in stco. This is technically invalid,
4254 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4255 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4257 av_freep(&sc->stsc_data);
4261 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4262 (!sc->sample_size && !sc->sample_count))) ||
4263 (!sc->chunk_count && sc->sample_count)) {
4264 av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4268 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4269 av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4271 return AVERROR_INVALIDDATA;
4274 fix_timescale(c, sc);
4276 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4278 mov_build_index(c, st);
4280 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4281 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4282 if (c->enable_drefs) {
4283 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4284 av_log(c->fc, AV_LOG_ERROR,
4285 "stream %d, error opening alias: path='%s', dir='%s', "
4286 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4287 st->index, dref->path, dref->dir, dref->filename,
4288 dref->volume, dref->nlvl_from, dref->nlvl_to);
4290 av_log(c->fc, AV_LOG_WARNING,
4291 "Skipped opening external track: "
4292 "stream %d, alias: path='%s', dir='%s', "
4293 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4294 "Set enable_drefs to allow this.\n",
4295 st->index, dref->path, dref->dir, dref->filename,
4296 dref->volume, dref->nlvl_from, dref->nlvl_to);
4300 sc->pb_is_copied = 1;
4303 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4304 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4305 sc->height && sc->width &&
4306 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4307 st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4308 ((double)st->codecpar->width * sc->height), INT_MAX);
4311 #if FF_API_R_FRAME_RATE
4312 if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4313 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
4314 sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4318 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4319 if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4320 TAG_IS_AVCI(st->codecpar->codec_tag)) {
4321 ret = ff_generate_avci_extradata(st);
4326 switch (st->codecpar->codec_id) {
4327 #if CONFIG_H261_DECODER
4328 case AV_CODEC_ID_H261:
4330 #if CONFIG_H263_DECODER
4331 case AV_CODEC_ID_H263:
4333 #if CONFIG_MPEG4_DECODER
4334 case AV_CODEC_ID_MPEG4:
4336 st->codecpar->width = 0; /* let decoder init width/height */
4337 st->codecpar->height= 0;
4341 // If the duration of the mp3 packets is not constant, then they could need a parser
4342 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4343 && sc->stts_count > 3
4344 && sc->stts_count*10 > st->nb_frames
4345 && sc->time_scale == st->codecpar->sample_rate) {
4346 st->need_parsing = AVSTREAM_PARSE_FULL;
4348 /* Do not need those anymore. */
4349 av_freep(&sc->chunk_offsets);
4350 av_freep(&sc->sample_sizes);
4351 av_freep(&sc->keyframes);
4352 av_freep(&sc->stts_data);
4353 av_freep(&sc->stps_data);
4354 av_freep(&sc->elst_data);
4355 av_freep(&sc->rap_group);
4360 static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4363 c->itunes_metadata = 1;
4364 ret = mov_read_default(c, pb, atom);
4365 c->itunes_metadata = 0;
4369 static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4378 count = avio_rb32(pb);
4379 if (count > UINT_MAX / sizeof(*c->meta_keys) - 1) {
4380 av_log(c->fc, AV_LOG_ERROR,
4381 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
4382 return AVERROR_INVALIDDATA;
4385 c->meta_keys_count = count + 1;
4386 c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
4388 return AVERROR(ENOMEM);
4390 for (i = 1; i <= count; ++i) {
4391 uint32_t key_size = avio_rb32(pb);
4392 uint32_t type = avio_rl32(pb);
4394 av_log(c->fc, AV_LOG_ERROR,
4395 "The key# %"PRIu32" in meta has invalid size:"
4396 "%"PRIu32"\n", i, key_size);
4397 return AVERROR_INVALIDDATA;
4400 if (type != MKTAG('m','d','t','a')) {
4401 avio_skip(pb, key_size);
4403 c->meta_keys[i] = av_mallocz(key_size + 1);
4404 if (!c->meta_keys[i])
4405 return AVERROR(ENOMEM);
4406 avio_read(pb, c->meta_keys[i], key_size);
4412 static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4414 int64_t end = av_sat_add64(avio_tell(pb), atom.size);
4415 uint8_t *key = NULL, *val = NULL, *mean = NULL;
4419 MOVStreamContext *sc;
4421 if (c->fc->nb_streams < 1)
4423 st = c->fc->streams[c->fc->nb_streams-1];
4426 for (i = 0; i < 3; i++) {
4430 if (end - avio_tell(pb) <= 12)
4433 len = avio_rb32(pb);
4434 tag = avio_rl32(pb);
4435 avio_skip(pb, 4); // flags
4437 if (len < 12 || len - 12 > end - avio_tell(pb))
4441 if (tag == MKTAG('m', 'e', 'a', 'n'))
4443 else if (tag == MKTAG('n', 'a', 'm', 'e'))
4445 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
4455 *p = av_malloc(len + 1);
4457 ret = AVERROR(ENOMEM);
4460 ret = ffio_read_size(pb, *p, len);
4468 if (mean && key && val) {
4469 if (strcmp(key, "iTunSMPB") == 0) {
4470 int priming, remainder, samples;
4471 if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
4472 if(priming>0 && priming<16384)
4473 sc->start_pad = priming;
4476 if (strcmp(key, "cdec") != 0) {
4477 av_dict_set(&c->fc->metadata, key, val,
4478 AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
4482 av_log(c->fc, AV_LOG_VERBOSE,
4483 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
4486 avio_seek(pb, end, SEEK_SET);
4493 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4495 while (atom.size > 8) {
4499 tag = avio_rl32(pb);
4501 if (tag == MKTAG('h','d','l','r')) {
4502 avio_seek(pb, -8, SEEK_CUR);
4504 return mov_read_default(c, pb, atom);
4510 // return 1 when matrix is identity, 0 otherwise
4511 #define IS_MATRIX_IDENT(matrix) \
4512 ( (matrix)[0][0] == (1 << 16) && \
4513 (matrix)[1][1] == (1 << 16) && \
4514 (matrix)[2][2] == (1 << 30) && \
4515 !(matrix)[0][1] && !(matrix)[0][2] && \
4516 !(matrix)[1][0] && !(matrix)[1][2] && \
4517 !(matrix)[2][0] && !(matrix)[2][1])
4519 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4524 int display_matrix[3][3];
4525 int res_display_matrix[3][3] = { { 0 } };
4527 MOVStreamContext *sc;
4531 if (c->fc->nb_streams < 1)
4533 st = c->fc->streams[c->fc->nb_streams-1];
4536 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4537 // avoids corrupting AVStreams mapped to an earlier tkhd.
4539 return AVERROR_INVALIDDATA;
4541 version = avio_r8(pb);
4542 flags = avio_rb24(pb);
4543 st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
4549 avio_rb32(pb); /* creation time */
4550 avio_rb32(pb); /* modification time */
4552 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4553 avio_rb32(pb); /* reserved */
4555 /* highlevel (considering edits) duration in movie timebase */
4556 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4557 avio_rb32(pb); /* reserved */
4558 avio_rb32(pb); /* reserved */
4560 avio_rb16(pb); /* layer */
4561 avio_rb16(pb); /* alternate group */
4562 avio_rb16(pb); /* volume */
4563 avio_rb16(pb); /* reserved */
4565 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4566 // they're kept in fixed point format through all calculations
4567 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4568 // side data, but the scale factor is not needed to calculate aspect ratio
4569 for (i = 0; i < 3; i++) {
4570 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
4571 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
4572 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
4575 width = avio_rb32(pb); // 16.16 fixed point track width
4576 height = avio_rb32(pb); // 16.16 fixed point track height
4577 sc->width = width >> 16;
4578 sc->height = height >> 16;
4580 // apply the moov display matrix (after the tkhd one)
4581 for (i = 0; i < 3; i++) {
4582 const int sh[3] = { 16, 16, 30 };
4583 for (j = 0; j < 3; j++) {
4584 for (e = 0; e < 3; e++) {
4585 res_display_matrix[i][j] +=
4586 ((int64_t) display_matrix[i][e] *
4587 c->movie_display_matrix[e][j]) >> sh[e];
4592 // save the matrix when it is not the default identity
4593 if (!IS_MATRIX_IDENT(res_display_matrix)) {
4596 av_freep(&sc->display_matrix);
4597 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4598 if (!sc->display_matrix)
4599 return AVERROR(ENOMEM);
4601 for (i = 0; i < 3; i++)
4602 for (j = 0; j < 3; j++)
4603 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4605 #if FF_API_OLD_ROTATE_API
4606 rotate = av_display_rotation_get(sc->display_matrix);
4607 if (!isnan(rotate)) {
4608 char rotate_buf[64];
4610 if (rotate < 0) // for backward compatibility
4612 snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate);
4613 av_dict_set(&st->metadata, "rotate", rotate_buf, 0);
4618 // transform the display width/height according to the matrix
4619 // to keep the same scale, use [width height 1<<16]
4620 if (width && height && sc->display_matrix) {
4621 double disp_transform[2];
4623 for (i = 0; i < 2; i++)
4624 disp_transform[i] = hypot(sc->display_matrix[0 + i],
4625 sc->display_matrix[3 + i]);
4627 if (disp_transform[0] > 0 && disp_transform[1] > 0 &&
4628 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4629 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4630 st->sample_aspect_ratio = av_d2q(
4631 disp_transform[0] / disp_transform[1],
4637 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4639 MOVFragment *frag = &c->fragment;
4640 MOVTrackExt *trex = NULL;
4641 int flags, track_id, i;
4642 MOVFragmentStreamInfo * frag_stream_info;
4644 avio_r8(pb); /* version */
4645 flags = avio_rb24(pb);
4647 track_id = avio_rb32(pb);
4649 return AVERROR_INVALIDDATA;
4650 for (i = 0; i < c->trex_count; i++)
4651 if (c->trex_data[i].track_id == track_id) {
4652 trex = &c->trex_data[i];
4656 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4659 c->fragment.found_tfhd = 1;
4660 frag->track_id = track_id;
4661 set_frag_stream(&c->frag_index, track_id);
4663 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4664 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4665 frag->moof_offset : frag->implicit_offset;
4666 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4668 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4669 avio_rb32(pb) : trex->duration;
4670 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4671 avio_rb32(pb) : trex->size;
4672 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4673 avio_rb32(pb) : trex->flags;
4674 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4676 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4677 if (frag_stream_info)
4678 frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
4683 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4688 num = atom.size / 4;
4689 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4690 return AVERROR(ENOMEM);
4692 av_free(c->chapter_tracks);
4693 c->chapter_tracks = new_tracks;
4694 c->nb_chapter_tracks = num;
4696 for (i = 0; i < num && !pb->eof_reached; i++)
4697 c->chapter_tracks[i] = avio_rb32(pb);
4702 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4707 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4708 return AVERROR_INVALIDDATA;
4709 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4710 sizeof(*c->trex_data))) < 0) {
4715 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4717 trex = &c->trex_data[c->trex_count++];
4718 avio_r8(pb); /* version */
4719 avio_rb24(pb); /* flags */
4720 trex->track_id = avio_rb32(pb);
4721 trex->stsd_id = avio_rb32(pb);
4722 trex->duration = avio_rb32(pb);
4723 trex->size = avio_rb32(pb);
4724 trex->flags = avio_rb32(pb);
4728 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4730 MOVFragment *frag = &c->fragment;
4731 AVStream *st = NULL;
4732 MOVStreamContext *sc;
4734 MOVFragmentStreamInfo * frag_stream_info;
4735 int64_t base_media_decode_time;
4737 for (i = 0; i < c->fc->nb_streams; i++) {
4738 if (c->fc->streams[i]->id == frag->track_id) {
4739 st = c->fc->streams[i];
4744 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4748 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4750 version = avio_r8(pb);
4751 avio_rb24(pb); /* flags */
4753 base_media_decode_time = avio_rb64(pb);
4755 base_media_decode_time = avio_rb32(pb);
4758 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4759 if (frag_stream_info)
4760 frag_stream_info->tfdt_dts = base_media_decode_time;
4761 sc->track_end = base_media_decode_time;
4766 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4768 MOVFragment *frag = &c->fragment;
4769 AVStream *st = NULL;
4770 MOVStreamContext *sc;
4773 int64_t dts, pts = AV_NOPTS_VALUE;
4774 int data_offset = 0;
4775 unsigned entries, first_sample_flags = frag->flags;
4776 int flags, distance, i;
4777 int64_t prev_dts = AV_NOPTS_VALUE;
4778 int next_frag_index = -1, index_entry_pos;
4779 size_t requested_size;
4780 size_t old_ctts_allocated_size;
4781 AVIndexEntry *new_entries;
4782 MOVFragmentStreamInfo * frag_stream_info;
4784 if (!frag->found_tfhd) {
4785 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4786 return AVERROR_INVALIDDATA;
4789 for (i = 0; i < c->fc->nb_streams; i++) {
4790 if (c->fc->streams[i]->id == frag->track_id) {
4791 st = c->fc->streams[i];
4796 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4800 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4803 // Find the next frag_index index that has a valid index_entry for
4804 // the current track_id.
4806 // A valid index_entry means the trun for the fragment was read
4807 // and it's samples are in index_entries at the given position.
4808 // New index entries will be inserted before the index_entry found.
4809 index_entry_pos = st->internal->nb_index_entries;
4810 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4811 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4812 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4813 next_frag_index = i;
4814 index_entry_pos = frag_stream_info->index_entry;
4818 av_assert0(index_entry_pos <= st->internal->nb_index_entries);
4820 avio_r8(pb); /* version */
4821 flags = avio_rb24(pb);
4822 entries = avio_rb32(pb);
4823 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4825 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4826 return AVERROR_INVALIDDATA;
4827 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4828 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4830 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4831 if (frag_stream_info) {
4832 if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
4833 dts = frag_stream_info->next_trun_dts - sc->time_offset;
4834 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4835 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4836 pts = frag_stream_info->first_tfra_pts;
4837 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4838 ", using it for pts\n", pts);
4839 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4840 c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
4841 dts = frag_stream_info->first_tfra_pts;
4842 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4843 ", using it for dts\n", pts);
4844 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4845 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4846 // pts = frag_stream_info->sidx_pts;
4847 dts = frag_stream_info->sidx_pts - sc->time_offset;
4848 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4849 ", using it for pts\n", pts);
4850 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4851 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4852 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4853 ", using it for dts\n", dts);
4855 dts = sc->track_end - sc->time_offset;
4856 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4857 ", using it for dts\n", dts);
4860 dts = sc->track_end - sc->time_offset;
4861 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4862 ", using it for dts\n", dts);
4864 offset = frag->base_data_offset + data_offset;
4866 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4868 // realloc space for new index entries
4869 if((uint64_t)st->internal->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4870 entries = UINT_MAX / sizeof(AVIndexEntry) - st->internal->nb_index_entries;
4871 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4876 requested_size = (st->internal->nb_index_entries + entries) * sizeof(AVIndexEntry);
4877 new_entries = av_fast_realloc(st->internal->index_entries,
4878 &st->internal->index_entries_allocated_size,
4881 return AVERROR(ENOMEM);
4882 st->internal->index_entries= new_entries;
4884 requested_size = (st->internal->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4885 old_ctts_allocated_size = sc->ctts_allocated_size;
4886 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4889 return AVERROR(ENOMEM);
4890 sc->ctts_data = ctts_data;
4892 // In case there were samples without ctts entries, ensure they get
4893 // zero valued entries. This ensures clips which mix boxes with and
4894 // without ctts entries don't pickup uninitialized data.
4895 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4896 sc->ctts_allocated_size - old_ctts_allocated_size);
4898 if (index_entry_pos < st->internal->nb_index_entries) {
4899 // Make hole in index_entries and ctts_data for new samples
4900 memmove(st->internal->index_entries + index_entry_pos + entries,
4901 st->internal->index_entries + index_entry_pos,
4902 sizeof(*st->internal->index_entries) *
4903 (st->internal->nb_index_entries - index_entry_pos));
4904 memmove(sc->ctts_data + index_entry_pos + entries,
4905 sc->ctts_data + index_entry_pos,
4906 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4907 if (index_entry_pos < sc->current_sample) {
4908 sc->current_sample += entries;
4912 st->internal->nb_index_entries += entries;
4913 sc->ctts_count = st->internal->nb_index_entries;
4915 // Record the index_entry position in frag_index of this fragment
4916 if (frag_stream_info)
4917 frag_stream_info->index_entry = index_entry_pos;
4919 if (index_entry_pos > 0)
4920 prev_dts = st->internal->index_entries[index_entry_pos-1].timestamp;
4922 for (i = 0; i < entries && !pb->eof_reached; i++) {
4923 unsigned sample_size = frag->size;
4924 int sample_flags = i ? frag->flags : first_sample_flags;
4925 unsigned sample_duration = frag->duration;
4926 unsigned ctts_duration = 0;
4928 int index_entry_flags = 0;
4930 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4931 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4932 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4933 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4935 mov_update_dts_shift(sc, ctts_duration, c->fc);
4936 if (pts != AV_NOPTS_VALUE) {
4937 dts = pts - sc->dts_shift;
4938 if (flags & MOV_TRUN_SAMPLE_CTS) {
4939 dts -= ctts_duration;
4941 dts -= sc->time_offset;
4943 av_log(c->fc, AV_LOG_DEBUG,
4944 "pts %"PRId64" calculated dts %"PRId64
4945 " sc->dts_shift %d ctts.duration %d"
4946 " sc->time_offset %"PRId64
4947 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4949 sc->dts_shift, ctts_duration,
4950 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4951 pts = AV_NOPTS_VALUE;
4954 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4958 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4959 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4962 index_entry_flags |= AVINDEX_KEYFRAME;
4964 // Fragments can overlap in time. Discard overlapping frames after
4966 if (prev_dts >= dts)
4967 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4969 st->internal->index_entries[index_entry_pos].pos = offset;
4970 st->internal->index_entries[index_entry_pos].timestamp = dts;
4971 st->internal->index_entries[index_entry_pos].size= sample_size;
4972 st->internal->index_entries[index_entry_pos].min_distance= distance;
4973 st->internal->index_entries[index_entry_pos].flags = index_entry_flags;
4975 sc->ctts_data[index_entry_pos].count = 1;
4976 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4979 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4980 "size %u, distance %d, keyframe %d\n", st->index,
4981 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4983 dts += sample_duration;
4984 offset += sample_size;
4985 sc->data_size += sample_size;
4987 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4988 1 <= INT_MAX - sc->nb_frames_for_fps
4990 sc->duration_for_fps += sample_duration;
4991 sc->nb_frames_for_fps ++;
4994 if (frag_stream_info)
4995 frag_stream_info->next_trun_dts = dts + sc->time_offset;
4997 // EOF found before reading all entries. Fix the hole this would
4998 // leave in index_entries and ctts_data
4999 int gap = entries - i;
5000 memmove(st->internal->index_entries + index_entry_pos,
5001 st->internal->index_entries + index_entry_pos + gap,
5002 sizeof(*st->internal->index_entries) *
5003 (st->internal->nb_index_entries - (index_entry_pos + gap)));
5004 memmove(sc->ctts_data + index_entry_pos,
5005 sc->ctts_data + index_entry_pos + gap,
5006 sizeof(*sc->ctts_data) *
5007 (sc->ctts_count - (index_entry_pos + gap)));
5009 st->internal->nb_index_entries -= gap;
5010 sc->ctts_count -= gap;
5011 if (index_entry_pos < sc->current_sample) {
5012 sc->current_sample -= gap;
5017 // The end of this new fragment may overlap in time with the start
5018 // of the next fragment in index_entries. Mark the samples in the next
5019 // fragment that overlap with AVINDEX_DISCARD_FRAME
5020 prev_dts = AV_NOPTS_VALUE;
5021 if (index_entry_pos > 0)
5022 prev_dts = st->internal->index_entries[index_entry_pos-1].timestamp;
5023 for (i = index_entry_pos; i < st->internal->nb_index_entries; i++) {
5024 if (prev_dts < st->internal->index_entries[i].timestamp)
5026 st->internal->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
5029 // If a hole was created to insert the new index_entries into,
5030 // the index_entry recorded for all subsequent moof must
5031 // be incremented by the number of entries inserted.
5032 fix_frag_index_entries(&c->frag_index, next_frag_index,
5033 frag->track_id, entries);
5035 if (pb->eof_reached) {
5036 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
5040 frag->implicit_offset = offset;
5042 sc->track_end = dts + sc->time_offset;
5043 if (st->duration < sc->track_end)
5044 st->duration = sc->track_end;
5049 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5051 int64_t stream_size = avio_size(pb);
5052 int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
5053 uint8_t version, is_complete;
5054 unsigned i, j, track_id, item_count;
5055 AVStream *st = NULL;
5056 AVStream *ref_st = NULL;
5057 MOVStreamContext *sc, *ref_sc = NULL;
5058 AVRational timescale;
5060 version = avio_r8(pb);
5062 avpriv_request_sample(c->fc, "sidx version %u", version);
5066 avio_rb24(pb); // flags
5068 track_id = avio_rb32(pb); // Reference ID
5069 for (i = 0; i < c->fc->nb_streams; i++) {
5070 if (c->fc->streams[i]->id == track_id) {
5071 st = c->fc->streams[i];
5076 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5082 timescale = av_make_q(1, avio_rb32(pb));
5084 if (timescale.den <= 0) {
5085 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5086 return AVERROR_INVALIDDATA;
5090 pts = avio_rb32(pb);
5091 offset += avio_rb32(pb);
5093 pts = avio_rb64(pb);
5094 offset += avio_rb64(pb);
5097 avio_rb16(pb); // reserved
5099 item_count = avio_rb16(pb);
5101 for (i = 0; i < item_count; i++) {
5103 MOVFragmentStreamInfo * frag_stream_info;
5104 uint32_t size = avio_rb32(pb);
5105 uint32_t duration = avio_rb32(pb);
5106 if (size & 0x80000000) {
5107 avpriv_request_sample(c->fc, "sidx reference_type 1");
5108 return AVERROR_PATCHWELCOME;
5110 avio_rb32(pb); // sap_flags
5111 timestamp = av_rescale_q(pts, timescale, st->time_base);
5113 index = update_frag_index(c, offset);
5114 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5115 if (frag_stream_info)
5116 frag_stream_info->sidx_pts = timestamp;
5122 st->duration = sc->track_end = pts;
5126 // See if the remaining bytes are just an mfra which we can ignore.
5127 is_complete = offset == stream_size;
5128 if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL)) {
5130 int64_t original_pos = avio_tell(pb);
5131 if (!c->have_read_mfra_size) {
5132 if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
5134 c->mfra_size = avio_rb32(pb);
5135 c->have_read_mfra_size = 1;
5136 if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
5139 if (offset + c->mfra_size == stream_size)
5144 // Find first entry in fragment index that came from an sidx.
5145 // This will pretty much always be the first entry.
5146 for (i = 0; i < c->frag_index.nb_items; i++) {
5147 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5148 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5149 MOVFragmentStreamInfo * si;
5150 si = &item->stream_info[j];
5151 if (si->sidx_pts != AV_NOPTS_VALUE) {
5152 ref_st = c->fc->streams[j];
5153 ref_sc = ref_st->priv_data;
5158 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5159 st = c->fc->streams[i];
5161 if (!sc->has_sidx) {
5162 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5166 c->frag_index.complete = 1;
5172 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5173 /* like the files created with Adobe Premiere 5.0, for samples see */
5174 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5175 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5180 return 0; /* continue */
5181 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5182 avio_skip(pb, atom.size - 4);
5185 atom.type = avio_rl32(pb);
5187 if (atom.type != MKTAG('m','d','a','t')) {
5188 avio_skip(pb, atom.size);
5191 err = mov_read_mdat(c, pb, atom);
5195 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5200 uint8_t *moov_data; /* uncompressed data */
5201 long cmov_len, moov_len;
5204 avio_rb32(pb); /* dcom atom */
5205 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5206 return AVERROR_INVALIDDATA;
5207 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5208 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5209 return AVERROR_INVALIDDATA;
5211 avio_rb32(pb); /* cmvd atom */
5212 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5213 return AVERROR_INVALIDDATA;
5214 moov_len = avio_rb32(pb); /* uncompressed size */
5215 cmov_len = atom.size - 6 * 4;
5217 cmov_data = av_malloc(cmov_len);
5219 return AVERROR(ENOMEM);
5220 moov_data = av_malloc(moov_len);
5223 return AVERROR(ENOMEM);
5225 ret = ffio_read_size(pb, cmov_data, cmov_len);
5227 goto free_and_return;
5229 ret = AVERROR_INVALIDDATA;
5230 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5231 goto free_and_return;
5232 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5233 goto free_and_return;
5234 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5235 atom.type = MKTAG('m','o','o','v');
5236 atom.size = moov_len;
5237 ret = mov_read_default(c, &ctx, atom);
5243 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5244 return AVERROR(ENOSYS);
5248 /* edit list atom */
5249 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5251 MOVStreamContext *sc;
5252 int i, edit_count, version;
5253 int64_t elst_entry_size;
5255 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5257 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5259 version = avio_r8(pb); /* version */
5260 avio_rb24(pb); /* flags */
5261 edit_count = avio_rb32(pb); /* entries */
5264 elst_entry_size = version == 1 ? 20 : 12;
5265 if (atom.size != edit_count * elst_entry_size) {
5266 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5267 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5268 edit_count, atom.size + 8);
5269 return AVERROR_INVALIDDATA;
5271 edit_count = atom.size / elst_entry_size;
5272 if (edit_count * elst_entry_size != atom.size) {
5273 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
5281 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5282 av_free(sc->elst_data);
5284 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5286 return AVERROR(ENOMEM);
5288 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5289 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5290 MOVElst *e = &sc->elst_data[i];
5293 e->duration = avio_rb64(pb);
5294 e->time = avio_rb64(pb);
5297 e->duration = avio_rb32(pb); /* segment duration */
5298 e->time = (int32_t)avio_rb32(pb); /* media time */
5301 e->rate = avio_rb32(pb) / 65536.0;
5303 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5304 e->duration, e->time, e->rate);
5306 if (e->time < 0 && e->time != -1 &&
5307 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5308 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5309 c->fc->nb_streams-1, i, e->time);
5310 return AVERROR_INVALIDDATA;
5318 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5320 MOVStreamContext *sc;
5322 if (c->fc->nb_streams < 1)
5323 return AVERROR_INVALIDDATA;
5324 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5325 sc->timecode_track = avio_rb32(pb);
5329 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5334 if (c->fc->nb_streams < 1)
5336 st = c->fc->streams[c->fc->nb_streams - 1];
5338 if (atom.size < 4) {
5339 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5340 return AVERROR_INVALIDDATA;
5343 /* For now, propagate only the OBUs, if any. Once libavcodec is
5344 updated to handle isobmff style extradata this can be removed. */
5350 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5357 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5360 int version, color_range, color_primaries, color_trc, color_space;
5362 if (c->fc->nb_streams < 1)
5364 st = c->fc->streams[c->fc->nb_streams - 1];
5366 if (atom.size < 5) {
5367 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5368 return AVERROR_INVALIDDATA;
5371 version = avio_r8(pb);
5373 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5376 avio_skip(pb, 3); /* flags */
5378 avio_skip(pb, 2); /* profile + level */
5379 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5380 color_primaries = avio_r8(pb);
5381 color_trc = avio_r8(pb);
5382 color_space = avio_r8(pb);
5383 if (avio_rb16(pb)) /* codecIntializationDataSize */
5384 return AVERROR_INVALIDDATA;
5386 if (!av_color_primaries_name(color_primaries))
5387 color_primaries = AVCOL_PRI_UNSPECIFIED;
5388 if (!av_color_transfer_name(color_trc))
5389 color_trc = AVCOL_TRC_UNSPECIFIED;
5390 if (!av_color_space_name(color_space))
5391 color_space = AVCOL_SPC_UNSPECIFIED;
5393 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5394 st->codecpar->color_primaries = color_primaries;
5395 st->codecpar->color_trc = color_trc;
5396 st->codecpar->color_space = color_space;
5401 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5403 MOVStreamContext *sc;
5406 if (c->fc->nb_streams < 1)
5407 return AVERROR_INVALIDDATA;
5409 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5411 if (atom.size < 5) {
5412 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5413 return AVERROR_INVALIDDATA;
5416 version = avio_r8(pb);
5418 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5421 avio_skip(pb, 3); /* flags */
5423 sc->mastering = av_mastering_display_metadata_alloc();
5425 return AVERROR(ENOMEM);
5427 for (i = 0; i < 3; i++) {
5428 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5429 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5431 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5432 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5434 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5435 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5437 sc->mastering->has_primaries = 1;
5438 sc->mastering->has_luminance = 1;
5443 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5445 MOVStreamContext *sc;
5446 const int mapping[3] = {1, 2, 0};
5447 const int chroma_den = 50000;
5448 const int luma_den = 10000;
5451 if (c->fc->nb_streams < 1)
5452 return AVERROR_INVALIDDATA;
5454 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5456 if (atom.size < 24) {
5457 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5458 return AVERROR_INVALIDDATA;
5461 sc->mastering = av_mastering_display_metadata_alloc();
5463 return AVERROR(ENOMEM);
5465 for (i = 0; i < 3; i++) {
5466 const int j = mapping[i];
5467 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5468 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5470 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5471 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5473 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5474 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5476 sc->mastering->has_luminance = 1;
5477 sc->mastering->has_primaries = 1;
5482 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5484 MOVStreamContext *sc;
5487 if (c->fc->nb_streams < 1)
5488 return AVERROR_INVALIDDATA;
5490 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5492 if (atom.size < 5) {
5493 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5494 return AVERROR_INVALIDDATA;
5497 version = avio_r8(pb);
5499 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5502 avio_skip(pb, 3); /* flags */
5504 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5506 return AVERROR(ENOMEM);
5508 sc->coll->MaxCLL = avio_rb16(pb);
5509 sc->coll->MaxFALL = avio_rb16(pb);
5514 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5516 MOVStreamContext *sc;
5518 if (c->fc->nb_streams < 1)
5519 return AVERROR_INVALIDDATA;
5521 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5523 if (atom.size < 4) {
5524 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5525 return AVERROR_INVALIDDATA;
5528 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5530 return AVERROR(ENOMEM);
5532 sc->coll->MaxCLL = avio_rb16(pb);
5533 sc->coll->MaxFALL = avio_rb16(pb);
5538 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5541 MOVStreamContext *sc;
5542 enum AVStereo3DType type;
5545 if (c->fc->nb_streams < 1)
5548 st = c->fc->streams[c->fc->nb_streams - 1];
5551 if (atom.size < 5) {
5552 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5553 return AVERROR_INVALIDDATA;
5557 return AVERROR_INVALIDDATA;
5559 avio_skip(pb, 4); /* version + flags */
5564 type = AV_STEREO3D_2D;
5567 type = AV_STEREO3D_TOPBOTTOM;
5570 type = AV_STEREO3D_SIDEBYSIDE;
5573 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5577 sc->stereo3d = av_stereo3d_alloc();
5579 return AVERROR(ENOMEM);
5581 sc->stereo3d->type = type;
5585 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5588 MOVStreamContext *sc;
5589 int size, version, layout;
5590 int32_t yaw, pitch, roll;
5591 uint32_t l = 0, t = 0, r = 0, b = 0;
5592 uint32_t tag, padding = 0;
5593 enum AVSphericalProjection projection;
5595 if (c->fc->nb_streams < 1)
5598 st = c->fc->streams[c->fc->nb_streams - 1];
5601 if (atom.size < 8) {
5602 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5603 return AVERROR_INVALIDDATA;
5606 size = avio_rb32(pb);
5607 if (size <= 12 || size > atom.size)
5608 return AVERROR_INVALIDDATA;
5610 tag = avio_rl32(pb);
5611 if (tag != MKTAG('s','v','h','d')) {
5612 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5615 version = avio_r8(pb);
5617 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5621 avio_skip(pb, 3); /* flags */
5622 avio_skip(pb, size - 12); /* metadata_source */
5624 size = avio_rb32(pb);
5625 if (size > atom.size)
5626 return AVERROR_INVALIDDATA;
5628 tag = avio_rl32(pb);
5629 if (tag != MKTAG('p','r','o','j')) {
5630 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5634 size = avio_rb32(pb);
5635 if (size > atom.size)
5636 return AVERROR_INVALIDDATA;
5638 tag = avio_rl32(pb);
5639 if (tag != MKTAG('p','r','h','d')) {
5640 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5643 version = avio_r8(pb);
5645 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5649 avio_skip(pb, 3); /* flags */
5651 /* 16.16 fixed point */
5652 yaw = avio_rb32(pb);
5653 pitch = avio_rb32(pb);
5654 roll = avio_rb32(pb);
5656 size = avio_rb32(pb);
5657 if (size > atom.size)
5658 return AVERROR_INVALIDDATA;
5660 tag = avio_rl32(pb);
5661 version = avio_r8(pb);
5663 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5667 avio_skip(pb, 3); /* flags */
5669 case MKTAG('c','b','m','p'):
5670 layout = avio_rb32(pb);
5672 av_log(c->fc, AV_LOG_WARNING,
5673 "Unsupported cubemap layout %d\n", layout);
5676 projection = AV_SPHERICAL_CUBEMAP;
5677 padding = avio_rb32(pb);
5679 case MKTAG('e','q','u','i'):
5685 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5686 av_log(c->fc, AV_LOG_ERROR,
5687 "Invalid bounding rectangle coordinates "
5688 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5689 return AVERROR_INVALIDDATA;
5692 if (l || t || r || b)
5693 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5695 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5698 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5702 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5704 return AVERROR(ENOMEM);
5706 sc->spherical->projection = projection;
5708 sc->spherical->yaw = yaw;
5709 sc->spherical->pitch = pitch;
5710 sc->spherical->roll = roll;
5712 sc->spherical->padding = padding;
5714 sc->spherical->bound_left = l;
5715 sc->spherical->bound_top = t;
5716 sc->spherical->bound_right = r;
5717 sc->spherical->bound_bottom = b;
5722 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5725 uint8_t *buffer = av_malloc(len + 1);
5729 return AVERROR(ENOMEM);
5732 ret = ffio_read_size(pb, buffer, len);
5736 /* Check for mandatory keys and values, try to support XML as best-effort */
5737 if (!sc->spherical &&
5738 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5739 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5740 av_stristr(val, "true") &&
5741 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5742 av_stristr(val, "true") &&
5743 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5744 av_stristr(val, "equirectangular")) {
5745 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5749 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5751 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5752 enum AVStereo3DType mode;
5754 if (av_stristr(buffer, "left-right"))
5755 mode = AV_STEREO3D_SIDEBYSIDE;
5756 else if (av_stristr(buffer, "top-bottom"))
5757 mode = AV_STEREO3D_TOPBOTTOM;
5759 mode = AV_STEREO3D_2D;
5761 sc->stereo3d = av_stereo3d_alloc();
5765 sc->stereo3d->type = mode;
5769 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5771 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5772 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5774 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5775 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5777 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5785 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5788 MOVStreamContext *sc;
5791 static const uint8_t uuid_isml_manifest[] = {
5792 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5793 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5795 static const uint8_t uuid_xmp[] = {
5796 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5797 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5799 static const uint8_t uuid_spherical[] = {
5800 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5801 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5804 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5805 return AVERROR_INVALIDDATA;
5807 if (c->fc->nb_streams < 1)
5809 st = c->fc->streams[c->fc->nb_streams - 1];
5812 ret = ffio_read_size(pb, uuid, sizeof(uuid));
5815 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5816 uint8_t *buffer, *ptr;
5818 size_t len = atom.size - sizeof(uuid);
5821 return AVERROR_INVALIDDATA;
5823 ret = avio_skip(pb, 4); // zeroes
5826 buffer = av_mallocz(len + 1);
5828 return AVERROR(ENOMEM);
5830 ret = ffio_read_size(pb, buffer, len);
5837 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5838 ptr += sizeof("systemBitrate=\"") - 1;
5839 c->bitrates_count++;
5840 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5842 c->bitrates_count = 0;
5844 return AVERROR(ENOMEM);
5847 ret = strtol(ptr, &endptr, 10);
5848 if (ret < 0 || errno || *endptr != '"') {
5849 c->bitrates[c->bitrates_count - 1] = 0;
5851 c->bitrates[c->bitrates_count - 1] = ret;
5856 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5858 size_t len = atom.size - sizeof(uuid);
5859 if (c->export_xmp) {
5860 buffer = av_mallocz(len + 1);
5862 return AVERROR(ENOMEM);
5864 ret = ffio_read_size(pb, buffer, len);
5870 av_dict_set(&c->fc->metadata, "xmp",
5871 buffer, AV_DICT_DONT_STRDUP_VAL);
5873 // skip all uuid atom, which makes it fast for long uuid-xmp file
5874 ret = avio_skip(pb, len);
5878 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5879 size_t len = atom.size - sizeof(uuid);
5880 ret = mov_parse_uuid_spherical(sc, pb, len);
5884 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5890 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5893 uint8_t content[16];
5898 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5904 && !memcmp(content, "Anevia\x1A\x1A", 8)
5905 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5906 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5912 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5914 uint32_t format = avio_rl32(pb);
5915 MOVStreamContext *sc;
5919 if (c->fc->nb_streams < 1)
5921 st = c->fc->streams[c->fc->nb_streams - 1];
5926 case MKTAG('e','n','c','v'): // encrypted video
5927 case MKTAG('e','n','c','a'): // encrypted audio
5928 id = mov_codec_id(st, format);
5929 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5930 st->codecpar->codec_id != id) {
5931 av_log(c->fc, AV_LOG_WARNING,
5932 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5933 (char*)&format, st->codecpar->codec_id);
5937 st->codecpar->codec_id = id;
5938 sc->format = format;
5942 if (format != sc->format) {
5943 av_log(c->fc, AV_LOG_WARNING,
5944 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5945 (char*)&format, (char*)&sc->format);
5954 * Gets the current encryption info and associated current stream context. If
5955 * we are parsing a track fragment, this will return the specific encryption
5956 * info for this fragment; otherwise this will return the global encryption
5957 * info for the current stream.
5959 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5961 MOVFragmentStreamInfo *frag_stream_info;
5965 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5966 if (frag_stream_info) {
5967 for (i = 0; i < c->fc->nb_streams; i++) {
5968 if (c->fc->streams[i]->id == frag_stream_info->id) {
5969 st = c->fc->streams[i];
5973 if (i == c->fc->nb_streams)
5975 *sc = st->priv_data;
5977 if (!frag_stream_info->encryption_index) {
5978 // If this stream isn't encrypted, don't create the index.
5979 if (!(*sc)->cenc.default_encrypted_sample)
5981 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5982 if (!frag_stream_info->encryption_index)
5983 return AVERROR(ENOMEM);
5985 *encryption_index = frag_stream_info->encryption_index;
5988 // No current track fragment, using stream level encryption info.
5990 if (c->fc->nb_streams < 1)
5992 st = c->fc->streams[c->fc->nb_streams - 1];
5993 *sc = st->priv_data;
5995 if (!(*sc)->cenc.encryption_index) {
5996 // If this stream isn't encrypted, don't create the index.
5997 if (!(*sc)->cenc.default_encrypted_sample)
5999 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
6000 if (!(*sc)->cenc.encryption_index)
6001 return AVERROR(ENOMEM);
6004 *encryption_index = (*sc)->cenc.encryption_index;
6009 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
6012 unsigned int subsample_count;
6013 AVSubsampleEncryptionInfo *subsamples;
6015 if (!sc->cenc.default_encrypted_sample) {
6016 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
6017 return AVERROR_INVALIDDATA;
6020 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
6022 return AVERROR(ENOMEM);
6024 if (sc->cenc.per_sample_iv_size != 0) {
6025 if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
6026 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
6027 av_encryption_info_free(*sample);
6033 if (use_subsamples) {
6034 subsample_count = avio_rb16(pb);
6035 av_free((*sample)->subsamples);
6036 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
6037 if (!(*sample)->subsamples) {
6038 av_encryption_info_free(*sample);
6040 return AVERROR(ENOMEM);
6043 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
6044 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
6045 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
6048 if (pb->eof_reached) {
6049 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
6050 av_encryption_info_free(*sample);
6052 return AVERROR_INVALIDDATA;
6054 (*sample)->subsample_count = subsample_count;
6060 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6062 AVEncryptionInfo **encrypted_samples;
6063 MOVEncryptionIndex *encryption_index;
6064 MOVStreamContext *sc;
6065 int use_subsamples, ret;
6066 unsigned int sample_count, i, alloc_size = 0;
6068 ret = get_current_encryption_info(c, &encryption_index, &sc);
6072 if (encryption_index->nb_encrypted_samples) {
6073 // This can happen if we have both saio/saiz and senc atoms.
6074 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6078 avio_r8(pb); /* version */
6079 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6081 sample_count = avio_rb32(pb);
6082 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6083 return AVERROR(ENOMEM);
6085 for (i = 0; i < sample_count; i++) {
6086 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6087 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6088 min_samples * sizeof(*encrypted_samples));
6089 if (encrypted_samples) {
6090 encryption_index->encrypted_samples = encrypted_samples;
6092 ret = mov_read_sample_encryption_info(
6093 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6095 ret = AVERROR(ENOMEM);
6097 if (pb->eof_reached) {
6098 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6099 ret = AVERROR_INVALIDDATA;
6104 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6105 av_freep(&encryption_index->encrypted_samples);
6109 encryption_index->nb_encrypted_samples = sample_count;
6114 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6116 AVEncryptionInfo **sample, **encrypted_samples;
6118 size_t sample_count, sample_info_size, i;
6120 unsigned int alloc_size = 0;
6122 if (encryption_index->nb_encrypted_samples)
6124 sample_count = encryption_index->auxiliary_info_sample_count;
6125 if (encryption_index->auxiliary_offsets_count != 1) {
6126 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6127 return AVERROR_PATCHWELCOME;
6129 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6130 return AVERROR(ENOMEM);
6132 prev_pos = avio_tell(pb);
6133 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6134 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6135 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6139 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6140 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6141 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6142 min_samples * sizeof(*encrypted_samples));
6143 if (!encrypted_samples) {
6144 ret = AVERROR(ENOMEM);
6147 encryption_index->encrypted_samples = encrypted_samples;
6149 sample = &encryption_index->encrypted_samples[i];
6150 sample_info_size = encryption_index->auxiliary_info_default_size
6151 ? encryption_index->auxiliary_info_default_size
6152 : encryption_index->auxiliary_info_sizes[i];
6154 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6158 if (pb->eof_reached) {
6159 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6160 ret = AVERROR_INVALIDDATA;
6162 encryption_index->nb_encrypted_samples = sample_count;
6166 avio_seek(pb, prev_pos, SEEK_SET);
6168 for (; i > 0; i--) {
6169 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6171 av_freep(&encryption_index->encrypted_samples);
6177 * Tries to read the given number of bytes from the stream and puts it in a
6178 * newly allocated buffer. This reads in small chunks to avoid allocating large
6179 * memory if the file contains an invalid/malicious size value.
6181 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6183 const unsigned int block_size = 1024 * 1024;
6184 uint8_t *buffer = NULL;
6185 unsigned int alloc_size = 0, offset = 0;
6186 while (offset < size) {
6187 unsigned int new_size =
6188 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6189 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6190 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6193 return AVERROR(ENOMEM);
6195 buffer = new_buffer;
6197 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6199 return AVERROR_INVALIDDATA;
6208 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6210 MOVEncryptionIndex *encryption_index;
6211 MOVStreamContext *sc;
6213 unsigned int sample_count, aux_info_type, aux_info_param;
6215 ret = get_current_encryption_info(c, &encryption_index, &sc);
6219 if (encryption_index->nb_encrypted_samples) {
6220 // This can happen if we have both saio/saiz and senc atoms.
6221 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6225 if (encryption_index->auxiliary_info_sample_count) {
6226 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6227 return AVERROR_INVALIDDATA;
6230 avio_r8(pb); /* version */
6231 if (avio_rb24(pb) & 0x01) { /* flags */
6232 aux_info_type = avio_rb32(pb);
6233 aux_info_param = avio_rb32(pb);
6234 if (sc->cenc.default_encrypted_sample) {
6235 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6236 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6239 if (aux_info_param != 0) {
6240 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6244 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6245 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6246 aux_info_type == MKBETAG('c','e','n','s') ||
6247 aux_info_type == MKBETAG('c','b','c','1') ||
6248 aux_info_type == MKBETAG('c','b','c','s')) &&
6249 aux_info_param == 0) {
6250 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6251 return AVERROR_INVALIDDATA;
6256 } else if (!sc->cenc.default_encrypted_sample) {
6257 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6261 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6262 sample_count = avio_rb32(pb);
6263 encryption_index->auxiliary_info_sample_count = sample_count;
6265 if (encryption_index->auxiliary_info_default_size == 0) {
6266 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6268 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6273 if (encryption_index->auxiliary_offsets_count) {
6274 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6280 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6282 uint64_t *auxiliary_offsets;
6283 MOVEncryptionIndex *encryption_index;
6284 MOVStreamContext *sc;
6286 unsigned int version, entry_count, aux_info_type, aux_info_param;
6287 unsigned int alloc_size = 0;
6289 ret = get_current_encryption_info(c, &encryption_index, &sc);
6293 if (encryption_index->nb_encrypted_samples) {
6294 // This can happen if we have both saio/saiz and senc atoms.
6295 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6299 if (encryption_index->auxiliary_offsets_count) {
6300 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6301 return AVERROR_INVALIDDATA;
6304 version = avio_r8(pb); /* version */
6305 if (avio_rb24(pb) & 0x01) { /* flags */
6306 aux_info_type = avio_rb32(pb);
6307 aux_info_param = avio_rb32(pb);
6308 if (sc->cenc.default_encrypted_sample) {
6309 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6310 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6313 if (aux_info_param != 0) {
6314 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6318 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6319 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6320 aux_info_type == MKBETAG('c','e','n','s') ||
6321 aux_info_type == MKBETAG('c','b','c','1') ||
6322 aux_info_type == MKBETAG('c','b','c','s')) &&
6323 aux_info_param == 0) {
6324 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6325 return AVERROR_INVALIDDATA;
6330 } else if (!sc->cenc.default_encrypted_sample) {
6331 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6335 entry_count = avio_rb32(pb);
6336 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6337 return AVERROR(ENOMEM);
6339 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6340 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6341 auxiliary_offsets = av_fast_realloc(
6342 encryption_index->auxiliary_offsets, &alloc_size,
6343 min_offsets * sizeof(*auxiliary_offsets));
6344 if (!auxiliary_offsets) {
6345 av_freep(&encryption_index->auxiliary_offsets);
6346 return AVERROR(ENOMEM);
6348 encryption_index->auxiliary_offsets = auxiliary_offsets;
6351 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6353 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6355 if (c->frag_index.current >= 0) {
6356 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6360 if (pb->eof_reached) {
6361 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6362 av_freep(&encryption_index->auxiliary_offsets);
6363 return AVERROR_INVALIDDATA;
6366 encryption_index->auxiliary_offsets_count = entry_count;
6368 if (encryption_index->auxiliary_info_sample_count) {
6369 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6375 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6377 AVEncryptionInitInfo *info, *old_init_info;
6380 uint8_t *side_data, *extra_data, *old_side_data;
6381 size_t side_data_size;
6382 buffer_size_t old_side_data_size;
6384 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6386 if (c->fc->nb_streams < 1)
6388 st = c->fc->streams[c->fc->nb_streams-1];
6390 version = avio_r8(pb); /* version */
6391 avio_rb24(pb); /* flags */
6393 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6394 /* key_id_size */ 16, /* data_size */ 0);
6396 return AVERROR(ENOMEM);
6398 if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
6399 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6404 kid_count = avio_rb32(pb);
6405 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
6406 ret = AVERROR(ENOMEM);
6410 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6411 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6412 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6413 min_kid_count * sizeof(*key_ids));
6415 ret = AVERROR(ENOMEM);
6418 info->key_ids = key_ids;
6420 info->key_ids[i] = av_mallocz(16);
6421 if (!info->key_ids[i]) {
6422 ret = AVERROR(ENOMEM);
6425 info->num_key_ids = i + 1;
6427 if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
6428 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6433 if (pb->eof_reached) {
6434 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6435 ret = AVERROR_INVALIDDATA;
6440 extra_data_size = avio_rb32(pb);
6441 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6445 av_freep(&info->data); // malloc(0) may still allocate something.
6446 info->data = extra_data;
6447 info->data_size = extra_data_size;
6449 // If there is existing initialization data, append to the list.
6450 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6451 if (old_side_data) {
6452 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6453 if (old_init_info) {
6454 // Append to the end of the list.
6455 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6461 info = old_init_info;
6463 // Assume existing side-data will be valid, so the only error we could get is OOM.
6464 ret = AVERROR(ENOMEM);
6469 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6471 ret = AVERROR(ENOMEM);
6474 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6475 side_data, side_data_size);
6480 av_encryption_init_info_free(info);
6484 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6487 MOVStreamContext *sc;
6489 if (c->fc->nb_streams < 1)
6491 st = c->fc->streams[c->fc->nb_streams-1];
6494 if (sc->pseudo_stream_id != 0) {
6495 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6496 return AVERROR_PATCHWELCOME;
6500 return AVERROR_INVALIDDATA;
6502 avio_rb32(pb); /* version and flags */
6504 if (!sc->cenc.default_encrypted_sample) {
6505 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6506 if (!sc->cenc.default_encrypted_sample) {
6507 return AVERROR(ENOMEM);
6511 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6515 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6518 MOVStreamContext *sc;
6519 unsigned int version, pattern, is_protected, iv_size;
6521 if (c->fc->nb_streams < 1)
6523 st = c->fc->streams[c->fc->nb_streams-1];
6526 if (sc->pseudo_stream_id != 0) {
6527 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6528 return AVERROR_PATCHWELCOME;
6531 if (!sc->cenc.default_encrypted_sample) {
6532 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6533 if (!sc->cenc.default_encrypted_sample) {
6534 return AVERROR(ENOMEM);
6539 return AVERROR_INVALIDDATA;
6541 version = avio_r8(pb); /* version */
6542 avio_rb24(pb); /* flags */
6544 avio_r8(pb); /* reserved */
6545 pattern = avio_r8(pb);
6548 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6549 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6552 is_protected = avio_r8(pb);
6553 if (is_protected && !sc->cenc.encryption_index) {
6554 // The whole stream should be by-default encrypted.
6555 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6556 if (!sc->cenc.encryption_index)
6557 return AVERROR(ENOMEM);
6559 sc->cenc.per_sample_iv_size = avio_r8(pb);
6560 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6561 sc->cenc.per_sample_iv_size != 16) {
6562 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6563 return AVERROR_INVALIDDATA;
6565 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6566 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6567 return AVERROR_INVALIDDATA;
6570 if (is_protected && !sc->cenc.per_sample_iv_size) {
6571 iv_size = avio_r8(pb);
6572 if (iv_size != 8 && iv_size != 16) {
6573 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6574 return AVERROR_INVALIDDATA;
6577 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6578 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6579 return AVERROR_INVALIDDATA;
6586 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6589 int last, type, size, ret;
6592 if (c->fc->nb_streams < 1)
6594 st = c->fc->streams[c->fc->nb_streams-1];
6596 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6597 return AVERROR_INVALIDDATA;
6599 /* Check FlacSpecificBox version. */
6600 if (avio_r8(pb) != 0)
6601 return AVERROR_INVALIDDATA;
6603 avio_rb24(pb); /* Flags */
6605 avio_read(pb, buf, sizeof(buf));
6606 flac_parse_block_header(buf, &last, &type, &size);
6608 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6609 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6610 return AVERROR_INVALIDDATA;
6613 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6618 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6623 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6627 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6628 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6629 return AVERROR_PATCHWELCOME;
6632 if (!sc->cenc.aes_ctr) {
6633 /* initialize the cipher */
6634 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6635 if (!sc->cenc.aes_ctr) {
6636 return AVERROR(ENOMEM);
6639 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6645 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6647 if (!sample->subsample_count) {
6648 /* decrypt the whole packet */
6649 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6653 for (i = 0; i < sample->subsample_count; i++) {
6654 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6655 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6656 return AVERROR_INVALIDDATA;
6659 /* skip the clear bytes */
6660 input += sample->subsamples[i].bytes_of_clear_data;
6661 size -= sample->subsamples[i].bytes_of_clear_data;
6663 /* decrypt the encrypted bytes */
6664 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6665 input += sample->subsamples[i].bytes_of_protected_data;
6666 size -= sample->subsamples[i].bytes_of_protected_data;
6670 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6671 return AVERROR_INVALIDDATA;
6677 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6679 MOVFragmentStreamInfo *frag_stream_info;
6680 MOVEncryptionIndex *encryption_index;
6681 AVEncryptionInfo *encrypted_sample;
6682 int encrypted_index, ret;
6684 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6685 encrypted_index = current_index;
6686 encryption_index = NULL;
6687 if (frag_stream_info) {
6688 // Note this only supports encryption info in the first sample descriptor.
6689 if (mov->fragment.stsd_id == 1) {
6690 if (frag_stream_info->encryption_index) {
6691 encrypted_index = current_index - frag_stream_info->index_entry;
6692 encryption_index = frag_stream_info->encryption_index;
6694 encryption_index = sc->cenc.encryption_index;
6698 encryption_index = sc->cenc.encryption_index;
6701 if (encryption_index) {
6702 if (encryption_index->auxiliary_info_sample_count &&
6703 !encryption_index->nb_encrypted_samples) {
6704 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6705 return AVERROR_INVALIDDATA;
6707 if (encryption_index->auxiliary_offsets_count &&
6708 !encryption_index->nb_encrypted_samples) {
6709 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6710 return AVERROR_INVALIDDATA;
6713 if (!encryption_index->nb_encrypted_samples) {
6714 // Full-sample encryption with default settings.
6715 encrypted_sample = sc->cenc.default_encrypted_sample;
6716 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6717 // Per-sample setting override.
6718 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6720 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6721 return AVERROR_INVALIDDATA;
6724 if (mov->decryption_key) {
6725 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6728 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6730 return AVERROR(ENOMEM);
6731 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6741 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6743 const int OPUS_SEEK_PREROLL_MS = 80;
6749 if (c->fc->nb_streams < 1)
6751 st = c->fc->streams[c->fc->nb_streams-1];
6753 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6754 return AVERROR_INVALIDDATA;
6756 /* Check OpusSpecificBox version. */
6757 if (avio_r8(pb) != 0) {
6758 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6759 return AVERROR_INVALIDDATA;
6762 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6763 size = atom.size + 8;
6765 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
6768 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6769 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6770 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6771 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6773 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6774 little-endian; aside from the preceeding magic and version they're
6775 otherwise currently identical. Data after output gain at offset 16
6776 doesn't need to be bytewapped. */
6777 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6778 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6779 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6780 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6782 st->codecpar->initial_padding = pre_skip;
6783 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6784 (AVRational){1, 1000},
6785 (AVRational){1, 48000});
6790 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6793 unsigned format_info;
6794 int channel_assignment, channel_assignment1, channel_assignment2;
6797 if (c->fc->nb_streams < 1)
6799 st = c->fc->streams[c->fc->nb_streams-1];
6802 return AVERROR_INVALIDDATA;
6804 format_info = avio_rb32(pb);
6806 ratebits = (format_info >> 28) & 0xF;
6807 channel_assignment1 = (format_info >> 15) & 0x1F;
6808 channel_assignment2 = format_info & 0x1FFF;
6809 if (channel_assignment2)
6810 channel_assignment = channel_assignment2;
6812 channel_assignment = channel_assignment1;
6814 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6815 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6816 st->codecpar->channels = truehd_channels(channel_assignment);
6817 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6822 static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6826 AVDOVIDecoderConfigurationRecord *dovi;
6830 if (c->fc->nb_streams < 1)
6832 st = c->fc->streams[c->fc->nb_streams-1];
6834 if ((uint64_t)atom.size > (1<<30) || atom.size < 4)
6835 return AVERROR_INVALIDDATA;
6837 dovi = av_dovi_alloc(&dovi_size);
6839 return AVERROR(ENOMEM);
6841 dovi->dv_version_major = avio_r8(pb);
6842 dovi->dv_version_minor = avio_r8(pb);
6844 buf = avio_rb16(pb);
6845 dovi->dv_profile = (buf >> 9) & 0x7f; // 7 bits
6846 dovi->dv_level = (buf >> 3) & 0x3f; // 6 bits
6847 dovi->rpu_present_flag = (buf >> 2) & 0x01; // 1 bit
6848 dovi->el_present_flag = (buf >> 1) & 0x01; // 1 bit
6849 dovi->bl_present_flag = buf & 0x01; // 1 bit
6850 if (atom.size >= 24) { // 4 + 4 + 4 * 4
6852 dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits
6854 // 0 stands for None
6855 // Dolby Vision V1.2.93 profiles and levels
6856 dovi->dv_bl_signal_compatibility_id = 0;
6859 ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF,
6860 (uint8_t *)dovi, dovi_size);
6866 av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC box, version: %d.%d, profile: %d, level: %d, "
6867 "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n",
6868 dovi->dv_version_major, dovi->dv_version_minor,
6869 dovi->dv_profile, dovi->dv_level,
6870 dovi->rpu_present_flag,
6871 dovi->el_present_flag,
6872 dovi->bl_present_flag,
6873 dovi->dv_bl_signal_compatibility_id
6879 static const MOVParseTableEntry mov_default_parse_table[] = {
6880 { MKTAG('A','C','L','R'), mov_read_aclr },
6881 { MKTAG('A','P','R','G'), mov_read_avid },
6882 { MKTAG('A','A','L','P'), mov_read_avid },
6883 { MKTAG('A','R','E','S'), mov_read_ares },
6884 { MKTAG('a','v','s','s'), mov_read_avss },
6885 { MKTAG('a','v','1','C'), mov_read_av1c },
6886 { MKTAG('c','h','p','l'), mov_read_chpl },
6887 { MKTAG('c','o','6','4'), mov_read_stco },
6888 { MKTAG('c','o','l','r'), mov_read_colr },
6889 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6890 { MKTAG('d','i','n','f'), mov_read_default },
6891 { MKTAG('D','p','x','E'), mov_read_dpxe },
6892 { MKTAG('d','r','e','f'), mov_read_dref },
6893 { MKTAG('e','d','t','s'), mov_read_default },
6894 { MKTAG('e','l','s','t'), mov_read_elst },
6895 { MKTAG('e','n','d','a'), mov_read_enda },
6896 { MKTAG('f','i','e','l'), mov_read_fiel },
6897 { MKTAG('a','d','r','m'), mov_read_adrm },
6898 { MKTAG('f','t','y','p'), mov_read_ftyp },
6899 { MKTAG('g','l','b','l'), mov_read_glbl },
6900 { MKTAG('h','d','l','r'), mov_read_hdlr },
6901 { MKTAG('i','l','s','t'), mov_read_ilst },
6902 { MKTAG('j','p','2','h'), mov_read_jp2h },
6903 { MKTAG('m','d','a','t'), mov_read_mdat },
6904 { MKTAG('m','d','h','d'), mov_read_mdhd },
6905 { MKTAG('m','d','i','a'), mov_read_default },
6906 { MKTAG('m','e','t','a'), mov_read_meta },
6907 { MKTAG('m','i','n','f'), mov_read_default },
6908 { MKTAG('m','o','o','f'), mov_read_moof },
6909 { MKTAG('m','o','o','v'), mov_read_moov },
6910 { MKTAG('m','v','e','x'), mov_read_default },
6911 { MKTAG('m','v','h','d'), mov_read_mvhd },
6912 { MKTAG('S','M','I',' '), mov_read_svq3 },
6913 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6914 { MKTAG('a','v','c','C'), mov_read_glbl },
6915 { MKTAG('p','a','s','p'), mov_read_pasp },
6916 { MKTAG('s','i','d','x'), mov_read_sidx },
6917 { MKTAG('s','t','b','l'), mov_read_default },
6918 { MKTAG('s','t','c','o'), mov_read_stco },
6919 { MKTAG('s','t','p','s'), mov_read_stps },
6920 { MKTAG('s','t','r','f'), mov_read_strf },
6921 { MKTAG('s','t','s','c'), mov_read_stsc },
6922 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6923 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6924 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6925 { MKTAG('s','t','t','s'), mov_read_stts },
6926 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6927 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
6928 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6929 { MKTAG('t','f','d','t'), mov_read_tfdt },
6930 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6931 { MKTAG('t','r','a','k'), mov_read_trak },
6932 { MKTAG('t','r','a','f'), mov_read_default },
6933 { MKTAG('t','r','e','f'), mov_read_default },
6934 { MKTAG('t','m','c','d'), mov_read_tmcd },
6935 { MKTAG('c','h','a','p'), mov_read_chap },
6936 { MKTAG('t','r','e','x'), mov_read_trex },
6937 { MKTAG('t','r','u','n'), mov_read_trun },
6938 { MKTAG('u','d','t','a'), mov_read_default },
6939 { MKTAG('w','a','v','e'), mov_read_wave },
6940 { MKTAG('e','s','d','s'), mov_read_esds },
6941 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6942 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6943 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6944 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6945 { MKTAG('w','f','e','x'), mov_read_wfex },
6946 { MKTAG('c','m','o','v'), mov_read_cmov },
6947 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6948 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6949 { MKTAG('s','b','g','p'), mov_read_sbgp },
6950 { MKTAG('h','v','c','C'), mov_read_glbl },
6951 { MKTAG('u','u','i','d'), mov_read_uuid },
6952 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6953 { MKTAG('f','r','e','e'), mov_read_free },
6954 { MKTAG('-','-','-','-'), mov_read_custom },
6955 { MKTAG('s','i','n','f'), mov_read_default },
6956 { MKTAG('f','r','m','a'), mov_read_frma },
6957 { MKTAG('s','e','n','c'), mov_read_senc },
6958 { MKTAG('s','a','i','z'), mov_read_saiz },
6959 { MKTAG('s','a','i','o'), mov_read_saio },
6960 { MKTAG('p','s','s','h'), mov_read_pssh },
6961 { MKTAG('s','c','h','m'), mov_read_schm },
6962 { MKTAG('s','c','h','i'), mov_read_default },
6963 { MKTAG('t','e','n','c'), mov_read_tenc },
6964 { MKTAG('d','f','L','a'), mov_read_dfla },
6965 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6966 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6967 { MKTAG('d','O','p','s'), mov_read_dops },
6968 { MKTAG('d','m','l','p'), mov_read_dmlp },
6969 { MKTAG('S','m','D','m'), mov_read_smdm },
6970 { MKTAG('C','o','L','L'), mov_read_coll },
6971 { MKTAG('v','p','c','C'), mov_read_vpcc },
6972 { MKTAG('m','d','c','v'), mov_read_mdcv },
6973 { MKTAG('c','l','l','i'), mov_read_clli },
6974 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
6975 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
6979 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6981 int64_t total_size = 0;
6985 if (c->atom_depth > 10) {
6986 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6987 return AVERROR_INVALIDDATA;
6992 atom.size = INT64_MAX;
6993 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6994 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
6997 if (atom.size >= 8) {
6998 a.size = avio_rb32(pb);
6999 a.type = avio_rl32(pb);
7000 if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
7001 a.type == MKTAG('h','o','o','v')) &&
7003 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
7006 type = avio_rl32(pb);
7009 avio_seek(pb, -8, SEEK_CUR);
7010 if (type == MKTAG('m','v','h','d') ||
7011 type == MKTAG('c','m','o','v')) {
7012 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
7013 a.type = MKTAG('m','o','o','v');
7016 if (atom.type != MKTAG('r','o','o','t') &&
7017 atom.type != MKTAG('m','o','o','v')) {
7018 if (a.type == MKTAG('t','r','a','k') ||
7019 a.type == MKTAG('m','d','a','t')) {
7020 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
7027 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
7028 a.size = avio_rb64(pb) - 8;
7032 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
7033 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
7035 a.size = atom.size - total_size + 8;
7040 a.size = FFMIN(a.size, atom.size - total_size);
7042 for (i = 0; mov_default_parse_table[i].type; i++)
7043 if (mov_default_parse_table[i].type == a.type) {
7044 parse = mov_default_parse_table[i].parse;
7048 // container is user data
7049 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
7050 atom.type == MKTAG('i','l','s','t')))
7051 parse = mov_read_udta_string;
7053 // Supports parsing the QuickTime Metadata Keys.
7054 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
7055 if (!parse && c->found_hdlr_mdta &&
7056 atom.type == MKTAG('m','e','t','a') &&
7057 a.type == MKTAG('k','e','y','s') &&
7058 c->meta_keys_count == 0) {
7059 parse = mov_read_keys;
7062 if (!parse) { /* skip leaf atoms data */
7063 avio_skip(pb, a.size);
7065 int64_t start_pos = avio_tell(pb);
7067 int err = parse(c, pb, a);
7072 if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
7073 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
7074 start_pos + a.size == avio_size(pb))) {
7075 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
7076 c->next_root_atom = start_pos + a.size;
7080 left = a.size - avio_tell(pb) + start_pos;
7081 if (left > 0) /* skip garbage at atom end */
7082 avio_skip(pb, left);
7083 else if (left < 0) {
7084 av_log(c->fc, AV_LOG_WARNING,
7085 "overread end of atom '%s' by %"PRId64" bytes\n",
7086 av_fourcc2str(a.type), -left);
7087 avio_seek(pb, left, SEEK_CUR);
7091 total_size += a.size;
7094 if (total_size < atom.size && atom.size < 0x7ffff)
7095 avio_skip(pb, atom.size - total_size);
7101 static int mov_probe(const AVProbeData *p)
7106 int moov_offset = -1;
7108 /* check file header */
7113 /* ignore invalid offset */
7114 if ((offset + 8) > (unsigned int)p->buf_size)
7116 size = AV_RB32(p->buf + offset);
7117 if (size == 1 && offset + 16 > (unsigned int)p->buf_size) {
7118 size = AV_RB64(p->buf+offset + 8);
7120 } else if (size == 0) {
7121 size = p->buf_size - offset;
7123 if (size < minsize) {
7127 tag = AV_RL32(p->buf + offset + 4);
7129 /* check for obvious tags */
7130 case MKTAG('m','o','o','v'):
7131 moov_offset = offset + 4;
7132 case MKTAG('m','d','a','t'):
7133 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
7134 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
7135 case MKTAG('f','t','y','p'):
7136 if (tag == MKTAG('f','t','y','p') &&
7137 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
7138 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
7140 score = FFMAX(score, 5);
7142 score = AVPROBE_SCORE_MAX;
7145 /* those are more common words, so rate then a bit less */
7146 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
7147 case MKTAG('w','i','d','e'):
7148 case MKTAG('f','r','e','e'):
7149 case MKTAG('j','u','n','k'):
7150 case MKTAG('p','i','c','t'):
7151 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
7153 case MKTAG(0x82,0x82,0x7f,0x7d):
7154 case MKTAG('s','k','i','p'):
7155 case MKTAG('u','u','i','d'):
7156 case MKTAG('p','r','f','l'):
7157 /* if we only find those cause probedata is too small at least rate them */
7158 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7163 if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
7164 /* moov atom in the header - we should make sure that this is not a
7165 * MOV-packed MPEG-PS */
7166 offset = moov_offset;
7168 while (offset < (p->buf_size - 16)) { /* Sufficient space */
7169 /* We found an actual hdlr atom */
7170 if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7171 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7172 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
7173 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7174 /* We found a media handler reference atom describing an
7175 * MPEG-PS-in-MOV, return a
7176 * low score to force expanding the probe window until
7177 * mpegps_probe finds what it needs */
7189 // must be done after parsing all trak because there's no order requirement
7190 static void mov_read_chapters(AVFormatContext *s)
7192 MOVContext *mov = s->priv_data;
7194 MOVStreamContext *sc;
7199 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7200 chapter_track = mov->chapter_tracks[j];
7202 for (i = 0; i < s->nb_streams; i++)
7203 if (s->streams[i]->id == chapter_track) {
7208 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7213 cur_pos = avio_tell(sc->pb);
7215 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7216 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7217 if (st->internal->nb_index_entries) {
7218 // Retrieve the first frame, if possible
7219 AVIndexEntry *sample = &st->internal->index_entries[0];
7220 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7221 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7225 if (av_get_packet(sc->pb, &st->attached_pic, sample->size) < 0)
7228 st->attached_pic.stream_index = st->index;
7229 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
7232 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7233 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7234 st->discard = AVDISCARD_ALL;
7235 for (i = 0; i < st->internal->nb_index_entries; i++) {
7236 AVIndexEntry *sample = &st->internal->index_entries[i];
7237 int64_t end = i+1 < st->internal->nb_index_entries ? st->internal->index_entries[i+1].timestamp : st->duration;
7242 if (end < sample->timestamp) {
7243 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7244 end = AV_NOPTS_VALUE;
7247 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7248 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7252 // the first two bytes are the length of the title
7253 len = avio_rb16(sc->pb);
7254 if (len > sample->size-2)
7256 title_len = 2*len + 1;
7257 if (!(title = av_mallocz(title_len)))
7260 // The samples could theoretically be in any encoding if there's an encd
7261 // atom following, but in practice are only utf-8 or utf-16, distinguished
7262 // instead by the presence of a BOM
7266 ch = avio_rb16(sc->pb);
7268 avio_get_str16be(sc->pb, len, title, title_len);
7269 else if (ch == 0xfffe)
7270 avio_get_str16le(sc->pb, len, title, title_len);
7273 if (len == 1 || len == 2)
7276 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7280 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7285 avio_seek(sc->pb, cur_pos, SEEK_SET);
7289 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7290 uint32_t value, int flags)
7293 char buf[AV_TIMECODE_STR_SIZE];
7294 AVRational rate = st->avg_frame_rate;
7295 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7298 av_dict_set(&st->metadata, "timecode",
7299 av_timecode_make_string(&tc, buf, value), 0);
7303 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7305 MOVStreamContext *sc = st->priv_data;
7306 char buf[AV_TIMECODE_STR_SIZE];
7307 int64_t cur_pos = avio_tell(sc->pb);
7308 int hh, mm, ss, ff, drop;
7310 if (!st->internal->nb_index_entries)
7313 avio_seek(sc->pb, st->internal->index_entries->pos, SEEK_SET);
7314 avio_skip(s->pb, 13);
7315 hh = avio_r8(s->pb);
7316 mm = avio_r8(s->pb);
7317 ss = avio_r8(s->pb);
7318 drop = avio_r8(s->pb);
7319 ff = avio_r8(s->pb);
7320 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7321 hh, mm, ss, drop ? ';' : ':', ff);
7322 av_dict_set(&st->metadata, "timecode", buf, 0);
7324 avio_seek(sc->pb, cur_pos, SEEK_SET);
7328 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7330 MOVStreamContext *sc = st->priv_data;
7332 int64_t cur_pos = avio_tell(sc->pb);
7335 if (!st->internal->nb_index_entries)
7338 avio_seek(sc->pb, st->internal->index_entries->pos, SEEK_SET);
7339 value = avio_rb32(s->pb);
7341 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7342 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7343 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7345 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7346 * not the case) and thus assume "frame number format" instead of QT one.
7347 * No sample with tmcd track can be found with a QT timecode at the moment,
7348 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7350 parse_timecode_in_framenum_format(s, st, value, flags);
7352 avio_seek(sc->pb, cur_pos, SEEK_SET);
7356 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7358 if (!index || !*index) return;
7359 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7360 av_encryption_info_free((*index)->encrypted_samples[i]);
7362 av_freep(&(*index)->encrypted_samples);
7363 av_freep(&(*index)->auxiliary_info_sizes);
7364 av_freep(&(*index)->auxiliary_offsets);
7368 static int mov_read_close(AVFormatContext *s)
7370 MOVContext *mov = s->priv_data;
7373 for (i = 0; i < s->nb_streams; i++) {
7374 AVStream *st = s->streams[i];
7375 MOVStreamContext *sc = st->priv_data;
7380 av_freep(&sc->ctts_data);
7381 for (j = 0; j < sc->drefs_count; j++) {
7382 av_freep(&sc->drefs[j].path);
7383 av_freep(&sc->drefs[j].dir);
7385 av_freep(&sc->drefs);
7387 sc->drefs_count = 0;
7389 if (!sc->pb_is_copied)
7390 ff_format_io_close(s, &sc->pb);
7393 av_freep(&sc->chunk_offsets);
7394 av_freep(&sc->stsc_data);
7395 av_freep(&sc->sample_sizes);
7396 av_freep(&sc->keyframes);
7397 av_freep(&sc->stts_data);
7398 av_freep(&sc->sdtp_data);
7399 av_freep(&sc->stps_data);
7400 av_freep(&sc->elst_data);
7401 av_freep(&sc->rap_group);
7402 av_freep(&sc->display_matrix);
7403 av_freep(&sc->index_ranges);
7406 for (j = 0; j < sc->stsd_count; j++)
7407 av_free(sc->extradata[j]);
7408 av_freep(&sc->extradata);
7409 av_freep(&sc->extradata_size);
7411 mov_free_encryption_index(&sc->cenc.encryption_index);
7412 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7413 av_aes_ctr_free(sc->cenc.aes_ctr);
7415 av_freep(&sc->stereo3d);
7416 av_freep(&sc->spherical);
7417 av_freep(&sc->mastering);
7418 av_freep(&sc->coll);
7421 av_freep(&mov->dv_demux);
7422 avformat_free_context(mov->dv_fctx);
7423 mov->dv_fctx = NULL;
7425 if (mov->meta_keys) {
7426 for (i = 1; i < mov->meta_keys_count; i++) {
7427 av_freep(&mov->meta_keys[i]);
7429 av_freep(&mov->meta_keys);
7432 av_freep(&mov->trex_data);
7433 av_freep(&mov->bitrates);
7435 for (i = 0; i < mov->frag_index.nb_items; i++) {
7436 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7437 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7438 mov_free_encryption_index(&frag[j].encryption_index);
7440 av_freep(&mov->frag_index.item[i].stream_info);
7442 av_freep(&mov->frag_index.item);
7444 av_freep(&mov->aes_decrypt);
7445 av_freep(&mov->chapter_tracks);
7450 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7454 for (i = 0; i < s->nb_streams; i++) {
7455 AVStream *st = s->streams[i];
7456 MOVStreamContext *sc = st->priv_data;
7458 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7459 sc->timecode_track == tmcd_id)
7465 /* look for a tmcd track not referenced by any video track, and export it globally */
7466 static void export_orphan_timecode(AVFormatContext *s)
7470 for (i = 0; i < s->nb_streams; i++) {
7471 AVStream *st = s->streams[i];
7473 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7474 !tmcd_is_referenced(s, i + 1)) {
7475 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7477 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7484 static int read_tfra(MOVContext *mov, AVIOContext *f)
7486 int version, fieldlength, i, j;
7487 int64_t pos = avio_tell(f);
7488 uint32_t size = avio_rb32(f);
7489 unsigned track_id, item_count;
7491 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7494 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7496 version = avio_r8(f);
7498 track_id = avio_rb32(f);
7499 fieldlength = avio_rb32(f);
7500 item_count = avio_rb32(f);
7501 for (i = 0; i < item_count; i++) {
7502 int64_t time, offset;
7504 MOVFragmentStreamInfo * frag_stream_info;
7507 return AVERROR_INVALIDDATA;
7511 time = avio_rb64(f);
7512 offset = avio_rb64(f);
7514 time = avio_rb32(f);
7515 offset = avio_rb32(f);
7518 // The first sample of each stream in a fragment is always a random
7519 // access sample. So it's entry in the tfra can be used as the
7520 // initial PTS of the fragment.
7521 index = update_frag_index(mov, offset);
7522 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7523 if (frag_stream_info &&
7524 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7525 frag_stream_info->first_tfra_pts = time;
7527 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7529 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7531 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7535 avio_seek(f, pos + size, SEEK_SET);
7539 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7541 int64_t stream_size = avio_size(f);
7542 int64_t original_pos = avio_tell(f);
7545 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7549 c->mfra_size = avio_rb32(f);
7550 c->have_read_mfra_size = 1;
7551 if (!c->mfra_size || c->mfra_size > stream_size) {
7552 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7555 if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
7559 if (avio_rb32(f) != c->mfra_size) {
7560 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7563 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7564 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7567 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7569 ret = read_tfra(c, f);
7574 c->frag_index.complete = 1;
7576 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7578 av_log(c->fc, AV_LOG_ERROR,
7579 "failed to seek back after looking for mfra\n");
7585 static int mov_read_header(AVFormatContext *s)
7587 MOVContext *mov = s->priv_data;
7588 AVIOContext *pb = s->pb;
7590 MOVAtom atom = { AV_RL32("root") };
7593 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7594 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7595 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7596 return AVERROR(EINVAL);
7600 mov->trak_index = -1;
7601 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7602 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7603 atom.size = avio_size(pb);
7605 atom.size = INT64_MAX;
7607 /* check MOV header */
7609 if (mov->moov_retry)
7610 avio_seek(pb, 0, SEEK_SET);
7611 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7612 av_log(s, AV_LOG_ERROR, "error reading header\n");
7615 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7616 if (!mov->found_moov) {
7617 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7618 err = AVERROR_INVALIDDATA;
7621 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7623 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7624 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7625 mov_read_chapters(s);
7626 for (i = 0; i < s->nb_streams; i++)
7627 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7628 mov_read_timecode_track(s, s->streams[i]);
7629 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7630 mov_read_rtmd_track(s, s->streams[i]);
7634 /* copy timecode metadata from tmcd tracks to the related video streams */
7635 for (i = 0; i < s->nb_streams; i++) {
7636 AVStream *st = s->streams[i];
7637 MOVStreamContext *sc = st->priv_data;
7638 if (sc->timecode_track > 0) {
7639 AVDictionaryEntry *tcr;
7640 int tmcd_st_id = -1;
7642 for (j = 0; j < s->nb_streams; j++)
7643 if (s->streams[j]->id == sc->timecode_track)
7646 if (tmcd_st_id < 0 || tmcd_st_id == i)
7648 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7650 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7653 export_orphan_timecode(s);
7655 for (i = 0; i < s->nb_streams; i++) {
7656 AVStream *st = s->streams[i];
7657 MOVStreamContext *sc = st->priv_data;
7658 fix_timescale(mov, sc);
7659 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
7660 st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7661 st->internal->skip_samples = sc->start_pad;
7663 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7664 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7665 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7666 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7667 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7668 st->codecpar->width = sc->width;
7669 st->codecpar->height = sc->height;
7671 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7672 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7676 if (mov->handbrake_version &&
7677 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7678 st->codecpar->codec_id == AV_CODEC_ID_MP3) {
7679 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7680 st->need_parsing = AVSTREAM_PARSE_FULL;
7684 if (mov->trex_data) {
7685 for (i = 0; i < s->nb_streams; i++) {
7686 AVStream *st = s->streams[i];
7687 MOVStreamContext *sc = st->priv_data;
7688 if (st->duration > 0) {
7689 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7690 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7691 sc->data_size, sc->time_scale);
7692 err = AVERROR_INVALIDDATA;
7695 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7700 if (mov->use_mfra_for > 0) {
7701 for (i = 0; i < s->nb_streams; i++) {
7702 AVStream *st = s->streams[i];
7703 MOVStreamContext *sc = st->priv_data;
7704 if (sc->duration_for_fps > 0) {
7705 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7706 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7707 sc->data_size, sc->time_scale);
7708 err = AVERROR_INVALIDDATA;
7711 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7712 sc->duration_for_fps;
7717 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7718 if (mov->bitrates[i]) {
7719 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7723 ff_rfps_calculate(s);
7725 for (i = 0; i < s->nb_streams; i++) {
7726 AVStream *st = s->streams[i];
7727 MOVStreamContext *sc = st->priv_data;
7729 switch (st->codecpar->codec_type) {
7730 case AVMEDIA_TYPE_AUDIO:
7731 err = ff_replaygain_export(st, s->metadata);
7735 case AVMEDIA_TYPE_VIDEO:
7736 if (sc->display_matrix) {
7737 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7738 sizeof(int32_t) * 9);
7742 sc->display_matrix = NULL;
7745 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7746 (uint8_t *)sc->stereo3d,
7747 sizeof(*sc->stereo3d));
7751 sc->stereo3d = NULL;
7753 if (sc->spherical) {
7754 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7755 (uint8_t *)sc->spherical,
7756 sc->spherical_size);
7760 sc->spherical = NULL;
7762 if (sc->mastering) {
7763 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7764 (uint8_t *)sc->mastering,
7765 sizeof(*sc->mastering));
7769 sc->mastering = NULL;
7772 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7773 (uint8_t *)sc->coll,
7783 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7785 for (i = 0; i < mov->frag_index.nb_items; i++)
7786 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7787 mov->frag_index.item[i].headers_read = 1;
7795 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7797 AVIndexEntry *sample = NULL;
7798 int64_t best_dts = INT64_MAX;
7800 for (i = 0; i < s->nb_streams; i++) {
7801 AVStream *avst = s->streams[i];
7802 MOVStreamContext *msc = avst->priv_data;
7803 if (msc->pb && msc->current_sample < avst->internal->nb_index_entries) {
7804 AVIndexEntry *current_sample = &avst->internal->index_entries[msc->current_sample];
7805 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7806 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7807 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7808 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7809 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
7810 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7811 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7812 sample = current_sample;
7821 static int should_retry(AVIOContext *pb, int error_code) {
7822 if (error_code == AVERROR_EOF || avio_feof(pb))
7828 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7831 MOVContext *mov = s->priv_data;
7833 if (index >= 0 && index < mov->frag_index.nb_items)
7834 target = mov->frag_index.item[index].moof_offset;
7835 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7836 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7837 return AVERROR_INVALIDDATA;
7840 mov->next_root_atom = 0;
7841 if (index < 0 || index >= mov->frag_index.nb_items)
7842 index = search_frag_moof_offset(&mov->frag_index, target);
7843 if (index < mov->frag_index.nb_items &&
7844 mov->frag_index.item[index].moof_offset == target) {
7845 if (index + 1 < mov->frag_index.nb_items)
7846 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7847 if (mov->frag_index.item[index].headers_read)
7849 mov->frag_index.item[index].headers_read = 1;
7852 mov->found_mdat = 0;
7854 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7857 if (avio_feof(s->pb))
7859 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7864 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7866 uint8_t *side, *extradata;
7869 /* Save the current index. */
7870 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7872 /* Notify the decoder that extradata changed. */
7873 extradata_size = sc->extradata_size[sc->last_stsd_index];
7874 extradata = sc->extradata[sc->last_stsd_index];
7875 if (extradata_size > 0 && extradata) {
7876 side = av_packet_new_side_data(pkt,
7877 AV_PKT_DATA_NEW_EXTRADATA,
7880 return AVERROR(ENOMEM);
7881 memcpy(side, extradata, extradata_size);
7887 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int size)
7892 return AVERROR_INVALIDDATA;
7893 new_size = ((size - 8) / 2) * 3;
7894 ret = av_new_packet(pkt, new_size);
7899 for (int j = 0; j < new_size; j += 3) {
7900 pkt->data[j] = 0xFC;
7901 pkt->data[j+1] = avio_r8(pb);
7902 pkt->data[j+2] = avio_r8(pb);
7908 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7910 MOVContext *mov = s->priv_data;
7911 MOVStreamContext *sc;
7912 AVIndexEntry *sample;
7913 AVStream *st = NULL;
7914 int64_t current_index;
7918 sample = mov_find_next_sample(s, &st);
7919 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7920 if (!mov->next_root_atom)
7922 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7927 /* must be done just before reading, to avoid infinite loop on sample */
7928 current_index = sc->current_index;
7929 mov_current_sample_inc(sc);
7931 if (mov->next_root_atom) {
7932 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7933 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7936 if (st->discard != AVDISCARD_ALL) {
7937 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7938 if (ret64 != sample->pos) {
7939 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7940 sc->ffindex, sample->pos);
7941 if (should_retry(sc->pb, ret64)) {
7942 mov_current_sample_dec(sc);
7944 return AVERROR_INVALIDDATA;
7947 if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
7948 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7952 if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
7953 ret = get_eia608_packet(sc->pb, pkt, sample->size);
7955 ret = av_get_packet(sc->pb, pkt, sample->size);
7957 if (should_retry(sc->pb, ret)) {
7958 mov_current_sample_dec(sc);
7962 #if CONFIG_DV_DEMUXER
7963 if (mov->dv_demux && sc->dv_audio_container) {
7964 AVBufferRef *buf = pkt->buf;
7965 ret = avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7967 av_packet_unref(pkt);
7970 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7975 if (sc->has_palette) {
7978 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7980 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7982 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7983 sc->has_palette = 0;
7986 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7987 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7988 st->need_parsing = AVSTREAM_PARSE_FULL;
7992 pkt->stream_index = sc->ffindex;
7993 pkt->dts = sample->timestamp;
7994 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7995 pkt->flags |= AV_PKT_FLAG_DISCARD;
7997 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7998 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
7999 /* update ctts context */
8001 if (sc->ctts_index < sc->ctts_count &&
8002 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
8004 sc->ctts_sample = 0;
8007 int64_t next_dts = (sc->current_sample < st->internal->nb_index_entries) ?
8008 st->internal->index_entries[sc->current_sample].timestamp : st->duration;
8010 if (next_dts >= pkt->dts)
8011 pkt->duration = next_dts - pkt->dts;
8012 pkt->pts = pkt->dts;
8014 if (st->discard == AVDISCARD_ALL)
8016 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
8017 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
8018 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
8019 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
8021 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
8022 pkt->pos = sample->pos;
8024 /* Multiple stsd handling. */
8025 if (sc->stsc_data) {
8026 /* Keep track of the stsc index for the given sample, then check
8027 * if the stsd index is different from the last used one. */
8029 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
8030 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
8032 sc->stsc_sample = 0;
8033 /* Do not check indexes after a switch. */
8034 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
8035 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
8036 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
8037 ret = mov_change_extradata(sc, pkt);
8044 aax_filter(pkt->data, pkt->size, mov);
8046 ret = cenc_filter(mov, st, sc, pkt, current_index);
8054 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
8056 MOVContext *mov = s->priv_data;
8059 if (!mov->frag_index.complete)
8062 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
8065 if (!mov->frag_index.item[index].headers_read)
8066 return mov_switch_root(s, -1, index);
8067 if (index + 1 < mov->frag_index.nb_items)
8068 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
8073 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
8075 MOVStreamContext *sc = st->priv_data;
8076 int sample, time_sample, ret;
8079 // Here we consider timestamp to be PTS, hence try to offset it so that we
8080 // can search over the DTS timeline.
8081 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
8083 ret = mov_seek_fragment(s, st, timestamp);
8087 sample = av_index_search_timestamp(st, timestamp, flags);
8088 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
8089 if (sample < 0 && st->internal->nb_index_entries && timestamp < st->internal->index_entries[0].timestamp)
8091 if (sample < 0) /* not sure what to do */
8092 return AVERROR_INVALIDDATA;
8093 mov_current_sample_set(sc, sample);
8094 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
8095 /* adjust ctts index */
8096 if (sc->ctts_data) {
8098 for (i = 0; i < sc->ctts_count; i++) {
8099 int next = time_sample + sc->ctts_data[i].count;
8100 if (next > sc->current_sample) {
8102 sc->ctts_sample = sc->current_sample - time_sample;
8109 /* adjust stsd index */
8110 if (sc->chunk_count) {
8112 for (i = 0; i < sc->stsc_count; i++) {
8113 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
8114 if (next > sc->current_sample) {
8116 sc->stsc_sample = sc->current_sample - time_sample;
8119 av_assert0(next == (int)next);
8127 static int64_t mov_get_skip_samples(AVStream *st, int sample)
8129 MOVStreamContext *sc = st->priv_data;
8130 int64_t first_ts = st->internal->index_entries[0].timestamp;
8131 int64_t ts = st->internal->index_entries[sample].timestamp;
8134 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO)
8137 /* compute skip samples according to stream start_pad, seek ts and first ts */
8138 off = av_rescale_q(ts - first_ts, st->time_base,
8139 (AVRational){1, st->codecpar->sample_rate});
8140 return FFMAX(sc->start_pad - off, 0);
8143 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
8145 MOVContext *mc = s->priv_data;
8150 if (stream_index >= s->nb_streams)
8151 return AVERROR_INVALIDDATA;
8153 st = s->streams[stream_index];
8154 sample = mov_seek_stream(s, st, sample_time, flags);
8158 if (mc->seek_individually) {
8159 /* adjust seek timestamp to found sample timestamp */
8160 int64_t seek_timestamp = st->internal->index_entries[sample].timestamp;
8161 st->internal->skip_samples = mov_get_skip_samples(st, sample);
8163 for (i = 0; i < s->nb_streams; i++) {
8167 if (stream_index == i)
8170 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
8171 sample = mov_seek_stream(s, st, timestamp, flags);
8173 st->internal->skip_samples = mov_get_skip_samples(st, sample);
8176 for (i = 0; i < s->nb_streams; i++) {
8177 MOVStreamContext *sc;
8180 mov_current_sample_set(sc, 0);
8183 MOVStreamContext *sc;
8184 AVIndexEntry *entry = mov_find_next_sample(s, &st);
8186 return AVERROR_INVALIDDATA;
8188 if (sc->ffindex == stream_index && sc->current_sample == sample)
8190 mov_current_sample_inc(sc);
8196 #define OFFSET(x) offsetof(MOVContext, x)
8197 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
8198 static const AVOption mov_options[] = {
8199 {"use_absolute_path",
8200 "allow using absolute path when opening alias, this is a possible security issue",
8201 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
8203 {"seek_streams_individually",
8204 "Seek each stream individually to the closest point",
8205 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
8207 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
8209 {"advanced_editlist",
8210 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
8211 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
8213 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8216 "use mfra for fragment timestamps",
8217 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8218 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8220 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8221 FLAGS, "use_mfra_for" },
8222 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8223 FLAGS, "use_mfra_for" },
8224 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8225 FLAGS, "use_mfra_for" },
8226 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8227 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8228 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8229 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8230 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8231 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8232 { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
8233 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8234 { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
8235 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8236 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8237 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8238 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8239 .flags = AV_OPT_FLAG_DECODING_PARAM },
8240 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8241 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8242 {.i64 = 0}, 0, 1, FLAGS },
8247 static const AVClass mov_class = {
8248 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8249 .item_name = av_default_item_name,
8250 .option = mov_options,
8251 .version = LIBAVUTIL_VERSION_INT,
8254 AVInputFormat ff_mov_demuxer = {
8255 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8256 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8257 .priv_class = &mov_class,
8258 .priv_data_size = sizeof(MOVContext),
8259 .extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
8260 .read_probe = mov_probe,
8261 .read_header = mov_read_header,
8262 .read_packet = mov_read_packet,
8263 .read_close = mov_read_close,
8264 .read_seek = mov_read_seek,
8265 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,