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