1 /*
2 * MOV demuxer
3 * Copyright (c) 2001 Fabrice Bellard
4 * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
5 *
6 * first version by Francois Revol <revol@free.fr>
7 * seek function by Gael Chardon <gael.dev@4now.net>
8 *
9 * This file is part of FFmpeg.
10 *
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.
15 *
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.
20 *
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
24 */
25
26 #include <inttypes.h>
27 #include <limits.h>
28 #include <stdint.h>
29
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"
54 #include "avformat.h"
55 #include "internal.h"
56 #include "avio_internal.h"
57 #include "riff.h"
58 #include "isom.h"
59 #include "libavcodec/get_bits.h"
60 #include "id3v1.h"
61 #include "mov_chan.h"
62 #include "replaygain.h"
63
64 #if CONFIG_ZLIB
65 #include <zlib.h>
66 #endif
67
68 #include "qtpalette.h"
69
70 /* those functions parse an atom */
71 /* links atom IDs to parse functions */
72 typedef struct MOVParseTableEntry {
73 uint32_t type;
74 int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
75 } MOVParseTableEntry;
76
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);
81
mov_metadata_track_or_disc_number(MOVContext * c,AVIOContext * pb,unsigned len,const char * key)82 static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb,
83 unsigned len, const char *key)
84 {
85 char buf[16];
86
87 short current, total = 0;
88 avio_rb16(pb); // unknown
89 current = avio_rb16(pb);
90 if (len >= 6)
91 total = avio_rb16(pb);
92 if (!total)
93 snprintf(buf, sizeof(buf), "%d", current);
94 else
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);
98
99 return 0;
100 }
101
mov_metadata_int8_bypass_padding(MOVContext * c,AVIOContext * pb,unsigned len,const char * key)102 static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb,
103 unsigned len, const char *key)
104 {
105 /* bypass padding bytes */
106 avio_r8(pb);
107 avio_r8(pb);
108 avio_r8(pb);
109
110 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
111 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
112
113 return 0;
114 }
115
mov_metadata_int8_no_padding(MOVContext * c,AVIOContext * pb,unsigned len,const char * key)116 static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb,
117 unsigned len, const char *key)
118 {
119 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
120 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
121
122 return 0;
123 }
124
mov_metadata_gnre(MOVContext * c,AVIOContext * pb,unsigned len,const char * key)125 static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb,
126 unsigned len, const char *key)
127 {
128 short genre;
129
130 avio_r8(pb); // unknown
131
132 genre = avio_r8(pb);
133 if (genre < 1 || genre > ID3v1_GENRE_MAX)
134 return 0;
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);
137
138 return 0;
139 }
140
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,
158 };
159
mov_read_mac_string(MOVContext * c,AVIOContext * pb,int len,char * dst,int dstlen)160 static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len,
161 char *dst, int dstlen)
162 {
163 char *p = dst;
164 char *end = dst+dstlen-1;
165 int i;
166
167 for (i = 0; i < len; i++) {
168 uint8_t t, c = avio_r8(pb);
169
170 if (p >= end)
171 continue;
172
173 if (c < 0x80)
174 *p++ = c;
175 else if (p < end)
176 PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
177 }
178 *p = 0;
179 return p - dst;
180 }
181
mov_read_covr(MOVContext * c,AVIOContext * pb,int type,int len)182 static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
183 {
184 AVStream *st;
185 MOVStreamContext *sc;
186 enum AVCodecID id;
187 int ret;
188
189 switch (type) {
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;
193 default:
194 av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
195 avio_skip(pb, len);
196 return 0;
197 }
198
199 st = avformat_new_stream(c->fc, NULL);
200 if (!st)
201 return AVERROR(ENOMEM);
202 sc = av_mallocz(sizeof(*sc));
203 if (!sc)
204 return AVERROR(ENOMEM);
205 st->priv_data = sc;
206
207 ret = av_get_packet(pb, &st->attached_pic, len);
208 if (ret < 0)
209 return ret;
210
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;
214 } else {
215 id = AV_CODEC_ID_MJPEG;
216 }
217 }
218
219 st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
220
221 st->attached_pic.stream_index = st->index;
222 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
223
224 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
225 st->codecpar->codec_id = id;
226
227 return 0;
228 }
229
230 // 3GPP TS 26.244
mov_metadata_loci(MOVContext * c,AVIOContext * pb,unsigned len)231 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
232 {
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";
238
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;
242 }
243
244 avio_skip(pb, 4); // version+flags
245 langcode = avio_rb16(pb);
246 ff_mov_lang_to_iso639(langcode, language);
247 len -= 6;
248
249 len -= avio_get_str(pb, len, place, sizeof(place));
250 if (len < 1) {
251 av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
252 return AVERROR_INVALIDDATA;
253 }
254 avio_skip(pb, 1); // role
255 len -= 1;
256
257 if (len < 12) {
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;
261 }
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);
265
266 // Try to output in the same format as the ?xyz field
267 snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
268 if (altitude)
269 av_strlcatf(buf, sizeof(buf), "%+f", altitude);
270 av_strlcatf(buf, sizeof(buf), "/%s", place);
271
272 if (*language && strcmp(language, "und")) {
273 char key2[16];
274 snprintf(key2, sizeof(key2), "%s-%s", key, language);
275 av_dict_set(&c->fc->metadata, key2, buf, 0);
276 }
277 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
278 return av_dict_set(&c->fc->metadata, key, buf, 0);
279 }
280
mov_metadata_hmmt(MOVContext * c,AVIOContext * pb,unsigned len)281 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
282 {
283 int i, n_hmmt;
284
285 if (len < 2)
286 return 0;
287 if (c->ignore_chapters)
288 return 0;
289
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);
296 }
297 if (avio_feof(pb))
298 return AVERROR_INVALIDDATA;
299 return 0;
300 }
301
mov_read_udta_string(MOVContext * c,AVIOContext * pb,MOVAtom atom)302 static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
303 {
304 char tmp_key[AV_FOURCC_MAX_STRING_SIZE] = {0};
305 char key2[32], language[4] = {0};
306 char *str = NULL;
307 const char *key = NULL;
308 uint16_t langcode = 0;
309 uint32_t data_type = 0, str_size, str_size_alloc;
310 int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
311 int raw = 0;
312 int num = 0;
313
314 switch (atom.type) {
315 case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
316 case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
317 case MKTAG( 'X','M','P','_'):
318 if (c->export_xmp) { key = "xmp"; raw = 1; } break;
319 case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
320 case MKTAG( 'a','k','I','D'): key = "account_type";
321 parse = mov_metadata_int8_no_padding; break;
322 case MKTAG( 'a','p','I','D'): key = "account_id"; break;
323 case MKTAG( 'c','a','t','g'): key = "category"; break;
324 case MKTAG( 'c','p','i','l'): key = "compilation";
325 parse = mov_metadata_int8_no_padding; break;
326 case MKTAG( 'c','p','r','t'): key = "copyright"; break;
327 case MKTAG( 'd','e','s','c'): key = "description"; break;
328 case MKTAG( 'd','i','s','k'): key = "disc";
329 parse = mov_metadata_track_or_disc_number; break;
330 case MKTAG( 'e','g','i','d'): key = "episode_uid";
331 parse = mov_metadata_int8_no_padding; break;
332 case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
333 case MKTAG( 'g','n','r','e'): key = "genre";
334 parse = mov_metadata_gnre; break;
335 case MKTAG( 'h','d','v','d'): key = "hd_video";
336 parse = mov_metadata_int8_no_padding; break;
337 case MKTAG( 'H','M','M','T'):
338 return mov_metadata_hmmt(c, pb, atom.size);
339 case MKTAG( 'k','e','y','w'): key = "keywords"; break;
340 case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
341 case MKTAG( 'l','o','c','i'):
342 return mov_metadata_loci(c, pb, atom.size);
343 case MKTAG( 'm','a','n','u'): key = "make"; break;
344 case MKTAG( 'm','o','d','l'): key = "model"; break;
345 case MKTAG( 'p','c','s','t'): key = "podcast";
346 parse = mov_metadata_int8_no_padding; break;
347 case MKTAG( 'p','g','a','p'): key = "gapless_playback";
348 parse = mov_metadata_int8_no_padding; break;
349 case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
350 case MKTAG( 'r','t','n','g'): key = "rating";
351 parse = mov_metadata_int8_no_padding; break;
352 case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
353 case MKTAG( 's','o','a','l'): key = "sort_album"; break;
354 case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
355 case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
356 case MKTAG( 's','o','n','m'): key = "sort_name"; break;
357 case MKTAG( 's','o','s','n'): key = "sort_show"; break;
358 case MKTAG( 's','t','i','k'): key = "media_type";
359 parse = mov_metadata_int8_no_padding; break;
360 case MKTAG( 't','r','k','n'): key = "track";
361 parse = mov_metadata_track_or_disc_number; break;
362 case MKTAG( 't','v','e','n'): key = "episode_id"; break;
363 case MKTAG( 't','v','e','s'): key = "episode_sort";
364 parse = mov_metadata_int8_bypass_padding; break;
365 case MKTAG( 't','v','n','n'): key = "network"; break;
366 case MKTAG( 't','v','s','h'): key = "show"; break;
367 case MKTAG( 't','v','s','n'): key = "season_number";
368 parse = mov_metadata_int8_bypass_padding; break;
369 case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
370 case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
371 case MKTAG(0xa9,'a','l','b'): key = "album"; break;
372 case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
373 case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
374 case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
375 case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
376 case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
377 case MKTAG(0xa9,'d','a','y'): key = "date"; break;
378 case MKTAG(0xa9,'d','i','r'): key = "director"; break;
379 case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
380 case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
381 case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
382 case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
383 case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
384 case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
385 case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
386 case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
387 case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
388 case MKTAG(0xa9,'m','a','k'): key = "make"; break;
389 case MKTAG(0xa9,'m','o','d'): key = "model"; break;
390 case MKTAG(0xa9,'n','a','m'): key = "title"; break;
391 case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
392 case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
393 case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
394 case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
395 case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
396 case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
397 case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
398 case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
399 case MKTAG(0xa9,'t','r','k'): key = "track"; break;
400 case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
401 case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
402 case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
403 case MKTAG(0xa9,'x','y','z'): key = "location"; break;
404 }
405 retry:
406 if (c->itunes_metadata && atom.size > 8) {
407 int data_size = avio_rb32(pb);
408 int tag = avio_rl32(pb);
409 if (tag == MKTAG('d','a','t','a') && data_size <= atom.size && data_size >= 16) {
410 data_type = avio_rb32(pb); // type
411 avio_rb32(pb); // unknown
412 str_size = data_size - 16;
413 atom.size -= 16;
414
415 if (atom.type == MKTAG('c', 'o', 'v', 'r')) {
416 int ret = mov_read_covr(c, pb, data_type, str_size);
417 if (ret < 0) {
418 av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
419 return ret;
420 }
421 atom.size -= str_size;
422 if (atom.size > 8)
423 goto retry;
424 return ret;
425 } else if (!key && c->found_hdlr_mdta && c->meta_keys) {
426 uint32_t index = AV_RB32(&atom.type);
427 if (index < c->meta_keys_count && index > 0) {
428 key = c->meta_keys[index];
429 } else {
430 av_log(c->fc, AV_LOG_WARNING,
431 "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
432 index, c->meta_keys_count);
433 }
434 }
435 } else return 0;
436 } else if (atom.size > 4 && key && !c->itunes_metadata && !raw) {
437 str_size = avio_rb16(pb); // string length
438 if (str_size > atom.size) {
439 raw = 1;
440 avio_seek(pb, -2, SEEK_CUR);
441 av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
442 goto retry;
443 }
444 langcode = avio_rb16(pb);
445 ff_mov_lang_to_iso639(langcode, language);
446 atom.size -= 4;
447 } else
448 str_size = atom.size;
449
450 if (c->export_all && !key) {
451 key = av_fourcc_make_string(tmp_key, atom.type);
452 }
453
454 if (!key)
455 return 0;
456 if (atom.size < 0 || str_size >= INT_MAX/2)
457 return AVERROR_INVALIDDATA;
458
459 // Allocates enough space if data_type is a int32 or float32 number, otherwise
460 // worst-case requirement for output string in case of utf8 coded input
461 num = (data_type >= 21 && data_type <= 23);
462 str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
463 str = av_mallocz(str_size_alloc);
464 if (!str)
465 return AVERROR(ENOMEM);
466
467 if (parse)
468 parse(c, pb, str_size, key);
469 else {
470 if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
471 mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
472 } else if (data_type == 21) { // BE signed integer, variable size
473 int val = 0;
474 if (str_size == 1)
475 val = (int8_t)avio_r8(pb);
476 else if (str_size == 2)
477 val = (int16_t)avio_rb16(pb);
478 else if (str_size == 3)
479 val = ((int32_t)(avio_rb24(pb)<<8))>>8;
480 else if (str_size == 4)
481 val = (int32_t)avio_rb32(pb);
482 if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
483 av_log(c->fc, AV_LOG_ERROR,
484 "Failed to store the number (%d) in string.\n", val);
485 av_free(str);
486 return AVERROR_INVALIDDATA;
487 }
488 } else if (data_type == 22) { // BE unsigned integer, variable size
489 unsigned int val = 0;
490 if (str_size == 1)
491 val = avio_r8(pb);
492 else if (str_size == 2)
493 val = avio_rb16(pb);
494 else if (str_size == 3)
495 val = avio_rb24(pb);
496 else if (str_size == 4)
497 val = avio_rb32(pb);
498 if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
499 av_log(c->fc, AV_LOG_ERROR,
500 "Failed to store the number (%u) in string.\n", val);
501 av_free(str);
502 return AVERROR_INVALIDDATA;
503 }
504 } else if (data_type == 23 && str_size >= 4) { // BE float32
505 float val = av_int2float(avio_rb32(pb));
506 if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
507 av_log(c->fc, AV_LOG_ERROR,
508 "Failed to store the float32 number (%f) in string.\n", val);
509 av_free(str);
510 return AVERROR_INVALIDDATA;
511 }
512 } else {
513 int ret = ffio_read_size(pb, str, str_size);
514 if (ret < 0) {
515 av_free(str);
516 return ret;
517 }
518 str[str_size] = 0;
519 }
520 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
521 av_dict_set(&c->fc->metadata, key, str, 0);
522 if (*language && strcmp(language, "und")) {
523 snprintf(key2, sizeof(key2), "%s-%s", key, language);
524 av_dict_set(&c->fc->metadata, key2, str, 0);
525 }
526 if (!strcmp(key, "encoder")) {
527 int major, minor, micro;
528 if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, µ) == 3) {
529 c->handbrake_version = 1000000*major + 1000*minor + micro;
530 }
531 }
532 }
533
534 av_freep(&str);
535 return 0;
536 }
537
mov_read_chpl(MOVContext * c,AVIOContext * pb,MOVAtom atom)538 static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
539 {
540 int64_t start;
541 int i, nb_chapters, str_len, version;
542 char str[256+1];
543 int ret;
544
545 if (c->ignore_chapters)
546 return 0;
547
548 if ((atom.size -= 5) < 0)
549 return 0;
550
551 version = avio_r8(pb);
552 avio_rb24(pb);
553 if (version)
554 avio_rb32(pb); // ???
555 nb_chapters = avio_r8(pb);
556
557 for (i = 0; i < nb_chapters; i++) {
558 if (atom.size < 9)
559 return 0;
560
561 start = avio_rb64(pb);
562 str_len = avio_r8(pb);
563
564 if ((atom.size -= 9+str_len) < 0)
565 return 0;
566
567 ret = ffio_read_size(pb, str, str_len);
568 if (ret < 0)
569 return ret;
570 str[str_len] = 0;
571 avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
572 }
573 return 0;
574 }
575
576 #define MIN_DATA_ENTRY_BOX_SIZE 12
mov_read_dref(MOVContext * c,AVIOContext * pb,MOVAtom atom)577 static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
578 {
579 AVStream *st;
580 MOVStreamContext *sc;
581 int entries, i, j;
582
583 if (c->fc->nb_streams < 1)
584 return 0;
585 st = c->fc->streams[c->fc->nb_streams-1];
586 sc = st->priv_data;
587
588 avio_rb32(pb); // version + flags
589 entries = avio_rb32(pb);
590 if (!entries ||
591 entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
592 entries >= UINT_MAX / sizeof(*sc->drefs))
593 return AVERROR_INVALIDDATA;
594
595 for (i = 0; i < sc->drefs_count; i++) {
596 MOVDref *dref = &sc->drefs[i];
597 av_freep(&dref->path);
598 av_freep(&dref->dir);
599 }
600 av_free(sc->drefs);
601 sc->drefs_count = 0;
602 sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
603 if (!sc->drefs)
604 return AVERROR(ENOMEM);
605 sc->drefs_count = entries;
606
607 for (i = 0; i < entries; i++) {
608 MOVDref *dref = &sc->drefs[i];
609 uint32_t size = avio_rb32(pb);
610 int64_t next = avio_tell(pb) + size - 4;
611
612 if (size < 12)
613 return AVERROR_INVALIDDATA;
614
615 dref->type = avio_rl32(pb);
616 avio_rb32(pb); // version + flags
617
618 if (dref->type == MKTAG('a','l','i','s') && size > 150) {
619 /* macintosh alias record */
620 uint16_t volume_len, len;
621 int16_t type;
622 int ret;
623
624 avio_skip(pb, 10);
625
626 volume_len = avio_r8(pb);
627 volume_len = FFMIN(volume_len, 27);
628 ret = ffio_read_size(pb, dref->volume, 27);
629 if (ret < 0)
630 return ret;
631 dref->volume[volume_len] = 0;
632 av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
633
634 avio_skip(pb, 12);
635
636 len = avio_r8(pb);
637 len = FFMIN(len, 63);
638 ret = ffio_read_size(pb, dref->filename, 63);
639 if (ret < 0)
640 return ret;
641 dref->filename[len] = 0;
642 av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
643
644 avio_skip(pb, 16);
645
646 /* read next level up_from_alias/down_to_target */
647 dref->nlvl_from = avio_rb16(pb);
648 dref->nlvl_to = avio_rb16(pb);
649 av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
650 dref->nlvl_from, dref->nlvl_to);
651
652 avio_skip(pb, 16);
653
654 for (type = 0; type != -1 && avio_tell(pb) < next; ) {
655 if (avio_feof(pb))
656 return AVERROR_EOF;
657 type = avio_rb16(pb);
658 len = avio_rb16(pb);
659 av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
660 if (len&1)
661 len += 1;
662 if (type == 2) { // absolute path
663 av_free(dref->path);
664 dref->path = av_mallocz(len+1);
665 if (!dref->path)
666 return AVERROR(ENOMEM);
667
668 ret = ffio_read_size(pb, dref->path, len);
669 if (ret < 0) {
670 av_freep(&dref->path);
671 return ret;
672 }
673 if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
674 len -= volume_len;
675 memmove(dref->path, dref->path+volume_len, len);
676 dref->path[len] = 0;
677 }
678 // trim string of any ending zeros
679 for (j = len - 1; j >= 0; j--) {
680 if (dref->path[j] == 0)
681 len--;
682 else
683 break;
684 }
685 for (j = 0; j < len; j++)
686 if (dref->path[j] == ':' || dref->path[j] == 0)
687 dref->path[j] = '/';
688 av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
689 } else if (type == 0) { // directory name
690 av_free(dref->dir);
691 dref->dir = av_malloc(len+1);
692 if (!dref->dir)
693 return AVERROR(ENOMEM);
694
695 ret = ffio_read_size(pb, dref->dir, len);
696 if (ret < 0) {
697 av_freep(&dref->dir);
698 return ret;
699 }
700 dref->dir[len] = 0;
701 for (j = 0; j < len; j++)
702 if (dref->dir[j] == ':')
703 dref->dir[j] = '/';
704 av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
705 } else
706 avio_skip(pb, len);
707 }
708 } else {
709 av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
710 dref->type, size);
711 entries--;
712 i--;
713 }
714 avio_seek(pb, next, SEEK_SET);
715 }
716 return 0;
717 }
718
mov_read_hdlr(MOVContext * c,AVIOContext * pb,MOVAtom atom)719 static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
720 {
721 AVStream *st;
722 uint32_t type;
723 uint32_t ctype;
724 int64_t title_size;
725 char *title_str;
726 int ret;
727
728 avio_r8(pb); /* version */
729 avio_rb24(pb); /* flags */
730
731 /* component type */
732 ctype = avio_rl32(pb);
733 type = avio_rl32(pb); /* component subtype */
734
735 av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
736 av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
737
738 if (c->trak_index < 0) { // meta not inside a trak
739 if (type == MKTAG('m','d','t','a')) {
740 c->found_hdlr_mdta = 1;
741 }
742 return 0;
743 }
744
745 st = c->fc->streams[c->fc->nb_streams-1];
746
747 if (type == MKTAG('v','i','d','e'))
748 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
749 else if (type == MKTAG('s','o','u','n'))
750 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
751 else if (type == MKTAG('m','1','a',' '))
752 st->codecpar->codec_id = AV_CODEC_ID_MP2;
753 else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
754 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
755
756 avio_rb32(pb); /* component manufacture */
757 avio_rb32(pb); /* component flags */
758 avio_rb32(pb); /* component flags mask */
759
760 title_size = atom.size - 24;
761 if (title_size > 0) {
762 if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
763 return AVERROR_INVALIDDATA;
764 title_str = av_malloc(title_size + 1); /* Add null terminator */
765 if (!title_str)
766 return AVERROR(ENOMEM);
767
768 ret = ffio_read_size(pb, title_str, title_size);
769 if (ret < 0) {
770 av_freep(&title_str);
771 return ret;
772 }
773 title_str[title_size] = 0;
774 if (title_str[0]) {
775 int off = (!c->isom && title_str[0] == title_size - 1);
776 // flag added so as to not set stream handler name if already set from mdia->hdlr
777 av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
778 }
779 av_freep(&title_str);
780 }
781
782 return 0;
783 }
784
mov_read_esds(MOVContext * c,AVIOContext * pb,MOVAtom atom)785 static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
786 {
787 return ff_mov_read_esds(c->fc, pb);
788 }
789
mov_read_dac3(MOVContext * c,AVIOContext * pb,MOVAtom atom)790 static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
791 {
792 AVStream *st;
793 enum AVAudioServiceType *ast;
794 int ac3info, acmod, lfeon, bsmod;
795
796 if (c->fc->nb_streams < 1)
797 return 0;
798 st = c->fc->streams[c->fc->nb_streams-1];
799
800 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
801 sizeof(*ast));
802 if (!ast)
803 return AVERROR(ENOMEM);
804
805 ac3info = avio_rb24(pb);
806 bsmod = (ac3info >> 14) & 0x7;
807 acmod = (ac3info >> 11) & 0x7;
808 lfeon = (ac3info >> 10) & 0x1;
809 st->codecpar->channels = ((int[]){2,1,2,3,3,4,4,5})[acmod] + lfeon;
810 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
811 if (lfeon)
812 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
813 *ast = bsmod;
814 if (st->codecpar->channels > 1 && bsmod == 0x7)
815 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
816
817 #if FF_API_LAVF_AVCTX
818 FF_DISABLE_DEPRECATION_WARNINGS
819 st->codec->audio_service_type = *ast;
820 FF_ENABLE_DEPRECATION_WARNINGS
821 #endif
822
823 return 0;
824 }
825
mov_read_dec3(MOVContext * c,AVIOContext * pb,MOVAtom atom)826 static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
827 {
828 AVStream *st;
829 enum AVAudioServiceType *ast;
830 int eac3info, acmod, lfeon, bsmod;
831
832 if (c->fc->nb_streams < 1)
833 return 0;
834 st = c->fc->streams[c->fc->nb_streams-1];
835
836 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
837 sizeof(*ast));
838 if (!ast)
839 return AVERROR(ENOMEM);
840
841 /* No need to parse fields for additional independent substreams and its
842 * associated dependent substreams since libavcodec's E-AC-3 decoder
843 * does not support them yet. */
844 avio_rb16(pb); /* data_rate and num_ind_sub */
845 eac3info = avio_rb24(pb);
846 bsmod = (eac3info >> 12) & 0x1f;
847 acmod = (eac3info >> 9) & 0x7;
848 lfeon = (eac3info >> 8) & 0x1;
849 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
850 if (lfeon)
851 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
852 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
853 *ast = bsmod;
854 if (st->codecpar->channels > 1 && bsmod == 0x7)
855 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
856
857 #if FF_API_LAVF_AVCTX
858 FF_DISABLE_DEPRECATION_WARNINGS
859 st->codec->audio_service_type = *ast;
860 FF_ENABLE_DEPRECATION_WARNINGS
861 #endif
862
863 return 0;
864 }
865
mov_read_ddts(MOVContext * c,AVIOContext * pb,MOVAtom atom)866 static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
867 {
868 #define DDTS_SIZE 20
869 uint8_t buf[DDTS_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
870 AVStream *st = NULL;
871 uint32_t frame_duration_code = 0;
872 uint32_t channel_layout_code = 0;
873 GetBitContext gb;
874 int ret;
875
876 if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
877 return ret;
878
879 init_get_bits(&gb, buf, 8 * DDTS_SIZE);
880
881 if (c->fc->nb_streams < 1) {
882 return 0;
883 }
884 st = c->fc->streams[c->fc->nb_streams-1];
885
886 st->codecpar->sample_rate = get_bits_long(&gb, 32);
887 if (st->codecpar->sample_rate <= 0) {
888 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
889 return AVERROR_INVALIDDATA;
890 }
891 skip_bits_long(&gb, 32); /* max bitrate */
892 st->codecpar->bit_rate = get_bits_long(&gb, 32);
893 st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
894 frame_duration_code = get_bits(&gb, 2);
895 skip_bits(&gb, 30); /* various fields */
896 channel_layout_code = get_bits(&gb, 16);
897
898 st->codecpar->frame_size =
899 (frame_duration_code == 0) ? 512 :
900 (frame_duration_code == 1) ? 1024 :
901 (frame_duration_code == 2) ? 2048 :
902 (frame_duration_code == 3) ? 4096 : 0;
903
904 if (channel_layout_code > 0xff) {
905 av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout\n");
906 }
907 st->codecpar->channel_layout =
908 ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
909 ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
910 ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
911 ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
912 ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
913 ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0);
914
915 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
916
917 return 0;
918 }
919
mov_read_chan(MOVContext * c,AVIOContext * pb,MOVAtom atom)920 static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
921 {
922 AVStream *st;
923
924 if (c->fc->nb_streams < 1)
925 return 0;
926 st = c->fc->streams[c->fc->nb_streams-1];
927
928 if (atom.size < 16)
929 return 0;
930
931 /* skip version and flags */
932 avio_skip(pb, 4);
933
934 ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
935
936 return 0;
937 }
938
mov_read_wfex(MOVContext * c,AVIOContext * pb,MOVAtom atom)939 static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
940 {
941 AVStream *st;
942 int ret;
943
944 if (c->fc->nb_streams < 1)
945 return 0;
946 st = c->fc->streams[c->fc->nb_streams-1];
947
948 if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
949 av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
950
951 return ret;
952 }
953
mov_read_pasp(MOVContext * c,AVIOContext * pb,MOVAtom atom)954 static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
955 {
956 const int num = avio_rb32(pb);
957 const int den = avio_rb32(pb);
958 AVStream *st;
959
960 if (c->fc->nb_streams < 1)
961 return 0;
962 st = c->fc->streams[c->fc->nb_streams-1];
963
964 if ((st->sample_aspect_ratio.den != 1 || st->sample_aspect_ratio.num) && // default
965 (den != st->sample_aspect_ratio.den || num != st->sample_aspect_ratio.num)) {
966 av_log(c->fc, AV_LOG_WARNING,
967 "sample aspect ratio already set to %d:%d, ignoring 'pasp' atom (%d:%d)\n",
968 st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
969 num, den);
970 } else if (den != 0) {
971 av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den,
972 num, den, 32767);
973 }
974 return 0;
975 }
976
977 /* this atom contains actual media data */
mov_read_mdat(MOVContext * c,AVIOContext * pb,MOVAtom atom)978 static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
979 {
980 if (atom.size == 0) /* wrong one (MP4) */
981 return 0;
982 c->found_mdat=1;
983 return 0; /* now go for moov */
984 }
985
986 #define DRM_BLOB_SIZE 56
987
mov_read_adrm(MOVContext * c,AVIOContext * pb,MOVAtom atom)988 static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
989 {
990 uint8_t intermediate_key[20];
991 uint8_t intermediate_iv[20];
992 uint8_t input[64];
993 uint8_t output[64];
994 uint8_t file_checksum[20];
995 uint8_t calculated_checksum[20];
996 struct AVSHA *sha;
997 int i;
998 int ret = 0;
999 uint8_t *activation_bytes = c->activation_bytes;
1000 uint8_t *fixed_key = c->audible_fixed_key;
1001
1002 c->aax_mode = 1;
1003
1004 sha = av_sha_alloc();
1005 if (!sha)
1006 return AVERROR(ENOMEM);
1007 av_free(c->aes_decrypt);
1008 c->aes_decrypt = av_aes_alloc();
1009 if (!c->aes_decrypt) {
1010 ret = AVERROR(ENOMEM);
1011 goto fail;
1012 }
1013
1014 /* drm blob processing */
1015 avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1016 avio_read(pb, input, DRM_BLOB_SIZE);
1017 avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1018 avio_read(pb, file_checksum, 20);
1019
1020 av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == "); // required by external tools
1021 for (i = 0; i < 20; i++)
1022 av_log(c->fc, AV_LOG_INFO, "%02x", file_checksum[i]);
1023 av_log(c->fc, AV_LOG_INFO, "\n");
1024
1025 /* verify activation data */
1026 if (!activation_bytes) {
1027 av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1028 ret = 0; /* allow ffprobe to continue working on .aax files */
1029 goto fail;
1030 }
1031 if (c->activation_bytes_size != 4) {
1032 av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1033 ret = AVERROR(EINVAL);
1034 goto fail;
1035 }
1036
1037 /* verify fixed key */
1038 if (c->audible_fixed_key_size != 16) {
1039 av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1040 ret = AVERROR(EINVAL);
1041 goto fail;
1042 }
1043
1044 /* AAX (and AAX+) key derivation */
1045 av_sha_init(sha, 160);
1046 av_sha_update(sha, fixed_key, 16);
1047 av_sha_update(sha, activation_bytes, 4);
1048 av_sha_final(sha, intermediate_key);
1049 av_sha_init(sha, 160);
1050 av_sha_update(sha, fixed_key, 16);
1051 av_sha_update(sha, intermediate_key, 20);
1052 av_sha_update(sha, activation_bytes, 4);
1053 av_sha_final(sha, intermediate_iv);
1054 av_sha_init(sha, 160);
1055 av_sha_update(sha, intermediate_key, 16);
1056 av_sha_update(sha, intermediate_iv, 16);
1057 av_sha_final(sha, calculated_checksum);
1058 if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1059 av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1060 ret = AVERROR_INVALIDDATA;
1061 goto fail;
1062 }
1063 av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1064 av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1065 for (i = 0; i < 4; i++) {
1066 // file data (in output) is stored in big-endian mode
1067 if (activation_bytes[i] != output[3 - i]) { // critical error
1068 av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1069 ret = AVERROR_INVALIDDATA;
1070 goto fail;
1071 }
1072 }
1073 memcpy(c->file_key, output + 8, 16);
1074 memcpy(input, output + 26, 16);
1075 av_sha_init(sha, 160);
1076 av_sha_update(sha, input, 16);
1077 av_sha_update(sha, c->file_key, 16);
1078 av_sha_update(sha, fixed_key, 16);
1079 av_sha_final(sha, c->file_iv);
1080
1081 fail:
1082 av_free(sha);
1083
1084 return ret;
1085 }
1086
mov_aaxc_crypto(MOVContext * c)1087 static int mov_aaxc_crypto(MOVContext *c)
1088 {
1089 if (c->audible_key_size != 16) {
1090 av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
1091 return AVERROR(EINVAL);
1092 }
1093
1094 if (c->audible_iv_size != 16) {
1095 av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
1096 return AVERROR(EINVAL);
1097 }
1098
1099 c->aes_decrypt = av_aes_alloc();
1100 if (!c->aes_decrypt) {
1101 return AVERROR(ENOMEM);
1102 }
1103
1104 memcpy(c->file_key, c->audible_key, 16);
1105 memcpy(c->file_iv, c->audible_iv, 16);
1106 c->aax_mode = 1;
1107
1108 return 0;
1109 }
1110
1111 // Audible AAX (and AAX+) bytestream decryption
aax_filter(uint8_t * input,int size,MOVContext * c)1112 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1113 {
1114 int blocks = 0;
1115 unsigned char iv[16];
1116
1117 memcpy(iv, c->file_iv, 16); // iv is overwritten
1118 blocks = size >> 4; // trailing bytes are not encrypted!
1119 av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1120 av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1121
1122 return 0;
1123 }
1124
1125 /* read major brand, minor version and compatible brands and store them as metadata */
mov_read_ftyp(MOVContext * c,AVIOContext * pb,MOVAtom atom)1126 static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1127 {
1128 uint32_t minor_ver;
1129 int comp_brand_size;
1130 char* comp_brands_str;
1131 uint8_t type[5] = {0};
1132 int ret = ffio_read_size(pb, type, 4);
1133 if (ret < 0)
1134 return ret;
1135
1136 if (strcmp(type, "qt "))
1137 c->isom = 1;
1138 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1139 av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1140 minor_ver = avio_rb32(pb); /* minor version */
1141 av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1142
1143 comp_brand_size = atom.size - 8;
1144 if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1145 return AVERROR_INVALIDDATA;
1146 comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1147 if (!comp_brands_str)
1148 return AVERROR(ENOMEM);
1149
1150 ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1151 if (ret < 0) {
1152 av_freep(&comp_brands_str);
1153 return ret;
1154 }
1155 comp_brands_str[comp_brand_size] = 0;
1156 av_dict_set(&c->fc->metadata, "compatible_brands",
1157 comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1158
1159 // Logic for handling Audible's .aaxc files
1160 if (!strcmp(type, "aaxc")) {
1161 mov_aaxc_crypto(c);
1162 }
1163
1164 return 0;
1165 }
1166
1167 /* this atom should contain all header atoms */
mov_read_moov(MOVContext * c,AVIOContext * pb,MOVAtom atom)1168 static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1169 {
1170 int ret;
1171
1172 if (c->found_moov) {
1173 av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1174 avio_skip(pb, atom.size);
1175 return 0;
1176 }
1177
1178 if ((ret = mov_read_default(c, pb, atom)) < 0)
1179 return ret;
1180 /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1181 /* so we don't parse the whole file if over a network */
1182 c->found_moov=1;
1183 return 0; /* now go for mdat */
1184 }
1185
get_frag_stream_info(MOVFragmentIndex * frag_index,int index,int id)1186 static MOVFragmentStreamInfo * get_frag_stream_info(
1187 MOVFragmentIndex *frag_index,
1188 int index,
1189 int id)
1190 {
1191 int i;
1192 MOVFragmentIndexItem * item;
1193
1194 if (index < 0 || index >= frag_index->nb_items)
1195 return NULL;
1196 item = &frag_index->item[index];
1197 for (i = 0; i < item->nb_stream_info; i++)
1198 if (item->stream_info[i].id == id)
1199 return &item->stream_info[i];
1200
1201 // This shouldn't happen
1202 return NULL;
1203 }
1204
set_frag_stream(MOVFragmentIndex * frag_index,int id)1205 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1206 {
1207 int i;
1208 MOVFragmentIndexItem * item;
1209
1210 if (frag_index->current < 0 ||
1211 frag_index->current >= frag_index->nb_items)
1212 return;
1213
1214 item = &frag_index->item[frag_index->current];
1215 for (i = 0; i < item->nb_stream_info; i++)
1216 if (item->stream_info[i].id == id) {
1217 item->current = i;
1218 return;
1219 }
1220
1221 // id not found. This shouldn't happen.
1222 item->current = -1;
1223 }
1224
get_current_frag_stream_info(MOVFragmentIndex * frag_index)1225 static MOVFragmentStreamInfo * get_current_frag_stream_info(
1226 MOVFragmentIndex *frag_index)
1227 {
1228 MOVFragmentIndexItem *item;
1229 if (frag_index->current < 0 ||
1230 frag_index->current >= frag_index->nb_items)
1231 return NULL;
1232
1233 item = &frag_index->item[frag_index->current];
1234 if (item->current >= 0 && item->current < item->nb_stream_info)
1235 return &item->stream_info[item->current];
1236
1237 // This shouldn't happen
1238 return NULL;
1239 }
1240
search_frag_moof_offset(MOVFragmentIndex * frag_index,int64_t offset)1241 static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
1242 {
1243 int a, b, m;
1244 int64_t moof_offset;
1245
1246 // Optimize for appending new entries
1247 if (!frag_index->nb_items ||
1248 frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1249 return frag_index->nb_items;
1250
1251 a = -1;
1252 b = frag_index->nb_items;
1253
1254 while (b - a > 1) {
1255 m = (a + b) >> 1;
1256 moof_offset = frag_index->item[m].moof_offset;
1257 if (moof_offset >= offset)
1258 b = m;
1259 if (moof_offset <= offset)
1260 a = m;
1261 }
1262 return b;
1263 }
1264
get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)1265 static int64_t get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
1266 {
1267 av_assert0(frag_stream_info);
1268 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1269 return frag_stream_info->sidx_pts;
1270 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1271 return frag_stream_info->first_tfra_pts;
1272 return frag_stream_info->tfdt_dts;
1273 }
1274
get_frag_time(MOVFragmentIndex * frag_index,int index,int track_id)1275 static int64_t get_frag_time(MOVFragmentIndex *frag_index,
1276 int index, int track_id)
1277 {
1278 MOVFragmentStreamInfo * frag_stream_info;
1279 int64_t timestamp;
1280 int i;
1281
1282 if (track_id >= 0) {
1283 frag_stream_info = get_frag_stream_info(frag_index, index, track_id);
1284 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1285 return frag_stream_info->sidx_pts;
1286 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1287 return frag_stream_info->first_tfra_pts;
1288 return frag_stream_info->sidx_pts;
1289 }
1290
1291 for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1292 frag_stream_info = &frag_index->item[index].stream_info[i];
1293 timestamp = get_stream_info_time(frag_stream_info);
1294 if (timestamp != AV_NOPTS_VALUE)
1295 return timestamp;
1296 }
1297 return AV_NOPTS_VALUE;
1298 }
1299
search_frag_timestamp(MOVFragmentIndex * frag_index,AVStream * st,int64_t timestamp)1300 static int search_frag_timestamp(MOVFragmentIndex *frag_index,
1301 AVStream *st, int64_t timestamp)
1302 {
1303 int a, b, m, m0;
1304 int64_t frag_time;
1305 int id = -1;
1306
1307 if (st) {
1308 // If the stream is referenced by any sidx, limit the search
1309 // to fragments that referenced this stream in the sidx
1310 MOVStreamContext *sc = st->priv_data;
1311 if (sc->has_sidx)
1312 id = st->id;
1313 }
1314
1315 a = -1;
1316 b = frag_index->nb_items;
1317
1318 while (b - a > 1) {
1319 m0 = m = (a + b) >> 1;
1320
1321 while (m < b &&
1322 (frag_time = get_frag_time(frag_index, m, id)) == AV_NOPTS_VALUE)
1323 m++;
1324
1325 if (m < b && frag_time <= timestamp)
1326 a = m;
1327 else
1328 b = m0;
1329 }
1330
1331 return a;
1332 }
1333
update_frag_index(MOVContext * c,int64_t offset)1334 static int update_frag_index(MOVContext *c, int64_t offset)
1335 {
1336 int index, i;
1337 MOVFragmentIndexItem * item;
1338 MOVFragmentStreamInfo * frag_stream_info;
1339
1340 // If moof_offset already exists in frag_index, return index to it
1341 index = search_frag_moof_offset(&c->frag_index, offset);
1342 if (index < c->frag_index.nb_items &&
1343 c->frag_index.item[index].moof_offset == offset)
1344 return index;
1345
1346 // offset is not yet in frag index.
1347 // Insert new item at index (sorted by moof offset)
1348 item = av_fast_realloc(c->frag_index.item,
1349 &c->frag_index.allocated_size,
1350 (c->frag_index.nb_items + 1) *
1351 sizeof(*c->frag_index.item));
1352 if (!item)
1353 return -1;
1354 c->frag_index.item = item;
1355
1356 frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1357 sizeof(*item->stream_info));
1358 if (!frag_stream_info)
1359 return -1;
1360
1361 for (i = 0; i < c->fc->nb_streams; i++) {
1362 // Avoid building frag index if streams lack track id.
1363 if (c->fc->streams[i]->id < 0) {
1364 av_free(frag_stream_info);
1365 return AVERROR_INVALIDDATA;
1366 }
1367
1368 frag_stream_info[i].id = c->fc->streams[i]->id;
1369 frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1370 frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1371 frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1372 frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1373 frag_stream_info[i].index_entry = -1;
1374 frag_stream_info[i].encryption_index = NULL;
1375 }
1376
1377 if (index < c->frag_index.nb_items)
1378 memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1379 (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1380
1381 item = &c->frag_index.item[index];
1382 item->headers_read = 0;
1383 item->current = 0;
1384 item->nb_stream_info = c->fc->nb_streams;
1385 item->moof_offset = offset;
1386 item->stream_info = frag_stream_info;
1387 c->frag_index.nb_items++;
1388
1389 return index;
1390 }
1391
fix_frag_index_entries(MOVFragmentIndex * frag_index,int index,int id,int entries)1392 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1393 int id, int entries)
1394 {
1395 int i;
1396 MOVFragmentStreamInfo * frag_stream_info;
1397
1398 if (index < 0)
1399 return;
1400 for (i = index; i < frag_index->nb_items; i++) {
1401 frag_stream_info = get_frag_stream_info(frag_index, i, id);
1402 if (frag_stream_info && frag_stream_info->index_entry >= 0)
1403 frag_stream_info->index_entry += entries;
1404 }
1405 }
1406
mov_read_moof(MOVContext * c,AVIOContext * pb,MOVAtom atom)1407 static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1408 {
1409 // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1410 c->fragment.found_tfhd = 0;
1411
1412 if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1413 c->has_looked_for_mfra = 1;
1414 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1415 int ret;
1416 av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1417 "for a mfra\n");
1418 if ((ret = mov_read_mfra(c, pb)) < 0) {
1419 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1420 "read the mfra (may be a live ismv)\n");
1421 }
1422 } else {
1423 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1424 "seekable, can not look for mfra\n");
1425 }
1426 }
1427 c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1428 av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1429 c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1430 return mov_read_default(c, pb, atom);
1431 }
1432
mov_metadata_creation_time(AVDictionary ** metadata,int64_t time,void * logctx)1433 static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time, void *logctx)
1434 {
1435 if (time) {
1436 if (time >= 2082844800)
1437 time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1438
1439 if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1440 av_log(logctx, AV_LOG_DEBUG, "creation_time is not representable\n");
1441 return;
1442 }
1443
1444 avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1445 }
1446 }
1447
mov_read_mdhd(MOVContext * c,AVIOContext * pb,MOVAtom atom)1448 static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1449 {
1450 AVStream *st;
1451 MOVStreamContext *sc;
1452 int version;
1453 char language[4] = {0};
1454 unsigned lang;
1455 int64_t creation_time;
1456
1457 if (c->fc->nb_streams < 1)
1458 return 0;
1459 st = c->fc->streams[c->fc->nb_streams-1];
1460 sc = st->priv_data;
1461
1462 if (sc->time_scale) {
1463 av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1464 return AVERROR_INVALIDDATA;
1465 }
1466
1467 version = avio_r8(pb);
1468 if (version > 1) {
1469 avpriv_request_sample(c->fc, "Version %d", version);
1470 return AVERROR_PATCHWELCOME;
1471 }
1472 avio_rb24(pb); /* flags */
1473 if (version == 1) {
1474 creation_time = avio_rb64(pb);
1475 avio_rb64(pb);
1476 } else {
1477 creation_time = avio_rb32(pb);
1478 avio_rb32(pb); /* modification time */
1479 }
1480 mov_metadata_creation_time(&st->metadata, creation_time, c->fc);
1481
1482 sc->time_scale = avio_rb32(pb);
1483 if (sc->time_scale <= 0) {
1484 av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1485 sc->time_scale = 1;
1486 }
1487 st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1488
1489 lang = avio_rb16(pb); /* language */
1490 if (ff_mov_lang_to_iso639(lang, language))
1491 av_dict_set(&st->metadata, "language", language, 0);
1492 avio_rb16(pb); /* quality */
1493
1494 return 0;
1495 }
1496
mov_read_mvhd(MOVContext * c,AVIOContext * pb,MOVAtom atom)1497 static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1498 {
1499 int i;
1500 int64_t creation_time;
1501 int version = avio_r8(pb); /* version */
1502 avio_rb24(pb); /* flags */
1503
1504 if (version == 1) {
1505 creation_time = avio_rb64(pb);
1506 avio_rb64(pb);
1507 } else {
1508 creation_time = avio_rb32(pb);
1509 avio_rb32(pb); /* modification time */
1510 }
1511 mov_metadata_creation_time(&c->fc->metadata, creation_time, c->fc);
1512 c->time_scale = avio_rb32(pb); /* time scale */
1513 if (c->time_scale <= 0) {
1514 av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1515 c->time_scale = 1;
1516 }
1517 av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1518
1519 c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1520 // set the AVFormatContext duration because the duration of individual tracks
1521 // may be inaccurate
1522 if (!c->trex_data)
1523 c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale);
1524 avio_rb32(pb); /* preferred scale */
1525
1526 avio_rb16(pb); /* preferred volume */
1527
1528 avio_skip(pb, 10); /* reserved */
1529
1530 /* movie display matrix, store it in main context and use it later on */
1531 for (i = 0; i < 3; i++) {
1532 c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1533 c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1534 c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1535 }
1536
1537 avio_rb32(pb); /* preview time */
1538 avio_rb32(pb); /* preview duration */
1539 avio_rb32(pb); /* poster time */
1540 avio_rb32(pb); /* selection time */
1541 avio_rb32(pb); /* selection duration */
1542 avio_rb32(pb); /* current time */
1543 avio_rb32(pb); /* next track ID */
1544
1545 return 0;
1546 }
1547
mov_read_enda(MOVContext * c,AVIOContext * pb,MOVAtom atom)1548 static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1549 {
1550 AVStream *st;
1551 int little_endian;
1552
1553 if (c->fc->nb_streams < 1)
1554 return 0;
1555 st = c->fc->streams[c->fc->nb_streams-1];
1556
1557 little_endian = avio_rb16(pb) & 0xFF;
1558 av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1559 if (little_endian == 1) {
1560 switch (st->codecpar->codec_id) {
1561 case AV_CODEC_ID_PCM_S24BE:
1562 st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE;
1563 break;
1564 case AV_CODEC_ID_PCM_S32BE:
1565 st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE;
1566 break;
1567 case AV_CODEC_ID_PCM_F32BE:
1568 st->codecpar->codec_id = AV_CODEC_ID_PCM_F32LE;
1569 break;
1570 case AV_CODEC_ID_PCM_F64BE:
1571 st->codecpar->codec_id = AV_CODEC_ID_PCM_F64LE;
1572 break;
1573 default:
1574 break;
1575 }
1576 }
1577 return 0;
1578 }
1579
mov_read_colr(MOVContext * c,AVIOContext * pb,MOVAtom atom)1580 static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1581 {
1582 AVStream *st;
1583 uint8_t *icc_profile;
1584 char color_parameter_type[5] = { 0 };
1585 uint16_t color_primaries, color_trc, color_matrix;
1586 int ret;
1587
1588 if (c->fc->nb_streams < 1)
1589 return 0;
1590 st = c->fc->streams[c->fc->nb_streams - 1];
1591
1592 ret = ffio_read_size(pb, color_parameter_type, 4);
1593 if (ret < 0)
1594 return ret;
1595 if (strncmp(color_parameter_type, "nclx", 4) &&
1596 strncmp(color_parameter_type, "nclc", 4) &&
1597 strncmp(color_parameter_type, "prof", 4)) {
1598 av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
1599 color_parameter_type);
1600 return 0;
1601 }
1602
1603 if (!strncmp(color_parameter_type, "prof", 4)) {
1604 icc_profile = av_stream_new_side_data(st, AV_PKT_DATA_ICC_PROFILE, atom.size - 4);
1605 if (!icc_profile)
1606 return AVERROR(ENOMEM);
1607 ret = ffio_read_size(pb, icc_profile, atom.size - 4);
1608 if (ret < 0)
1609 return ret;
1610 } else {
1611 color_primaries = avio_rb16(pb);
1612 color_trc = avio_rb16(pb);
1613 color_matrix = avio_rb16(pb);
1614
1615 av_log(c->fc, AV_LOG_TRACE,
1616 "%s: pri %d trc %d matrix %d",
1617 color_parameter_type, color_primaries, color_trc, color_matrix);
1618
1619 if (!strncmp(color_parameter_type, "nclx", 4)) {
1620 uint8_t color_range = avio_r8(pb) >> 7;
1621 av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
1622 if (color_range)
1623 st->codecpar->color_range = AVCOL_RANGE_JPEG;
1624 else
1625 st->codecpar->color_range = AVCOL_RANGE_MPEG;
1626 }
1627
1628 if (!av_color_primaries_name(color_primaries))
1629 color_primaries = AVCOL_PRI_UNSPECIFIED;
1630 if (!av_color_transfer_name(color_trc))
1631 color_trc = AVCOL_TRC_UNSPECIFIED;
1632 if (!av_color_space_name(color_matrix))
1633 color_matrix = AVCOL_SPC_UNSPECIFIED;
1634
1635 st->codecpar->color_primaries = color_primaries;
1636 st->codecpar->color_trc = color_trc;
1637 st->codecpar->color_space = color_matrix;
1638 av_log(c->fc, AV_LOG_TRACE, "\n");
1639 }
1640 return 0;
1641 }
1642
mov_read_fiel(MOVContext * c,AVIOContext * pb,MOVAtom atom)1643 static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1644 {
1645 AVStream *st;
1646 unsigned mov_field_order;
1647 enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
1648
1649 if (c->fc->nb_streams < 1) // will happen with jp2 files
1650 return 0;
1651 st = c->fc->streams[c->fc->nb_streams-1];
1652 if (atom.size < 2)
1653 return AVERROR_INVALIDDATA;
1654 mov_field_order = avio_rb16(pb);
1655 if ((mov_field_order & 0xFF00) == 0x0100)
1656 decoded_field_order = AV_FIELD_PROGRESSIVE;
1657 else if ((mov_field_order & 0xFF00) == 0x0200) {
1658 switch (mov_field_order & 0xFF) {
1659 case 0x01: decoded_field_order = AV_FIELD_TT;
1660 break;
1661 case 0x06: decoded_field_order = AV_FIELD_BB;
1662 break;
1663 case 0x09: decoded_field_order = AV_FIELD_TB;
1664 break;
1665 case 0x0E: decoded_field_order = AV_FIELD_BT;
1666 break;
1667 }
1668 }
1669 if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
1670 av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
1671 }
1672 st->codecpar->field_order = decoded_field_order;
1673
1674 return 0;
1675 }
1676
mov_realloc_extradata(AVCodecParameters * par,MOVAtom atom)1677 static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
1678 {
1679 int err = 0;
1680 uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
1681 if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
1682 return AVERROR_INVALIDDATA;
1683 if ((err = av_reallocp(&par->extradata, size)) < 0) {
1684 par->extradata_size = 0;
1685 return err;
1686 }
1687 par->extradata_size = size - AV_INPUT_BUFFER_PADDING_SIZE;
1688 return 0;
1689 }
1690
1691 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
mov_read_atom_into_extradata(MOVContext * c,AVIOContext * pb,MOVAtom atom,AVCodecParameters * par,uint8_t * buf)1692 static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1693 AVCodecParameters *par, uint8_t *buf)
1694 {
1695 int64_t result = atom.size;
1696 int err;
1697
1698 AV_WB32(buf , atom.size + 8);
1699 AV_WL32(buf + 4, atom.type);
1700 err = ffio_read_size(pb, buf + 8, atom.size);
1701 if (err < 0) {
1702 par->extradata_size -= atom.size;
1703 return err;
1704 } else if (err < atom.size) {
1705 av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
1706 par->extradata_size -= atom.size - err;
1707 result = err;
1708 }
1709 memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1710 return result;
1711 }
1712
1713 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
mov_read_extradata(MOVContext * c,AVIOContext * pb,MOVAtom atom,enum AVCodecID codec_id)1714 static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1715 enum AVCodecID codec_id)
1716 {
1717 AVStream *st;
1718 uint64_t original_size;
1719 int err;
1720
1721 if (c->fc->nb_streams < 1) // will happen with jp2 files
1722 return 0;
1723 st = c->fc->streams[c->fc->nb_streams-1];
1724
1725 if (st->codecpar->codec_id != codec_id)
1726 return 0; /* unexpected codec_id - don't mess with extradata */
1727
1728 original_size = st->codecpar->extradata_size;
1729 err = mov_realloc_extradata(st->codecpar, atom);
1730 if (err)
1731 return err;
1732
1733 err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
1734 if (err < 0)
1735 return err;
1736 return 0; // Note: this is the original behavior to ignore truncation.
1737 }
1738
1739 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
mov_read_alac(MOVContext * c,AVIOContext * pb,MOVAtom atom)1740 static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1741 {
1742 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
1743 }
1744
mov_read_avss(MOVContext * c,AVIOContext * pb,MOVAtom atom)1745 static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1746 {
1747 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS);
1748 }
1749
mov_read_jp2h(MOVContext * c,AVIOContext * pb,MOVAtom atom)1750 static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1751 {
1752 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
1753 }
1754
mov_read_dpxe(MOVContext * c,AVIOContext * pb,MOVAtom atom)1755 static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1756 {
1757 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
1758 }
1759
mov_read_avid(MOVContext * c,AVIOContext * pb,MOVAtom atom)1760 static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1761 {
1762 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
1763 if (!ret)
1764 ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
1765 return ret;
1766 }
1767
mov_read_targa_y216(MOVContext * c,AVIOContext * pb,MOVAtom atom)1768 static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1769 {
1770 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
1771
1772 if (!ret && c->fc->nb_streams >= 1) {
1773 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1774 if (par->extradata_size >= 40) {
1775 par->height = AV_RB16(&par->extradata[36]);
1776 par->width = AV_RB16(&par->extradata[38]);
1777 }
1778 }
1779 return ret;
1780 }
1781
mov_read_ares(MOVContext * c,AVIOContext * pb,MOVAtom atom)1782 static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1783 {
1784 if (c->fc->nb_streams >= 1) {
1785 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1786 if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
1787 par->codec_id == AV_CODEC_ID_H264 &&
1788 atom.size > 11) {
1789 int cid;
1790 avio_skip(pb, 10);
1791 cid = avio_rb16(pb);
1792 /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
1793 if (cid == 0xd4d || cid == 0xd4e)
1794 par->width = 1440;
1795 return 0;
1796 } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
1797 par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
1798 par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
1799 atom.size >= 24) {
1800 int num, den;
1801 avio_skip(pb, 12);
1802 num = avio_rb32(pb);
1803 den = avio_rb32(pb);
1804 if (num <= 0 || den <= 0)
1805 return 0;
1806 switch (avio_rb32(pb)) {
1807 case 2:
1808 if (den >= INT_MAX / 2)
1809 return 0;
1810 den *= 2;
1811 case 1:
1812 c->fc->streams[c->fc->nb_streams-1]->internal->display_aspect_ratio.num = num;
1813 c->fc->streams[c->fc->nb_streams-1]->internal->display_aspect_ratio.den = den;
1814 default:
1815 return 0;
1816 }
1817 }
1818 }
1819
1820 return mov_read_avid(c, pb, atom);
1821 }
1822
mov_read_aclr(MOVContext * c,AVIOContext * pb,MOVAtom atom)1823 static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1824 {
1825 int ret = 0;
1826 int length = 0;
1827 uint64_t original_size;
1828 if (c->fc->nb_streams >= 1) {
1829 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1830 if (par->codec_id == AV_CODEC_ID_H264)
1831 return 0;
1832 if (atom.size == 16) {
1833 original_size = par->extradata_size;
1834 ret = mov_realloc_extradata(par, atom);
1835 if (!ret) {
1836 length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
1837 if (length == atom.size) {
1838 const uint8_t range_value = par->extradata[original_size + 19];
1839 switch (range_value) {
1840 case 1:
1841 par->color_range = AVCOL_RANGE_MPEG;
1842 break;
1843 case 2:
1844 par->color_range = AVCOL_RANGE_JPEG;
1845 break;
1846 default:
1847 av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
1848 break;
1849 }
1850 ff_dlog(c->fc, "color_range: %d\n", par->color_range);
1851 } else {
1852 /* For some reason the whole atom was not added to the extradata */
1853 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
1854 }
1855 } else {
1856 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
1857 }
1858 } else {
1859 av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
1860 }
1861 }
1862
1863 return ret;
1864 }
1865
mov_read_svq3(MOVContext * c,AVIOContext * pb,MOVAtom atom)1866 static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1867 {
1868 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
1869 }
1870
mov_read_wave(MOVContext * c,AVIOContext * pb,MOVAtom atom)1871 static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1872 {
1873 AVStream *st;
1874 int ret;
1875
1876 if (c->fc->nb_streams < 1)
1877 return 0;
1878 st = c->fc->streams[c->fc->nb_streams-1];
1879
1880 if ((uint64_t)atom.size > (1<<30))
1881 return AVERROR_INVALIDDATA;
1882
1883 if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
1884 st->codecpar->codec_id == AV_CODEC_ID_QDMC ||
1885 st->codecpar->codec_id == AV_CODEC_ID_SPEEX) {
1886 // pass all frma atom to codec, needed at least for QDMC and QDM2
1887 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1888 if (ret < 0)
1889 return ret;
1890 } else if (atom.size > 8) { /* to read frma, esds atoms */
1891 if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
1892 uint64_t buffer;
1893 ret = ffio_ensure_seekback(pb, 8);
1894 if (ret < 0)
1895 return ret;
1896 buffer = avio_rb64(pb);
1897 atom.size -= 8;
1898 if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
1899 && buffer >> 32 <= atom.size
1900 && buffer >> 32 >= 8) {
1901 avio_skip(pb, -8);
1902 atom.size += 8;
1903 } else if (!st->codecpar->extradata_size) {
1904 #define ALAC_EXTRADATA_SIZE 36
1905 st->codecpar->extradata = av_mallocz(ALAC_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
1906 if (!st->codecpar->extradata)
1907 return AVERROR(ENOMEM);
1908 st->codecpar->extradata_size = ALAC_EXTRADATA_SIZE;
1909 AV_WB32(st->codecpar->extradata , ALAC_EXTRADATA_SIZE);
1910 AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
1911 AV_WB64(st->codecpar->extradata + 12, buffer);
1912 avio_read(pb, st->codecpar->extradata + 20, 16);
1913 avio_skip(pb, atom.size - 24);
1914 return 0;
1915 }
1916 }
1917 if ((ret = mov_read_default(c, pb, atom)) < 0)
1918 return ret;
1919 } else
1920 avio_skip(pb, atom.size);
1921 return 0;
1922 }
1923
1924 /**
1925 * This function reads atom content and puts data in extradata without tag
1926 * nor size unlike mov_read_extradata.
1927 */
mov_read_glbl(MOVContext * c,AVIOContext * pb,MOVAtom atom)1928 static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1929 {
1930 AVStream *st;
1931 int ret;
1932
1933 if (c->fc->nb_streams < 1)
1934 return 0;
1935 st = c->fc->streams[c->fc->nb_streams-1];
1936
1937 if ((uint64_t)atom.size > (1<<30))
1938 return AVERROR_INVALIDDATA;
1939
1940 if (atom.size >= 10) {
1941 // Broken files created by legacy versions of libavformat will
1942 // wrap a whole fiel atom inside of a glbl atom.
1943 unsigned size = avio_rb32(pb);
1944 unsigned type = avio_rl32(pb);
1945 avio_seek(pb, -8, SEEK_CUR);
1946 if (type == MKTAG('f','i','e','l') && size == atom.size)
1947 return mov_read_default(c, pb, atom);
1948 }
1949 if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
1950 av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
1951 return 0;
1952 }
1953 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1954 if (ret < 0)
1955 return ret;
1956 if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
1957 /* HEVC-based Dolby Vision derived from hvc1.
1958 Happens to match with an identifier
1959 previously utilized for DV. Thus, if we have
1960 the hvcC extradata box available as specified,
1961 set codec to HEVC */
1962 st->codecpar->codec_id = AV_CODEC_ID_HEVC;
1963
1964 return 0;
1965 }
1966
mov_read_dvc1(MOVContext * c,AVIOContext * pb,MOVAtom atom)1967 static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1968 {
1969 AVStream *st;
1970 uint8_t profile_level;
1971 int ret;
1972
1973 if (c->fc->nb_streams < 1)
1974 return 0;
1975 st = c->fc->streams[c->fc->nb_streams-1];
1976
1977 if (atom.size >= (1<<28) || atom.size < 7)
1978 return AVERROR_INVALIDDATA;
1979
1980 profile_level = avio_r8(pb);
1981 if ((profile_level & 0xf0) != 0xc0)
1982 return 0;
1983
1984 avio_seek(pb, 6, SEEK_CUR);
1985 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
1986 if (ret < 0)
1987 return ret;
1988
1989 return 0;
1990 }
1991
1992 /**
1993 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
1994 * but can have extradata appended at the end after the 40 bytes belonging
1995 * to the struct.
1996 */
mov_read_strf(MOVContext * c,AVIOContext * pb,MOVAtom atom)1997 static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1998 {
1999 AVStream *st;
2000 int ret;
2001
2002 if (c->fc->nb_streams < 1)
2003 return 0;
2004 if (atom.size <= 40)
2005 return 0;
2006 st = c->fc->streams[c->fc->nb_streams-1];
2007
2008 if ((uint64_t)atom.size > (1<<30))
2009 return AVERROR_INVALIDDATA;
2010
2011 avio_skip(pb, 40);
2012 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2013 if (ret < 0)
2014 return ret;
2015
2016 return 0;
2017 }
2018
mov_read_stco(MOVContext * c,AVIOContext * pb,MOVAtom atom)2019 static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2020 {
2021 AVStream *st;
2022 MOVStreamContext *sc;
2023 unsigned int i, entries;
2024
2025 if (c->trak_index < 0) {
2026 av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2027 return 0;
2028 }
2029 if (c->fc->nb_streams < 1)
2030 return 0;
2031 st = c->fc->streams[c->fc->nb_streams-1];
2032 sc = st->priv_data;
2033
2034 avio_r8(pb); /* version */
2035 avio_rb24(pb); /* flags */
2036
2037 entries = avio_rb32(pb);
2038
2039 if (!entries)
2040 return 0;
2041
2042 if (sc->chunk_offsets) {
2043 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STCO atom\n");
2044 return 0;
2045 }
2046 av_free(sc->chunk_offsets);
2047 sc->chunk_count = 0;
2048 sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2049 if (!sc->chunk_offsets)
2050 return AVERROR(ENOMEM);
2051 sc->chunk_count = entries;
2052
2053 if (atom.type == MKTAG('s','t','c','o'))
2054 for (i = 0; i < entries && !pb->eof_reached; i++)
2055 sc->chunk_offsets[i] = avio_rb32(pb);
2056 else if (atom.type == MKTAG('c','o','6','4'))
2057 for (i = 0; i < entries && !pb->eof_reached; i++)
2058 sc->chunk_offsets[i] = avio_rb64(pb);
2059 else
2060 return AVERROR_INVALIDDATA;
2061
2062 sc->chunk_count = i;
2063
2064 if (pb->eof_reached) {
2065 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2066 return AVERROR_EOF;
2067 }
2068
2069 return 0;
2070 }
2071
mov_codec_id(AVStream * st,uint32_t format)2072 static int mov_codec_id(AVStream *st, uint32_t format)
2073 {
2074 int id = ff_codec_get_id(ff_codec_movaudio_tags, format);
2075
2076 if (id <= 0 &&
2077 ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2078 (format & 0xFFFF) == 'T' + ('S' << 8)))
2079 id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format) & 0xFFFF);
2080
2081 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2082 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2083 } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2084 /* skip old ASF MPEG-4 tag */
2085 format && format != MKTAG('m','p','4','s')) {
2086 id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2087 if (id <= 0)
2088 id = ff_codec_get_id(ff_codec_bmp_tags, format);
2089 if (id > 0)
2090 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
2091 else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2092 (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE &&
2093 st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2094 id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
2095 if (id > 0)
2096 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
2097 else
2098 id = ff_codec_get_id(ff_codec_movdata_tags, format);
2099 }
2100 }
2101
2102 st->codecpar->codec_tag = format;
2103
2104 return id;
2105 }
2106
mov_parse_stsd_video(MOVContext * c,AVIOContext * pb,AVStream * st,MOVStreamContext * sc)2107 static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
2108 AVStream *st, MOVStreamContext *sc)
2109 {
2110 uint8_t codec_name[32] = { 0 };
2111 int64_t stsd_start;
2112 unsigned int len;
2113 uint32_t id = 0;
2114
2115 /* The first 16 bytes of the video sample description are already
2116 * read in ff_mov_read_stsd_entries() */
2117 stsd_start = avio_tell(pb) - 16;
2118
2119 avio_rb16(pb); /* version */
2120 avio_rb16(pb); /* revision level */
2121 id = avio_rl32(pb); /* vendor */
2122 av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2123 avio_rb32(pb); /* temporal quality */
2124 avio_rb32(pb); /* spatial quality */
2125
2126 st->codecpar->width = avio_rb16(pb); /* width */
2127 st->codecpar->height = avio_rb16(pb); /* height */
2128
2129 avio_rb32(pb); /* horiz resolution */
2130 avio_rb32(pb); /* vert resolution */
2131 avio_rb32(pb); /* data size, always 0 */
2132 avio_rb16(pb); /* frames per samples */
2133
2134 len = avio_r8(pb); /* codec name, pascal string */
2135 if (len > 31)
2136 len = 31;
2137 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2138 if (len < 31)
2139 avio_skip(pb, 31 - len);
2140
2141 if (codec_name[0])
2142 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2143
2144 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2145 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2146 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2147 st->codecpar->width &= ~1;
2148 st->codecpar->height &= ~1;
2149 }
2150 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2151 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2152 !strncmp(codec_name, "Sorenson H263", 13))
2153 st->codecpar->codec_id = AV_CODEC_ID_FLV1;
2154
2155 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2156
2157 avio_seek(pb, stsd_start, SEEK_SET);
2158
2159 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2160 st->codecpar->bits_per_coded_sample &= 0x1F;
2161 sc->has_palette = 1;
2162 }
2163 }
2164
mov_parse_stsd_audio(MOVContext * c,AVIOContext * pb,AVStream * st,MOVStreamContext * sc)2165 static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
2166 AVStream *st, MOVStreamContext *sc)
2167 {
2168 int bits_per_sample, flags;
2169 uint16_t version = avio_rb16(pb);
2170 uint32_t id = 0;
2171 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2172
2173 avio_rb16(pb); /* revision level */
2174 id = avio_rl32(pb); /* vendor */
2175 av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2176
2177 st->codecpar->channels = avio_rb16(pb); /* channel count */
2178 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2179 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", st->codecpar->channels);
2180
2181 sc->audio_cid = avio_rb16(pb);
2182 avio_rb16(pb); /* packet size = 0 */
2183
2184 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2185
2186 // Read QT version 1 fields. In version 0 these do not exist.
2187 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2188 if (!c->isom ||
2189 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2190 (sc->stsd_version == 0 && version > 0)) {
2191 if (version == 1) {
2192 sc->samples_per_frame = avio_rb32(pb);
2193 avio_rb32(pb); /* bytes per packet */
2194 sc->bytes_per_frame = avio_rb32(pb);
2195 avio_rb32(pb); /* bytes per sample */
2196 } else if (version == 2) {
2197 avio_rb32(pb); /* sizeof struct only */
2198 st->codecpar->sample_rate = av_int2double(avio_rb64(pb));
2199 st->codecpar->channels = avio_rb32(pb);
2200 avio_rb32(pb); /* always 0x7F000000 */
2201 st->codecpar->bits_per_coded_sample = avio_rb32(pb);
2202
2203 flags = avio_rb32(pb); /* lpcm format specific flag */
2204 sc->bytes_per_frame = avio_rb32(pb);
2205 sc->samples_per_frame = avio_rb32(pb);
2206 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2207 st->codecpar->codec_id =
2208 ff_mov_get_lpcm_codec_id(st->codecpar->bits_per_coded_sample,
2209 flags);
2210 }
2211 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2212 /* can't correctly handle variable sized packet as audio unit */
2213 switch (st->codecpar->codec_id) {
2214 case AV_CODEC_ID_MP2:
2215 case AV_CODEC_ID_MP3:
2216 st->need_parsing = AVSTREAM_PARSE_FULL;
2217 break;
2218 }
2219 }
2220 }
2221
2222 if (sc->format == 0) {
2223 if (st->codecpar->bits_per_coded_sample == 8)
2224 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2225 else if (st->codecpar->bits_per_coded_sample == 16)
2226 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2227 }
2228
2229 switch (st->codecpar->codec_id) {
2230 case AV_CODEC_ID_PCM_S8:
2231 case AV_CODEC_ID_PCM_U8:
2232 if (st->codecpar->bits_per_coded_sample == 16)
2233 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16BE;
2234 break;
2235 case AV_CODEC_ID_PCM_S16LE:
2236 case AV_CODEC_ID_PCM_S16BE:
2237 if (st->codecpar->bits_per_coded_sample == 8)
2238 st->codecpar->codec_id = AV_CODEC_ID_PCM_S8;
2239 else if (st->codecpar->bits_per_coded_sample == 24)
2240 st->codecpar->codec_id =
2241 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2242 AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
2243 else if (st->codecpar->bits_per_coded_sample == 32)
2244 st->codecpar->codec_id =
2245 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2246 AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
2247 break;
2248 /* set values for old format before stsd version 1 appeared */
2249 case AV_CODEC_ID_MACE3:
2250 sc->samples_per_frame = 6;
2251 sc->bytes_per_frame = 2 * st->codecpar->channels;
2252 break;
2253 case AV_CODEC_ID_MACE6:
2254 sc->samples_per_frame = 6;
2255 sc->bytes_per_frame = 1 * st->codecpar->channels;
2256 break;
2257 case AV_CODEC_ID_ADPCM_IMA_QT:
2258 sc->samples_per_frame = 64;
2259 sc->bytes_per_frame = 34 * st->codecpar->channels;
2260 break;
2261 case AV_CODEC_ID_GSM:
2262 sc->samples_per_frame = 160;
2263 sc->bytes_per_frame = 33;
2264 break;
2265 default:
2266 break;
2267 }
2268
2269 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2270 if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->channels <= INT_MAX) {
2271 st->codecpar->bits_per_coded_sample = bits_per_sample;
2272 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->channels;
2273 }
2274 }
2275
mov_parse_stsd_subtitle(MOVContext * c,AVIOContext * pb,AVStream * st,MOVStreamContext * sc,int64_t size)2276 static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
2277 AVStream *st, MOVStreamContext *sc,
2278 int64_t size)
2279 {
2280 // ttxt stsd contains display flags, justification, background
2281 // color, fonts, and default styles, so fake an atom to read it
2282 MOVAtom fake_atom = { .size = size };
2283 // mp4s contains a regular esds atom
2284 if (st->codecpar->codec_tag != AV_RL32("mp4s"))
2285 mov_read_glbl(c, pb, fake_atom);
2286 st->codecpar->width = sc->width;
2287 st->codecpar->height = sc->height;
2288 }
2289
yuv_to_rgba(uint32_t ycbcr)2290 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2291 {
2292 uint8_t r, g, b;
2293 int y, cb, cr;
2294
2295 y = (ycbcr >> 16) & 0xFF;
2296 cr = (ycbcr >> 8) & 0xFF;
2297 cb = ycbcr & 0xFF;
2298
2299 b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
2300 g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
2301 r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
2302
2303 return (r << 16) | (g << 8) | b;
2304 }
2305
mov_rewrite_dvd_sub_extradata(AVStream * st)2306 static int mov_rewrite_dvd_sub_extradata(AVStream *st)
2307 {
2308 char buf[256] = {0};
2309 uint8_t *src = st->codecpar->extradata;
2310 int i, ret;
2311
2312 if (st->codecpar->extradata_size != 64)
2313 return 0;
2314
2315 if (st->codecpar->width > 0 && st->codecpar->height > 0)
2316 snprintf(buf, sizeof(buf), "size: %dx%d\n",
2317 st->codecpar->width, st->codecpar->height);
2318 av_strlcat(buf, "palette: ", sizeof(buf));
2319
2320 for (i = 0; i < 16; i++) {
2321 uint32_t yuv = AV_RB32(src + i * 4);
2322 uint32_t rgba = yuv_to_rgba(yuv);
2323
2324 av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2325 }
2326
2327 if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2328 return 0;
2329
2330 ret = ff_alloc_extradata(st->codecpar, strlen(buf));
2331 if (ret < 0)
2332 return ret;
2333 memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2334
2335 return 0;
2336 }
2337
mov_parse_stsd_data(MOVContext * c,AVIOContext * pb,AVStream * st,MOVStreamContext * sc,int64_t size)2338 static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
2339 AVStream *st, MOVStreamContext *sc,
2340 int64_t size)
2341 {
2342 int ret;
2343
2344 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2345 if ((int)size != size)
2346 return AVERROR(ENOMEM);
2347
2348 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2349 if (ret < 0)
2350 return ret;
2351 if (size > 16) {
2352 MOVStreamContext *tmcd_ctx = st->priv_data;
2353 int val;
2354 val = AV_RB32(st->codecpar->extradata + 4);
2355 tmcd_ctx->tmcd_flags = val;
2356 st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2357 st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2358 #if FF_API_LAVF_AVCTX
2359 FF_DISABLE_DEPRECATION_WARNINGS
2360 st->codec->time_base = av_inv_q(st->avg_frame_rate);
2361 FF_ENABLE_DEPRECATION_WARNINGS
2362 #endif
2363 if (size > 30) {
2364 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2365 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2366 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2367 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2368 if (str_size > 0 && size >= (int)str_size + 30 &&
2369 st->codecpar->extradata[30] /* Don't add empty string */) {
2370 char *reel_name = av_malloc(str_size + 1);
2371 if (!reel_name)
2372 return AVERROR(ENOMEM);
2373 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2374 reel_name[str_size] = 0; /* Add null terminator */
2375 av_dict_set(&st->metadata, "reel_name", reel_name,
2376 AV_DICT_DONT_STRDUP_VAL);
2377 }
2378 }
2379 }
2380 }
2381 } else {
2382 /* other codec type, just skip (rtp, mp4s ...) */
2383 avio_skip(pb, size);
2384 }
2385 return 0;
2386 }
2387
mov_finalize_stsd_codec(MOVContext * c,AVIOContext * pb,AVStream * st,MOVStreamContext * sc)2388 static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
2389 AVStream *st, MOVStreamContext *sc)
2390 {
2391 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2392 !st->codecpar->sample_rate && sc->time_scale > 1)
2393 st->codecpar->sample_rate = sc->time_scale;
2394
2395 /* special codec parameters handling */
2396 switch (st->codecpar->codec_id) {
2397 #if CONFIG_DV_DEMUXER
2398 case AV_CODEC_ID_DVAUDIO:
2399 c->dv_fctx = avformat_alloc_context();
2400 if (!c->dv_fctx) {
2401 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2402 return AVERROR(ENOMEM);
2403 }
2404 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2405 if (!c->dv_demux) {
2406 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2407 return AVERROR(ENOMEM);
2408 }
2409 sc->dv_audio_container = 1;
2410 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
2411 break;
2412 #endif
2413 /* no ifdef since parameters are always those */
2414 case AV_CODEC_ID_QCELP:
2415 st->codecpar->channels = 1;
2416 // force sample rate for qcelp when not stored in mov
2417 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2418 st->codecpar->sample_rate = 8000;
2419 // FIXME: Why is the following needed for some files?
2420 sc->samples_per_frame = 160;
2421 if (!sc->bytes_per_frame)
2422 sc->bytes_per_frame = 35;
2423 break;
2424 case AV_CODEC_ID_AMR_NB:
2425 st->codecpar->channels = 1;
2426 /* force sample rate for amr, stsd in 3gp does not store sample rate */
2427 st->codecpar->sample_rate = 8000;
2428 break;
2429 case AV_CODEC_ID_AMR_WB:
2430 st->codecpar->channels = 1;
2431 st->codecpar->sample_rate = 16000;
2432 break;
2433 case AV_CODEC_ID_MP2:
2434 case AV_CODEC_ID_MP3:
2435 /* force type after stsd for m1a hdlr */
2436 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2437 break;
2438 case AV_CODEC_ID_GSM:
2439 case AV_CODEC_ID_ADPCM_MS:
2440 case AV_CODEC_ID_ADPCM_IMA_WAV:
2441 case AV_CODEC_ID_ILBC:
2442 case AV_CODEC_ID_MACE3:
2443 case AV_CODEC_ID_MACE6:
2444 case AV_CODEC_ID_QDM2:
2445 st->codecpar->block_align = sc->bytes_per_frame;
2446 break;
2447 case AV_CODEC_ID_ALAC:
2448 if (st->codecpar->extradata_size == 36) {
2449 st->codecpar->channels = AV_RB8 (st->codecpar->extradata + 21);
2450 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2451 }
2452 break;
2453 case AV_CODEC_ID_AC3:
2454 case AV_CODEC_ID_EAC3:
2455 case AV_CODEC_ID_MPEG1VIDEO:
2456 case AV_CODEC_ID_VC1:
2457 case AV_CODEC_ID_VP8:
2458 case AV_CODEC_ID_VP9:
2459 st->need_parsing = AVSTREAM_PARSE_FULL;
2460 break;
2461 case AV_CODEC_ID_AV1:
2462 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2463 break;
2464 default:
2465 break;
2466 }
2467 return 0;
2468 }
2469
mov_skip_multiple_stsd(MOVContext * c,AVIOContext * pb,int codec_tag,int format,int64_t size)2470 static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
2471 int codec_tag, int format,
2472 int64_t size)
2473 {
2474 int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2475
2476 if (codec_tag &&
2477 (codec_tag != format &&
2478 // AVID 1:1 samples with differing data format and codec tag exist
2479 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
2480 // prores is allowed to have differing data format and codec tag
2481 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
2482 // so is dv (sigh)
2483 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
2484 (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id
2485 : codec_tag != MKTAG('j','p','e','g')))) {
2486 /* Multiple fourcc, we skip JPEG. This is not correct, we should
2487 * export it as a separate AVStream but this needs a few changes
2488 * in the MOV demuxer, patch welcome. */
2489
2490 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
2491 avio_skip(pb, size);
2492 return 1;
2493 }
2494
2495 return 0;
2496 }
2497
ff_mov_read_stsd_entries(MOVContext * c,AVIOContext * pb,int entries)2498 int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
2499 {
2500 AVStream *st;
2501 MOVStreamContext *sc;
2502 int pseudo_stream_id;
2503
2504 av_assert0 (c->fc->nb_streams >= 1);
2505 st = c->fc->streams[c->fc->nb_streams-1];
2506 sc = st->priv_data;
2507
2508 for (pseudo_stream_id = 0;
2509 pseudo_stream_id < entries && !pb->eof_reached;
2510 pseudo_stream_id++) {
2511 //Parsing Sample description table
2512 enum AVCodecID id;
2513 int ret, dref_id = 1;
2514 MOVAtom a = { AV_RL32("stsd") };
2515 int64_t start_pos = avio_tell(pb);
2516 int64_t size = avio_rb32(pb); /* size */
2517 uint32_t format = avio_rl32(pb); /* data format */
2518
2519 if (size >= 16) {
2520 avio_rb32(pb); /* reserved */
2521 avio_rb16(pb); /* reserved */
2522 dref_id = avio_rb16(pb);
2523 } else if (size <= 7) {
2524 av_log(c->fc, AV_LOG_ERROR,
2525 "invalid size %"PRId64" in stsd\n", size);
2526 return AVERROR_INVALIDDATA;
2527 }
2528
2529 if (mov_skip_multiple_stsd(c, pb, st->codecpar->codec_tag, format,
2530 size - (avio_tell(pb) - start_pos))) {
2531 sc->stsd_count++;
2532 continue;
2533 }
2534
2535 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
2536 sc->dref_id= dref_id;
2537 sc->format = format;
2538
2539 id = mov_codec_id(st, format);
2540
2541 av_log(c->fc, AV_LOG_TRACE,
2542 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
2543 av_fourcc2str(format), st->codecpar->codec_type);
2544
2545 st->codecpar->codec_id = id;
2546 if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) {
2547 mov_parse_stsd_video(c, pb, st, sc);
2548 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
2549 mov_parse_stsd_audio(c, pb, st, sc);
2550 if (st->codecpar->sample_rate < 0) {
2551 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
2552 return AVERROR_INVALIDDATA;
2553 }
2554 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
2555 mov_parse_stsd_subtitle(c, pb, st, sc,
2556 size - (avio_tell(pb) - start_pos));
2557 } else {
2558 ret = mov_parse_stsd_data(c, pb, st, sc,
2559 size - (avio_tell(pb) - start_pos));
2560 if (ret < 0)
2561 return ret;
2562 }
2563 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
2564 a.size = size - (avio_tell(pb) - start_pos);
2565 if (a.size > 8) {
2566 if ((ret = mov_read_default(c, pb, a)) < 0)
2567 return ret;
2568 } else if (a.size > 0)
2569 avio_skip(pb, a.size);
2570
2571 if (sc->extradata && st->codecpar->extradata) {
2572 int extra_size = st->codecpar->extradata_size;
2573
2574 /* Move the current stream extradata to the stream context one. */
2575 sc->extradata_size[pseudo_stream_id] = extra_size;
2576 sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
2577 st->codecpar->extradata = NULL;
2578 st->codecpar->extradata_size = 0;
2579 }
2580 sc->stsd_count++;
2581 }
2582
2583 if (pb->eof_reached) {
2584 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
2585 return AVERROR_EOF;
2586 }
2587
2588 return 0;
2589 }
2590
mov_read_stsd(MOVContext * c,AVIOContext * pb,MOVAtom atom)2591 static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2592 {
2593 AVStream *st;
2594 MOVStreamContext *sc;
2595 int ret, entries;
2596
2597 if (c->fc->nb_streams < 1)
2598 return 0;
2599 st = c->fc->streams[c->fc->nb_streams - 1];
2600 sc = st->priv_data;
2601
2602 sc->stsd_version = avio_r8(pb);
2603 avio_rb24(pb); /* flags */
2604 entries = avio_rb32(pb);
2605
2606 /* Each entry contains a size (4 bytes) and format (4 bytes). */
2607 if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
2608 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
2609 return AVERROR_INVALIDDATA;
2610 }
2611
2612 if (sc->extradata) {
2613 av_log(c->fc, AV_LOG_ERROR,
2614 "Duplicate stsd found in this track.\n");
2615 return AVERROR_INVALIDDATA;
2616 }
2617
2618 /* Prepare space for hosting multiple extradata. */
2619 sc->extradata = av_mallocz_array(entries, sizeof(*sc->extradata));
2620 if (!sc->extradata)
2621 return AVERROR(ENOMEM);
2622
2623 sc->extradata_size = av_mallocz_array(entries, sizeof(*sc->extradata_size));
2624 if (!sc->extradata_size) {
2625 ret = AVERROR(ENOMEM);
2626 goto fail;
2627 }
2628
2629 ret = ff_mov_read_stsd_entries(c, pb, entries);
2630 if (ret < 0)
2631 goto fail;
2632
2633 /* Restore back the primary extradata. */
2634 av_freep(&st->codecpar->extradata);
2635 st->codecpar->extradata_size = sc->extradata_size[0];
2636 if (sc->extradata_size[0]) {
2637 st->codecpar->extradata = av_mallocz(sc->extradata_size[0] + AV_INPUT_BUFFER_PADDING_SIZE);
2638 if (!st->codecpar->extradata)
2639 return AVERROR(ENOMEM);
2640 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
2641 }
2642
2643 return mov_finalize_stsd_codec(c, pb, st, sc);
2644 fail:
2645 if (sc->extradata) {
2646 int j;
2647 for (j = 0; j < sc->stsd_count; j++)
2648 av_freep(&sc->extradata[j]);
2649 }
2650
2651 av_freep(&sc->extradata);
2652 av_freep(&sc->extradata_size);
2653 return ret;
2654 }
2655
mov_read_stsc(MOVContext * c,AVIOContext * pb,MOVAtom atom)2656 static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2657 {
2658 AVStream *st;
2659 MOVStreamContext *sc;
2660 unsigned int i, entries;
2661
2662 if (c->fc->nb_streams < 1)
2663 return 0;
2664 st = c->fc->streams[c->fc->nb_streams-1];
2665 sc = st->priv_data;
2666
2667 avio_r8(pb); /* version */
2668 avio_rb24(pb); /* flags */
2669
2670 entries = avio_rb32(pb);
2671 if ((uint64_t)entries * 12 + 4 > atom.size)
2672 return AVERROR_INVALIDDATA;
2673
2674 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
2675
2676 if (!entries)
2677 return 0;
2678 if (sc->stsc_data) {
2679 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n");
2680 return 0;
2681 }
2682 av_free(sc->stsc_data);
2683 sc->stsc_count = 0;
2684 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
2685 if (!sc->stsc_data)
2686 return AVERROR(ENOMEM);
2687
2688 for (i = 0; i < entries && !pb->eof_reached; i++) {
2689 sc->stsc_data[i].first = avio_rb32(pb);
2690 sc->stsc_data[i].count = avio_rb32(pb);
2691 sc->stsc_data[i].id = avio_rb32(pb);
2692 }
2693
2694 sc->stsc_count = i;
2695 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
2696 int64_t first_min = i + 1;
2697 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
2698 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
2699 sc->stsc_data[i].first < first_min ||
2700 sc->stsc_data[i].count < 1 ||
2701 sc->stsc_data[i].id < 1) {
2702 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);
2703 if (i+1 >= sc->stsc_count) {
2704 if (sc->stsc_data[i].count == 0 && i > 0) {
2705 sc->stsc_count --;
2706 continue;
2707 }
2708 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
2709 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
2710 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
2711 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
2712 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
2713 continue;
2714 }
2715 av_assert0(sc->stsc_data[i+1].first >= 2);
2716 // We replace this entry by the next valid
2717 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
2718 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
2719 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
2720 }
2721 }
2722
2723 if (pb->eof_reached) {
2724 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
2725 return AVERROR_EOF;
2726 }
2727
2728 return 0;
2729 }
2730
mov_stsc_index_valid(unsigned int index,unsigned int count)2731 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
2732 {
2733 return index < count - 1;
2734 }
2735
2736 /* Compute the samples value for the stsc entry at the given index. */
mov_get_stsc_samples(MOVStreamContext * sc,unsigned int index)2737 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
2738 {
2739 int chunk_count;
2740
2741 if (mov_stsc_index_valid(index, sc->stsc_count))
2742 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
2743 else {
2744 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
2745 av_assert0(sc->stsc_data[index].first <= sc->chunk_count);
2746 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
2747 }
2748
2749 return sc->stsc_data[index].count * (int64_t)chunk_count;
2750 }
2751
mov_read_stps(MOVContext * c,AVIOContext * pb,MOVAtom atom)2752 static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2753 {
2754 AVStream *st;
2755 MOVStreamContext *sc;
2756 unsigned i, entries;
2757
2758 if (c->fc->nb_streams < 1)
2759 return 0;
2760 st = c->fc->streams[c->fc->nb_streams-1];
2761 sc = st->priv_data;
2762
2763 avio_rb32(pb); // version + flags
2764
2765 entries = avio_rb32(pb);
2766 if (sc->stps_data)
2767 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
2768 av_free(sc->stps_data);
2769 sc->stps_count = 0;
2770 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
2771 if (!sc->stps_data)
2772 return AVERROR(ENOMEM);
2773
2774 for (i = 0; i < entries && !pb->eof_reached; i++) {
2775 sc->stps_data[i] = avio_rb32(pb);
2776 }
2777
2778 sc->stps_count = i;
2779
2780 if (pb->eof_reached) {
2781 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
2782 return AVERROR_EOF;
2783 }
2784
2785 return 0;
2786 }
2787
mov_read_stss(MOVContext * c,AVIOContext * pb,MOVAtom atom)2788 static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2789 {
2790 AVStream *st;
2791 MOVStreamContext *sc;
2792 unsigned int i, entries;
2793
2794 if (c->fc->nb_streams < 1)
2795 return 0;
2796 st = c->fc->streams[c->fc->nb_streams-1];
2797 sc = st->priv_data;
2798
2799 avio_r8(pb); /* version */
2800 avio_rb24(pb); /* flags */
2801
2802 entries = avio_rb32(pb);
2803
2804 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
2805
2806 if (!entries) {
2807 sc->keyframe_absent = 1;
2808 if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
2809 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2810 return 0;
2811 }
2812 if (sc->keyframes)
2813 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
2814 if (entries >= UINT_MAX / sizeof(int))
2815 return AVERROR_INVALIDDATA;
2816 av_freep(&sc->keyframes);
2817 sc->keyframe_count = 0;
2818 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
2819 if (!sc->keyframes)
2820 return AVERROR(ENOMEM);
2821
2822 for (i = 0; i < entries && !pb->eof_reached; i++) {
2823 sc->keyframes[i] = avio_rb32(pb);
2824 }
2825
2826 sc->keyframe_count = i;
2827
2828 if (pb->eof_reached) {
2829 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
2830 return AVERROR_EOF;
2831 }
2832
2833 return 0;
2834 }
2835
mov_read_stsz(MOVContext * c,AVIOContext * pb,MOVAtom atom)2836 static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2837 {
2838 AVStream *st;
2839 MOVStreamContext *sc;
2840 unsigned int i, entries, sample_size, field_size, num_bytes;
2841 GetBitContext gb;
2842 unsigned char* buf;
2843 int ret;
2844
2845 if (c->fc->nb_streams < 1)
2846 return 0;
2847 st = c->fc->streams[c->fc->nb_streams-1];
2848 sc = st->priv_data;
2849
2850 avio_r8(pb); /* version */
2851 avio_rb24(pb); /* flags */
2852
2853 if (atom.type == MKTAG('s','t','s','z')) {
2854 sample_size = avio_rb32(pb);
2855 if (!sc->sample_size) /* do not overwrite value computed in stsd */
2856 sc->sample_size = sample_size;
2857 sc->stsz_sample_size = sample_size;
2858 field_size = 32;
2859 } else {
2860 sample_size = 0;
2861 avio_rb24(pb); /* reserved */
2862 field_size = avio_r8(pb);
2863 }
2864 entries = avio_rb32(pb);
2865
2866 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
2867
2868 sc->sample_count = entries;
2869 if (sample_size)
2870 return 0;
2871
2872 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
2873 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
2874 return AVERROR_INVALIDDATA;
2875 }
2876
2877 if (!entries)
2878 return 0;
2879 if (entries >= (UINT_MAX - 4) / field_size)
2880 return AVERROR_INVALIDDATA;
2881 if (sc->sample_sizes)
2882 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
2883 av_free(sc->sample_sizes);
2884 sc->sample_count = 0;
2885 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
2886 if (!sc->sample_sizes)
2887 return AVERROR(ENOMEM);
2888
2889 num_bytes = (entries*field_size+4)>>3;
2890
2891 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
2892 if (!buf) {
2893 av_freep(&sc->sample_sizes);
2894 return AVERROR(ENOMEM);
2895 }
2896
2897 ret = ffio_read_size(pb, buf, num_bytes);
2898 if (ret < 0) {
2899 av_freep(&sc->sample_sizes);
2900 av_free(buf);
2901 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
2902 return 0;
2903 }
2904
2905 init_get_bits(&gb, buf, 8*num_bytes);
2906
2907 for (i = 0; i < entries && !pb->eof_reached; i++) {
2908 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
2909 if (sc->sample_sizes[i] < 0) {
2910 av_free(buf);
2911 av_log(c->fc, AV_LOG_ERROR, "Invalid sample size %d\n", sc->sample_sizes[i]);
2912 return AVERROR_INVALIDDATA;
2913 }
2914 sc->data_size += sc->sample_sizes[i];
2915 }
2916
2917 sc->sample_count = i;
2918
2919 av_free(buf);
2920
2921 if (pb->eof_reached) {
2922 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSZ atom\n");
2923 return AVERROR_EOF;
2924 }
2925
2926 return 0;
2927 }
2928
mov_read_stts(MOVContext * c,AVIOContext * pb,MOVAtom atom)2929 static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2930 {
2931 AVStream *st;
2932 MOVStreamContext *sc;
2933 unsigned int i, entries, alloc_size = 0;
2934 int64_t duration = 0;
2935 int64_t total_sample_count = 0;
2936
2937 if (c->fc->nb_streams < 1)
2938 return 0;
2939 st = c->fc->streams[c->fc->nb_streams-1];
2940 sc = st->priv_data;
2941
2942 avio_r8(pb); /* version */
2943 avio_rb24(pb); /* flags */
2944 entries = avio_rb32(pb);
2945
2946 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
2947 c->fc->nb_streams-1, entries);
2948
2949 if (sc->stts_data)
2950 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
2951 av_freep(&sc->stts_data);
2952 sc->stts_count = 0;
2953 if (entries >= INT_MAX / sizeof(*sc->stts_data))
2954 return AVERROR(ENOMEM);
2955
2956 for (i = 0; i < entries && !pb->eof_reached; i++) {
2957 int sample_duration;
2958 unsigned int sample_count;
2959 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
2960 MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
2961 min_entries * sizeof(*sc->stts_data));
2962 if (!stts_data) {
2963 av_freep(&sc->stts_data);
2964 sc->stts_count = 0;
2965 return AVERROR(ENOMEM);
2966 }
2967 sc->stts_count = min_entries;
2968 sc->stts_data = stts_data;
2969
2970 sample_count = avio_rb32(pb);
2971 sample_duration = avio_rb32(pb);
2972
2973 sc->stts_data[i].count= sample_count;
2974 sc->stts_data[i].duration= sample_duration;
2975
2976 av_log(c->fc, AV_LOG_TRACE, "sample_count=%d, sample_duration=%d\n",
2977 sample_count, sample_duration);
2978
2979 duration+=(int64_t)sample_duration*(uint64_t)sample_count;
2980 total_sample_count+=sample_count;
2981 }
2982
2983 sc->stts_count = i;
2984
2985 if (duration > 0 &&
2986 duration <= INT64_MAX - sc->duration_for_fps &&
2987 total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
2988 sc->duration_for_fps += duration;
2989 sc->nb_frames_for_fps += total_sample_count;
2990 }
2991
2992 if (pb->eof_reached) {
2993 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
2994 return AVERROR_EOF;
2995 }
2996
2997 st->nb_frames= total_sample_count;
2998 if (duration)
2999 st->duration= FFMIN(st->duration, duration);
3000 sc->track_end = duration;
3001 return 0;
3002 }
3003
mov_read_sdtp(MOVContext * c,AVIOContext * pb,MOVAtom atom)3004 static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3005 {
3006 AVStream *st;
3007 MOVStreamContext *sc;
3008 int64_t i, entries;
3009
3010 if (c->fc->nb_streams < 1)
3011 return 0;
3012 st = c->fc->streams[c->fc->nb_streams - 1];
3013 sc = st->priv_data;
3014
3015 avio_r8(pb); /* version */
3016 avio_rb24(pb); /* flags */
3017 entries = atom.size - 4;
3018
3019 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3020 c->fc->nb_streams - 1, entries);
3021
3022 if (sc->sdtp_data)
3023 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3024 av_freep(&sc->sdtp_data);
3025 sc->sdtp_count = 0;
3026
3027 sc->sdtp_data = av_malloc(entries);
3028 if (!sc->sdtp_data)
3029 return AVERROR(ENOMEM);
3030
3031 for (i = 0; i < entries && !pb->eof_reached; i++)
3032 sc->sdtp_data[i] = avio_r8(pb);
3033 sc->sdtp_count = i;
3034
3035 return 0;
3036 }
3037
mov_update_dts_shift(MOVStreamContext * sc,int duration,void * logctx)3038 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3039 {
3040 if (duration < 0) {
3041 if (duration == INT_MIN) {
3042 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3043 duration++;
3044 }
3045 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3046 }
3047 }
3048
mov_read_ctts(MOVContext * c,AVIOContext * pb,MOVAtom atom)3049 static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3050 {
3051 AVStream *st;
3052 MOVStreamContext *sc;
3053 unsigned int i, entries, ctts_count = 0;
3054
3055 if (c->fc->nb_streams < 1)
3056 return 0;
3057 st = c->fc->streams[c->fc->nb_streams-1];
3058 sc = st->priv_data;
3059
3060 avio_r8(pb); /* version */
3061 avio_rb24(pb); /* flags */
3062 entries = avio_rb32(pb);
3063
3064 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3065
3066 if (!entries)
3067 return 0;
3068 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3069 return AVERROR_INVALIDDATA;
3070 av_freep(&sc->ctts_data);
3071 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3072 if (!sc->ctts_data)
3073 return AVERROR(ENOMEM);
3074
3075 for (i = 0; i < entries && !pb->eof_reached; i++) {
3076 int count = avio_rb32(pb);
3077 int duration = avio_rb32(pb);
3078
3079 if (count <= 0) {
3080 av_log(c->fc, AV_LOG_TRACE,
3081 "ignoring CTTS entry with count=%d duration=%d\n",
3082 count, duration);
3083 continue;
3084 }
3085
3086 add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3087 count, duration);
3088
3089 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3090 count, duration);
3091
3092 if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3093 av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3094 av_freep(&sc->ctts_data);
3095 sc->ctts_count = 0;
3096 return 0;
3097 }
3098
3099 if (i+2<entries)
3100 mov_update_dts_shift(sc, duration, c->fc);
3101 }
3102
3103 sc->ctts_count = ctts_count;
3104
3105 if (pb->eof_reached) {
3106 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3107 return AVERROR_EOF;
3108 }
3109
3110 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3111
3112 return 0;
3113 }
3114
mov_read_sbgp(MOVContext * c,AVIOContext * pb,MOVAtom atom)3115 static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3116 {
3117 AVStream *st;
3118 MOVStreamContext *sc;
3119 unsigned int i, entries;
3120 uint8_t version;
3121 uint32_t grouping_type;
3122
3123 if (c->fc->nb_streams < 1)
3124 return 0;
3125 st = c->fc->streams[c->fc->nb_streams-1];
3126 sc = st->priv_data;
3127
3128 version = avio_r8(pb); /* version */
3129 avio_rb24(pb); /* flags */
3130 grouping_type = avio_rl32(pb);
3131 if (grouping_type != MKTAG( 'r','a','p',' '))
3132 return 0; /* only support 'rap ' grouping */
3133 if (version == 1)
3134 avio_rb32(pb); /* grouping_type_parameter */
3135
3136 entries = avio_rb32(pb);
3137 if (!entries)
3138 return 0;
3139 if (sc->rap_group)
3140 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP atom\n");
3141 av_free(sc->rap_group);
3142 sc->rap_group_count = 0;
3143 sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group));
3144 if (!sc->rap_group)
3145 return AVERROR(ENOMEM);
3146
3147 for (i = 0; i < entries && !pb->eof_reached; i++) {
3148 sc->rap_group[i].count = avio_rb32(pb); /* sample_count */
3149 sc->rap_group[i].index = avio_rb32(pb); /* group_description_index */
3150 }
3151
3152 sc->rap_group_count = i;
3153
3154 if (pb->eof_reached) {
3155 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3156 return AVERROR_EOF;
3157 }
3158
3159 return 0;
3160 }
3161
3162 /**
3163 * Get ith edit list entry (media time, duration).
3164 */
get_edit_list_entry(MOVContext * mov,const MOVStreamContext * msc,unsigned int edit_list_index,int64_t * edit_list_media_time,int64_t * edit_list_duration,int64_t global_timescale)3165 static int get_edit_list_entry(MOVContext *mov,
3166 const MOVStreamContext *msc,
3167 unsigned int edit_list_index,
3168 int64_t *edit_list_media_time,
3169 int64_t *edit_list_duration,
3170 int64_t global_timescale)
3171 {
3172 if (edit_list_index == msc->elst_count) {
3173 return 0;
3174 }
3175 *edit_list_media_time = msc->elst_data[edit_list_index].time;
3176 *edit_list_duration = msc->elst_data[edit_list_index].duration;
3177
3178 /* duration is in global timescale units;convert to msc timescale */
3179 if (global_timescale == 0) {
3180 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3181 return 0;
3182 }
3183 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3184 global_timescale);
3185 return 1;
3186 }
3187
3188 /**
3189 * Find the closest previous frame to the timestamp_pts, in e_old index
3190 * entries. Searching for just any frame / just key frames can be controlled by
3191 * last argument 'flag'.
3192 * Note that if ctts_data is not NULL, we will always search for a key frame
3193 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3194 * return the first frame of the video.
3195 *
3196 * Here the timestamp_pts is considered to be a presentation timestamp and
3197 * the timestamp of index entries are considered to be decoding timestamps.
3198 *
3199 * Returns 0 if successful in finding a frame, else returns -1.
3200 * Places the found index corresponding output arg.
3201 *
3202 * If ctts_old is not NULL, then refines the searched entry by searching
3203 * backwards from the found timestamp, to find the frame with correct PTS.
3204 *
3205 * Places the found ctts_index and ctts_sample in corresponding output args.
3206 */
find_prev_closest_index(AVStream * st,AVIndexEntry * e_old,int nb_old,MOVStts * ctts_data,int64_t ctts_count,int64_t timestamp_pts,int flag,int64_t * index,int64_t * ctts_index,int64_t * ctts_sample)3207 static int find_prev_closest_index(AVStream *st,
3208 AVIndexEntry *e_old,
3209 int nb_old,
3210 MOVStts* ctts_data,
3211 int64_t ctts_count,
3212 int64_t timestamp_pts,
3213 int flag,
3214 int64_t* index,
3215 int64_t* ctts_index,
3216 int64_t* ctts_sample)
3217 {
3218 MOVStreamContext *msc = st->priv_data;
3219 AVIndexEntry *e_keep = st->index_entries;
3220 int nb_keep = st->nb_index_entries;
3221 int64_t i = 0;
3222 int64_t index_ctts_count;
3223
3224 av_assert0(index);
3225
3226 // If dts_shift > 0, then all the index timestamps will have to be offset by
3227 // at least dts_shift amount to obtain PTS.
3228 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3229 if (msc->dts_shift > 0) {
3230 timestamp_pts -= msc->dts_shift;
3231 }
3232
3233 st->index_entries = e_old;
3234 st->nb_index_entries = nb_old;
3235 *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3236
3237 // Keep going backwards in the index entries until the timestamp is the same.
3238 if (*index >= 0) {
3239 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3240 i--) {
3241 if ((flag & AVSEEK_FLAG_ANY) ||
3242 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3243 *index = i - 1;
3244 }
3245 }
3246 }
3247
3248 // If we have CTTS then refine the search, by searching backwards over PTS
3249 // computed by adding corresponding CTTS durations to index timestamps.
3250 if (ctts_data && *index >= 0) {
3251 av_assert0(ctts_index);
3252 av_assert0(ctts_sample);
3253 // Find out the ctts_index for the found frame.
3254 *ctts_index = 0;
3255 *ctts_sample = 0;
3256 for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3257 if (*ctts_index < ctts_count) {
3258 (*ctts_sample)++;
3259 if (ctts_data[*ctts_index].count == *ctts_sample) {
3260 (*ctts_index)++;
3261 *ctts_sample = 0;
3262 }
3263 }
3264 }
3265
3266 while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3267 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3268 // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3269 // compensated by dts_shift above.
3270 if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3271 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3272 break;
3273 }
3274
3275 (*index)--;
3276 if (*ctts_sample == 0) {
3277 (*ctts_index)--;
3278 if (*ctts_index >= 0)
3279 *ctts_sample = ctts_data[*ctts_index].count - 1;
3280 } else {
3281 (*ctts_sample)--;
3282 }
3283 }
3284 }
3285
3286 /* restore AVStream state*/
3287 st->index_entries = e_keep;
3288 st->nb_index_entries = nb_keep;
3289 return *index >= 0 ? 0 : -1;
3290 }
3291
3292 /**
3293 * Add index entry with the given values, to the end of st->index_entries.
3294 * Returns the new size st->index_entries if successful, else returns -1.
3295 *
3296 * This function is similar to ff_add_index_entry in libavformat/utils.c
3297 * except that here we are always unconditionally adding an index entry to
3298 * the end, instead of searching the entries list and skipping the add if
3299 * there is an existing entry with the same timestamp.
3300 * This is needed because the mov_fix_index calls this func with the same
3301 * unincremented timestamp for successive discarded frames.
3302 */
add_index_entry(AVStream * st,int64_t pos,int64_t timestamp,int size,int distance,int flags)3303 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3304 int size, int distance, int flags)
3305 {
3306 AVIndexEntry *entries, *ie;
3307 int64_t index = -1;
3308 const size_t min_size_needed = (st->nb_index_entries + 1) * sizeof(AVIndexEntry);
3309
3310 // Double the allocation each time, to lower memory fragmentation.
3311 // Another difference from ff_add_index_entry function.
3312 const size_t requested_size =
3313 min_size_needed > st->index_entries_allocated_size ?
3314 FFMAX(min_size_needed, 2 * st->index_entries_allocated_size) :
3315 min_size_needed;
3316
3317 if (st->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
3318 return -1;
3319
3320 entries = av_fast_realloc(st->index_entries,
3321 &st->index_entries_allocated_size,
3322 requested_size);
3323 if (!entries)
3324 return -1;
3325
3326 st->index_entries= entries;
3327
3328 index= st->nb_index_entries++;
3329 ie= &entries[index];
3330
3331 ie->pos = pos;
3332 ie->timestamp = timestamp;
3333 ie->min_distance= distance;
3334 ie->size= size;
3335 ie->flags = flags;
3336 return index;
3337 }
3338
3339 /**
3340 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3341 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3342 */
fix_index_entry_timestamps(AVStream * st,int end_index,int64_t end_ts,int64_t * frame_duration_buffer,int frame_duration_buffer_size)3343 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3344 int64_t* frame_duration_buffer,
3345 int frame_duration_buffer_size) {
3346 int i = 0;
3347 av_assert0(end_index >= 0 && end_index <= st->nb_index_entries);
3348 for (i = 0; i < frame_duration_buffer_size; i++) {
3349 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3350 st->index_entries[end_index - 1 - i].timestamp = end_ts;
3351 }
3352 }
3353
3354 /**
3355 * Append a new ctts entry to ctts_data.
3356 * Returns the new ctts_count if successful, else returns -1.
3357 */
add_ctts_entry(MOVStts ** ctts_data,unsigned int * ctts_count,unsigned int * allocated_size,int count,int duration)3358 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3359 int count, int duration)
3360 {
3361 MOVStts *ctts_buf_new;
3362 const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVStts);
3363 const size_t requested_size =
3364 min_size_needed > *allocated_size ?
3365 FFMAX(min_size_needed, 2 * (*allocated_size)) :
3366 min_size_needed;
3367
3368 if ((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
3369 return -1;
3370
3371 ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3372
3373 if (!ctts_buf_new)
3374 return -1;
3375
3376 *ctts_data = ctts_buf_new;
3377
3378 ctts_buf_new[*ctts_count].count = count;
3379 ctts_buf_new[*ctts_count].duration = duration;
3380
3381 *ctts_count = (*ctts_count) + 1;
3382 return *ctts_count;
3383 }
3384
3385 #define MAX_REORDER_DELAY 16
mov_estimate_video_delay(MOVContext * c,AVStream * st)3386 static void mov_estimate_video_delay(MOVContext *c, AVStream* st)
3387 {
3388 MOVStreamContext *msc = st->priv_data;
3389 int ind;
3390 int ctts_ind = 0;
3391 int ctts_sample = 0;
3392 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3393 int buf_start = 0;
3394 int j, r, num_swaps;
3395
3396 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3397 pts_buf[j] = INT64_MIN;
3398
3399 if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3400 st->codecpar->codec_id == AV_CODEC_ID_H264) {
3401 st->codecpar->video_delay = 0;
3402 for (ind = 0; ind < st->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3403 // Point j to the last elem of the buffer and insert the current pts there.
3404 j = buf_start;
3405 buf_start = (buf_start + 1);
3406 if (buf_start == MAX_REORDER_DELAY + 1)
3407 buf_start = 0;
3408
3409 pts_buf[j] = st->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3410
3411 // The timestamps that are already in the sorted buffer, and are greater than the
3412 // current pts, are exactly the timestamps that need to be buffered to output PTS
3413 // in correct sorted order.
3414 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3415 // can be computed as the maximum no. of swaps any particular timestamp needs to
3416 // go through, to keep this buffer in sorted order.
3417 num_swaps = 0;
3418 while (j != buf_start) {
3419 r = j - 1;
3420 if (r < 0) r = MAX_REORDER_DELAY;
3421 if (pts_buf[j] < pts_buf[r]) {
3422 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3423 ++num_swaps;
3424 } else {
3425 break;
3426 }
3427 j = r;
3428 }
3429 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3430
3431 ctts_sample++;
3432 if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3433 ctts_ind++;
3434 ctts_sample = 0;
3435 }
3436 }
3437 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3438 st->codecpar->video_delay, st->index);
3439 }
3440 }
3441
mov_current_sample_inc(MOVStreamContext * sc)3442 static void mov_current_sample_inc(MOVStreamContext *sc)
3443 {
3444 sc->current_sample++;
3445 sc->current_index++;
3446 if (sc->index_ranges &&
3447 sc->current_index >= sc->current_index_range->end &&
3448 sc->current_index_range->end) {
3449 sc->current_index_range++;
3450 sc->current_index = sc->current_index_range->start;
3451 }
3452 }
3453
mov_current_sample_dec(MOVStreamContext * sc)3454 static void mov_current_sample_dec(MOVStreamContext *sc)
3455 {
3456 sc->current_sample--;
3457 sc->current_index--;
3458 if (sc->index_ranges &&
3459 sc->current_index < sc->current_index_range->start &&
3460 sc->current_index_range > sc->index_ranges) {
3461 sc->current_index_range--;
3462 sc->current_index = sc->current_index_range->end - 1;
3463 }
3464 }
3465
mov_current_sample_set(MOVStreamContext * sc,int current_sample)3466 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3467 {
3468 int64_t range_size;
3469
3470 sc->current_sample = current_sample;
3471 sc->current_index = current_sample;
3472 if (!sc->index_ranges) {
3473 return;
3474 }
3475
3476 for (sc->current_index_range = sc->index_ranges;
3477 sc->current_index_range->end;
3478 sc->current_index_range++) {
3479 range_size = sc->current_index_range->end - sc->current_index_range->start;
3480 if (range_size > current_sample) {
3481 sc->current_index = sc->current_index_range->start + current_sample;
3482 break;
3483 }
3484 current_sample -= range_size;
3485 }
3486 }
3487
3488 /**
3489 * Fix st->index_entries, so that it contains only the entries (and the entries
3490 * which are needed to decode them) that fall in the edit list time ranges.
3491 * Also fixes the timestamps of the index entries to match the timeline
3492 * specified the edit lists.
3493 */
mov_fix_index(MOVContext * mov,AVStream * st)3494 static void mov_fix_index(MOVContext *mov, AVStream *st)
3495 {
3496 MOVStreamContext *msc = st->priv_data;
3497 AVIndexEntry *e_old = st->index_entries;
3498 int nb_old = st->nb_index_entries;
3499 const AVIndexEntry *e_old_end = e_old + nb_old;
3500 const AVIndexEntry *current = NULL;
3501 MOVStts *ctts_data_old = msc->ctts_data;
3502 int64_t ctts_index_old = 0;
3503 int64_t ctts_sample_old = 0;
3504 int64_t ctts_count_old = msc->ctts_count;
3505 int64_t edit_list_media_time = 0;
3506 int64_t edit_list_duration = 0;
3507 int64_t frame_duration = 0;
3508 int64_t edit_list_dts_counter = 0;
3509 int64_t edit_list_dts_entry_end = 0;
3510 int64_t edit_list_start_ctts_sample = 0;
3511 int64_t curr_cts;
3512 int64_t curr_ctts = 0;
3513 int64_t empty_edits_sum_duration = 0;
3514 int64_t edit_list_index = 0;
3515 int64_t index;
3516 int flags;
3517 int64_t start_dts = 0;
3518 int64_t edit_list_start_encountered = 0;
3519 int64_t search_timestamp = 0;
3520 int64_t* frame_duration_buffer = NULL;
3521 int num_discarded_begin = 0;
3522 int first_non_zero_audio_edit = -1;
3523 int packet_skip_samples = 0;
3524 MOVIndexRange *current_index_range;
3525 int i;
3526 int found_keyframe_after_edit = 0;
3527 int found_non_empty_edit = 0;
3528
3529 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
3530 return;
3531 }
3532
3533 // allocate the index ranges array
3534 msc->index_ranges = av_malloc((msc->elst_count + 1) * sizeof(msc->index_ranges[0]));
3535 if (!msc->index_ranges) {
3536 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
3537 return;
3538 }
3539 msc->current_index_range = msc->index_ranges;
3540 current_index_range = msc->index_ranges - 1;
3541
3542 // Clean AVStream from traces of old index
3543 st->index_entries = NULL;
3544 st->index_entries_allocated_size = 0;
3545 st->nb_index_entries = 0;
3546
3547 // Clean ctts fields of MOVStreamContext
3548 msc->ctts_data = NULL;
3549 msc->ctts_count = 0;
3550 msc->ctts_index = 0;
3551 msc->ctts_sample = 0;
3552 msc->ctts_allocated_size = 0;
3553
3554 // Reinitialize min_corrected_pts so that it can be computed again.
3555 msc->min_corrected_pts = -1;
3556
3557 // If the dts_shift is positive (in case of negative ctts values in mov),
3558 // then negate the DTS by dts_shift
3559 if (msc->dts_shift > 0) {
3560 edit_list_dts_entry_end -= msc->dts_shift;
3561 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
3562 }
3563
3564 start_dts = edit_list_dts_entry_end;
3565
3566 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
3567 &edit_list_duration, mov->time_scale)) {
3568 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
3569 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
3570 edit_list_index++;
3571 edit_list_dts_counter = edit_list_dts_entry_end;
3572 edit_list_dts_entry_end += edit_list_duration;
3573 num_discarded_begin = 0;
3574 if (!found_non_empty_edit && edit_list_media_time == -1) {
3575 empty_edits_sum_duration += edit_list_duration;
3576 continue;
3577 }
3578 found_non_empty_edit = 1;
3579
3580 // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
3581 // according to the edit list below.
3582 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3583 if (first_non_zero_audio_edit < 0) {
3584 first_non_zero_audio_edit = 1;
3585 } else {
3586 first_non_zero_audio_edit = 0;
3587 }
3588
3589 if (first_non_zero_audio_edit > 0)
3590 st->internal->skip_samples = msc->start_pad = 0;
3591 }
3592
3593 // While reordering frame index according to edit list we must handle properly
3594 // the scenario when edit list entry starts from none key frame.
3595 // We find closest previous key frame and preserve it and consequent frames in index.
3596 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
3597 search_timestamp = edit_list_media_time;
3598 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3599 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
3600 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
3601 // edit_list_media_time to cover the decoder delay.
3602 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
3603 }
3604
3605 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
3606 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3607 av_log(mov->fc, AV_LOG_WARNING,
3608 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
3609 st->index, edit_list_index, search_timestamp);
3610 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
3611 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3612 av_log(mov->fc, AV_LOG_WARNING,
3613 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
3614 st->index, edit_list_index, search_timestamp);
3615 index = 0;
3616 ctts_index_old = 0;
3617 ctts_sample_old = 0;
3618 }
3619 }
3620 current = e_old + index;
3621 edit_list_start_ctts_sample = ctts_sample_old;
3622
3623 // Iterate over index and arrange it according to edit list
3624 edit_list_start_encountered = 0;
3625 found_keyframe_after_edit = 0;
3626 for (; current < e_old_end; current++, index++) {
3627 // check if frame outside edit list mark it for discard
3628 frame_duration = (current + 1 < e_old_end) ?
3629 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
3630
3631 flags = current->flags;
3632
3633 // frames (pts) before or after edit list
3634 curr_cts = current->timestamp + msc->dts_shift;
3635 curr_ctts = 0;
3636
3637 if (ctts_data_old && ctts_index_old < ctts_count_old) {
3638 curr_ctts = ctts_data_old[ctts_index_old].duration;
3639 av_log(mov->fc, AV_LOG_DEBUG, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
3640 curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
3641 curr_cts += curr_ctts;
3642 ctts_sample_old++;
3643 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
3644 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3645 &msc->ctts_allocated_size,
3646 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3647 ctts_data_old[ctts_index_old].duration) == -1) {
3648 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3649 ctts_index_old,
3650 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3651 ctts_data_old[ctts_index_old].duration);
3652 break;
3653 }
3654 ctts_index_old++;
3655 ctts_sample_old = 0;
3656 edit_list_start_ctts_sample = 0;
3657 }
3658 }
3659
3660 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
3661 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
3662 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
3663 first_non_zero_audio_edit > 0) {
3664 packet_skip_samples = edit_list_media_time - curr_cts;
3665 st->internal->skip_samples += packet_skip_samples;
3666
3667 // Shift the index entry timestamp by packet_skip_samples to be correct.
3668 edit_list_dts_counter -= packet_skip_samples;
3669 if (edit_list_start_encountered == 0) {
3670 edit_list_start_encountered = 1;
3671 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
3672 // discarded packets.
3673 if (frame_duration_buffer) {
3674 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3675 frame_duration_buffer, num_discarded_begin);
3676 av_freep(&frame_duration_buffer);
3677 }
3678 }
3679
3680 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
3681 } else {
3682 flags |= AVINDEX_DISCARD_FRAME;
3683 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
3684
3685 if (edit_list_start_encountered == 0) {
3686 num_discarded_begin++;
3687 frame_duration_buffer = av_realloc(frame_duration_buffer,
3688 num_discarded_begin * sizeof(int64_t));
3689 if (!frame_duration_buffer) {
3690 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
3691 break;
3692 }
3693 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
3694
3695 // Increment skip_samples for the first non-zero audio edit list
3696 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3697 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
3698 st->internal->skip_samples += frame_duration;
3699 }
3700 }
3701 }
3702 } else {
3703 if (msc->min_corrected_pts < 0) {
3704 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
3705 } else {
3706 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
3707 }
3708 if (edit_list_start_encountered == 0) {
3709 edit_list_start_encountered = 1;
3710 // Make timestamps strictly monotonically increasing by rewriting timestamps for
3711 // discarded packets.
3712 if (frame_duration_buffer) {
3713 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3714 frame_duration_buffer, num_discarded_begin);
3715 av_freep(&frame_duration_buffer);
3716 }
3717 }
3718 }
3719
3720 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
3721 current->min_distance, flags) == -1) {
3722 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
3723 break;
3724 }
3725
3726 // Update the index ranges array
3727 if (current_index_range < msc->index_ranges || index != current_index_range->end) {
3728 current_index_range++;
3729 current_index_range->start = index;
3730 }
3731 current_index_range->end = index + 1;
3732
3733 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
3734 if (edit_list_start_encountered > 0) {
3735 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
3736 }
3737
3738 // Break when found first key frame after edit entry completion
3739 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
3740 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
3741 if (ctts_data_old) {
3742 // If we have CTTS and this is the first keyframe after edit elist,
3743 // wait for one more, because there might be trailing B-frames after this I-frame
3744 // that do belong to the edit.
3745 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
3746 found_keyframe_after_edit = 1;
3747 continue;
3748 }
3749 if (ctts_sample_old != 0) {
3750 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3751 &msc->ctts_allocated_size,
3752 ctts_sample_old - edit_list_start_ctts_sample,
3753 ctts_data_old[ctts_index_old].duration) == -1) {
3754 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3755 ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
3756 ctts_data_old[ctts_index_old].duration);
3757 break;
3758 }
3759 }
3760 }
3761 break;
3762 }
3763 }
3764 }
3765 // If there are empty edits, then msc->min_corrected_pts might be positive
3766 // intentionally. So we subtract the sum duration of emtpy edits here.
3767 msc->min_corrected_pts -= empty_edits_sum_duration;
3768
3769 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
3770 // dts by that amount to make the first pts zero.
3771 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
3772 if (msc->min_corrected_pts > 0) {
3773 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
3774 for (i = 0; i < st->nb_index_entries; ++i) {
3775 st->index_entries[i].timestamp -= msc->min_corrected_pts;
3776 }
3777 }
3778 }
3779 // Start time should be equal to zero or the duration of any empty edits.
3780 st->start_time = empty_edits_sum_duration;
3781
3782 // Update av stream length, if it ends up shorter than the track's media duration
3783 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
3784 msc->start_pad = st->internal->skip_samples;
3785
3786 // Free the old index and the old CTTS structures
3787 av_free(e_old);
3788 av_free(ctts_data_old);
3789 av_freep(&frame_duration_buffer);
3790
3791 // Null terminate the index ranges array
3792 current_index_range++;
3793 current_index_range->start = 0;
3794 current_index_range->end = 0;
3795 msc->current_index = msc->index_ranges[0].start;
3796 }
3797
mov_build_index(MOVContext * mov,AVStream * st)3798 static void mov_build_index(MOVContext *mov, AVStream *st)
3799 {
3800 MOVStreamContext *sc = st->priv_data;
3801 int64_t current_offset;
3802 int64_t current_dts = 0;
3803 unsigned int stts_index = 0;
3804 unsigned int stsc_index = 0;
3805 unsigned int stss_index = 0;
3806 unsigned int stps_index = 0;
3807 unsigned int i, j;
3808 uint64_t stream_size = 0;
3809 MOVStts *ctts_data_old = sc->ctts_data;
3810 unsigned int ctts_count_old = sc->ctts_count;
3811
3812 if (sc->elst_count) {
3813 int i, edit_start_index = 0, multiple_edits = 0;
3814 int64_t empty_duration = 0; // empty duration of the first edit list entry
3815 int64_t start_time = 0; // start time of the media
3816
3817 for (i = 0; i < sc->elst_count; i++) {
3818 const MOVElst *e = &sc->elst_data[i];
3819 if (i == 0 && e->time == -1) {
3820 /* if empty, the first entry is the start time of the stream
3821 * relative to the presentation itself */
3822 empty_duration = e->duration;
3823 edit_start_index = 1;
3824 } else if (i == edit_start_index && e->time >= 0) {
3825 start_time = e->time;
3826 } else {
3827 multiple_edits = 1;
3828 }
3829 }
3830
3831 if (multiple_edits && !mov->advanced_editlist)
3832 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
3833 "Use -advanced_editlist to correctly decode otherwise "
3834 "a/v desync might occur\n");
3835
3836 /* adjust first dts according to edit list */
3837 if ((empty_duration || start_time) && mov->time_scale > 0) {
3838 if (empty_duration)
3839 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
3840
3841 if (av_sat_sub64(start_time, empty_duration) != start_time - (uint64_t)empty_duration)
3842 av_log(mov->fc, AV_LOG_WARNING, "start_time - empty_duration is not representable\n");
3843
3844 sc->time_offset = start_time - (uint64_t)empty_duration;
3845 sc->min_corrected_pts = start_time;
3846 if (!mov->advanced_editlist)
3847 current_dts = -sc->time_offset;
3848 }
3849
3850 if (!multiple_edits && !mov->advanced_editlist &&
3851 st->codecpar->codec_id == AV_CODEC_ID_AAC && start_time > 0)
3852 sc->start_pad = start_time;
3853 }
3854
3855 /* only use old uncompressed audio chunk demuxing when stts specifies it */
3856 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3857 sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
3858 unsigned int current_sample = 0;
3859 unsigned int stts_sample = 0;
3860 unsigned int sample_size;
3861 unsigned int distance = 0;
3862 unsigned int rap_group_index = 0;
3863 unsigned int rap_group_sample = 0;
3864 int64_t last_dts = 0;
3865 int64_t dts_correction = 0;
3866 int rap_group_present = sc->rap_group_count && sc->rap_group;
3867 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
3868
3869 current_dts -= sc->dts_shift;
3870 last_dts = current_dts;
3871
3872 if (!sc->sample_count || st->nb_index_entries)
3873 return;
3874 if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
3875 return;
3876 if (av_reallocp_array(&st->index_entries,
3877 st->nb_index_entries + sc->sample_count,
3878 sizeof(*st->index_entries)) < 0) {
3879 st->nb_index_entries = 0;
3880 return;
3881 }
3882 st->index_entries_allocated_size = (st->nb_index_entries + sc->sample_count) * sizeof(*st->index_entries);
3883
3884 if (ctts_data_old) {
3885 // Expand ctts entries such that we have a 1-1 mapping with samples
3886 if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
3887 return;
3888 sc->ctts_count = 0;
3889 sc->ctts_allocated_size = 0;
3890 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size,
3891 sc->sample_count * sizeof(*sc->ctts_data));
3892 if (!sc->ctts_data) {
3893 av_free(ctts_data_old);
3894 return;
3895 }
3896
3897 memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
3898
3899 for (i = 0; i < ctts_count_old &&
3900 sc->ctts_count < sc->sample_count; i++)
3901 for (j = 0; j < ctts_data_old[i].count &&
3902 sc->ctts_count < sc->sample_count; j++)
3903 add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
3904 &sc->ctts_allocated_size, 1,
3905 ctts_data_old[i].duration);
3906 av_free(ctts_data_old);
3907 }
3908
3909 for (i = 0; i < sc->chunk_count; i++) {
3910 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
3911 current_offset = sc->chunk_offsets[i];
3912 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3913 i + 1 == sc->stsc_data[stsc_index + 1].first)
3914 stsc_index++;
3915
3916 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
3917 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
3918 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
3919 sc->stsz_sample_size = sc->sample_size;
3920 }
3921 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
3922 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
3923 sc->stsz_sample_size = sc->sample_size;
3924 }
3925
3926 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
3927 int keyframe = 0;
3928 if (current_sample >= sc->sample_count) {
3929 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
3930 return;
3931 }
3932
3933 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
3934 keyframe = 1;
3935 if (stss_index + 1 < sc->keyframe_count)
3936 stss_index++;
3937 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
3938 keyframe = 1;
3939 if (stps_index + 1 < sc->stps_count)
3940 stps_index++;
3941 }
3942 if (rap_group_present && rap_group_index < sc->rap_group_count) {
3943 if (sc->rap_group[rap_group_index].index > 0)
3944 keyframe = 1;
3945 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
3946 rap_group_sample = 0;
3947 rap_group_index++;
3948 }
3949 }
3950 if (sc->keyframe_absent
3951 && !sc->stps_count
3952 && !rap_group_present
3953 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
3954 keyframe = 1;
3955 if (keyframe)
3956 distance = 0;
3957 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
3958 if (sc->pseudo_stream_id == -1 ||
3959 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
3960 AVIndexEntry *e;
3961 if (sample_size > 0x3FFFFFFF) {
3962 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
3963 return;
3964 }
3965 e = &st->index_entries[st->nb_index_entries++];
3966 e->pos = current_offset;
3967 e->timestamp = current_dts;
3968 e->size = sample_size;
3969 e->min_distance = distance;
3970 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
3971 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
3972 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
3973 current_offset, current_dts, sample_size, distance, keyframe);
3974 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries < 100)
3975 ff_rfps_add_frame(mov->fc, st, current_dts);
3976 }
3977
3978 current_offset += sample_size;
3979 stream_size += sample_size;
3980
3981 /* A negative sample duration is invalid based on the spec,
3982 * but some samples need it to correct the DTS. */
3983 if (sc->stts_data[stts_index].duration < 0) {
3984 av_log(mov->fc, AV_LOG_WARNING,
3985 "Invalid SampleDelta %d in STTS, at %d st:%d\n",
3986 sc->stts_data[stts_index].duration, stts_index,
3987 st->index);
3988 dts_correction += sc->stts_data[stts_index].duration - 1;
3989 sc->stts_data[stts_index].duration = 1;
3990 }
3991 current_dts += sc->stts_data[stts_index].duration;
3992 if (!dts_correction || current_dts + dts_correction > last_dts) {
3993 current_dts += dts_correction;
3994 dts_correction = 0;
3995 } else {
3996 /* Avoid creating non-monotonous DTS */
3997 dts_correction += current_dts - last_dts - 1;
3998 current_dts = last_dts + 1;
3999 }
4000 last_dts = current_dts;
4001 distance++;
4002 stts_sample++;
4003 current_sample++;
4004 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
4005 stts_sample = 0;
4006 stts_index++;
4007 }
4008 }
4009 }
4010 if (st->duration > 0)
4011 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
4012 } else {
4013 unsigned chunk_samples, total = 0;
4014
4015 if (!sc->chunk_count)
4016 return;
4017
4018 // compute total chunk count
4019 for (i = 0; i < sc->stsc_count; i++) {
4020 unsigned count, chunk_count;
4021
4022 chunk_samples = sc->stsc_data[i].count;
4023 if (i != sc->stsc_count - 1 &&
4024 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
4025 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
4026 return;
4027 }
4028
4029 if (sc->samples_per_frame >= 160) { // gsm
4030 count = chunk_samples / sc->samples_per_frame;
4031 } else if (sc->samples_per_frame > 1) {
4032 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4033 count = (chunk_samples+samples-1) / samples;
4034 } else {
4035 count = (chunk_samples+1023) / 1024;
4036 }
4037
4038 if (mov_stsc_index_valid(i, sc->stsc_count))
4039 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4040 else
4041 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4042 total += chunk_count * count;
4043 }
4044
4045 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4046 if (total >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
4047 return;
4048 if (av_reallocp_array(&st->index_entries,
4049 st->nb_index_entries + total,
4050 sizeof(*st->index_entries)) < 0) {
4051 st->nb_index_entries = 0;
4052 return;
4053 }
4054 st->index_entries_allocated_size = (st->nb_index_entries + total) * sizeof(*st->index_entries);
4055
4056 // populate index
4057 for (i = 0; i < sc->chunk_count; i++) {
4058 current_offset = sc->chunk_offsets[i];
4059 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4060 i + 1 == sc->stsc_data[stsc_index + 1].first)
4061 stsc_index++;
4062 chunk_samples = sc->stsc_data[stsc_index].count;
4063
4064 while (chunk_samples > 0) {
4065 AVIndexEntry *e;
4066 unsigned size, samples;
4067
4068 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4069 avpriv_request_sample(mov->fc,
4070 "Zero bytes per frame, but %d samples per frame",
4071 sc->samples_per_frame);
4072 return;
4073 }
4074
4075 if (sc->samples_per_frame >= 160) { // gsm
4076 samples = sc->samples_per_frame;
4077 size = sc->bytes_per_frame;
4078 } else {
4079 if (sc->samples_per_frame > 1) {
4080 samples = FFMIN((1024 / sc->samples_per_frame)*
4081 sc->samples_per_frame, chunk_samples);
4082 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
4083 } else {
4084 samples = FFMIN(1024, chunk_samples);
4085 size = samples * sc->sample_size;
4086 }
4087 }
4088
4089 if (st->nb_index_entries >= total) {
4090 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4091 return;
4092 }
4093 if (size > 0x3FFFFFFF) {
4094 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4095 return;
4096 }
4097 e = &st->index_entries[st->nb_index_entries++];
4098 e->pos = current_offset;
4099 e->timestamp = current_dts;
4100 e->size = size;
4101 e->min_distance = 0;
4102 e->flags = AVINDEX_KEYFRAME;
4103 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4104 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4105 size, samples);
4106
4107 current_offset += size;
4108 current_dts += samples;
4109 chunk_samples -= samples;
4110 }
4111 }
4112 }
4113
4114 if (!mov->ignore_editlist && mov->advanced_editlist) {
4115 // Fix index according to edit lists.
4116 mov_fix_index(mov, st);
4117 }
4118
4119 // Update start time of the stream.
4120 if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries > 0) {
4121 st->start_time = st->index_entries[0].timestamp + sc->dts_shift;
4122 if (sc->ctts_data) {
4123 st->start_time += sc->ctts_data[0].duration;
4124 }
4125 }
4126
4127 mov_estimate_video_delay(mov, st);
4128 }
4129
test_same_origin(const char * src,const char * ref)4130 static int test_same_origin(const char *src, const char *ref) {
4131 char src_proto[64];
4132 char ref_proto[64];
4133 char src_auth[256];
4134 char ref_auth[256];
4135 char src_host[256];
4136 char ref_host[256];
4137 int src_port=-1;
4138 int ref_port=-1;
4139
4140 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4141 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4142
4143 if (strlen(src) == 0) {
4144 return -1;
4145 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4146 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4147 strlen(src_host) + 1 >= sizeof(src_host) ||
4148 strlen(ref_host) + 1 >= sizeof(ref_host)) {
4149 return 0;
4150 } else if (strcmp(src_proto, ref_proto) ||
4151 strcmp(src_auth, ref_auth) ||
4152 strcmp(src_host, ref_host) ||
4153 src_port != ref_port) {
4154 return 0;
4155 } else
4156 return 1;
4157 }
4158
mov_open_dref(MOVContext * c,AVIOContext ** pb,const char * src,MOVDref * ref)4159 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4160 {
4161 /* try relative path, we do not try the absolute because it can leak information about our
4162 system to an attacker */
4163 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4164 char filename[1025];
4165 const char *src_path;
4166 int i, l;
4167
4168 /* find a source dir */
4169 src_path = strrchr(src, '/');
4170 if (src_path)
4171 src_path++;
4172 else
4173 src_path = src;
4174
4175 /* find a next level down to target */
4176 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4177 if (ref->path[l] == '/') {
4178 if (i == ref->nlvl_to - 1)
4179 break;
4180 else
4181 i++;
4182 }
4183
4184 /* compose filename if next level down to target was found */
4185 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4186 memcpy(filename, src, src_path - src);
4187 filename[src_path - src] = 0;
4188
4189 for (i = 1; i < ref->nlvl_from; i++)
4190 av_strlcat(filename, "../", sizeof(filename));
4191
4192 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4193 if (!c->use_absolute_path) {
4194 int same_origin = test_same_origin(src, filename);
4195
4196 if (!same_origin) {
4197 av_log(c->fc, AV_LOG_ERROR,
4198 "Reference with mismatching origin, %s not tried for security reasons, "
4199 "set demuxer option use_absolute_path to allow it anyway\n",
4200 ref->path);
4201 return AVERROR(ENOENT);
4202 }
4203
4204 if (strstr(ref->path + l + 1, "..") ||
4205 strstr(ref->path + l + 1, ":") ||
4206 (ref->nlvl_from > 1 && same_origin < 0) ||
4207 (filename[0] == '/' && src_path == src))
4208 return AVERROR(ENOENT);
4209 }
4210
4211 if (strlen(filename) + 1 == sizeof(filename))
4212 return AVERROR(ENOENT);
4213 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4214 return 0;
4215 }
4216 } else if (c->use_absolute_path) {
4217 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4218 "this is a possible security issue\n");
4219 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4220 return 0;
4221 } else {
4222 av_log(c->fc, AV_LOG_ERROR,
4223 "Absolute path %s not tried for security reasons, "
4224 "set demuxer option use_absolute_path to allow absolute paths\n",
4225 ref->path);
4226 }
4227
4228 return AVERROR(ENOENT);
4229 }
4230
fix_timescale(MOVContext * c,MOVStreamContext * sc)4231 static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
4232 {
4233 if (sc->time_scale <= 0) {
4234 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4235 sc->time_scale = c->time_scale;
4236 if (sc->time_scale <= 0)
4237 sc->time_scale = 1;
4238 }
4239 }
4240
mov_read_trak(MOVContext * c,AVIOContext * pb,MOVAtom atom)4241 static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4242 {
4243 AVStream *st;
4244 MOVStreamContext *sc;
4245 int ret;
4246
4247 st = avformat_new_stream(c->fc, NULL);
4248 if (!st) return AVERROR(ENOMEM);
4249 st->id = -1;
4250 sc = av_mallocz(sizeof(MOVStreamContext));
4251 if (!sc) return AVERROR(ENOMEM);
4252
4253 st->priv_data = sc;
4254 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
4255 sc->ffindex = st->index;
4256 c->trak_index = st->index;
4257
4258 if ((ret = mov_read_default(c, pb, atom)) < 0)
4259 return ret;
4260
4261 c->trak_index = -1;
4262
4263 // Here stsc refers to a chunk not described in stco. This is technically invalid,
4264 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4265 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4266 sc->stsc_count = 0;
4267 av_freep(&sc->stsc_data);
4268 }
4269
4270 /* sanity checks */
4271 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4272 (!sc->sample_size && !sc->sample_count))) ||
4273 (!sc->chunk_count && sc->sample_count)) {
4274 av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4275 st->index);
4276 return 0;
4277 }
4278 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4279 av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4280 st->index);
4281 return AVERROR_INVALIDDATA;
4282 }
4283
4284 fix_timescale(c, sc);
4285
4286 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4287
4288 mov_build_index(c, st);
4289
4290 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4291 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4292 if (c->enable_drefs) {
4293 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4294 av_log(c->fc, AV_LOG_ERROR,
4295 "stream %d, error opening alias: path='%s', dir='%s', "
4296 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4297 st->index, dref->path, dref->dir, dref->filename,
4298 dref->volume, dref->nlvl_from, dref->nlvl_to);
4299 } else {
4300 av_log(c->fc, AV_LOG_WARNING,
4301 "Skipped opening external track: "
4302 "stream %d, alias: path='%s', dir='%s', "
4303 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4304 "Set enable_drefs to allow this.\n",
4305 st->index, dref->path, dref->dir, dref->filename,
4306 dref->volume, dref->nlvl_from, dref->nlvl_to);
4307 }
4308 } else {
4309 sc->pb = c->fc->pb;
4310 sc->pb_is_copied = 1;
4311 }
4312
4313 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4314 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4315 sc->height && sc->width &&
4316 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4317 st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4318 ((double)st->codecpar->width * sc->height), INT_MAX);
4319 }
4320
4321 #if FF_API_R_FRAME_RATE
4322 if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4323 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
4324 sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4325 #endif
4326 }
4327
4328 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4329 if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4330 TAG_IS_AVCI(st->codecpar->codec_tag)) {
4331 ret = ff_generate_avci_extradata(st);
4332 if (ret < 0)
4333 return ret;
4334 }
4335
4336 switch (st->codecpar->codec_id) {
4337 #if CONFIG_H261_DECODER
4338 case AV_CODEC_ID_H261:
4339 #endif
4340 #if CONFIG_H263_DECODER
4341 case AV_CODEC_ID_H263:
4342 #endif
4343 #if CONFIG_MPEG4_DECODER
4344 case AV_CODEC_ID_MPEG4:
4345 #endif
4346 st->codecpar->width = 0; /* let decoder init width/height */
4347 st->codecpar->height= 0;
4348 break;
4349 }
4350
4351 // If the duration of the mp3 packets is not constant, then they could need a parser
4352 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4353 && sc->stts_count > 3
4354 && sc->stts_count*10 > st->nb_frames
4355 && sc->time_scale == st->codecpar->sample_rate) {
4356 st->need_parsing = AVSTREAM_PARSE_FULL;
4357 }
4358 /* Do not need those anymore. */
4359 av_freep(&sc->chunk_offsets);
4360 av_freep(&sc->sample_sizes);
4361 av_freep(&sc->keyframes);
4362 av_freep(&sc->stts_data);
4363 av_freep(&sc->stps_data);
4364 av_freep(&sc->elst_data);
4365 av_freep(&sc->rap_group);
4366
4367 return 0;
4368 }
4369
mov_read_ilst(MOVContext * c,AVIOContext * pb,MOVAtom atom)4370 static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4371 {
4372 int ret;
4373 c->itunes_metadata = 1;
4374 ret = mov_read_default(c, pb, atom);
4375 c->itunes_metadata = 0;
4376 return ret;
4377 }
4378
mov_read_keys(MOVContext * c,AVIOContext * pb,MOVAtom atom)4379 static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4380 {
4381 uint32_t count;
4382 uint32_t i;
4383
4384 if (atom.size < 8)
4385 return 0;
4386
4387 avio_skip(pb, 4);
4388 count = avio_rb32(pb);
4389 if (count > UINT_MAX / sizeof(*c->meta_keys) - 1) {
4390 av_log(c->fc, AV_LOG_ERROR,
4391 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
4392 return AVERROR_INVALIDDATA;
4393 }
4394
4395 c->meta_keys_count = count + 1;
4396 c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
4397 if (!c->meta_keys)
4398 return AVERROR(ENOMEM);
4399
4400 for (i = 1; i <= count; ++i) {
4401 uint32_t key_size = avio_rb32(pb);
4402 uint32_t type = avio_rl32(pb);
4403 if (key_size < 8) {
4404 av_log(c->fc, AV_LOG_ERROR,
4405 "The key# %"PRIu32" in meta has invalid size:"
4406 "%"PRIu32"\n", i, key_size);
4407 return AVERROR_INVALIDDATA;
4408 }
4409 key_size -= 8;
4410 if (type != MKTAG('m','d','t','a')) {
4411 avio_skip(pb, key_size);
4412 }
4413 c->meta_keys[i] = av_mallocz(key_size + 1);
4414 if (!c->meta_keys[i])
4415 return AVERROR(ENOMEM);
4416 avio_read(pb, c->meta_keys[i], key_size);
4417 }
4418
4419 return 0;
4420 }
4421
mov_read_custom(MOVContext * c,AVIOContext * pb,MOVAtom atom)4422 static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4423 {
4424 int64_t end = av_sat_add64(avio_tell(pb), atom.size);
4425 uint8_t *key = NULL, *val = NULL, *mean = NULL;
4426 int i;
4427 int ret = 0;
4428 AVStream *st;
4429 MOVStreamContext *sc;
4430
4431 if (c->fc->nb_streams < 1)
4432 return 0;
4433 st = c->fc->streams[c->fc->nb_streams-1];
4434 sc = st->priv_data;
4435
4436 for (i = 0; i < 3; i++) {
4437 uint8_t **p;
4438 uint32_t len, tag;
4439
4440 if (end - avio_tell(pb) <= 12)
4441 break;
4442
4443 len = avio_rb32(pb);
4444 tag = avio_rl32(pb);
4445 avio_skip(pb, 4); // flags
4446
4447 if (len < 12 || len - 12 > end - avio_tell(pb))
4448 break;
4449 len -= 12;
4450
4451 if (tag == MKTAG('m', 'e', 'a', 'n'))
4452 p = &mean;
4453 else if (tag == MKTAG('n', 'a', 'm', 'e'))
4454 p = &key;
4455 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
4456 avio_skip(pb, 4);
4457 len -= 4;
4458 p = &val;
4459 } else
4460 break;
4461
4462 if (*p)
4463 break;
4464
4465 *p = av_malloc(len + 1);
4466 if (!*p) {
4467 ret = AVERROR(ENOMEM);
4468 break;
4469 }
4470 ret = ffio_read_size(pb, *p, len);
4471 if (ret < 0) {
4472 av_freep(p);
4473 break;
4474 }
4475 (*p)[len] = 0;
4476 }
4477
4478 if (mean && key && val) {
4479 if (strcmp(key, "iTunSMPB") == 0) {
4480 int priming, remainder, samples;
4481 if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
4482 if(priming>0 && priming<16384)
4483 sc->start_pad = priming;
4484 }
4485 }
4486 if (strcmp(key, "cdec") != 0) {
4487 av_dict_set(&c->fc->metadata, key, val,
4488 AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
4489 key = val = NULL;
4490 }
4491 } else {
4492 av_log(c->fc, AV_LOG_VERBOSE,
4493 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
4494 }
4495
4496 avio_seek(pb, end, SEEK_SET);
4497 av_freep(&key);
4498 av_freep(&val);
4499 av_freep(&mean);
4500 return ret;
4501 }
4502
mov_read_meta(MOVContext * c,AVIOContext * pb,MOVAtom atom)4503 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4504 {
4505 while (atom.size > 8) {
4506 uint32_t tag;
4507 if (avio_feof(pb))
4508 return AVERROR_EOF;
4509 tag = avio_rl32(pb);
4510 atom.size -= 4;
4511 if (tag == MKTAG('h','d','l','r')) {
4512 avio_seek(pb, -8, SEEK_CUR);
4513 atom.size += 8;
4514 return mov_read_default(c, pb, atom);
4515 }
4516 }
4517 return 0;
4518 }
4519
4520 // return 1 when matrix is identity, 0 otherwise
4521 #define IS_MATRIX_IDENT(matrix) \
4522 ( (matrix)[0][0] == (1 << 16) && \
4523 (matrix)[1][1] == (1 << 16) && \
4524 (matrix)[2][2] == (1 << 30) && \
4525 !(matrix)[0][1] && !(matrix)[0][2] && \
4526 !(matrix)[1][0] && !(matrix)[1][2] && \
4527 !(matrix)[2][0] && !(matrix)[2][1])
4528
mov_read_tkhd(MOVContext * c,AVIOContext * pb,MOVAtom atom)4529 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4530 {
4531 int i, j, e;
4532 int width;
4533 int height;
4534 int display_matrix[3][3];
4535 int res_display_matrix[3][3] = { { 0 } };
4536 AVStream *st;
4537 MOVStreamContext *sc;
4538 int version;
4539 int flags;
4540
4541 if (c->fc->nb_streams < 1)
4542 return 0;
4543 st = c->fc->streams[c->fc->nb_streams-1];
4544 sc = st->priv_data;
4545
4546 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4547 // avoids corrupting AVStreams mapped to an earlier tkhd.
4548 if (st->id != -1)
4549 return AVERROR_INVALIDDATA;
4550
4551 version = avio_r8(pb);
4552 flags = avio_rb24(pb);
4553 st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
4554
4555 if (version == 1) {
4556 avio_rb64(pb);
4557 avio_rb64(pb);
4558 } else {
4559 avio_rb32(pb); /* creation time */
4560 avio_rb32(pb); /* modification time */
4561 }
4562 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4563 avio_rb32(pb); /* reserved */
4564
4565 /* highlevel (considering edits) duration in movie timebase */
4566 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4567 avio_rb32(pb); /* reserved */
4568 avio_rb32(pb); /* reserved */
4569
4570 avio_rb16(pb); /* layer */
4571 avio_rb16(pb); /* alternate group */
4572 avio_rb16(pb); /* volume */
4573 avio_rb16(pb); /* reserved */
4574
4575 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4576 // they're kept in fixed point format through all calculations
4577 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4578 // side data, but the scale factor is not needed to calculate aspect ratio
4579 for (i = 0; i < 3; i++) {
4580 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
4581 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
4582 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
4583 }
4584
4585 width = avio_rb32(pb); // 16.16 fixed point track width
4586 height = avio_rb32(pb); // 16.16 fixed point track height
4587 sc->width = width >> 16;
4588 sc->height = height >> 16;
4589
4590 // apply the moov display matrix (after the tkhd one)
4591 for (i = 0; i < 3; i++) {
4592 const int sh[3] = { 16, 16, 30 };
4593 for (j = 0; j < 3; j++) {
4594 for (e = 0; e < 3; e++) {
4595 res_display_matrix[i][j] +=
4596 ((int64_t) display_matrix[i][e] *
4597 c->movie_display_matrix[e][j]) >> sh[e];
4598 }
4599 }
4600 }
4601
4602 // save the matrix when it is not the default identity
4603 if (!IS_MATRIX_IDENT(res_display_matrix)) {
4604 double rotate;
4605
4606 av_freep(&sc->display_matrix);
4607 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4608 if (!sc->display_matrix)
4609 return AVERROR(ENOMEM);
4610
4611 for (i = 0; i < 3; i++)
4612 for (j = 0; j < 3; j++)
4613 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4614
4615 #if FF_API_OLD_ROTATE_API
4616 rotate = av_display_rotation_get(sc->display_matrix);
4617 if (!isnan(rotate)) {
4618 char rotate_buf[64];
4619 rotate = -rotate;
4620 if (rotate < 0) // for backward compatibility
4621 rotate += 360;
4622 snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate);
4623 av_dict_set(&st->metadata, "rotate", rotate_buf, 0);
4624 }
4625 #endif
4626 }
4627
4628 // transform the display width/height according to the matrix
4629 // to keep the same scale, use [width height 1<<16]
4630 if (width && height && sc->display_matrix) {
4631 double disp_transform[2];
4632
4633 for (i = 0; i < 2; i++)
4634 disp_transform[i] = hypot(sc->display_matrix[0 + i],
4635 sc->display_matrix[3 + i]);
4636
4637 if (disp_transform[0] > 0 && disp_transform[1] > 0 &&
4638 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4639 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4640 st->sample_aspect_ratio = av_d2q(
4641 disp_transform[0] / disp_transform[1],
4642 INT_MAX);
4643 }
4644 return 0;
4645 }
4646
mov_read_tfhd(MOVContext * c,AVIOContext * pb,MOVAtom atom)4647 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4648 {
4649 MOVFragment *frag = &c->fragment;
4650 MOVTrackExt *trex = NULL;
4651 int flags, track_id, i;
4652 MOVFragmentStreamInfo * frag_stream_info;
4653
4654 avio_r8(pb); /* version */
4655 flags = avio_rb24(pb);
4656
4657 track_id = avio_rb32(pb);
4658 if (!track_id)
4659 return AVERROR_INVALIDDATA;
4660 for (i = 0; i < c->trex_count; i++)
4661 if (c->trex_data[i].track_id == track_id) {
4662 trex = &c->trex_data[i];
4663 break;
4664 }
4665 if (!trex) {
4666 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4667 return 0;
4668 }
4669 c->fragment.found_tfhd = 1;
4670 frag->track_id = track_id;
4671 set_frag_stream(&c->frag_index, track_id);
4672
4673 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4674 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4675 frag->moof_offset : frag->implicit_offset;
4676 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4677
4678 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4679 avio_rb32(pb) : trex->duration;
4680 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4681 avio_rb32(pb) : trex->size;
4682 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4683 avio_rb32(pb) : trex->flags;
4684 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4685
4686 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4687 if (frag_stream_info)
4688 frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
4689
4690 return 0;
4691 }
4692
mov_read_chap(MOVContext * c,AVIOContext * pb,MOVAtom atom)4693 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4694 {
4695 unsigned i, num;
4696 void *new_tracks;
4697
4698 num = atom.size / 4;
4699 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4700 return AVERROR(ENOMEM);
4701
4702 av_free(c->chapter_tracks);
4703 c->chapter_tracks = new_tracks;
4704 c->nb_chapter_tracks = num;
4705
4706 for (i = 0; i < num && !pb->eof_reached; i++)
4707 c->chapter_tracks[i] = avio_rb32(pb);
4708
4709 c->nb_chapter_tracks = i;
4710
4711 return 0;
4712 }
4713
mov_read_trex(MOVContext * c,AVIOContext * pb,MOVAtom atom)4714 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4715 {
4716 MOVTrackExt *trex;
4717 int err;
4718
4719 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4720 return AVERROR_INVALIDDATA;
4721 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4722 sizeof(*c->trex_data))) < 0) {
4723 c->trex_count = 0;
4724 return err;
4725 }
4726
4727 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4728
4729 trex = &c->trex_data[c->trex_count++];
4730 avio_r8(pb); /* version */
4731 avio_rb24(pb); /* flags */
4732 trex->track_id = avio_rb32(pb);
4733 trex->stsd_id = avio_rb32(pb);
4734 trex->duration = avio_rb32(pb);
4735 trex->size = avio_rb32(pb);
4736 trex->flags = avio_rb32(pb);
4737 return 0;
4738 }
4739
mov_read_tfdt(MOVContext * c,AVIOContext * pb,MOVAtom atom)4740 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4741 {
4742 MOVFragment *frag = &c->fragment;
4743 AVStream *st = NULL;
4744 MOVStreamContext *sc;
4745 int version, i;
4746 MOVFragmentStreamInfo * frag_stream_info;
4747 int64_t base_media_decode_time;
4748
4749 for (i = 0; i < c->fc->nb_streams; i++) {
4750 if (c->fc->streams[i]->id == frag->track_id) {
4751 st = c->fc->streams[i];
4752 break;
4753 }
4754 }
4755 if (!st) {
4756 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4757 return 0;
4758 }
4759 sc = st->priv_data;
4760 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4761 return 0;
4762 version = avio_r8(pb);
4763 avio_rb24(pb); /* flags */
4764 if (version) {
4765 base_media_decode_time = avio_rb64(pb);
4766 } else {
4767 base_media_decode_time = avio_rb32(pb);
4768 }
4769
4770 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4771 if (frag_stream_info)
4772 frag_stream_info->tfdt_dts = base_media_decode_time;
4773 sc->track_end = base_media_decode_time;
4774
4775 return 0;
4776 }
4777
mov_read_trun(MOVContext * c,AVIOContext * pb,MOVAtom atom)4778 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4779 {
4780 MOVFragment *frag = &c->fragment;
4781 AVStream *st = NULL;
4782 MOVStreamContext *sc;
4783 MOVStts *ctts_data;
4784 uint64_t offset;
4785 int64_t dts, pts = AV_NOPTS_VALUE;
4786 int data_offset = 0;
4787 unsigned entries, first_sample_flags = frag->flags;
4788 int flags, distance, i;
4789 int64_t prev_dts = AV_NOPTS_VALUE;
4790 int next_frag_index = -1, index_entry_pos;
4791 size_t requested_size;
4792 size_t old_ctts_allocated_size;
4793 AVIndexEntry *new_entries;
4794 MOVFragmentStreamInfo * frag_stream_info;
4795
4796 if (!frag->found_tfhd) {
4797 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4798 return AVERROR_INVALIDDATA;
4799 }
4800
4801 for (i = 0; i < c->fc->nb_streams; i++) {
4802 if (c->fc->streams[i]->id == frag->track_id) {
4803 st = c->fc->streams[i];
4804 break;
4805 }
4806 }
4807 if (!st) {
4808 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4809 return 0;
4810 }
4811 sc = st->priv_data;
4812 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4813 return 0;
4814
4815 // Find the next frag_index index that has a valid index_entry for
4816 // the current track_id.
4817 //
4818 // A valid index_entry means the trun for the fragment was read
4819 // and it's samples are in index_entries at the given position.
4820 // New index entries will be inserted before the index_entry found.
4821 index_entry_pos = st->nb_index_entries;
4822 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4823 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4824 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4825 next_frag_index = i;
4826 index_entry_pos = frag_stream_info->index_entry;
4827 break;
4828 }
4829 }
4830 av_assert0(index_entry_pos <= st->nb_index_entries);
4831
4832 avio_r8(pb); /* version */
4833 flags = avio_rb24(pb);
4834 entries = avio_rb32(pb);
4835 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4836
4837 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4838 return AVERROR_INVALIDDATA;
4839 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4840 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4841
4842 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4843 if (frag_stream_info) {
4844 if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
4845 dts = frag_stream_info->next_trun_dts - sc->time_offset;
4846 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4847 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4848 pts = frag_stream_info->first_tfra_pts;
4849 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4850 ", using it for pts\n", pts);
4851 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4852 c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
4853 dts = frag_stream_info->first_tfra_pts;
4854 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4855 ", using it for dts\n", pts);
4856 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4857 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4858 // pts = frag_stream_info->sidx_pts;
4859 dts = frag_stream_info->sidx_pts - sc->time_offset;
4860 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4861 ", using it for pts\n", pts);
4862 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4863 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4864 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4865 ", using it for dts\n", dts);
4866 } else {
4867 dts = sc->track_end - sc->time_offset;
4868 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4869 ", using it for dts\n", dts);
4870 }
4871 } else {
4872 dts = sc->track_end - sc->time_offset;
4873 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4874 ", using it for dts\n", dts);
4875 }
4876 offset = frag->base_data_offset + data_offset;
4877 distance = 0;
4878 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4879
4880 // realloc space for new index entries
4881 if((uint64_t)st->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4882 entries = UINT_MAX / sizeof(AVIndexEntry) - st->nb_index_entries;
4883 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4884 }
4885 if (entries == 0)
4886 return 0;
4887
4888 requested_size = (st->nb_index_entries + entries) * sizeof(AVIndexEntry);
4889 new_entries = av_fast_realloc(st->index_entries,
4890 &st->index_entries_allocated_size,
4891 requested_size);
4892 if (!new_entries)
4893 return AVERROR(ENOMEM);
4894 st->index_entries= new_entries;
4895
4896 requested_size = (st->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4897 old_ctts_allocated_size = sc->ctts_allocated_size;
4898 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4899 requested_size);
4900 if (!ctts_data)
4901 return AVERROR(ENOMEM);
4902 sc->ctts_data = ctts_data;
4903
4904 // In case there were samples without ctts entries, ensure they get
4905 // zero valued entries. This ensures clips which mix boxes with and
4906 // without ctts entries don't pickup uninitialized data.
4907 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4908 sc->ctts_allocated_size - old_ctts_allocated_size);
4909
4910 if (index_entry_pos < st->nb_index_entries) {
4911 // Make hole in index_entries and ctts_data for new samples
4912 memmove(st->index_entries + index_entry_pos + entries,
4913 st->index_entries + index_entry_pos,
4914 sizeof(*st->index_entries) *
4915 (st->nb_index_entries - index_entry_pos));
4916 memmove(sc->ctts_data + index_entry_pos + entries,
4917 sc->ctts_data + index_entry_pos,
4918 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4919 if (index_entry_pos < sc->current_sample) {
4920 sc->current_sample += entries;
4921 }
4922 }
4923
4924 st->nb_index_entries += entries;
4925 sc->ctts_count = st->nb_index_entries;
4926
4927 // Record the index_entry position in frag_index of this fragment
4928 if (frag_stream_info)
4929 frag_stream_info->index_entry = index_entry_pos;
4930
4931 if (index_entry_pos > 0)
4932 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4933
4934 for (i = 0; i < entries && !pb->eof_reached; i++) {
4935 unsigned sample_size = frag->size;
4936 int sample_flags = i ? frag->flags : first_sample_flags;
4937 unsigned sample_duration = frag->duration;
4938 unsigned ctts_duration = 0;
4939 int keyframe = 0;
4940 int index_entry_flags = 0;
4941
4942 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4943 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4944 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4945 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4946
4947 mov_update_dts_shift(sc, ctts_duration, c->fc);
4948 if (pts != AV_NOPTS_VALUE) {
4949 dts = pts - sc->dts_shift;
4950 if (flags & MOV_TRUN_SAMPLE_CTS) {
4951 dts -= ctts_duration;
4952 } else {
4953 dts -= sc->time_offset;
4954 }
4955 av_log(c->fc, AV_LOG_DEBUG,
4956 "pts %"PRId64" calculated dts %"PRId64
4957 " sc->dts_shift %d ctts.duration %d"
4958 " sc->time_offset %"PRId64
4959 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4960 pts, dts,
4961 sc->dts_shift, ctts_duration,
4962 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4963 pts = AV_NOPTS_VALUE;
4964 }
4965
4966 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4967 keyframe = 1;
4968 else
4969 keyframe =
4970 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4971 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4972 if (keyframe) {
4973 distance = 0;
4974 index_entry_flags |= AVINDEX_KEYFRAME;
4975 }
4976 // Fragments can overlap in time. Discard overlapping frames after
4977 // decoding.
4978 if (prev_dts >= dts)
4979 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4980
4981 st->index_entries[index_entry_pos].pos = offset;
4982 st->index_entries[index_entry_pos].timestamp = dts;
4983 st->index_entries[index_entry_pos].size= sample_size;
4984 st->index_entries[index_entry_pos].min_distance= distance;
4985 st->index_entries[index_entry_pos].flags = index_entry_flags;
4986
4987 sc->ctts_data[index_entry_pos].count = 1;
4988 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4989 index_entry_pos++;
4990
4991 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4992 "size %u, distance %d, keyframe %d\n", st->index,
4993 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4994 distance++;
4995 if (av_sat_add64(dts, sample_duration) != dts + (uint64_t)sample_duration)
4996 return AVERROR_INVALIDDATA;
4997 dts += sample_duration;
4998 offset += sample_size;
4999 sc->data_size += sample_size;
5000
5001 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
5002 1 <= INT_MAX - sc->nb_frames_for_fps
5003 ) {
5004 sc->duration_for_fps += sample_duration;
5005 sc->nb_frames_for_fps ++;
5006 }
5007 }
5008 if (frag_stream_info)
5009 frag_stream_info->next_trun_dts = dts + sc->time_offset;
5010 if (i < entries) {
5011 // EOF found before reading all entries. Fix the hole this would
5012 // leave in index_entries and ctts_data
5013 int gap = entries - i;
5014 memmove(st->index_entries + index_entry_pos,
5015 st->index_entries + index_entry_pos + gap,
5016 sizeof(*st->index_entries) *
5017 (st->nb_index_entries - (index_entry_pos + gap)));
5018 memmove(sc->ctts_data + index_entry_pos,
5019 sc->ctts_data + index_entry_pos + gap,
5020 sizeof(*sc->ctts_data) *
5021 (sc->ctts_count - (index_entry_pos + gap)));
5022
5023 st->nb_index_entries -= gap;
5024 sc->ctts_count -= gap;
5025 if (index_entry_pos < sc->current_sample) {
5026 sc->current_sample -= gap;
5027 }
5028 entries = i;
5029 }
5030
5031 // The end of this new fragment may overlap in time with the start
5032 // of the next fragment in index_entries. Mark the samples in the next
5033 // fragment that overlap with AVINDEX_DISCARD_FRAME
5034 prev_dts = AV_NOPTS_VALUE;
5035 if (index_entry_pos > 0)
5036 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
5037 for (i = index_entry_pos; i < st->nb_index_entries; i++) {
5038 if (prev_dts < st->index_entries[i].timestamp)
5039 break;
5040 st->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
5041 }
5042
5043 // If a hole was created to insert the new index_entries into,
5044 // the index_entry recorded for all subsequent moof must
5045 // be incremented by the number of entries inserted.
5046 fix_frag_index_entries(&c->frag_index, next_frag_index,
5047 frag->track_id, entries);
5048
5049 if (pb->eof_reached) {
5050 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
5051 return AVERROR_EOF;
5052 }
5053
5054 frag->implicit_offset = offset;
5055
5056 sc->track_end = dts + sc->time_offset;
5057 if (st->duration < sc->track_end)
5058 st->duration = sc->track_end;
5059
5060 return 0;
5061 }
5062
mov_read_sidx(MOVContext * c,AVIOContext * pb,MOVAtom atom)5063 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5064 {
5065 int64_t stream_size = avio_size(pb);
5066 int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
5067 uint8_t version, is_complete;
5068 int64_t offadd;
5069 unsigned i, j, track_id, item_count;
5070 AVStream *st = NULL;
5071 AVStream *ref_st = NULL;
5072 MOVStreamContext *sc, *ref_sc = NULL;
5073 AVRational timescale;
5074
5075 version = avio_r8(pb);
5076 if (version > 1) {
5077 avpriv_request_sample(c->fc, "sidx version %u", version);
5078 return 0;
5079 }
5080
5081 avio_rb24(pb); // flags
5082
5083 track_id = avio_rb32(pb); // Reference ID
5084 for (i = 0; i < c->fc->nb_streams; i++) {
5085 if (c->fc->streams[i]->id == track_id) {
5086 st = c->fc->streams[i];
5087 break;
5088 }
5089 }
5090 if (!st) {
5091 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5092 return 0;
5093 }
5094
5095 sc = st->priv_data;
5096
5097 timescale = av_make_q(1, avio_rb32(pb));
5098
5099 if (timescale.den <= 0) {
5100 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5101 return AVERROR_INVALIDDATA;
5102 }
5103
5104 if (version == 0) {
5105 pts = avio_rb32(pb);
5106 offadd= avio_rb32(pb);
5107 } else {
5108 pts = avio_rb64(pb);
5109 offadd= avio_rb64(pb);
5110 }
5111 if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
5112 return AVERROR_INVALIDDATA;
5113
5114 offset += (uint64_t)offadd;
5115
5116 avio_rb16(pb); // reserved
5117
5118 item_count = avio_rb16(pb);
5119
5120 for (i = 0; i < item_count; i++) {
5121 int index;
5122 MOVFragmentStreamInfo * frag_stream_info;
5123 uint32_t size = avio_rb32(pb);
5124 uint32_t duration = avio_rb32(pb);
5125 if (size & 0x80000000) {
5126 avpriv_request_sample(c->fc, "sidx reference_type 1");
5127 return AVERROR_PATCHWELCOME;
5128 }
5129 avio_rb32(pb); // sap_flags
5130 timestamp = av_rescale_q(pts, timescale, st->time_base);
5131
5132 index = update_frag_index(c, offset);
5133 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5134 if (frag_stream_info)
5135 frag_stream_info->sidx_pts = timestamp;
5136
5137 if (av_sat_add64(offset, size) != offset + (uint64_t)size ||
5138 av_sat_add64(pts, duration) != pts + (uint64_t)duration
5139 )
5140 return AVERROR_INVALIDDATA;
5141 offset += size;
5142 pts += duration;
5143 }
5144
5145 st->duration = sc->track_end = pts;
5146
5147 sc->has_sidx = 1;
5148
5149 // See if the remaining bytes are just an mfra which we can ignore.
5150 is_complete = offset == stream_size;
5151 if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL) && stream_size > 0 ) {
5152 int64_t ret;
5153 int64_t original_pos = avio_tell(pb);
5154 if (!c->have_read_mfra_size) {
5155 if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
5156 return ret;
5157 c->mfra_size = avio_rb32(pb);
5158 c->have_read_mfra_size = 1;
5159 if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
5160 return ret;
5161 }
5162 if (offset == stream_size - c->mfra_size)
5163 is_complete = 1;
5164 }
5165
5166 if (is_complete) {
5167 // Find first entry in fragment index that came from an sidx.
5168 // This will pretty much always be the first entry.
5169 for (i = 0; i < c->frag_index.nb_items; i++) {
5170 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5171 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5172 MOVFragmentStreamInfo * si;
5173 si = &item->stream_info[j];
5174 if (si->sidx_pts != AV_NOPTS_VALUE) {
5175 ref_st = c->fc->streams[j];
5176 ref_sc = ref_st->priv_data;
5177 break;
5178 }
5179 }
5180 }
5181 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5182 st = c->fc->streams[i];
5183 sc = st->priv_data;
5184 if (!sc->has_sidx) {
5185 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5186 }
5187 }
5188
5189 c->frag_index.complete = 1;
5190 }
5191
5192 return 0;
5193 }
5194
5195 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5196 /* like the files created with Adobe Premiere 5.0, for samples see */
5197 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
mov_read_wide(MOVContext * c,AVIOContext * pb,MOVAtom atom)5198 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5199 {
5200 int err;
5201
5202 if (atom.size < 8)
5203 return 0; /* continue */
5204 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5205 avio_skip(pb, atom.size - 4);
5206 return 0;
5207 }
5208 atom.type = avio_rl32(pb);
5209 atom.size -= 8;
5210 if (atom.type != MKTAG('m','d','a','t')) {
5211 avio_skip(pb, atom.size);
5212 return 0;
5213 }
5214 err = mov_read_mdat(c, pb, atom);
5215 return err;
5216 }
5217
mov_read_cmov(MOVContext * c,AVIOContext * pb,MOVAtom atom)5218 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5219 {
5220 #if CONFIG_ZLIB
5221 AVIOContext ctx;
5222 uint8_t *cmov_data;
5223 uint8_t *moov_data; /* uncompressed data */
5224 long cmov_len, moov_len;
5225 int ret = -1;
5226
5227 avio_rb32(pb); /* dcom atom */
5228 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5229 return AVERROR_INVALIDDATA;
5230 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5231 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5232 return AVERROR_INVALIDDATA;
5233 }
5234 avio_rb32(pb); /* cmvd atom */
5235 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5236 return AVERROR_INVALIDDATA;
5237 moov_len = avio_rb32(pb); /* uncompressed size */
5238 cmov_len = atom.size - 6 * 4;
5239
5240 cmov_data = av_malloc(cmov_len);
5241 if (!cmov_data)
5242 return AVERROR(ENOMEM);
5243 moov_data = av_malloc(moov_len);
5244 if (!moov_data) {
5245 av_free(cmov_data);
5246 return AVERROR(ENOMEM);
5247 }
5248 ret = ffio_read_size(pb, cmov_data, cmov_len);
5249 if (ret < 0)
5250 goto free_and_return;
5251
5252 ret = AVERROR_INVALIDDATA;
5253 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5254 goto free_and_return;
5255 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5256 goto free_and_return;
5257 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5258 atom.type = MKTAG('m','o','o','v');
5259 atom.size = moov_len;
5260 ret = mov_read_default(c, &ctx, atom);
5261 free_and_return:
5262 av_free(moov_data);
5263 av_free(cmov_data);
5264 return ret;
5265 #else
5266 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5267 return AVERROR(ENOSYS);
5268 #endif
5269 }
5270
5271 /* edit list atom */
mov_read_elst(MOVContext * c,AVIOContext * pb,MOVAtom atom)5272 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5273 {
5274 MOVStreamContext *sc;
5275 int i, edit_count, version;
5276 int64_t elst_entry_size;
5277
5278 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5279 return 0;
5280 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5281
5282 version = avio_r8(pb); /* version */
5283 avio_rb24(pb); /* flags */
5284 edit_count = avio_rb32(pb); /* entries */
5285 atom.size -= 8;
5286
5287 elst_entry_size = version == 1 ? 20 : 12;
5288 if (atom.size != edit_count * elst_entry_size) {
5289 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5290 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5291 edit_count, atom.size + 8);
5292 return AVERROR_INVALIDDATA;
5293 } else {
5294 edit_count = atom.size / elst_entry_size;
5295 if (edit_count * elst_entry_size != atom.size) {
5296 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
5297 }
5298 }
5299 }
5300
5301 if (!edit_count)
5302 return 0;
5303 if (sc->elst_data)
5304 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5305 av_free(sc->elst_data);
5306 sc->elst_count = 0;
5307 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5308 if (!sc->elst_data)
5309 return AVERROR(ENOMEM);
5310
5311 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5312 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5313 MOVElst *e = &sc->elst_data[i];
5314
5315 if (version == 1) {
5316 e->duration = avio_rb64(pb);
5317 e->time = avio_rb64(pb);
5318 atom.size -= 16;
5319 } else {
5320 e->duration = avio_rb32(pb); /* segment duration */
5321 e->time = (int32_t)avio_rb32(pb); /* media time */
5322 atom.size -= 8;
5323 }
5324 e->rate = avio_rb32(pb) / 65536.0;
5325 atom.size -= 4;
5326 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5327 e->duration, e->time, e->rate);
5328
5329 if (e->time < 0 && e->time != -1 &&
5330 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5331 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5332 c->fc->nb_streams-1, i, e->time);
5333 return AVERROR_INVALIDDATA;
5334 }
5335 }
5336 sc->elst_count = i;
5337
5338 return 0;
5339 }
5340
mov_read_tmcd(MOVContext * c,AVIOContext * pb,MOVAtom atom)5341 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5342 {
5343 MOVStreamContext *sc;
5344
5345 if (c->fc->nb_streams < 1)
5346 return AVERROR_INVALIDDATA;
5347 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5348 sc->timecode_track = avio_rb32(pb);
5349 return 0;
5350 }
5351
mov_read_av1c(MOVContext * c,AVIOContext * pb,MOVAtom atom)5352 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5353 {
5354 AVStream *st;
5355 int ret;
5356
5357 if (c->fc->nb_streams < 1)
5358 return 0;
5359 st = c->fc->streams[c->fc->nb_streams - 1];
5360
5361 if (atom.size < 4) {
5362 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5363 return AVERROR_INVALIDDATA;
5364 }
5365
5366 /* For now, propagate only the OBUs, if any. Once libavcodec is
5367 updated to handle isobmff style extradata this can be removed. */
5368 avio_skip(pb, 4);
5369
5370 if (atom.size == 4)
5371 return 0;
5372
5373 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5374 if (ret < 0)
5375 return ret;
5376
5377 return 0;
5378 }
5379
mov_read_vpcc(MOVContext * c,AVIOContext * pb,MOVAtom atom)5380 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5381 {
5382 AVStream *st;
5383 int version, color_range, color_primaries, color_trc, color_space;
5384
5385 if (c->fc->nb_streams < 1)
5386 return 0;
5387 st = c->fc->streams[c->fc->nb_streams - 1];
5388
5389 if (atom.size < 5) {
5390 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5391 return AVERROR_INVALIDDATA;
5392 }
5393
5394 version = avio_r8(pb);
5395 if (version != 1) {
5396 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5397 return 0;
5398 }
5399 avio_skip(pb, 3); /* flags */
5400
5401 avio_skip(pb, 2); /* profile + level */
5402 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5403 color_primaries = avio_r8(pb);
5404 color_trc = avio_r8(pb);
5405 color_space = avio_r8(pb);
5406 if (avio_rb16(pb)) /* codecIntializationDataSize */
5407 return AVERROR_INVALIDDATA;
5408
5409 if (!av_color_primaries_name(color_primaries))
5410 color_primaries = AVCOL_PRI_UNSPECIFIED;
5411 if (!av_color_transfer_name(color_trc))
5412 color_trc = AVCOL_TRC_UNSPECIFIED;
5413 if (!av_color_space_name(color_space))
5414 color_space = AVCOL_SPC_UNSPECIFIED;
5415
5416 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5417 st->codecpar->color_primaries = color_primaries;
5418 st->codecpar->color_trc = color_trc;
5419 st->codecpar->color_space = color_space;
5420
5421 return 0;
5422 }
5423
mov_read_smdm(MOVContext * c,AVIOContext * pb,MOVAtom atom)5424 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5425 {
5426 MOVStreamContext *sc;
5427 int i, version;
5428
5429 if (c->fc->nb_streams < 1)
5430 return AVERROR_INVALIDDATA;
5431
5432 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5433
5434 if (atom.size < 5) {
5435 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5436 return AVERROR_INVALIDDATA;
5437 }
5438
5439 version = avio_r8(pb);
5440 if (version) {
5441 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5442 return 0;
5443 }
5444 avio_skip(pb, 3); /* flags */
5445
5446 sc->mastering = av_mastering_display_metadata_alloc();
5447 if (!sc->mastering)
5448 return AVERROR(ENOMEM);
5449
5450 for (i = 0; i < 3; i++) {
5451 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5452 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5453 }
5454 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5455 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5456
5457 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5458 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5459
5460 sc->mastering->has_primaries = 1;
5461 sc->mastering->has_luminance = 1;
5462
5463 return 0;
5464 }
5465
mov_read_mdcv(MOVContext * c,AVIOContext * pb,MOVAtom atom)5466 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5467 {
5468 MOVStreamContext *sc;
5469 const int mapping[3] = {1, 2, 0};
5470 const int chroma_den = 50000;
5471 const int luma_den = 10000;
5472 int i;
5473
5474 if (c->fc->nb_streams < 1)
5475 return AVERROR_INVALIDDATA;
5476
5477 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5478
5479 if (atom.size < 24 || sc->mastering) {
5480 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5481 return AVERROR_INVALIDDATA;
5482 }
5483
5484 sc->mastering = av_mastering_display_metadata_alloc();
5485 if (!sc->mastering)
5486 return AVERROR(ENOMEM);
5487
5488 for (i = 0; i < 3; i++) {
5489 const int j = mapping[i];
5490 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5491 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5492 }
5493 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5494 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5495
5496 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5497 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5498
5499 sc->mastering->has_luminance = 1;
5500 sc->mastering->has_primaries = 1;
5501
5502 return 0;
5503 }
5504
mov_read_coll(MOVContext * c,AVIOContext * pb,MOVAtom atom)5505 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5506 {
5507 MOVStreamContext *sc;
5508 int version;
5509
5510 if (c->fc->nb_streams < 1)
5511 return AVERROR_INVALIDDATA;
5512
5513 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5514
5515 if (atom.size < 5) {
5516 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5517 return AVERROR_INVALIDDATA;
5518 }
5519
5520 version = avio_r8(pb);
5521 if (version) {
5522 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5523 return 0;
5524 }
5525 avio_skip(pb, 3); /* flags */
5526
5527 if (sc->coll){
5528 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate COLL\n");
5529 return 0;
5530 }
5531
5532 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5533 if (!sc->coll)
5534 return AVERROR(ENOMEM);
5535
5536 sc->coll->MaxCLL = avio_rb16(pb);
5537 sc->coll->MaxFALL = avio_rb16(pb);
5538
5539 return 0;
5540 }
5541
mov_read_clli(MOVContext * c,AVIOContext * pb,MOVAtom atom)5542 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5543 {
5544 MOVStreamContext *sc;
5545
5546 if (c->fc->nb_streams < 1)
5547 return AVERROR_INVALIDDATA;
5548
5549 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5550
5551 if (atom.size < 4) {
5552 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5553 return AVERROR_INVALIDDATA;
5554 }
5555
5556 if (sc->coll){
5557 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate CLLI/COLL\n");
5558 return 0;
5559 }
5560
5561 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5562 if (!sc->coll)
5563 return AVERROR(ENOMEM);
5564
5565 sc->coll->MaxCLL = avio_rb16(pb);
5566 sc->coll->MaxFALL = avio_rb16(pb);
5567
5568 return 0;
5569 }
5570
mov_read_st3d(MOVContext * c,AVIOContext * pb,MOVAtom atom)5571 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5572 {
5573 AVStream *st;
5574 MOVStreamContext *sc;
5575 enum AVStereo3DType type;
5576 int mode;
5577
5578 if (c->fc->nb_streams < 1)
5579 return 0;
5580
5581 st = c->fc->streams[c->fc->nb_streams - 1];
5582 sc = st->priv_data;
5583
5584 if (atom.size < 5) {
5585 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5586 return AVERROR_INVALIDDATA;
5587 }
5588
5589 if (sc->stereo3d)
5590 return AVERROR_INVALIDDATA;
5591
5592 avio_skip(pb, 4); /* version + flags */
5593
5594 mode = avio_r8(pb);
5595 switch (mode) {
5596 case 0:
5597 type = AV_STEREO3D_2D;
5598 break;
5599 case 1:
5600 type = AV_STEREO3D_TOPBOTTOM;
5601 break;
5602 case 2:
5603 type = AV_STEREO3D_SIDEBYSIDE;
5604 break;
5605 default:
5606 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5607 return 0;
5608 }
5609
5610 sc->stereo3d = av_stereo3d_alloc();
5611 if (!sc->stereo3d)
5612 return AVERROR(ENOMEM);
5613
5614 sc->stereo3d->type = type;
5615 return 0;
5616 }
5617
mov_read_sv3d(MOVContext * c,AVIOContext * pb,MOVAtom atom)5618 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5619 {
5620 AVStream *st;
5621 MOVStreamContext *sc;
5622 int size, version, layout;
5623 int32_t yaw, pitch, roll;
5624 uint32_t l = 0, t = 0, r = 0, b = 0;
5625 uint32_t tag, padding = 0;
5626 enum AVSphericalProjection projection;
5627
5628 if (c->fc->nb_streams < 1)
5629 return 0;
5630
5631 st = c->fc->streams[c->fc->nb_streams - 1];
5632 sc = st->priv_data;
5633
5634 if (atom.size < 8) {
5635 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5636 return AVERROR_INVALIDDATA;
5637 }
5638
5639 size = avio_rb32(pb);
5640 if (size <= 12 || size > atom.size)
5641 return AVERROR_INVALIDDATA;
5642
5643 tag = avio_rl32(pb);
5644 if (tag != MKTAG('s','v','h','d')) {
5645 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5646 return 0;
5647 }
5648 version = avio_r8(pb);
5649 if (version != 0) {
5650 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5651 version);
5652 return 0;
5653 }
5654 avio_skip(pb, 3); /* flags */
5655 avio_skip(pb, size - 12); /* metadata_source */
5656
5657 size = avio_rb32(pb);
5658 if (size > atom.size)
5659 return AVERROR_INVALIDDATA;
5660
5661 tag = avio_rl32(pb);
5662 if (tag != MKTAG('p','r','o','j')) {
5663 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5664 return 0;
5665 }
5666
5667 size = avio_rb32(pb);
5668 if (size > atom.size)
5669 return AVERROR_INVALIDDATA;
5670
5671 tag = avio_rl32(pb);
5672 if (tag != MKTAG('p','r','h','d')) {
5673 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5674 return 0;
5675 }
5676 version = avio_r8(pb);
5677 if (version != 0) {
5678 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5679 version);
5680 return 0;
5681 }
5682 avio_skip(pb, 3); /* flags */
5683
5684 /* 16.16 fixed point */
5685 yaw = avio_rb32(pb);
5686 pitch = avio_rb32(pb);
5687 roll = avio_rb32(pb);
5688
5689 size = avio_rb32(pb);
5690 if (size > atom.size)
5691 return AVERROR_INVALIDDATA;
5692
5693 tag = avio_rl32(pb);
5694 version = avio_r8(pb);
5695 if (version != 0) {
5696 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5697 version);
5698 return 0;
5699 }
5700 avio_skip(pb, 3); /* flags */
5701 switch (tag) {
5702 case MKTAG('c','b','m','p'):
5703 layout = avio_rb32(pb);
5704 if (layout) {
5705 av_log(c->fc, AV_LOG_WARNING,
5706 "Unsupported cubemap layout %d\n", layout);
5707 return 0;
5708 }
5709 projection = AV_SPHERICAL_CUBEMAP;
5710 padding = avio_rb32(pb);
5711 break;
5712 case MKTAG('e','q','u','i'):
5713 t = avio_rb32(pb);
5714 b = avio_rb32(pb);
5715 l = avio_rb32(pb);
5716 r = avio_rb32(pb);
5717
5718 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5719 av_log(c->fc, AV_LOG_ERROR,
5720 "Invalid bounding rectangle coordinates "
5721 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5722 return AVERROR_INVALIDDATA;
5723 }
5724
5725 if (l || t || r || b)
5726 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5727 else
5728 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5729 break;
5730 default:
5731 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5732 return 0;
5733 }
5734
5735 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5736 if (!sc->spherical)
5737 return AVERROR(ENOMEM);
5738
5739 sc->spherical->projection = projection;
5740
5741 sc->spherical->yaw = yaw;
5742 sc->spherical->pitch = pitch;
5743 sc->spherical->roll = roll;
5744
5745 sc->spherical->padding = padding;
5746
5747 sc->spherical->bound_left = l;
5748 sc->spherical->bound_top = t;
5749 sc->spherical->bound_right = r;
5750 sc->spherical->bound_bottom = b;
5751
5752 return 0;
5753 }
5754
mov_parse_uuid_spherical(MOVStreamContext * sc,AVIOContext * pb,size_t len)5755 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5756 {
5757 int ret = 0;
5758 uint8_t *buffer = av_malloc(len + 1);
5759 const char *val;
5760
5761 if (!buffer)
5762 return AVERROR(ENOMEM);
5763 buffer[len] = '\0';
5764
5765 ret = ffio_read_size(pb, buffer, len);
5766 if (ret < 0)
5767 goto out;
5768
5769 /* Check for mandatory keys and values, try to support XML as best-effort */
5770 if (!sc->spherical &&
5771 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5772 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5773 av_stristr(val, "true") &&
5774 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5775 av_stristr(val, "true") &&
5776 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5777 av_stristr(val, "equirectangular")) {
5778 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5779 if (!sc->spherical)
5780 goto out;
5781
5782 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5783
5784 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5785 enum AVStereo3DType mode;
5786
5787 if (av_stristr(buffer, "left-right"))
5788 mode = AV_STEREO3D_SIDEBYSIDE;
5789 else if (av_stristr(buffer, "top-bottom"))
5790 mode = AV_STEREO3D_TOPBOTTOM;
5791 else
5792 mode = AV_STEREO3D_2D;
5793
5794 sc->stereo3d = av_stereo3d_alloc();
5795 if (!sc->stereo3d)
5796 goto out;
5797
5798 sc->stereo3d->type = mode;
5799 }
5800
5801 /* orientation */
5802 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5803 if (val)
5804 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5805 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5806 if (val)
5807 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5808 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5809 if (val)
5810 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5811 }
5812
5813 out:
5814 av_free(buffer);
5815 return ret;
5816 }
5817
mov_read_uuid(MOVContext * c,AVIOContext * pb,MOVAtom atom)5818 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5819 {
5820 AVStream *st;
5821 MOVStreamContext *sc;
5822 int64_t ret;
5823 uint8_t uuid[16];
5824 static const uint8_t uuid_isml_manifest[] = {
5825 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5826 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5827 };
5828 static const uint8_t uuid_xmp[] = {
5829 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5830 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5831 };
5832 static const uint8_t uuid_spherical[] = {
5833 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5834 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5835 };
5836
5837 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5838 return AVERROR_INVALIDDATA;
5839
5840 if (c->fc->nb_streams < 1)
5841 return 0;
5842 st = c->fc->streams[c->fc->nb_streams - 1];
5843 sc = st->priv_data;
5844
5845 ret = ffio_read_size(pb, uuid, sizeof(uuid));
5846 if (ret < 0)
5847 return ret;
5848 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5849 uint8_t *buffer, *ptr;
5850 char *endptr;
5851 size_t len = atom.size - sizeof(uuid);
5852
5853 if (len < 4) {
5854 return AVERROR_INVALIDDATA;
5855 }
5856 ret = avio_skip(pb, 4); // zeroes
5857 len -= 4;
5858
5859 buffer = av_mallocz(len + 1);
5860 if (!buffer) {
5861 return AVERROR(ENOMEM);
5862 }
5863 ret = ffio_read_size(pb, buffer, len);
5864 if (ret < 0) {
5865 av_free(buffer);
5866 return ret;
5867 }
5868
5869 ptr = buffer;
5870 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5871 ptr += sizeof("systemBitrate=\"") - 1;
5872 c->bitrates_count++;
5873 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5874 if (!c->bitrates) {
5875 c->bitrates_count = 0;
5876 av_free(buffer);
5877 return AVERROR(ENOMEM);
5878 }
5879 errno = 0;
5880 ret = strtol(ptr, &endptr, 10);
5881 if (ret < 0 || errno || *endptr != '"') {
5882 c->bitrates[c->bitrates_count - 1] = 0;
5883 } else {
5884 c->bitrates[c->bitrates_count - 1] = ret;
5885 }
5886 }
5887
5888 av_free(buffer);
5889 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5890 uint8_t *buffer;
5891 size_t len = atom.size - sizeof(uuid);
5892 if (c->export_xmp) {
5893 buffer = av_mallocz(len + 1);
5894 if (!buffer) {
5895 return AVERROR(ENOMEM);
5896 }
5897 ret = ffio_read_size(pb, buffer, len);
5898 if (ret < 0) {
5899 av_free(buffer);
5900 return ret;
5901 }
5902 buffer[len] = '\0';
5903 av_dict_set(&c->fc->metadata, "xmp",
5904 buffer, AV_DICT_DONT_STRDUP_VAL);
5905 } else {
5906 // skip all uuid atom, which makes it fast for long uuid-xmp file
5907 ret = avio_skip(pb, len);
5908 if (ret < 0)
5909 return ret;
5910 }
5911 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5912 size_t len = atom.size - sizeof(uuid);
5913 ret = mov_parse_uuid_spherical(sc, pb, len);
5914 if (ret < 0)
5915 return ret;
5916 if (!sc->spherical)
5917 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5918 }
5919
5920 return 0;
5921 }
5922
mov_read_free(MOVContext * c,AVIOContext * pb,MOVAtom atom)5923 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5924 {
5925 int ret;
5926 uint8_t content[16];
5927
5928 if (atom.size < 8)
5929 return 0;
5930
5931 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5932 if (ret < 0)
5933 return ret;
5934
5935 if ( !c->found_moov
5936 && !c->found_mdat
5937 && !memcmp(content, "Anevia\x1A\x1A", 8)
5938 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5939 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5940 }
5941
5942 return 0;
5943 }
5944
mov_read_frma(MOVContext * c,AVIOContext * pb,MOVAtom atom)5945 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5946 {
5947 uint32_t format = avio_rl32(pb);
5948 MOVStreamContext *sc;
5949 enum AVCodecID id;
5950 AVStream *st;
5951
5952 if (c->fc->nb_streams < 1)
5953 return 0;
5954 st = c->fc->streams[c->fc->nb_streams - 1];
5955 sc = st->priv_data;
5956
5957 switch (sc->format)
5958 {
5959 case MKTAG('e','n','c','v'): // encrypted video
5960 case MKTAG('e','n','c','a'): // encrypted audio
5961 id = mov_codec_id(st, format);
5962 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5963 st->codecpar->codec_id != id) {
5964 av_log(c->fc, AV_LOG_WARNING,
5965 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5966 (char*)&format, st->codecpar->codec_id);
5967 break;
5968 }
5969
5970 st->codecpar->codec_id = id;
5971 sc->format = format;
5972 break;
5973
5974 default:
5975 if (format != sc->format) {
5976 av_log(c->fc, AV_LOG_WARNING,
5977 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5978 (char*)&format, (char*)&sc->format);
5979 }
5980 break;
5981 }
5982
5983 return 0;
5984 }
5985
5986 /**
5987 * Gets the current encryption info and associated current stream context. If
5988 * we are parsing a track fragment, this will return the specific encryption
5989 * info for this fragment; otherwise this will return the global encryption
5990 * info for the current stream.
5991 */
get_current_encryption_info(MOVContext * c,MOVEncryptionIndex ** encryption_index,MOVStreamContext ** sc)5992 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5993 {
5994 MOVFragmentStreamInfo *frag_stream_info;
5995 AVStream *st;
5996 int i;
5997
5998 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5999 if (frag_stream_info) {
6000 for (i = 0; i < c->fc->nb_streams; i++) {
6001 if (c->fc->streams[i]->id == frag_stream_info->id) {
6002 st = c->fc->streams[i];
6003 break;
6004 }
6005 }
6006 if (i == c->fc->nb_streams)
6007 return 0;
6008 *sc = st->priv_data;
6009
6010 if (!frag_stream_info->encryption_index) {
6011 // If this stream isn't encrypted, don't create the index.
6012 if (!(*sc)->cenc.default_encrypted_sample)
6013 return 0;
6014 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
6015 if (!frag_stream_info->encryption_index)
6016 return AVERROR(ENOMEM);
6017 }
6018 *encryption_index = frag_stream_info->encryption_index;
6019 return 1;
6020 } else {
6021 // No current track fragment, using stream level encryption info.
6022
6023 if (c->fc->nb_streams < 1)
6024 return 0;
6025 st = c->fc->streams[c->fc->nb_streams - 1];
6026 *sc = st->priv_data;
6027
6028 if (!(*sc)->cenc.encryption_index) {
6029 // If this stream isn't encrypted, don't create the index.
6030 if (!(*sc)->cenc.default_encrypted_sample)
6031 return 0;
6032 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
6033 if (!(*sc)->cenc.encryption_index)
6034 return AVERROR(ENOMEM);
6035 }
6036
6037 *encryption_index = (*sc)->cenc.encryption_index;
6038 return 1;
6039 }
6040 }
6041
mov_read_sample_encryption_info(MOVContext * c,AVIOContext * pb,MOVStreamContext * sc,AVEncryptionInfo ** sample,int use_subsamples)6042 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
6043 {
6044 int i, ret;
6045 unsigned int subsample_count;
6046 AVSubsampleEncryptionInfo *subsamples;
6047
6048 if (!sc->cenc.default_encrypted_sample) {
6049 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
6050 return AVERROR_INVALIDDATA;
6051 }
6052
6053 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
6054 if (!*sample)
6055 return AVERROR(ENOMEM);
6056
6057 if (sc->cenc.per_sample_iv_size != 0) {
6058 if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
6059 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
6060 av_encryption_info_free(*sample);
6061 *sample = NULL;
6062 return ret;
6063 }
6064 }
6065
6066 if (use_subsamples) {
6067 subsample_count = avio_rb16(pb);
6068 av_free((*sample)->subsamples);
6069 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
6070 if (!(*sample)->subsamples) {
6071 av_encryption_info_free(*sample);
6072 *sample = NULL;
6073 return AVERROR(ENOMEM);
6074 }
6075
6076 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
6077 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
6078 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
6079 }
6080
6081 if (pb->eof_reached) {
6082 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
6083 av_encryption_info_free(*sample);
6084 *sample = NULL;
6085 return AVERROR_INVALIDDATA;
6086 }
6087 (*sample)->subsample_count = subsample_count;
6088 }
6089
6090 return 0;
6091 }
6092
mov_read_senc(MOVContext * c,AVIOContext * pb,MOVAtom atom)6093 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6094 {
6095 AVEncryptionInfo **encrypted_samples;
6096 MOVEncryptionIndex *encryption_index;
6097 MOVStreamContext *sc;
6098 int use_subsamples, ret;
6099 unsigned int sample_count, i, alloc_size = 0;
6100
6101 ret = get_current_encryption_info(c, &encryption_index, &sc);
6102 if (ret != 1)
6103 return ret;
6104
6105 if (encryption_index->nb_encrypted_samples) {
6106 // This can happen if we have both saio/saiz and senc atoms.
6107 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6108 return 0;
6109 }
6110
6111 avio_r8(pb); /* version */
6112 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6113
6114 sample_count = avio_rb32(pb);
6115 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6116 return AVERROR(ENOMEM);
6117
6118 for (i = 0; i < sample_count; i++) {
6119 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6120 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6121 min_samples * sizeof(*encrypted_samples));
6122 if (encrypted_samples) {
6123 encryption_index->encrypted_samples = encrypted_samples;
6124
6125 ret = mov_read_sample_encryption_info(
6126 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6127 } else {
6128 ret = AVERROR(ENOMEM);
6129 }
6130 if (pb->eof_reached) {
6131 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6132 ret = AVERROR_INVALIDDATA;
6133 }
6134
6135 if (ret < 0) {
6136 for (; i > 0; i--)
6137 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6138 av_freep(&encryption_index->encrypted_samples);
6139 return ret;
6140 }
6141 }
6142 encryption_index->nb_encrypted_samples = sample_count;
6143
6144 return 0;
6145 }
6146
mov_parse_auxiliary_info(MOVContext * c,MOVStreamContext * sc,AVIOContext * pb,MOVEncryptionIndex * encryption_index)6147 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6148 {
6149 AVEncryptionInfo **sample, **encrypted_samples;
6150 int64_t prev_pos;
6151 size_t sample_count, sample_info_size, i;
6152 int ret = 0;
6153 unsigned int alloc_size = 0;
6154
6155 if (encryption_index->nb_encrypted_samples)
6156 return 0;
6157 sample_count = encryption_index->auxiliary_info_sample_count;
6158 if (encryption_index->auxiliary_offsets_count != 1) {
6159 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6160 return AVERROR_PATCHWELCOME;
6161 }
6162 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6163 return AVERROR(ENOMEM);
6164
6165 prev_pos = avio_tell(pb);
6166 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6167 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6168 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6169 goto finish;
6170 }
6171
6172 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6173 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6174 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6175 min_samples * sizeof(*encrypted_samples));
6176 if (!encrypted_samples) {
6177 ret = AVERROR(ENOMEM);
6178 goto finish;
6179 }
6180 encryption_index->encrypted_samples = encrypted_samples;
6181
6182 sample = &encryption_index->encrypted_samples[i];
6183 sample_info_size = encryption_index->auxiliary_info_default_size
6184 ? encryption_index->auxiliary_info_default_size
6185 : encryption_index->auxiliary_info_sizes[i];
6186
6187 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6188 if (ret < 0)
6189 goto finish;
6190 }
6191 if (pb->eof_reached) {
6192 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6193 ret = AVERROR_INVALIDDATA;
6194 } else {
6195 encryption_index->nb_encrypted_samples = sample_count;
6196 }
6197
6198 finish:
6199 avio_seek(pb, prev_pos, SEEK_SET);
6200 if (ret < 0) {
6201 for (; i > 0; i--) {
6202 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6203 }
6204 av_freep(&encryption_index->encrypted_samples);
6205 }
6206 return ret;
6207 }
6208
6209 /**
6210 * Tries to read the given number of bytes from the stream and puts it in a
6211 * newly allocated buffer. This reads in small chunks to avoid allocating large
6212 * memory if the file contains an invalid/malicious size value.
6213 */
mov_try_read_block(AVIOContext * pb,size_t size,uint8_t ** data)6214 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6215 {
6216 const unsigned int block_size = 1024 * 1024;
6217 uint8_t *buffer = NULL;
6218 unsigned int alloc_size = 0, offset = 0;
6219 while (offset < size) {
6220 unsigned int new_size =
6221 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6222 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6223 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6224 if (!new_buffer) {
6225 av_free(buffer);
6226 return AVERROR(ENOMEM);
6227 }
6228 buffer = new_buffer;
6229
6230 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6231 av_free(buffer);
6232 return AVERROR_INVALIDDATA;
6233 }
6234 offset += to_read;
6235 }
6236
6237 *data = buffer;
6238 return 0;
6239 }
6240
mov_read_saiz(MOVContext * c,AVIOContext * pb,MOVAtom atom)6241 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6242 {
6243 MOVEncryptionIndex *encryption_index;
6244 MOVStreamContext *sc;
6245 int ret;
6246 unsigned int sample_count, aux_info_type, aux_info_param;
6247
6248 ret = get_current_encryption_info(c, &encryption_index, &sc);
6249 if (ret != 1)
6250 return ret;
6251
6252 if (encryption_index->nb_encrypted_samples) {
6253 // This can happen if we have both saio/saiz and senc atoms.
6254 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6255 return 0;
6256 }
6257
6258 if (encryption_index->auxiliary_info_sample_count) {
6259 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6260 return AVERROR_INVALIDDATA;
6261 }
6262
6263 avio_r8(pb); /* version */
6264 if (avio_rb24(pb) & 0x01) { /* flags */
6265 aux_info_type = avio_rb32(pb);
6266 aux_info_param = avio_rb32(pb);
6267 if (sc->cenc.default_encrypted_sample) {
6268 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6269 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6270 return 0;
6271 }
6272 if (aux_info_param != 0) {
6273 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6274 return 0;
6275 }
6276 } else {
6277 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6278 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6279 aux_info_type == MKBETAG('c','e','n','s') ||
6280 aux_info_type == MKBETAG('c','b','c','1') ||
6281 aux_info_type == MKBETAG('c','b','c','s')) &&
6282 aux_info_param == 0) {
6283 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6284 return AVERROR_INVALIDDATA;
6285 } else {
6286 return 0;
6287 }
6288 }
6289 } else if (!sc->cenc.default_encrypted_sample) {
6290 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6291 return 0;
6292 }
6293
6294 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6295 sample_count = avio_rb32(pb);
6296 encryption_index->auxiliary_info_sample_count = sample_count;
6297
6298 if (encryption_index->auxiliary_info_default_size == 0) {
6299 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6300 if (ret < 0) {
6301 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6302 return ret;
6303 }
6304 }
6305
6306 if (encryption_index->auxiliary_offsets_count) {
6307 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6308 }
6309
6310 return 0;
6311 }
6312
mov_read_saio(MOVContext * c,AVIOContext * pb,MOVAtom atom)6313 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6314 {
6315 uint64_t *auxiliary_offsets;
6316 MOVEncryptionIndex *encryption_index;
6317 MOVStreamContext *sc;
6318 int i, ret;
6319 unsigned int version, entry_count, aux_info_type, aux_info_param;
6320 unsigned int alloc_size = 0;
6321
6322 ret = get_current_encryption_info(c, &encryption_index, &sc);
6323 if (ret != 1)
6324 return ret;
6325
6326 if (encryption_index->nb_encrypted_samples) {
6327 // This can happen if we have both saio/saiz and senc atoms.
6328 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6329 return 0;
6330 }
6331
6332 if (encryption_index->auxiliary_offsets_count) {
6333 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6334 return AVERROR_INVALIDDATA;
6335 }
6336
6337 version = avio_r8(pb); /* version */
6338 if (avio_rb24(pb) & 0x01) { /* flags */
6339 aux_info_type = avio_rb32(pb);
6340 aux_info_param = avio_rb32(pb);
6341 if (sc->cenc.default_encrypted_sample) {
6342 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6343 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6344 return 0;
6345 }
6346 if (aux_info_param != 0) {
6347 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6348 return 0;
6349 }
6350 } else {
6351 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6352 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6353 aux_info_type == MKBETAG('c','e','n','s') ||
6354 aux_info_type == MKBETAG('c','b','c','1') ||
6355 aux_info_type == MKBETAG('c','b','c','s')) &&
6356 aux_info_param == 0) {
6357 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6358 return AVERROR_INVALIDDATA;
6359 } else {
6360 return 0;
6361 }
6362 }
6363 } else if (!sc->cenc.default_encrypted_sample) {
6364 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6365 return 0;
6366 }
6367
6368 entry_count = avio_rb32(pb);
6369 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6370 return AVERROR(ENOMEM);
6371
6372 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6373 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6374 auxiliary_offsets = av_fast_realloc(
6375 encryption_index->auxiliary_offsets, &alloc_size,
6376 min_offsets * sizeof(*auxiliary_offsets));
6377 if (!auxiliary_offsets) {
6378 av_freep(&encryption_index->auxiliary_offsets);
6379 return AVERROR(ENOMEM);
6380 }
6381 encryption_index->auxiliary_offsets = auxiliary_offsets;
6382
6383 if (version == 0) {
6384 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6385 } else {
6386 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6387 }
6388 if (c->frag_index.current >= 0) {
6389 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6390 }
6391 }
6392
6393 if (pb->eof_reached) {
6394 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6395 av_freep(&encryption_index->auxiliary_offsets);
6396 return AVERROR_INVALIDDATA;
6397 }
6398
6399 encryption_index->auxiliary_offsets_count = entry_count;
6400
6401 if (encryption_index->auxiliary_info_sample_count) {
6402 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6403 }
6404
6405 return 0;
6406 }
6407
mov_read_pssh(MOVContext * c,AVIOContext * pb,MOVAtom atom)6408 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6409 {
6410 AVEncryptionInitInfo *info, *old_init_info;
6411 uint8_t **key_ids;
6412 AVStream *st;
6413 uint8_t *side_data, *extra_data, *old_side_data;
6414 size_t side_data_size;
6415 buffer_size_t old_side_data_size;
6416 int ret = 0;
6417 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6418
6419 if (c->fc->nb_streams < 1)
6420 return 0;
6421 st = c->fc->streams[c->fc->nb_streams-1];
6422
6423 version = avio_r8(pb); /* version */
6424 avio_rb24(pb); /* flags */
6425
6426 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6427 /* key_id_size */ 16, /* data_size */ 0);
6428 if (!info)
6429 return AVERROR(ENOMEM);
6430
6431 if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
6432 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6433 goto finish;
6434 }
6435
6436 if (version > 0) {
6437 kid_count = avio_rb32(pb);
6438 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
6439 ret = AVERROR(ENOMEM);
6440 goto finish;
6441 }
6442
6443 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6444 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6445 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6446 min_kid_count * sizeof(*key_ids));
6447 if (!key_ids) {
6448 ret = AVERROR(ENOMEM);
6449 goto finish;
6450 }
6451 info->key_ids = key_ids;
6452
6453 info->key_ids[i] = av_mallocz(16);
6454 if (!info->key_ids[i]) {
6455 ret = AVERROR(ENOMEM);
6456 goto finish;
6457 }
6458 info->num_key_ids = i + 1;
6459
6460 if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
6461 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6462 goto finish;
6463 }
6464 }
6465
6466 if (pb->eof_reached) {
6467 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6468 ret = AVERROR_INVALIDDATA;
6469 goto finish;
6470 }
6471 }
6472
6473 extra_data_size = avio_rb32(pb);
6474 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6475 if (ret < 0)
6476 goto finish;
6477
6478 av_freep(&info->data); // malloc(0) may still allocate something.
6479 info->data = extra_data;
6480 info->data_size = extra_data_size;
6481
6482 // If there is existing initialization data, append to the list.
6483 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6484 if (old_side_data) {
6485 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6486 if (old_init_info) {
6487 // Append to the end of the list.
6488 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6489 if (!cur->next) {
6490 cur->next = info;
6491 break;
6492 }
6493 }
6494 info = old_init_info;
6495 } else {
6496 // Assume existing side-data will be valid, so the only error we could get is OOM.
6497 ret = AVERROR(ENOMEM);
6498 goto finish;
6499 }
6500 }
6501
6502 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6503 if (!side_data) {
6504 ret = AVERROR(ENOMEM);
6505 goto finish;
6506 }
6507 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6508 side_data, side_data_size);
6509 if (ret < 0)
6510 av_free(side_data);
6511
6512 finish:
6513 av_encryption_init_info_free(info);
6514 return ret;
6515 }
6516
mov_read_schm(MOVContext * c,AVIOContext * pb,MOVAtom atom)6517 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6518 {
6519 AVStream *st;
6520 MOVStreamContext *sc;
6521
6522 if (c->fc->nb_streams < 1)
6523 return 0;
6524 st = c->fc->streams[c->fc->nb_streams-1];
6525 sc = st->priv_data;
6526
6527 if (sc->pseudo_stream_id != 0) {
6528 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6529 return AVERROR_PATCHWELCOME;
6530 }
6531
6532 if (atom.size < 8)
6533 return AVERROR_INVALIDDATA;
6534
6535 avio_rb32(pb); /* version and flags */
6536
6537 if (!sc->cenc.default_encrypted_sample) {
6538 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6539 if (!sc->cenc.default_encrypted_sample) {
6540 return AVERROR(ENOMEM);
6541 }
6542 }
6543
6544 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6545 return 0;
6546 }
6547
mov_read_tenc(MOVContext * c,AVIOContext * pb,MOVAtom atom)6548 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6549 {
6550 AVStream *st;
6551 MOVStreamContext *sc;
6552 unsigned int version, pattern, is_protected, iv_size;
6553
6554 if (c->fc->nb_streams < 1)
6555 return 0;
6556 st = c->fc->streams[c->fc->nb_streams-1];
6557 sc = st->priv_data;
6558
6559 if (sc->pseudo_stream_id != 0) {
6560 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6561 return AVERROR_PATCHWELCOME;
6562 }
6563
6564 if (!sc->cenc.default_encrypted_sample) {
6565 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6566 if (!sc->cenc.default_encrypted_sample) {
6567 return AVERROR(ENOMEM);
6568 }
6569 }
6570
6571 if (atom.size < 20)
6572 return AVERROR_INVALIDDATA;
6573
6574 version = avio_r8(pb); /* version */
6575 avio_rb24(pb); /* flags */
6576
6577 avio_r8(pb); /* reserved */
6578 pattern = avio_r8(pb);
6579
6580 if (version > 0) {
6581 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6582 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6583 }
6584
6585 is_protected = avio_r8(pb);
6586 if (is_protected && !sc->cenc.encryption_index) {
6587 // The whole stream should be by-default encrypted.
6588 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6589 if (!sc->cenc.encryption_index)
6590 return AVERROR(ENOMEM);
6591 }
6592 sc->cenc.per_sample_iv_size = avio_r8(pb);
6593 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6594 sc->cenc.per_sample_iv_size != 16) {
6595 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6596 return AVERROR_INVALIDDATA;
6597 }
6598 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6599 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6600 return AVERROR_INVALIDDATA;
6601 }
6602
6603 if (is_protected && !sc->cenc.per_sample_iv_size) {
6604 iv_size = avio_r8(pb);
6605 if (iv_size != 8 && iv_size != 16) {
6606 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6607 return AVERROR_INVALIDDATA;
6608 }
6609
6610 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6611 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6612 return AVERROR_INVALIDDATA;
6613 }
6614 }
6615
6616 return 0;
6617 }
6618
mov_read_dfla(MOVContext * c,AVIOContext * pb,MOVAtom atom)6619 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6620 {
6621 AVStream *st;
6622 int last, type, size, ret;
6623 uint8_t buf[4];
6624
6625 if (c->fc->nb_streams < 1)
6626 return 0;
6627 st = c->fc->streams[c->fc->nb_streams-1];
6628
6629 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6630 return AVERROR_INVALIDDATA;
6631
6632 /* Check FlacSpecificBox version. */
6633 if (avio_r8(pb) != 0)
6634 return AVERROR_INVALIDDATA;
6635
6636 avio_rb24(pb); /* Flags */
6637
6638 avio_read(pb, buf, sizeof(buf));
6639 flac_parse_block_header(buf, &last, &type, &size);
6640
6641 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6642 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6643 return AVERROR_INVALIDDATA;
6644 }
6645
6646 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6647 if (ret < 0)
6648 return ret;
6649
6650 if (!last)
6651 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6652
6653 return 0;
6654 }
6655
cenc_decrypt(MOVContext * c,MOVStreamContext * sc,AVEncryptionInfo * sample,uint8_t * input,int size)6656 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6657 {
6658 int i, ret;
6659
6660 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6661 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6662 return AVERROR_PATCHWELCOME;
6663 }
6664
6665 if (!sc->cenc.aes_ctr) {
6666 /* initialize the cipher */
6667 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6668 if (!sc->cenc.aes_ctr) {
6669 return AVERROR(ENOMEM);
6670 }
6671
6672 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6673 if (ret < 0) {
6674 return ret;
6675 }
6676 }
6677
6678 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6679
6680 if (!sample->subsample_count) {
6681 /* decrypt the whole packet */
6682 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6683 return 0;
6684 }
6685
6686 for (i = 0; i < sample->subsample_count; i++) {
6687 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6688 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6689 return AVERROR_INVALIDDATA;
6690 }
6691
6692 /* skip the clear bytes */
6693 input += sample->subsamples[i].bytes_of_clear_data;
6694 size -= sample->subsamples[i].bytes_of_clear_data;
6695
6696 /* decrypt the encrypted bytes */
6697 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6698 input += sample->subsamples[i].bytes_of_protected_data;
6699 size -= sample->subsamples[i].bytes_of_protected_data;
6700 }
6701
6702 if (size > 0) {
6703 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6704 return AVERROR_INVALIDDATA;
6705 }
6706
6707 return 0;
6708 }
6709
cenc_filter(MOVContext * mov,AVStream * st,MOVStreamContext * sc,AVPacket * pkt,int current_index)6710 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6711 {
6712 MOVFragmentStreamInfo *frag_stream_info;
6713 MOVEncryptionIndex *encryption_index;
6714 AVEncryptionInfo *encrypted_sample;
6715 int encrypted_index, ret;
6716
6717 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6718 encrypted_index = current_index;
6719 encryption_index = NULL;
6720 if (frag_stream_info) {
6721 // Note this only supports encryption info in the first sample descriptor.
6722 if (mov->fragment.stsd_id == 1) {
6723 if (frag_stream_info->encryption_index) {
6724 encrypted_index = current_index - frag_stream_info->index_entry;
6725 encryption_index = frag_stream_info->encryption_index;
6726 } else {
6727 encryption_index = sc->cenc.encryption_index;
6728 }
6729 }
6730 } else {
6731 encryption_index = sc->cenc.encryption_index;
6732 }
6733
6734 if (encryption_index) {
6735 if (encryption_index->auxiliary_info_sample_count &&
6736 !encryption_index->nb_encrypted_samples) {
6737 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6738 return AVERROR_INVALIDDATA;
6739 }
6740 if (encryption_index->auxiliary_offsets_count &&
6741 !encryption_index->nb_encrypted_samples) {
6742 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6743 return AVERROR_INVALIDDATA;
6744 }
6745
6746 if (!encryption_index->nb_encrypted_samples) {
6747 // Full-sample encryption with default settings.
6748 encrypted_sample = sc->cenc.default_encrypted_sample;
6749 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6750 // Per-sample setting override.
6751 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6752 } else {
6753 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6754 return AVERROR_INVALIDDATA;
6755 }
6756
6757 if (mov->decryption_key) {
6758 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6759 } else {
6760 size_t size;
6761 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6762 if (!side_data)
6763 return AVERROR(ENOMEM);
6764 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6765 if (ret < 0)
6766 av_free(side_data);
6767 return ret;
6768 }
6769 }
6770
6771 return 0;
6772 }
6773
mov_read_dops(MOVContext * c,AVIOContext * pb,MOVAtom atom)6774 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6775 {
6776 const int OPUS_SEEK_PREROLL_MS = 80;
6777 int ret;
6778 AVStream *st;
6779 size_t size;
6780 uint16_t pre_skip;
6781
6782 if (c->fc->nb_streams < 1)
6783 return 0;
6784 st = c->fc->streams[c->fc->nb_streams-1];
6785
6786 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6787 return AVERROR_INVALIDDATA;
6788
6789 /* Check OpusSpecificBox version. */
6790 if (avio_r8(pb) != 0) {
6791 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6792 return AVERROR_INVALIDDATA;
6793 }
6794
6795 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6796 size = atom.size + 8;
6797
6798 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
6799 return ret;
6800
6801 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6802 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6803 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6804 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6805
6806 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6807 little-endian; aside from the preceeding magic and version they're
6808 otherwise currently identical. Data after output gain at offset 16
6809 doesn't need to be bytewapped. */
6810 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6811 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6812 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6813 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6814
6815 st->codecpar->initial_padding = pre_skip;
6816 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6817 (AVRational){1, 1000},
6818 (AVRational){1, 48000});
6819
6820 return 0;
6821 }
6822
mov_read_dmlp(MOVContext * c,AVIOContext * pb,MOVAtom atom)6823 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6824 {
6825 AVStream *st;
6826 unsigned format_info;
6827 int channel_assignment, channel_assignment1, channel_assignment2;
6828 int ratebits;
6829
6830 if (c->fc->nb_streams < 1)
6831 return 0;
6832 st = c->fc->streams[c->fc->nb_streams-1];
6833
6834 if (atom.size < 10)
6835 return AVERROR_INVALIDDATA;
6836
6837 format_info = avio_rb32(pb);
6838
6839 ratebits = (format_info >> 28) & 0xF;
6840 channel_assignment1 = (format_info >> 15) & 0x1F;
6841 channel_assignment2 = format_info & 0x1FFF;
6842 if (channel_assignment2)
6843 channel_assignment = channel_assignment2;
6844 else
6845 channel_assignment = channel_assignment1;
6846
6847 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6848 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6849 st->codecpar->channels = truehd_channels(channel_assignment);
6850 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6851
6852 return 0;
6853 }
6854
mov_read_dvcc_dvvc(MOVContext * c,AVIOContext * pb,MOVAtom atom)6855 static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6856 {
6857 AVStream *st;
6858 uint32_t buf;
6859 AVDOVIDecoderConfigurationRecord *dovi;
6860 size_t dovi_size;
6861 int ret;
6862
6863 if (c->fc->nb_streams < 1)
6864 return 0;
6865 st = c->fc->streams[c->fc->nb_streams-1];
6866
6867 if ((uint64_t)atom.size > (1<<30) || atom.size < 4)
6868 return AVERROR_INVALIDDATA;
6869
6870 dovi = av_dovi_alloc(&dovi_size);
6871 if (!dovi)
6872 return AVERROR(ENOMEM);
6873
6874 dovi->dv_version_major = avio_r8(pb);
6875 dovi->dv_version_minor = avio_r8(pb);
6876
6877 buf = avio_rb16(pb);
6878 dovi->dv_profile = (buf >> 9) & 0x7f; // 7 bits
6879 dovi->dv_level = (buf >> 3) & 0x3f; // 6 bits
6880 dovi->rpu_present_flag = (buf >> 2) & 0x01; // 1 bit
6881 dovi->el_present_flag = (buf >> 1) & 0x01; // 1 bit
6882 dovi->bl_present_flag = buf & 0x01; // 1 bit
6883 if (atom.size >= 24) { // 4 + 4 + 4 * 4
6884 buf = avio_r8(pb);
6885 dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits
6886 } else {
6887 // 0 stands for None
6888 // Dolby Vision V1.2.93 profiles and levels
6889 dovi->dv_bl_signal_compatibility_id = 0;
6890 }
6891
6892 ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF,
6893 (uint8_t *)dovi, dovi_size);
6894 if (ret < 0) {
6895 av_free(dovi);
6896 return ret;
6897 }
6898
6899 av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC box, version: %d.%d, profile: %d, level: %d, "
6900 "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n",
6901 dovi->dv_version_major, dovi->dv_version_minor,
6902 dovi->dv_profile, dovi->dv_level,
6903 dovi->rpu_present_flag,
6904 dovi->el_present_flag,
6905 dovi->bl_present_flag,
6906 dovi->dv_bl_signal_compatibility_id
6907 );
6908
6909 return 0;
6910 }
6911
6912 static const MOVParseTableEntry mov_default_parse_table[] = {
6913 { MKTAG('A','C','L','R'), mov_read_aclr },
6914 { MKTAG('A','P','R','G'), mov_read_avid },
6915 { MKTAG('A','A','L','P'), mov_read_avid },
6916 { MKTAG('A','R','E','S'), mov_read_ares },
6917 { MKTAG('a','v','s','s'), mov_read_avss },
6918 { MKTAG('a','v','1','C'), mov_read_av1c },
6919 { MKTAG('c','h','p','l'), mov_read_chpl },
6920 { MKTAG('c','o','6','4'), mov_read_stco },
6921 { MKTAG('c','o','l','r'), mov_read_colr },
6922 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6923 { MKTAG('d','i','n','f'), mov_read_default },
6924 { MKTAG('D','p','x','E'), mov_read_dpxe },
6925 { MKTAG('d','r','e','f'), mov_read_dref },
6926 { MKTAG('e','d','t','s'), mov_read_default },
6927 { MKTAG('e','l','s','t'), mov_read_elst },
6928 { MKTAG('e','n','d','a'), mov_read_enda },
6929 { MKTAG('f','i','e','l'), mov_read_fiel },
6930 { MKTAG('a','d','r','m'), mov_read_adrm },
6931 { MKTAG('f','t','y','p'), mov_read_ftyp },
6932 { MKTAG('g','l','b','l'), mov_read_glbl },
6933 { MKTAG('h','d','l','r'), mov_read_hdlr },
6934 { MKTAG('i','l','s','t'), mov_read_ilst },
6935 { MKTAG('j','p','2','h'), mov_read_jp2h },
6936 { MKTAG('m','d','a','t'), mov_read_mdat },
6937 { MKTAG('m','d','h','d'), mov_read_mdhd },
6938 { MKTAG('m','d','i','a'), mov_read_default },
6939 { MKTAG('m','e','t','a'), mov_read_meta },
6940 { MKTAG('m','i','n','f'), mov_read_default },
6941 { MKTAG('m','o','o','f'), mov_read_moof },
6942 { MKTAG('m','o','o','v'), mov_read_moov },
6943 { MKTAG('m','v','e','x'), mov_read_default },
6944 { MKTAG('m','v','h','d'), mov_read_mvhd },
6945 { MKTAG('S','M','I',' '), mov_read_svq3 },
6946 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6947 { MKTAG('a','v','c','C'), mov_read_glbl },
6948 { MKTAG('p','a','s','p'), mov_read_pasp },
6949 { MKTAG('s','i','d','x'), mov_read_sidx },
6950 { MKTAG('s','t','b','l'), mov_read_default },
6951 { MKTAG('s','t','c','o'), mov_read_stco },
6952 { MKTAG('s','t','p','s'), mov_read_stps },
6953 { MKTAG('s','t','r','f'), mov_read_strf },
6954 { MKTAG('s','t','s','c'), mov_read_stsc },
6955 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6956 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6957 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6958 { MKTAG('s','t','t','s'), mov_read_stts },
6959 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6960 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
6961 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6962 { MKTAG('t','f','d','t'), mov_read_tfdt },
6963 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6964 { MKTAG('t','r','a','k'), mov_read_trak },
6965 { MKTAG('t','r','a','f'), mov_read_default },
6966 { MKTAG('t','r','e','f'), mov_read_default },
6967 { MKTAG('t','m','c','d'), mov_read_tmcd },
6968 { MKTAG('c','h','a','p'), mov_read_chap },
6969 { MKTAG('t','r','e','x'), mov_read_trex },
6970 { MKTAG('t','r','u','n'), mov_read_trun },
6971 { MKTAG('u','d','t','a'), mov_read_default },
6972 { MKTAG('w','a','v','e'), mov_read_wave },
6973 { MKTAG('e','s','d','s'), mov_read_esds },
6974 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6975 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6976 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6977 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6978 { MKTAG('w','f','e','x'), mov_read_wfex },
6979 { MKTAG('c','m','o','v'), mov_read_cmov },
6980 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6981 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6982 { MKTAG('s','b','g','p'), mov_read_sbgp },
6983 { MKTAG('h','v','c','C'), mov_read_glbl },
6984 { MKTAG('u','u','i','d'), mov_read_uuid },
6985 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6986 { MKTAG('f','r','e','e'), mov_read_free },
6987 { MKTAG('-','-','-','-'), mov_read_custom },
6988 { MKTAG('s','i','n','f'), mov_read_default },
6989 { MKTAG('f','r','m','a'), mov_read_frma },
6990 { MKTAG('s','e','n','c'), mov_read_senc },
6991 { MKTAG('s','a','i','z'), mov_read_saiz },
6992 { MKTAG('s','a','i','o'), mov_read_saio },
6993 { MKTAG('p','s','s','h'), mov_read_pssh },
6994 { MKTAG('s','c','h','m'), mov_read_schm },
6995 { MKTAG('s','c','h','i'), mov_read_default },
6996 { MKTAG('t','e','n','c'), mov_read_tenc },
6997 { MKTAG('d','f','L','a'), mov_read_dfla },
6998 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6999 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
7000 { MKTAG('d','O','p','s'), mov_read_dops },
7001 { MKTAG('d','m','l','p'), mov_read_dmlp },
7002 { MKTAG('S','m','D','m'), mov_read_smdm },
7003 { MKTAG('C','o','L','L'), mov_read_coll },
7004 { MKTAG('v','p','c','C'), mov_read_vpcc },
7005 { MKTAG('m','d','c','v'), mov_read_mdcv },
7006 { MKTAG('c','l','l','i'), mov_read_clli },
7007 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
7008 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
7009 { 0, NULL }
7010 };
7011
mov_read_default(MOVContext * c,AVIOContext * pb,MOVAtom atom)7012 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
7013 {
7014 int64_t total_size = 0;
7015 MOVAtom a;
7016 int i;
7017
7018 if (c->atom_depth > 10) {
7019 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
7020 return AVERROR_INVALIDDATA;
7021 }
7022 c->atom_depth ++;
7023
7024 if (atom.size < 0)
7025 atom.size = INT64_MAX;
7026 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
7027 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
7028 a.size = atom.size;
7029 a.type=0;
7030 if (atom.size >= 8) {
7031 a.size = avio_rb32(pb);
7032 a.type = avio_rl32(pb);
7033 if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
7034 a.type == MKTAG('h','o','o','v')) &&
7035 a.size >= 8 &&
7036 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
7037 uint32_t type;
7038 avio_skip(pb, 4);
7039 type = avio_rl32(pb);
7040 if (avio_feof(pb))
7041 break;
7042 avio_seek(pb, -8, SEEK_CUR);
7043 if (type == MKTAG('m','v','h','d') ||
7044 type == MKTAG('c','m','o','v')) {
7045 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
7046 a.type = MKTAG('m','o','o','v');
7047 }
7048 }
7049 if (atom.type != MKTAG('r','o','o','t') &&
7050 atom.type != MKTAG('m','o','o','v')) {
7051 if (a.type == MKTAG('t','r','a','k') ||
7052 a.type == MKTAG('m','d','a','t')) {
7053 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
7054 avio_skip(pb, -8);
7055 c->atom_depth --;
7056 return 0;
7057 }
7058 }
7059 total_size += 8;
7060 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
7061 a.size = avio_rb64(pb) - 8;
7062 total_size += 8;
7063 }
7064 }
7065 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
7066 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
7067 if (a.size == 0) {
7068 a.size = atom.size - total_size + 8;
7069 }
7070 a.size -= 8;
7071 if (a.size < 0)
7072 break;
7073 a.size = FFMIN(a.size, atom.size - total_size);
7074
7075 for (i = 0; mov_default_parse_table[i].type; i++)
7076 if (mov_default_parse_table[i].type == a.type) {
7077 parse = mov_default_parse_table[i].parse;
7078 break;
7079 }
7080
7081 // container is user data
7082 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
7083 atom.type == MKTAG('i','l','s','t')))
7084 parse = mov_read_udta_string;
7085
7086 // Supports parsing the QuickTime Metadata Keys.
7087 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
7088 if (!parse && c->found_hdlr_mdta &&
7089 atom.type == MKTAG('m','e','t','a') &&
7090 a.type == MKTAG('k','e','y','s') &&
7091 c->meta_keys_count == 0) {
7092 parse = mov_read_keys;
7093 }
7094
7095 if (!parse) { /* skip leaf atoms data */
7096 avio_skip(pb, a.size);
7097 } else {
7098 int64_t start_pos = avio_tell(pb);
7099 int64_t left;
7100 int err = parse(c, pb, a);
7101 if (err < 0) {
7102 c->atom_depth --;
7103 return err;
7104 }
7105 if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
7106 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
7107 start_pos + a.size == avio_size(pb))) {
7108 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
7109 c->next_root_atom = start_pos + a.size;
7110 c->atom_depth --;
7111 return 0;
7112 }
7113 left = a.size - avio_tell(pb) + start_pos;
7114 if (left > 0) /* skip garbage at atom end */
7115 avio_skip(pb, left);
7116 else if (left < 0) {
7117 av_log(c->fc, AV_LOG_WARNING,
7118 "overread end of atom '%s' by %"PRId64" bytes\n",
7119 av_fourcc2str(a.type), -left);
7120 avio_seek(pb, left, SEEK_CUR);
7121 }
7122 }
7123
7124 total_size += a.size;
7125 }
7126
7127 if (total_size < atom.size && atom.size < 0x7ffff)
7128 avio_skip(pb, atom.size - total_size);
7129
7130 c->atom_depth --;
7131 return 0;
7132 }
7133
mov_probe(const AVProbeData * p)7134 static int mov_probe(const AVProbeData *p)
7135 {
7136 int64_t offset;
7137 uint32_t tag;
7138 int score = 0;
7139 int moov_offset = -1;
7140
7141 /* check file header */
7142 offset = 0;
7143 for (;;) {
7144 int64_t size;
7145 int minsize = 8;
7146 /* ignore invalid offset */
7147 if ((offset + 8ULL) > (unsigned int)p->buf_size)
7148 break;
7149 size = AV_RB32(p->buf + offset);
7150 if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
7151 size = AV_RB64(p->buf+offset + 8);
7152 minsize = 16;
7153 } else if (size == 0) {
7154 size = p->buf_size - offset;
7155 }
7156 if (size < minsize) {
7157 offset += 4;
7158 continue;
7159 }
7160 tag = AV_RL32(p->buf + offset + 4);
7161 switch(tag) {
7162 /* check for obvious tags */
7163 case MKTAG('m','o','o','v'):
7164 moov_offset = offset + 4;
7165 case MKTAG('m','d','a','t'):
7166 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
7167 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
7168 case MKTAG('f','t','y','p'):
7169 if (tag == MKTAG('f','t','y','p') &&
7170 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
7171 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
7172 )) {
7173 score = FFMAX(score, 5);
7174 } else {
7175 score = AVPROBE_SCORE_MAX;
7176 }
7177 break;
7178 /* those are more common words, so rate then a bit less */
7179 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
7180 case MKTAG('w','i','d','e'):
7181 case MKTAG('f','r','e','e'):
7182 case MKTAG('j','u','n','k'):
7183 case MKTAG('p','i','c','t'):
7184 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
7185 break;
7186 case MKTAG(0x82,0x82,0x7f,0x7d):
7187 case MKTAG('s','k','i','p'):
7188 case MKTAG('u','u','i','d'):
7189 case MKTAG('p','r','f','l'):
7190 /* if we only find those cause probedata is too small at least rate them */
7191 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7192 break;
7193 }
7194 if (size > INT64_MAX - offset)
7195 break;
7196 offset += size;
7197 }
7198 if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
7199 /* moov atom in the header - we should make sure that this is not a
7200 * MOV-packed MPEG-PS */
7201 offset = moov_offset;
7202
7203 while (offset < (p->buf_size - 16)) { /* Sufficient space */
7204 /* We found an actual hdlr atom */
7205 if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7206 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7207 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
7208 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7209 /* We found a media handler reference atom describing an
7210 * MPEG-PS-in-MOV, return a
7211 * low score to force expanding the probe window until
7212 * mpegps_probe finds what it needs */
7213 return 5;
7214 } else {
7215 /* Keep looking */
7216 offset += 2;
7217 }
7218 }
7219 }
7220
7221 return score;
7222 }
7223
7224 // must be done after parsing all trak because there's no order requirement
mov_read_chapters(AVFormatContext * s)7225 static void mov_read_chapters(AVFormatContext *s)
7226 {
7227 MOVContext *mov = s->priv_data;
7228 AVStream *st;
7229 MOVStreamContext *sc;
7230 int64_t cur_pos;
7231 int i, j;
7232 int chapter_track;
7233
7234 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7235 chapter_track = mov->chapter_tracks[j];
7236 st = NULL;
7237 for (i = 0; i < s->nb_streams; i++)
7238 if (s->streams[i]->id == chapter_track) {
7239 st = s->streams[i];
7240 break;
7241 }
7242 if (!st) {
7243 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7244 continue;
7245 }
7246
7247 sc = st->priv_data;
7248 cur_pos = avio_tell(sc->pb);
7249
7250 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7251 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7252 if (st->nb_index_entries) {
7253 // Retrieve the first frame, if possible
7254 AVIndexEntry *sample = &st->index_entries[0];
7255 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7256 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7257 goto finish;
7258 }
7259
7260 if (av_get_packet(sc->pb, &st->attached_pic, sample->size) < 0)
7261 goto finish;
7262
7263 st->attached_pic.stream_index = st->index;
7264 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
7265 }
7266 } else {
7267 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7268 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7269 st->discard = AVDISCARD_ALL;
7270 for (i = 0; i < st->nb_index_entries; i++) {
7271 AVIndexEntry *sample = &st->index_entries[i];
7272 int64_t end = i+1 < st->nb_index_entries ? st->index_entries[i+1].timestamp : st->duration;
7273 uint8_t *title;
7274 uint16_t ch;
7275 int len, title_len;
7276
7277 if (end < sample->timestamp) {
7278 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7279 end = AV_NOPTS_VALUE;
7280 }
7281
7282 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7283 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7284 goto finish;
7285 }
7286
7287 // the first two bytes are the length of the title
7288 len = avio_rb16(sc->pb);
7289 if (len > sample->size-2)
7290 continue;
7291 title_len = 2*len + 1;
7292 if (!(title = av_mallocz(title_len)))
7293 goto finish;
7294
7295 // The samples could theoretically be in any encoding if there's an encd
7296 // atom following, but in practice are only utf-8 or utf-16, distinguished
7297 // instead by the presence of a BOM
7298 if (!len) {
7299 title[0] = 0;
7300 } else {
7301 ch = avio_rb16(sc->pb);
7302 if (ch == 0xfeff)
7303 avio_get_str16be(sc->pb, len, title, title_len);
7304 else if (ch == 0xfffe)
7305 avio_get_str16le(sc->pb, len, title, title_len);
7306 else {
7307 AV_WB16(title, ch);
7308 if (len == 1 || len == 2)
7309 title[len] = 0;
7310 else
7311 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7312 }
7313 }
7314
7315 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7316 av_freep(&title);
7317 }
7318 }
7319 finish:
7320 avio_seek(sc->pb, cur_pos, SEEK_SET);
7321 }
7322 }
7323
parse_timecode_in_framenum_format(AVFormatContext * s,AVStream * st,uint32_t value,int flags)7324 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7325 uint32_t value, int flags)
7326 {
7327 AVTimecode tc;
7328 char buf[AV_TIMECODE_STR_SIZE];
7329 AVRational rate = st->avg_frame_rate;
7330 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7331 if (ret < 0)
7332 return ret;
7333 av_dict_set(&st->metadata, "timecode",
7334 av_timecode_make_string(&tc, buf, value), 0);
7335 return 0;
7336 }
7337
mov_read_rtmd_track(AVFormatContext * s,AVStream * st)7338 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7339 {
7340 MOVStreamContext *sc = st->priv_data;
7341 char buf[AV_TIMECODE_STR_SIZE];
7342 int64_t cur_pos = avio_tell(sc->pb);
7343 int hh, mm, ss, ff, drop;
7344
7345 if (!st->nb_index_entries)
7346 return -1;
7347
7348 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7349 avio_skip(s->pb, 13);
7350 hh = avio_r8(s->pb);
7351 mm = avio_r8(s->pb);
7352 ss = avio_r8(s->pb);
7353 drop = avio_r8(s->pb);
7354 ff = avio_r8(s->pb);
7355 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7356 hh, mm, ss, drop ? ';' : ':', ff);
7357 av_dict_set(&st->metadata, "timecode", buf, 0);
7358
7359 avio_seek(sc->pb, cur_pos, SEEK_SET);
7360 return 0;
7361 }
7362
mov_read_timecode_track(AVFormatContext * s,AVStream * st)7363 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7364 {
7365 MOVStreamContext *sc = st->priv_data;
7366 int flags = 0;
7367 int64_t cur_pos = avio_tell(sc->pb);
7368 uint32_t value;
7369
7370 if (!st->nb_index_entries)
7371 return -1;
7372
7373 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7374 value = avio_rb32(s->pb);
7375
7376 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7377 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7378 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7379
7380 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7381 * not the case) and thus assume "frame number format" instead of QT one.
7382 * No sample with tmcd track can be found with a QT timecode at the moment,
7383 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7384 * format). */
7385 parse_timecode_in_framenum_format(s, st, value, flags);
7386
7387 avio_seek(sc->pb, cur_pos, SEEK_SET);
7388 return 0;
7389 }
7390
mov_free_encryption_index(MOVEncryptionIndex ** index)7391 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7392 int i;
7393 if (!index || !*index) return;
7394 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7395 av_encryption_info_free((*index)->encrypted_samples[i]);
7396 }
7397 av_freep(&(*index)->encrypted_samples);
7398 av_freep(&(*index)->auxiliary_info_sizes);
7399 av_freep(&(*index)->auxiliary_offsets);
7400 av_freep(index);
7401 }
7402
mov_read_close(AVFormatContext * s)7403 static int mov_read_close(AVFormatContext *s)
7404 {
7405 MOVContext *mov = s->priv_data;
7406 int i, j;
7407
7408 for (i = 0; i < s->nb_streams; i++) {
7409 AVStream *st = s->streams[i];
7410 MOVStreamContext *sc = st->priv_data;
7411
7412 if (!sc)
7413 continue;
7414
7415 av_freep(&sc->ctts_data);
7416 for (j = 0; j < sc->drefs_count; j++) {
7417 av_freep(&sc->drefs[j].path);
7418 av_freep(&sc->drefs[j].dir);
7419 }
7420 av_freep(&sc->drefs);
7421
7422 sc->drefs_count = 0;
7423
7424 if (!sc->pb_is_copied)
7425 ff_format_io_close(s, &sc->pb);
7426
7427 sc->pb = NULL;
7428 av_freep(&sc->chunk_offsets);
7429 av_freep(&sc->stsc_data);
7430 av_freep(&sc->sample_sizes);
7431 av_freep(&sc->keyframes);
7432 av_freep(&sc->stts_data);
7433 av_freep(&sc->sdtp_data);
7434 av_freep(&sc->stps_data);
7435 av_freep(&sc->elst_data);
7436 av_freep(&sc->rap_group);
7437 av_freep(&sc->display_matrix);
7438 av_freep(&sc->index_ranges);
7439
7440 if (sc->extradata)
7441 for (j = 0; j < sc->stsd_count; j++)
7442 av_free(sc->extradata[j]);
7443 av_freep(&sc->extradata);
7444 av_freep(&sc->extradata_size);
7445
7446 mov_free_encryption_index(&sc->cenc.encryption_index);
7447 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7448 av_aes_ctr_free(sc->cenc.aes_ctr);
7449
7450 av_freep(&sc->stereo3d);
7451 av_freep(&sc->spherical);
7452 av_freep(&sc->mastering);
7453 av_freep(&sc->coll);
7454 }
7455
7456 av_freep(&mov->dv_demux);
7457 avformat_free_context(mov->dv_fctx);
7458 mov->dv_fctx = NULL;
7459
7460 if (mov->meta_keys) {
7461 for (i = 1; i < mov->meta_keys_count; i++) {
7462 av_freep(&mov->meta_keys[i]);
7463 }
7464 av_freep(&mov->meta_keys);
7465 }
7466
7467 av_freep(&mov->trex_data);
7468 av_freep(&mov->bitrates);
7469
7470 for (i = 0; i < mov->frag_index.nb_items; i++) {
7471 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7472 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7473 mov_free_encryption_index(&frag[j].encryption_index);
7474 }
7475 av_freep(&mov->frag_index.item[i].stream_info);
7476 }
7477 av_freep(&mov->frag_index.item);
7478
7479 av_freep(&mov->aes_decrypt);
7480 av_freep(&mov->chapter_tracks);
7481
7482 return 0;
7483 }
7484
tmcd_is_referenced(AVFormatContext * s,int tmcd_id)7485 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7486 {
7487 int i;
7488
7489 for (i = 0; i < s->nb_streams; i++) {
7490 AVStream *st = s->streams[i];
7491 MOVStreamContext *sc = st->priv_data;
7492
7493 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7494 sc->timecode_track == tmcd_id)
7495 return 1;
7496 }
7497 return 0;
7498 }
7499
7500 /* look for a tmcd track not referenced by any video track, and export it globally */
export_orphan_timecode(AVFormatContext * s)7501 static void export_orphan_timecode(AVFormatContext *s)
7502 {
7503 int i;
7504
7505 for (i = 0; i < s->nb_streams; i++) {
7506 AVStream *st = s->streams[i];
7507
7508 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7509 !tmcd_is_referenced(s, i + 1)) {
7510 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7511 if (tcr) {
7512 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7513 break;
7514 }
7515 }
7516 }
7517 }
7518
read_tfra(MOVContext * mov,AVIOContext * f)7519 static int read_tfra(MOVContext *mov, AVIOContext *f)
7520 {
7521 int version, fieldlength, i, j;
7522 int64_t pos = avio_tell(f);
7523 uint32_t size = avio_rb32(f);
7524 unsigned track_id, item_count;
7525
7526 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7527 return 1;
7528 }
7529 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7530
7531 version = avio_r8(f);
7532 avio_rb24(f);
7533 track_id = avio_rb32(f);
7534 fieldlength = avio_rb32(f);
7535 item_count = avio_rb32(f);
7536 for (i = 0; i < item_count; i++) {
7537 int64_t time, offset;
7538 int index;
7539 MOVFragmentStreamInfo * frag_stream_info;
7540
7541 if (avio_feof(f)) {
7542 return AVERROR_INVALIDDATA;
7543 }
7544
7545 if (version == 1) {
7546 time = avio_rb64(f);
7547 offset = avio_rb64(f);
7548 } else {
7549 time = avio_rb32(f);
7550 offset = avio_rb32(f);
7551 }
7552
7553 // The first sample of each stream in a fragment is always a random
7554 // access sample. So it's entry in the tfra can be used as the
7555 // initial PTS of the fragment.
7556 index = update_frag_index(mov, offset);
7557 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7558 if (frag_stream_info &&
7559 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7560 frag_stream_info->first_tfra_pts = time;
7561
7562 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7563 avio_r8(f);
7564 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7565 avio_r8(f);
7566 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7567 avio_r8(f);
7568 }
7569
7570 avio_seek(f, pos + size, SEEK_SET);
7571 return 0;
7572 }
7573
mov_read_mfra(MOVContext * c,AVIOContext * f)7574 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7575 {
7576 int64_t stream_size = avio_size(f);
7577 int64_t original_pos = avio_tell(f);
7578 int64_t seek_ret;
7579 int ret = -1;
7580 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7581 ret = seek_ret;
7582 goto fail;
7583 }
7584 c->mfra_size = avio_rb32(f);
7585 c->have_read_mfra_size = 1;
7586 if (!c->mfra_size || c->mfra_size > stream_size) {
7587 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7588 goto fail;
7589 }
7590 if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
7591 ret = seek_ret;
7592 goto fail;
7593 }
7594 if (avio_rb32(f) != c->mfra_size) {
7595 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7596 goto fail;
7597 }
7598 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7599 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7600 goto fail;
7601 }
7602 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7603 do {
7604 ret = read_tfra(c, f);
7605 if (ret < 0)
7606 goto fail;
7607 } while (!ret);
7608 ret = 0;
7609 c->frag_index.complete = 1;
7610 fail:
7611 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7612 if (seek_ret < 0) {
7613 av_log(c->fc, AV_LOG_ERROR,
7614 "failed to seek back after looking for mfra\n");
7615 ret = seek_ret;
7616 }
7617 return ret;
7618 }
7619
mov_read_header(AVFormatContext * s)7620 static int mov_read_header(AVFormatContext *s)
7621 {
7622 MOVContext *mov = s->priv_data;
7623 AVIOContext *pb = s->pb;
7624 int j, err;
7625 MOVAtom atom = { AV_RL32("root") };
7626 int i;
7627
7628 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7629 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7630 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7631 return AVERROR(EINVAL);
7632 }
7633
7634 mov->fc = s;
7635 mov->trak_index = -1;
7636 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7637 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7638 atom.size = avio_size(pb);
7639 else
7640 atom.size = INT64_MAX;
7641
7642 /* check MOV header */
7643 do {
7644 if (mov->moov_retry)
7645 avio_seek(pb, 0, SEEK_SET);
7646 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7647 av_log(s, AV_LOG_ERROR, "error reading header\n");
7648 goto fail;
7649 }
7650 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7651 if (!mov->found_moov) {
7652 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7653 err = AVERROR_INVALIDDATA;
7654 goto fail;
7655 }
7656 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7657
7658 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7659 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7660 mov_read_chapters(s);
7661 for (i = 0; i < s->nb_streams; i++)
7662 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7663 mov_read_timecode_track(s, s->streams[i]);
7664 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7665 mov_read_rtmd_track(s, s->streams[i]);
7666 }
7667 }
7668
7669 /* copy timecode metadata from tmcd tracks to the related video streams */
7670 for (i = 0; i < s->nb_streams; i++) {
7671 AVStream *st = s->streams[i];
7672 MOVStreamContext *sc = st->priv_data;
7673 if (sc->timecode_track > 0) {
7674 AVDictionaryEntry *tcr;
7675 int tmcd_st_id = -1;
7676
7677 for (j = 0; j < s->nb_streams; j++)
7678 if (s->streams[j]->id == sc->timecode_track)
7679 tmcd_st_id = j;
7680
7681 if (tmcd_st_id < 0 || tmcd_st_id == i)
7682 continue;
7683 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7684 if (tcr)
7685 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7686 }
7687 }
7688 export_orphan_timecode(s);
7689
7690 for (i = 0; i < s->nb_streams; i++) {
7691 AVStream *st = s->streams[i];
7692 MOVStreamContext *sc = st->priv_data;
7693 fix_timescale(mov, sc);
7694 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
7695 st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7696 st->internal->skip_samples = sc->start_pad;
7697 }
7698 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7699 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7700 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7701 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7702 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7703 st->codecpar->width = sc->width;
7704 st->codecpar->height = sc->height;
7705 }
7706 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7707 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7708 goto fail;
7709 }
7710 }
7711 if (mov->handbrake_version &&
7712 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7713 st->codecpar->codec_id == AV_CODEC_ID_MP3) {
7714 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7715 st->need_parsing = AVSTREAM_PARSE_FULL;
7716 }
7717 }
7718
7719 if (mov->trex_data) {
7720 for (i = 0; i < s->nb_streams; i++) {
7721 AVStream *st = s->streams[i];
7722 MOVStreamContext *sc = st->priv_data;
7723 if (st->duration > 0) {
7724 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7725 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7726 sc->data_size, sc->time_scale);
7727 err = AVERROR_INVALIDDATA;
7728 goto fail;
7729 }
7730 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7731 }
7732 }
7733 }
7734
7735 if (mov->use_mfra_for > 0) {
7736 for (i = 0; i < s->nb_streams; i++) {
7737 AVStream *st = s->streams[i];
7738 MOVStreamContext *sc = st->priv_data;
7739 if (sc->duration_for_fps > 0) {
7740 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7741 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7742 sc->data_size, sc->time_scale);
7743 err = AVERROR_INVALIDDATA;
7744 goto fail;
7745 }
7746 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7747 sc->duration_for_fps;
7748 }
7749 }
7750 }
7751
7752 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7753 if (mov->bitrates[i]) {
7754 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7755 }
7756 }
7757
7758 ff_rfps_calculate(s);
7759
7760 for (i = 0; i < s->nb_streams; i++) {
7761 AVStream *st = s->streams[i];
7762 MOVStreamContext *sc = st->priv_data;
7763
7764 switch (st->codecpar->codec_type) {
7765 case AVMEDIA_TYPE_AUDIO:
7766 err = ff_replaygain_export(st, s->metadata);
7767 if (err < 0)
7768 goto fail;
7769 break;
7770 case AVMEDIA_TYPE_VIDEO:
7771 if (sc->display_matrix) {
7772 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7773 sizeof(int32_t) * 9);
7774 if (err < 0)
7775 goto fail;
7776
7777 sc->display_matrix = NULL;
7778 }
7779 if (sc->stereo3d) {
7780 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7781 (uint8_t *)sc->stereo3d,
7782 sizeof(*sc->stereo3d));
7783 if (err < 0)
7784 goto fail;
7785
7786 sc->stereo3d = NULL;
7787 }
7788 if (sc->spherical) {
7789 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7790 (uint8_t *)sc->spherical,
7791 sc->spherical_size);
7792 if (err < 0)
7793 goto fail;
7794
7795 sc->spherical = NULL;
7796 }
7797 if (sc->mastering) {
7798 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7799 (uint8_t *)sc->mastering,
7800 sizeof(*sc->mastering));
7801 if (err < 0)
7802 goto fail;
7803
7804 sc->mastering = NULL;
7805 }
7806 if (sc->coll) {
7807 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7808 (uint8_t *)sc->coll,
7809 sc->coll_size);
7810 if (err < 0)
7811 goto fail;
7812
7813 sc->coll = NULL;
7814 }
7815 break;
7816 }
7817 }
7818 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7819
7820 for (i = 0; i < mov->frag_index.nb_items; i++)
7821 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7822 mov->frag_index.item[i].headers_read = 1;
7823
7824 return 0;
7825 fail:
7826 mov_read_close(s);
7827 return err;
7828 }
7829
mov_find_next_sample(AVFormatContext * s,AVStream ** st)7830 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7831 {
7832 AVIndexEntry *sample = NULL;
7833 int64_t best_dts = INT64_MAX;
7834 int i;
7835 for (i = 0; i < s->nb_streams; i++) {
7836 AVStream *avst = s->streams[i];
7837 MOVStreamContext *msc = avst->priv_data;
7838 if (msc->pb && msc->current_sample < avst->nb_index_entries) {
7839 AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample];
7840 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7841 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7842 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7843 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7844 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
7845 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7846 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7847 sample = current_sample;
7848 best_dts = dts;
7849 *st = avst;
7850 }
7851 }
7852 }
7853 return sample;
7854 }
7855
should_retry(AVIOContext * pb,int error_code)7856 static int should_retry(AVIOContext *pb, int error_code) {
7857 if (error_code == AVERROR_EOF || avio_feof(pb))
7858 return 0;
7859
7860 return 1;
7861 }
7862
mov_switch_root(AVFormatContext * s,int64_t target,int index)7863 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7864 {
7865 int ret;
7866 MOVContext *mov = s->priv_data;
7867
7868 if (index >= 0 && index < mov->frag_index.nb_items)
7869 target = mov->frag_index.item[index].moof_offset;
7870 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7871 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7872 return AVERROR_INVALIDDATA;
7873 }
7874
7875 mov->next_root_atom = 0;
7876 if (index < 0 || index >= mov->frag_index.nb_items)
7877 index = search_frag_moof_offset(&mov->frag_index, target);
7878 if (index < mov->frag_index.nb_items &&
7879 mov->frag_index.item[index].moof_offset == target) {
7880 if (index + 1 < mov->frag_index.nb_items)
7881 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7882 if (mov->frag_index.item[index].headers_read)
7883 return 0;
7884 mov->frag_index.item[index].headers_read = 1;
7885 }
7886
7887 mov->found_mdat = 0;
7888
7889 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7890 if (ret < 0)
7891 return ret;
7892 if (avio_feof(s->pb))
7893 return AVERROR_EOF;
7894 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7895
7896 return 1;
7897 }
7898
mov_change_extradata(MOVStreamContext * sc,AVPacket * pkt)7899 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7900 {
7901 uint8_t *side, *extradata;
7902 int extradata_size;
7903
7904 /* Save the current index. */
7905 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7906
7907 /* Notify the decoder that extradata changed. */
7908 extradata_size = sc->extradata_size[sc->last_stsd_index];
7909 extradata = sc->extradata[sc->last_stsd_index];
7910 if (extradata_size > 0 && extradata) {
7911 side = av_packet_new_side_data(pkt,
7912 AV_PKT_DATA_NEW_EXTRADATA,
7913 extradata_size);
7914 if (!side)
7915 return AVERROR(ENOMEM);
7916 memcpy(side, extradata, extradata_size);
7917 }
7918
7919 return 0;
7920 }
7921
get_eia608_packet(AVIOContext * pb,AVPacket * pkt,int size)7922 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int size)
7923 {
7924 int new_size, ret;
7925
7926 if (size <= 8)
7927 return AVERROR_INVALIDDATA;
7928 new_size = ((size - 8) / 2) * 3;
7929 ret = av_new_packet(pkt, new_size);
7930 if (ret < 0)
7931 return ret;
7932
7933 avio_skip(pb, 8);
7934 for (int j = 0; j < new_size; j += 3) {
7935 pkt->data[j] = 0xFC;
7936 pkt->data[j+1] = avio_r8(pb);
7937 pkt->data[j+2] = avio_r8(pb);
7938 }
7939
7940 return 0;
7941 }
7942
mov_read_packet(AVFormatContext * s,AVPacket * pkt)7943 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7944 {
7945 MOVContext *mov = s->priv_data;
7946 MOVStreamContext *sc;
7947 AVIndexEntry *sample;
7948 AVStream *st = NULL;
7949 int64_t current_index;
7950 int ret;
7951 mov->fc = s;
7952 retry:
7953 sample = mov_find_next_sample(s, &st);
7954 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7955 if (!mov->next_root_atom)
7956 return AVERROR_EOF;
7957 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7958 return ret;
7959 goto retry;
7960 }
7961 sc = st->priv_data;
7962 /* must be done just before reading, to avoid infinite loop on sample */
7963 current_index = sc->current_index;
7964 mov_current_sample_inc(sc);
7965
7966 if (mov->next_root_atom) {
7967 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7968 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7969 }
7970
7971 if (st->discard != AVDISCARD_ALL) {
7972 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7973 if (ret64 != sample->pos) {
7974 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7975 sc->ffindex, sample->pos);
7976 if (should_retry(sc->pb, ret64)) {
7977 mov_current_sample_dec(sc);
7978 }
7979 return AVERROR_INVALIDDATA;
7980 }
7981
7982 if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
7983 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7984 goto retry;
7985 }
7986
7987 if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
7988 ret = get_eia608_packet(sc->pb, pkt, sample->size);
7989 else
7990 ret = av_get_packet(sc->pb, pkt, sample->size);
7991 if (ret < 0) {
7992 if (should_retry(sc->pb, ret)) {
7993 mov_current_sample_dec(sc);
7994 }
7995 return ret;
7996 }
7997 #if CONFIG_DV_DEMUXER
7998 if (mov->dv_demux && sc->dv_audio_container) {
7999 AVBufferRef *buf = pkt->buf;
8000 ret = avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
8001 pkt->buf = buf;
8002 av_packet_unref(pkt);
8003 if (ret < 0)
8004 return ret;
8005 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
8006 if (ret < 0)
8007 return ret;
8008 }
8009 #endif
8010 if (sc->has_palette) {
8011 uint8_t *pal;
8012
8013 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
8014 if (!pal) {
8015 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
8016 } else {
8017 memcpy(pal, sc->palette, AVPALETTE_SIZE);
8018 sc->has_palette = 0;
8019 }
8020 }
8021 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
8022 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
8023 st->need_parsing = AVSTREAM_PARSE_FULL;
8024 }
8025 }
8026
8027 pkt->stream_index = sc->ffindex;
8028 pkt->dts = sample->timestamp;
8029 if (sample->flags & AVINDEX_DISCARD_FRAME) {
8030 pkt->flags |= AV_PKT_FLAG_DISCARD;
8031 }
8032 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
8033 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
8034 /* update ctts context */
8035 sc->ctts_sample++;
8036 if (sc->ctts_index < sc->ctts_count &&
8037 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
8038 sc->ctts_index++;
8039 sc->ctts_sample = 0;
8040 }
8041 } else {
8042 int64_t next_dts = (sc->current_sample < st->nb_index_entries) ?
8043 st->index_entries[sc->current_sample].timestamp : st->duration;
8044
8045 if (next_dts >= pkt->dts)
8046 pkt->duration = next_dts - pkt->dts;
8047 pkt->pts = pkt->dts;
8048 }
8049 if (st->discard == AVDISCARD_ALL)
8050 goto retry;
8051 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
8052 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
8053 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
8054 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
8055 }
8056 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
8057 pkt->pos = sample->pos;
8058
8059 /* Multiple stsd handling. */
8060 if (sc->stsc_data) {
8061 /* Keep track of the stsc index for the given sample, then check
8062 * if the stsd index is different from the last used one. */
8063 sc->stsc_sample++;
8064 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
8065 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
8066 sc->stsc_index++;
8067 sc->stsc_sample = 0;
8068 /* Do not check indexes after a switch. */
8069 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
8070 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
8071 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
8072 ret = mov_change_extradata(sc, pkt);
8073 if (ret < 0)
8074 return ret;
8075 }
8076 }
8077
8078 if (mov->aax_mode)
8079 aax_filter(pkt->data, pkt->size, mov);
8080
8081 ret = cenc_filter(mov, st, sc, pkt, current_index);
8082 if (ret < 0) {
8083 return ret;
8084 }
8085
8086 return 0;
8087 }
8088
mov_seek_fragment(AVFormatContext * s,AVStream * st,int64_t timestamp)8089 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
8090 {
8091 MOVContext *mov = s->priv_data;
8092 int index;
8093
8094 if (!mov->frag_index.complete)
8095 return 0;
8096
8097 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
8098 if (index < 0)
8099 index = 0;
8100 if (!mov->frag_index.item[index].headers_read)
8101 return mov_switch_root(s, -1, index);
8102 if (index + 1 < mov->frag_index.nb_items)
8103 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
8104
8105 return 0;
8106 }
8107
mov_seek_stream(AVFormatContext * s,AVStream * st,int64_t timestamp,int flags)8108 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
8109 {
8110 MOVStreamContext *sc = st->priv_data;
8111 int sample, time_sample, ret;
8112 unsigned int i;
8113
8114 // Here we consider timestamp to be PTS, hence try to offset it so that we
8115 // can search over the DTS timeline.
8116 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
8117
8118 ret = mov_seek_fragment(s, st, timestamp);
8119 if (ret < 0)
8120 return ret;
8121
8122 sample = av_index_search_timestamp(st, timestamp, flags);
8123 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
8124 if (sample < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp)
8125 sample = 0;
8126 if (sample < 0) /* not sure what to do */
8127 return AVERROR_INVALIDDATA;
8128 mov_current_sample_set(sc, sample);
8129 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
8130 /* adjust ctts index */
8131 if (sc->ctts_data) {
8132 time_sample = 0;
8133 for (i = 0; i < sc->ctts_count; i++) {
8134 int next = time_sample + sc->ctts_data[i].count;
8135 if (next > sc->current_sample) {
8136 sc->ctts_index = i;
8137 sc->ctts_sample = sc->current_sample - time_sample;
8138 break;
8139 }
8140 time_sample = next;
8141 }
8142 }
8143
8144 /* adjust stsd index */
8145 if (sc->chunk_count) {
8146 time_sample = 0;
8147 for (i = 0; i < sc->stsc_count; i++) {
8148 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
8149 if (next > sc->current_sample) {
8150 sc->stsc_index = i;
8151 sc->stsc_sample = sc->current_sample - time_sample;
8152 break;
8153 }
8154 av_assert0(next == (int)next);
8155 time_sample = next;
8156 }
8157 }
8158
8159 return sample;
8160 }
8161
mov_get_skip_samples(AVStream * st,int sample)8162 static int64_t mov_get_skip_samples(AVStream *st, int sample)
8163 {
8164 MOVStreamContext *sc = st->priv_data;
8165 int64_t first_ts = st->index_entries[0].timestamp;
8166 int64_t ts = st->index_entries[sample].timestamp;
8167 int64_t off;
8168
8169 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO)
8170 return 0;
8171
8172 /* compute skip samples according to stream start_pad, seek ts and first ts */
8173 off = av_rescale_q(ts - first_ts, st->time_base,
8174 (AVRational){1, st->codecpar->sample_rate});
8175 return FFMAX(sc->start_pad - off, 0);
8176 }
8177
mov_read_seek(AVFormatContext * s,int stream_index,int64_t sample_time,int flags)8178 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
8179 {
8180 MOVContext *mc = s->priv_data;
8181 AVStream *st;
8182 int sample;
8183 int i;
8184
8185 if (stream_index >= s->nb_streams)
8186 return AVERROR_INVALIDDATA;
8187
8188 st = s->streams[stream_index];
8189 sample = mov_seek_stream(s, st, sample_time, flags);
8190 if (sample < 0)
8191 return sample;
8192
8193 if (mc->seek_individually) {
8194 /* adjust seek timestamp to found sample timestamp */
8195 int64_t seek_timestamp = st->index_entries[sample].timestamp;
8196 st->internal->skip_samples = mov_get_skip_samples(st, sample);
8197
8198 for (i = 0; i < s->nb_streams; i++) {
8199 int64_t timestamp;
8200 st = s->streams[i];
8201
8202 if (stream_index == i)
8203 continue;
8204
8205 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
8206 sample = mov_seek_stream(s, st, timestamp, flags);
8207 if (sample >= 0)
8208 st->internal->skip_samples = mov_get_skip_samples(st, sample);
8209 }
8210 } else {
8211 for (i = 0; i < s->nb_streams; i++) {
8212 MOVStreamContext *sc;
8213 st = s->streams[i];
8214 sc = st->priv_data;
8215 mov_current_sample_set(sc, 0);
8216 }
8217 while (1) {
8218 MOVStreamContext *sc;
8219 AVIndexEntry *entry = mov_find_next_sample(s, &st);
8220 if (!entry)
8221 return AVERROR_INVALIDDATA;
8222 sc = st->priv_data;
8223 if (sc->ffindex == stream_index && sc->current_sample == sample)
8224 break;
8225 mov_current_sample_inc(sc);
8226 }
8227 }
8228 return 0;
8229 }
8230
8231 #define OFFSET(x) offsetof(MOVContext, x)
8232 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
8233 static const AVOption mov_options[] = {
8234 {"use_absolute_path",
8235 "allow using absolute path when opening alias, this is a possible security issue",
8236 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
8237 0, 1, FLAGS},
8238 {"seek_streams_individually",
8239 "Seek each stream individually to the closest point",
8240 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
8241 0, 1, FLAGS},
8242 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
8243 0, 1, FLAGS},
8244 {"advanced_editlist",
8245 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
8246 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
8247 0, 1, FLAGS},
8248 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8249 0, 1, FLAGS},
8250 {"use_mfra_for",
8251 "use mfra for fragment timestamps",
8252 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8253 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8254 "use_mfra_for"},
8255 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8256 FLAGS, "use_mfra_for" },
8257 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8258 FLAGS, "use_mfra_for" },
8259 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8260 FLAGS, "use_mfra_for" },
8261 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8262 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8263 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8264 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8265 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8266 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8267 { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
8268 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8269 { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
8270 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8271 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8272 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8273 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8274 .flags = AV_OPT_FLAG_DECODING_PARAM },
8275 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8276 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8277 {.i64 = 0}, 0, 1, FLAGS },
8278
8279 { NULL },
8280 };
8281
8282 static const AVClass mov_class = {
8283 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8284 .item_name = av_default_item_name,
8285 .option = mov_options,
8286 .version = LIBAVUTIL_VERSION_INT,
8287 };
8288
8289 AVInputFormat ff_mov_demuxer = {
8290 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8291 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8292 .priv_class = &mov_class,
8293 .priv_data_size = sizeof(MOVContext),
8294 .extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
8295 .read_probe = mov_probe,
8296 .read_header = mov_read_header,
8297 .read_packet = mov_read_packet,
8298 .read_close = mov_read_close,
8299 .read_seek = mov_read_seek,
8300 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,
8301 };
8302