FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/mov.c
Date: 2024-04-25 05:10:44
Exec Total Coverage
Lines: 3885 6152 63.2%
Functions: 157 196 80.1%
Branches: 2200 4139 53.2%

Line Branch Exec Source
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 "config_components.h"
27
28 #include <inttypes.h>
29 #include <limits.h>
30 #include <stdint.h>
31
32 #include "libavutil/attributes.h"
33 #include "libavutil/bprint.h"
34 #include "libavutil/channel_layout.h"
35 #include "libavutil/dict_internal.h"
36 #include "libavutil/internal.h"
37 #include "libavutil/intreadwrite.h"
38 #include "libavutil/intfloat.h"
39 #include "libavutil/mathematics.h"
40 #include "libavutil/avassert.h"
41 #include "libavutil/avstring.h"
42 #include "libavutil/dict.h"
43 #include "libavutil/mem.h"
44 #include "libavutil/opt.h"
45 #include "libavutil/aes.h"
46 #include "libavutil/aes_ctr.h"
47 #include "libavutil/pixdesc.h"
48 #include "libavutil/sha.h"
49 #include "libavutil/spherical.h"
50 #include "libavutil/stereo3d.h"
51 #include "libavutil/timecode.h"
52 #include "libavutil/uuid.h"
53 #include "libavcodec/ac3tab.h"
54 #include "libavcodec/flac.h"
55 #include "libavcodec/hevc.h"
56 #include "libavcodec/mpegaudiodecheader.h"
57 #include "libavcodec/mlp_parse.h"
58 #include "avformat.h"
59 #include "internal.h"
60 #include "avio_internal.h"
61 #include "demux.h"
62 #include "iamf_parse.h"
63 #include "iamf_reader.h"
64 #include "dovi_isom.h"
65 #include "riff.h"
66 #include "isom.h"
67 #include "libavcodec/get_bits.h"
68 #include "id3v1.h"
69 #include "mov_chan.h"
70 #include "replaygain.h"
71
72 #if CONFIG_ZLIB
73 #include <zlib.h>
74 #endif
75
76 #include "qtpalette.h"
77
78 /* those functions parse an atom */
79 /* links atom IDs to parse functions */
80 typedef struct MOVParseTableEntry {
81 uint32_t type;
82 int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
83 } MOVParseTableEntry;
84
85 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
86 static int mov_read_mfra(MOVContext *c, AVIOContext *f);
87 static int64_t add_ctts_entry(MOVCtts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
88 int count, int duration);
89
90 24 static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb,
91 unsigned len, const char *key)
92 {
93 char buf[16];
94
95 24 short current, total = 0;
96 24 avio_rb16(pb); // unknown
97 24 current = avio_rb16(pb);
98
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 if (len >= 6)
99 24 total = avio_rb16(pb);
100
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 19 times.
24 if (!total)
101 5 snprintf(buf, sizeof(buf), "%d", current);
102 else
103 19 snprintf(buf, sizeof(buf), "%d/%d", current, total);
104 24 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
105 24 av_dict_set(&c->fc->metadata, key, buf, 0);
106
107 24 return 0;
108 }
109
110 static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb,
111 unsigned len, const char *key)
112 {
113 /* bypass padding bytes */
114 avio_r8(pb);
115 avio_r8(pb);
116 avio_r8(pb);
117
118 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
119 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
120
121 return 0;
122 }
123
124 26 static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb,
125 unsigned len, const char *key)
126 {
127 26 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
128 26 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
129
130 26 return 0;
131 }
132
133 10 static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb,
134 unsigned len, const char *key)
135 {
136 short genre;
137
138 10 avio_r8(pb); // unknown
139
140 10 genre = avio_r8(pb);
141
2/4
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
10 if (genre < 1 || genre > ID3v1_GENRE_MAX)
142 return 0;
143 10 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
144 10 av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
145
146 10 return 0;
147 }
148
149 static const uint32_t mac_to_unicode[128] = {
150 0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
151 0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
152 0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
153 0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
154 0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
155 0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
156 0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
157 0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
158 0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
159 0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
160 0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
161 0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
162 0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
163 0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
164 0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
165 0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
166 };
167
168 310 static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len,
169 char *dst, int dstlen)
170 {
171 310 char *p = dst;
172 310 char *end = dst+dstlen-1;
173 int i;
174
175
2/2
✓ Branch 0 taken 2744 times.
✓ Branch 1 taken 310 times.
3054 for (i = 0; i < len; i++) {
176 2744 uint8_t t, c = avio_r8(pb);
177
178
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2744 times.
2744 if (p >= end)
179 continue;
180
181
2/2
✓ Branch 0 taken 2741 times.
✓ Branch 1 taken 3 times.
2744 if (c < 0x80)
182 2741 *p++ = c;
183
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 else if (p < end)
184
5/10
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3 times.
✓ Branch 9 taken 3 times.
6 PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
185 }
186 310 *p = 0;
187 310 return p - dst;
188 }
189
190 168 static AVStream *get_curr_st(MOVContext *c)
191 {
192 168 AVStream *st = NULL;
193
194
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 168 times.
168 if (c->fc->nb_streams < 1)
195 return NULL;
196
197
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 147 times.
183 for (int i = 0; i < c->nb_heif_item; i++) {
198 36 HEIFItem *item = &c->heif_item[i];
199
200
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
36 if (!item->st)
201 continue;
202
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 21 times.
36 if (item->st->id != c->cur_item_id)
203 15 continue;
204
205 21 st = item->st;
206 21 break;
207 }
208
2/2
✓ Branch 0 taken 147 times.
✓ Branch 1 taken 21 times.
168 if (!st)
209 147 st = c->fc->streams[c->fc->nb_streams-1];
210
211 168 return st;
212 }
213
214 14 static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
215 {
216 AVStream *st;
217 MOVStreamContext *sc;
218 enum AVCodecID id;
219 int ret;
220
221
2/4
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
14 switch (type) {
222 7 case 0xd: id = AV_CODEC_ID_MJPEG; break;
223 7 case 0xe: id = AV_CODEC_ID_PNG; break;
224 case 0x1b: id = AV_CODEC_ID_BMP; break;
225 default:
226 av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
227 avio_skip(pb, len);
228 return 0;
229 }
230
231 14 sc = av_mallocz(sizeof(*sc));
232
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (!sc)
233 return AVERROR(ENOMEM);
234 14 ret = ff_add_attached_pic(c->fc, NULL, pb, NULL, len);
235
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (ret < 0) {
236 av_free(sc);
237 return ret;
238 }
239 14 st = c->fc->streams[c->fc->nb_streams - 1];
240 14 st->priv_data = sc;
241 14 sc->id = st->id;
242 14 sc->refcount = 1;
243
244
2/4
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
14 if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) {
245
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
14 if (AV_RB64(st->attached_pic.data) == 0x89504e470d0a1a0a) {
246 7 id = AV_CODEC_ID_PNG;
247 } else {
248 7 id = AV_CODEC_ID_MJPEG;
249 }
250 }
251 14 st->codecpar->codec_id = id;
252
253 14 return 0;
254 }
255
256 // 3GPP TS 26.244
257 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
258 {
259 char language[4] = { 0 };
260 char buf[200], place[100];
261 uint16_t langcode = 0;
262 double longitude, latitude, altitude;
263 const char *key = "location";
264
265 if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
266 av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
267 return AVERROR_INVALIDDATA;
268 }
269
270 avio_skip(pb, 4); // version+flags
271 langcode = avio_rb16(pb);
272 ff_mov_lang_to_iso639(langcode, language);
273 len -= 6;
274
275 len -= avio_get_str(pb, len, place, sizeof(place));
276 if (len < 1) {
277 av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
278 return AVERROR_INVALIDDATA;
279 }
280 avio_skip(pb, 1); // role
281 len -= 1;
282
283 if (len < 12) {
284 av_log(c->fc, AV_LOG_ERROR,
285 "loci too short (%u bytes left, need at least %d)\n", len, 12);
286 return AVERROR_INVALIDDATA;
287 }
288 longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
289 latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
290 altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
291
292 // Try to output in the same format as the ?xyz field
293 snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
294 if (altitude)
295 av_strlcatf(buf, sizeof(buf), "%+f", altitude);
296 av_strlcatf(buf, sizeof(buf), "/%s", place);
297
298 if (*language && strcmp(language, "und")) {
299 char key2[16];
300 snprintf(key2, sizeof(key2), "%s-%s", key, language);
301 av_dict_set(&c->fc->metadata, key2, buf, 0);
302 }
303 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
304 return av_dict_set(&c->fc->metadata, key, buf, 0);
305 }
306
307 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
308 {
309 int i, n_hmmt;
310
311 if (len < 2)
312 return 0;
313 if (c->ignore_chapters)
314 return 0;
315
316 n_hmmt = avio_rb32(pb);
317 if (n_hmmt > len / 4)
318 return AVERROR_INVALIDDATA;
319 for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
320 int moment_time = avio_rb32(pb);
321 avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
322 }
323 if (avio_feof(pb))
324 return AVERROR_INVALIDDATA;
325 return 0;
326 }
327
328 448 static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
329 {
330 448 char tmp_key[AV_FOURCC_MAX_STRING_SIZE] = {0};
331 448 char key2[32], language[4] = {0};
332 448 char *str = NULL;
333 448 const char *key = NULL;
334 448 uint16_t langcode = 0;
335 448 uint32_t data_type = 0, str_size, str_size_alloc;
336 448 int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
337 448 int raw = 0;
338 448 int num = 0;
339
340
24/74
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 144 times.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 13 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 12 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✓ Branch 14 taken 10 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✓ Branch 23 taken 13 times.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✓ Branch 33 taken 12 times.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✓ Branch 39 taken 16 times.
✗ Branch 40 not taken.
✓ Branch 41 taken 16 times.
✓ Branch 42 taken 3 times.
✗ Branch 43 not taken.
✓ Branch 44 taken 7 times.
✗ Branch 45 not taken.
✓ Branch 46 taken 4 times.
✓ Branch 47 taken 16 times.
✗ Branch 48 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✓ Branch 51 taken 2 times.
✗ Branch 52 not taken.
✓ Branch 53 taken 2 times.
✗ Branch 54 not taken.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✗ Branch 57 not taken.
✓ Branch 58 taken 5 times.
✓ Branch 59 taken 5 times.
✓ Branch 60 taken 36 times.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✗ Branch 66 not taken.
✓ Branch 67 taken 58 times.
✓ Branch 68 taken 49 times.
✗ Branch 69 not taken.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
✗ Branch 72 not taken.
✓ Branch 73 taken 5 times.
448 switch (atom.type) {
341 3 case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
342 3 case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
343 2 case MKTAG( 'X','M','P','_'):
344
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (c->export_xmp) { key = "xmp"; raw = 1; } break;
345 12 case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
346 case MKTAG( 'a','k','I','D'): key = "account_type";
347 parse = mov_metadata_int8_no_padding; break;
348 case MKTAG( 'a','p','I','D'): key = "account_id"; break;
349 case MKTAG( 'c','a','t','g'): key = "category"; break;
350 13 case MKTAG( 'c','p','i','l'): key = "compilation";
351 13 parse = mov_metadata_int8_no_padding; break;
352 case MKTAG( 'c','p','r','t'): key = "copyright"; break;
353 case MKTAG( 'd','e','s','c'): key = "description"; break;
354 12 case MKTAG( 'd','i','s','k'): key = "disc";
355 12 parse = mov_metadata_track_or_disc_number; break;
356 case MKTAG( 'e','g','i','d'): key = "episode_uid";
357 parse = mov_metadata_int8_no_padding; break;
358 case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
359 10 case MKTAG( 'g','n','r','e'): key = "genre";
360 10 parse = mov_metadata_gnre; break;
361 case MKTAG( 'h','d','v','d'): key = "hd_video";
362 parse = mov_metadata_int8_no_padding; break;
363 case MKTAG( 'H','M','M','T'):
364 return mov_metadata_hmmt(c, pb, atom.size);
365 case MKTAG( 'k','e','y','w'): key = "keywords"; break;
366 case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
367 case MKTAG( 'l','o','c','i'):
368 return mov_metadata_loci(c, pb, atom.size);
369 case MKTAG( 'm','a','n','u'): key = "make"; break;
370 case MKTAG( 'm','o','d','l'): key = "model"; break;
371 case MKTAG( 'p','c','s','t'): key = "podcast";
372 parse = mov_metadata_int8_no_padding; break;
373 13 case MKTAG( 'p','g','a','p'): key = "gapless_playback";
374 13 parse = mov_metadata_int8_no_padding; break;
375 case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
376 case MKTAG( 'r','t','n','g'): key = "rating";
377 parse = mov_metadata_int8_no_padding; break;
378 case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
379 case MKTAG( 's','o','a','l'): key = "sort_album"; break;
380 case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
381 case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
382 case MKTAG( 's','o','n','m'): key = "sort_name"; break;
383 case MKTAG( 's','o','s','n'): key = "sort_show"; break;
384 case MKTAG( 's','t','i','k'): key = "media_type";
385 parse = mov_metadata_int8_no_padding; break;
386 12 case MKTAG( 't','r','k','n'): key = "track";
387 12 parse = mov_metadata_track_or_disc_number; break;
388 case MKTAG( 't','v','e','n'): key = "episode_id"; break;
389 case MKTAG( 't','v','e','s'): key = "episode_sort";
390 parse = mov_metadata_int8_bypass_padding; break;
391 case MKTAG( 't','v','n','n'): key = "network"; break;
392 case MKTAG( 't','v','s','h'): key = "show"; break;
393 case MKTAG( 't','v','s','n'): key = "season_number";
394 parse = mov_metadata_int8_bypass_padding; break;
395 16 case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
396 case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
397 16 case MKTAG(0xa9,'a','l','b'): key = "album"; break;
398 3 case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
399 case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
400 7 case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
401 case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
402 4 case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
403 16 case MKTAG(0xa9,'d','a','y'): key = "date"; break;
404 case MKTAG(0xa9,'d','i','r'): key = "director"; break;
405 case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
406 case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
407 2 case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
408 case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
409 2 case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
410 case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
411 case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
412 case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
413 case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
414 5 case MKTAG(0xa9,'m','a','k'): key = "make"; break;
415 5 case MKTAG(0xa9,'m','o','d'): key = "model"; break;
416 36 case MKTAG(0xa9,'n','a','m'): key = "title"; break;
417 case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
418 case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
419 case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
420 case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
421 case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
422 case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
423 58 case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
424 49 case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
425 case MKTAG(0xa9,'t','r','k'): key = "track"; break;
426 case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
427 case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
428 case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
429 5 case MKTAG(0xa9,'x','y','z'): key = "location"; break;
430 }
431 2 retry:
432
3/4
✓ Branch 0 taken 278 times.
✓ Branch 1 taken 172 times.
✓ Branch 2 taken 278 times.
✗ Branch 3 not taken.
714 if (c->itunes_metadata && atom.size > 8) {
433 278 int data_size = avio_rb32(pb);
434 278 int tag = avio_rl32(pb);
435
3/6
✓ Branch 0 taken 278 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 278 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 278 times.
✗ Branch 5 not taken.
278 if (tag == MKTAG('d','a','t','a') && data_size <= atom.size && data_size >= 16) {
436 278 data_type = avio_rb32(pb); // type
437 278 avio_rb32(pb); // unknown
438 278 str_size = data_size - 16;
439 278 atom.size -= 16;
440
441
5/6
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 199 times.
✓ Branch 2 taken 45 times.
✓ Branch 3 taken 34 times.
✓ Branch 4 taken 45 times.
✗ Branch 5 not taken.
278 if (!key && c->found_hdlr_mdta && c->meta_keys) {
442 45 uint32_t index = av_bswap32(atom.type); // BE number has been read as LE
443
2/4
✓ Branch 0 taken 45 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45 times.
✗ Branch 3 not taken.
45 if (index < c->meta_keys_count && index > 0) {
444 45 key = c->meta_keys[index];
445 } else if (atom.type != MKTAG('c', 'o', 'v', 'r')) {
446 av_log(c->fc, AV_LOG_WARNING,
447 "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
448 index, c->meta_keys_count);
449 }
450 }
451
4/4
✓ Branch 0 taken 264 times.
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 244 times.
✓ Branch 3 taken 20 times.
278 if (atom.type == MKTAG('c', 'o', 'v', 'r') ||
452
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 244 times.
244 (key && !strcmp(key, "com.apple.quicktime.artwork"))) {
453 14 int ret = mov_read_covr(c, pb, data_type, str_size);
454
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (ret < 0) {
455 av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
456 return ret;
457 }
458 14 atom.size -= str_size;
459
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 12 times.
14 if (atom.size > 8)
460 2 goto retry;
461 12 return ret;
462 }
463 } else return 0;
464
7/8
✓ Branch 0 taken 154 times.
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 103 times.
✓ Branch 3 taken 51 times.
✓ Branch 4 taken 103 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 97 times.
✓ Branch 7 taken 6 times.
172 } else if (atom.size > 4 && key && !c->itunes_metadata && !raw) {
465 97 str_size = avio_rb16(pb); // string length
466
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 97 times.
97 if (str_size > atom.size) {
467 raw = 1;
468 avio_seek(pb, -2, SEEK_CUR);
469 av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
470 goto retry;
471 }
472 97 langcode = avio_rb16(pb);
473 97 ff_mov_lang_to_iso639(langcode, language);
474 97 atom.size -= 4;
475 } else
476 75 str_size = atom.size;
477
478
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 436 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
436 if (c->export_all && !key) {
479 key = av_fourcc_make_string(tmp_key, atom.type);
480 }
481
482
2/2
✓ Branch 0 taken 89 times.
✓ Branch 1 taken 347 times.
436 if (!key)
483 89 return 0;
484
2/4
✓ Branch 0 taken 347 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 347 times.
347 if (atom.size < 0 || str_size >= INT_MAX/2)
485 return AVERROR_INVALIDDATA;
486
487 // Allocates enough space if data_type is a int32 or float32 number, otherwise
488 // worst-case requirement for output string in case of utf8 coded input
489
3/4
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 308 times.
✓ Branch 2 taken 39 times.
✗ Branch 3 not taken.
347 num = (data_type >= 21 && data_type <= 23);
490
4/4
✓ Branch 0 taken 308 times.
✓ Branch 1 taken 39 times.
✓ Branch 2 taken 302 times.
✓ Branch 3 taken 6 times.
347 str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
491 347 str = av_mallocz(str_size_alloc);
492
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 347 times.
347 if (!str)
493 return AVERROR(ENOMEM);
494
495
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 287 times.
347 if (parse)
496 60 parse(c, pb, str_size, key);
497 else {
498
8/10
✓ Branch 0 taken 281 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 281 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 98 times.
✓ Branch 5 taken 183 times.
✓ Branch 6 taken 84 times.
✓ Branch 7 taken 14 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 84 times.
287 if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
499 14 mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
500
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 273 times.
273 } else if (data_type == 21) { // BE signed integer, variable size
501 int val = 0;
502 if (str_size == 1)
503 val = (int8_t)avio_r8(pb);
504 else if (str_size == 2)
505 val = (int16_t)avio_rb16(pb);
506 else if (str_size == 3)
507 val = ((int32_t)(avio_rb24(pb)<<8))>>8;
508 else if (str_size == 4)
509 val = (int32_t)avio_rb32(pb);
510 if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
511 av_log(c->fc, AV_LOG_ERROR,
512 "Failed to store the number (%d) in string.\n", val);
513 av_free(str);
514 return AVERROR_INVALIDDATA;
515 }
516
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 273 times.
273 } else if (data_type == 22) { // BE unsigned integer, variable size
517 unsigned int val = 0;
518 if (str_size == 1)
519 val = avio_r8(pb);
520 else if (str_size == 2)
521 val = avio_rb16(pb);
522 else if (str_size == 3)
523 val = avio_rb24(pb);
524 else if (str_size == 4)
525 val = avio_rb32(pb);
526 if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
527 av_log(c->fc, AV_LOG_ERROR,
528 "Failed to store the number (%u) in string.\n", val);
529 av_free(str);
530 return AVERROR_INVALIDDATA;
531 }
532
3/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 260 times.
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
286 } else if (data_type == 23 && str_size >= 4) { // BE float32
533 13 float val = av_int2float(avio_rb32(pb));
534
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
535 av_log(c->fc, AV_LOG_ERROR,
536 "Failed to store the float32 number (%f) in string.\n", val);
537 av_free(str);
538 return AVERROR_INVALIDDATA;
539 }
540
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 260 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
260 } else if (data_type > 1 && data_type != 4) {
541 // data_type can be 0 if not set at all above. data_type 1 means
542 // UTF8 and 4 means "UTF8 sort". For any other type (UTF16 or e.g.
543 // a picture), don't return it blindly in a string that is supposed
544 // to be UTF8 text.
545 av_log(c->fc, AV_LOG_WARNING, "Skipping unhandled metadata %s of type %d\n", key, data_type);
546 av_free(str);
547 return 0;
548 } else {
549 260 int ret = ffio_read_size(pb, str, str_size);
550
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 260 times.
260 if (ret < 0) {
551 av_free(str);
552 return ret;
553 }
554 260 str[str_size] = 0;
555 }
556 287 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
557 287 av_dict_set(&c->fc->metadata, key, str, 0);
558
4/4
✓ Branch 0 taken 97 times.
✓ Branch 1 taken 190 times.
✓ Branch 2 taken 37 times.
✓ Branch 3 taken 60 times.
287 if (*language && strcmp(language, "und")) {
559 37 snprintf(key2, sizeof(key2), "%s-%s", key, language);
560 37 av_dict_set(&c->fc->metadata, key2, str, 0);
561 }
562
2/2
✓ Branch 0 taken 109 times.
✓ Branch 1 taken 178 times.
287 if (!strcmp(key, "encoder")) {
563 int major, minor, micro;
564
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 109 times.
109 if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, &micro) == 3) {
565 c->handbrake_version = 1000000*major + 1000*minor + micro;
566 }
567 }
568 }
569
570 347 av_freep(&str);
571 347 return 0;
572 }
573
574 12 static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
575 {
576 int64_t start;
577 int i, nb_chapters, str_len, version;
578 char str[256+1];
579 int ret;
580
581
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (c->ignore_chapters)
582 return 0;
583
584
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if ((atom.size -= 5) < 0)
585 return 0;
586
587 12 version = avio_r8(pb);
588 12 avio_rb24(pb);
589
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if (version)
590 12 avio_rb32(pb); // ???
591 12 nb_chapters = avio_r8(pb);
592
593
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 12 times.
30 for (i = 0; i < nb_chapters; i++) {
594
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if (atom.size < 9)
595 return 0;
596
597 18 start = avio_rb64(pb);
598 18 str_len = avio_r8(pb);
599
600
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if ((atom.size -= 9+str_len) < 0)
601 return 0;
602
603 18 ret = ffio_read_size(pb, str, str_len);
604
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if (ret < 0)
605 return ret;
606 18 str[str_len] = 0;
607 18 avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
608 }
609 12 return 0;
610 }
611
612 #define MIN_DATA_ENTRY_BOX_SIZE 12
613 571 static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
614 {
615 AVStream *st;
616 MOVStreamContext *sc;
617 int entries, i, j;
618
619
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 571 times.
571 if (c->fc->nb_streams < 1)
620 return 0;
621 571 st = c->fc->streams[c->fc->nb_streams-1];
622 571 sc = st->priv_data;
623
624 571 avio_rb32(pb); // version + flags
625 571 entries = avio_rb32(pb);
626
1/2
✓ Branch 0 taken 571 times.
✗ Branch 1 not taken.
571 if (!entries ||
627
1/2
✓ Branch 0 taken 571 times.
✗ Branch 1 not taken.
571 entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
628
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 571 times.
571 entries >= UINT_MAX / sizeof(*sc->drefs))
629 return AVERROR_INVALIDDATA;
630
631
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 571 times.
571 for (i = 0; i < sc->drefs_count; i++) {
632 MOVDref *dref = &sc->drefs[i];
633 av_freep(&dref->path);
634 av_freep(&dref->dir);
635 }
636 571 av_free(sc->drefs);
637 571 sc->drefs_count = 0;
638 571 sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
639
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 571 times.
571 if (!sc->drefs)
640 return AVERROR(ENOMEM);
641 571 sc->drefs_count = entries;
642
643
2/2
✓ Branch 0 taken 571 times.
✓ Branch 1 taken 571 times.
1142 for (i = 0; i < entries; i++) {
644 571 MOVDref *dref = &sc->drefs[i];
645 571 uint32_t size = avio_rb32(pb);
646 571 int64_t next = avio_tell(pb);
647
648
3/6
✓ Branch 0 taken 571 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 571 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 571 times.
571 if (size < 12 || next < 0 || next > INT64_MAX - size)
649 return AVERROR_INVALIDDATA;
650
651 571 next += size - 4;
652
653 571 dref->type = avio_rl32(pb);
654 571 avio_rb32(pb); // version + flags
655
656
3/4
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 457 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 114 times.
571 if (dref->type == MKTAG('a','l','i','s') && size > 150) {
657 /* macintosh alias record */
658 uint16_t volume_len, len;
659 int16_t type;
660 int ret;
661
662 avio_skip(pb, 10);
663
664 volume_len = avio_r8(pb);
665 volume_len = FFMIN(volume_len, 27);
666 ret = ffio_read_size(pb, dref->volume, 27);
667 if (ret < 0)
668 return ret;
669 dref->volume[volume_len] = 0;
670 av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
671
672 avio_skip(pb, 12);
673
674 len = avio_r8(pb);
675 len = FFMIN(len, 63);
676 ret = ffio_read_size(pb, dref->filename, 63);
677 if (ret < 0)
678 return ret;
679 dref->filename[len] = 0;
680 av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
681
682 avio_skip(pb, 16);
683
684 /* read next level up_from_alias/down_to_target */
685 dref->nlvl_from = avio_rb16(pb);
686 dref->nlvl_to = avio_rb16(pb);
687 av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
688 dref->nlvl_from, dref->nlvl_to);
689
690 avio_skip(pb, 16);
691
692 for (type = 0; type != -1 && avio_tell(pb) < next; ) {
693 if (avio_feof(pb))
694 return AVERROR_EOF;
695 type = avio_rb16(pb);
696 len = avio_rb16(pb);
697 av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
698 if (len&1)
699 len += 1;
700 if (type == 2) { // absolute path
701 av_free(dref->path);
702 dref->path = av_mallocz(len+1);
703 if (!dref->path)
704 return AVERROR(ENOMEM);
705
706 ret = ffio_read_size(pb, dref->path, len);
707 if (ret < 0) {
708 av_freep(&dref->path);
709 return ret;
710 }
711 if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
712 len -= volume_len;
713 memmove(dref->path, dref->path+volume_len, len);
714 dref->path[len] = 0;
715 }
716 // trim string of any ending zeros
717 for (j = len - 1; j >= 0; j--) {
718 if (dref->path[j] == 0)
719 len--;
720 else
721 break;
722 }
723 for (j = 0; j < len; j++)
724 if (dref->path[j] == ':' || dref->path[j] == 0)
725 dref->path[j] = '/';
726 av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
727 } else if (type == 0) { // directory name
728 av_free(dref->dir);
729 dref->dir = av_malloc(len+1);
730 if (!dref->dir)
731 return AVERROR(ENOMEM);
732
733 ret = ffio_read_size(pb, dref->dir, len);
734 if (ret < 0) {
735 av_freep(&dref->dir);
736 return ret;
737 }
738 dref->dir[len] = 0;
739 for (j = 0; j < len; j++)
740 if (dref->dir[j] == ':')
741 dref->dir[j] = '/';
742 av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
743 } else
744 avio_skip(pb, len);
745 }
746 } else {
747 571 av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
748 dref->type, size);
749 571 entries--;
750 571 i--;
751 }
752 571 avio_seek(pb, next, SEEK_SET);
753 }
754 571 return 0;
755 }
756
757 1043 static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
758 {
759 AVStream *st;
760 uint32_t type;
761 uint32_t ctype;
762 int64_t title_size;
763 char *title_str;
764 int ret;
765
766 1043 avio_r8(pb); /* version */
767 1043 avio_rb24(pb); /* flags */
768
769 /* component type */
770 1043 ctype = avio_rl32(pb);
771 1043 type = avio_rl32(pb); /* component subtype */
772
773 1043 av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
774 1043 av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
775
776
2/2
✓ Branch 0 taken 127 times.
✓ Branch 1 taken 916 times.
1043 if (c->trak_index < 0) { // meta not inside a trak
777
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 118 times.
127 if (type == MKTAG('m','d','t','a')) {
778 9 c->found_hdlr_mdta = 1;
779 }
780 127 return 0;
781 }
782
783 916 st = c->fc->streams[c->fc->nb_streams-1];
784
785
2/2
✓ Branch 0 taken 286 times.
✓ Branch 1 taken 630 times.
916 if (type == MKTAG('v','i','d','e'))
786 286 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
787
2/2
✓ Branch 0 taken 236 times.
✓ Branch 1 taken 394 times.
630 else if (type == MKTAG('s','o','u','n'))
788 236 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
789
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 394 times.
394 else if (type == MKTAG('m','1','a',' '))
790 st->codecpar->codec_id = AV_CODEC_ID_MP2;
791
2/4
✓ Branch 0 taken 394 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 394 times.
394 else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
792 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
793
794 916 avio_rb32(pb); /* component manufacture */
795 916 avio_rb32(pb); /* component flags */
796 916 avio_rb32(pb); /* component flags mask */
797
798 916 title_size = atom.size - 24;
799
2/2
✓ Branch 0 taken 913 times.
✓ Branch 1 taken 3 times.
916 if (title_size > 0) {
800
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 913 times.
913 if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
801 return AVERROR_INVALIDDATA;
802 913 title_str = av_malloc(title_size + 1); /* Add null terminator */
803
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 913 times.
913 if (!title_str)
804 return AVERROR(ENOMEM);
805
806 913 ret = ffio_read_size(pb, title_str, title_size);
807
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 913 times.
913 if (ret < 0) {
808 av_freep(&title_str);
809 return ret;
810 }
811 913 title_str[title_size] = 0;
812
2/2
✓ Branch 0 taken 862 times.
✓ Branch 1 taken 51 times.
913 if (title_str[0]) {
813
4/4
✓ Branch 0 taken 666 times.
✓ Branch 1 taken 196 times.
✓ Branch 2 taken 664 times.
✓ Branch 3 taken 2 times.
862 int off = (!c->isom && title_str[0] == title_size - 1);
814 // flag added so as to not set stream handler name if already set from mdia->hdlr
815 862 av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
816 }
817 913 av_freep(&title_str);
818 }
819
820 916 return 0;
821 }
822
823 143 static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
824 {
825 143 return ff_mov_read_esds(c->fc, pb);
826 }
827
828 7 static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
829 {
830 AVStream *st;
831 AVPacketSideData *sd;
832 enum AVAudioServiceType *ast;
833 int ac3info, acmod, lfeon, bsmod;
834 uint64_t mask;
835
836
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (c->fc->nb_streams < 1)
837 return 0;
838 7 st = c->fc->streams[c->fc->nb_streams-1];
839
840 7 sd = av_packet_side_data_new(&st->codecpar->coded_side_data,
841 7 &st->codecpar->nb_coded_side_data,
842 AV_PKT_DATA_AUDIO_SERVICE_TYPE,
843 sizeof(*ast), 0);
844
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (!sd)
845 return AVERROR(ENOMEM);
846
847 7 ast = (enum AVAudioServiceType*)sd->data;
848 7 ac3info = avio_rb24(pb);
849 7 bsmod = (ac3info >> 14) & 0x7;
850 7 acmod = (ac3info >> 11) & 0x7;
851 7 lfeon = (ac3info >> 10) & 0x1;
852
853 7 mask = ff_ac3_channel_layout_tab[acmod];
854
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
7 if (lfeon)
855 1 mask |= AV_CH_LOW_FREQUENCY;
856 7 av_channel_layout_uninit(&st->codecpar->ch_layout);
857 7 av_channel_layout_from_mask(&st->codecpar->ch_layout, mask);
858
859 7 *ast = bsmod;
860
3/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
7 if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
861 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
862
863 7 return 0;
864 }
865
866 #if CONFIG_IAMFDEC
867 8 static int mov_read_iacb(MOVContext *c, AVIOContext *pb, MOVAtom atom)
868 {
869 AVStream *st;
870 MOVStreamContext *sc;
871 FFIOContext b;
872 AVIOContext *descriptor_pb;
873 AVDictionary *metadata;
874 IAMFContext *iamf;
875 int64_t start_time, duration;
876 unsigned descriptors_size;
877 int nb_frames, disposition;
878 int version, ret;
879
880
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (atom.size < 5)
881 return AVERROR_INVALIDDATA;
882
883
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (c->fc->nb_streams < 1)
884 return 0;
885
886 8 version = avio_r8(pb);
887
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (version != 1) {
888 av_log(c->fc, AV_LOG_ERROR, "%s configurationVersion %d",
889 version < 1 ? "invalid" : "unsupported", version);
890 return AVERROR_INVALIDDATA;
891 }
892
893 8 descriptors_size = ffio_read_leb(pb);
894
2/4
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
8 if (!descriptors_size || descriptors_size > INT_MAX)
895 return AVERROR_INVALIDDATA;
896
897 8 st = c->fc->streams[c->fc->nb_streams - 1];
898 8 sc = st->priv_data;
899
900 8 sc->iamf = av_mallocz(sizeof(*sc->iamf));
901
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (!sc->iamf)
902 return AVERROR(ENOMEM);
903 8 iamf = &sc->iamf->iamf;
904
905 8 st->codecpar->extradata = av_malloc(descriptors_size);
906
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (!st->codecpar->extradata)
907 return AVERROR(ENOMEM);
908 8 st->codecpar->extradata_size = descriptors_size;
909
910 8 ret = avio_read(pb, st->codecpar->extradata, descriptors_size);
911
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (ret != descriptors_size)
912 return ret < 0 ? ret : AVERROR_INVALIDDATA;
913
914 8 ffio_init_read_context(&b, st->codecpar->extradata, descriptors_size);
915 8 descriptor_pb = &b.pub;
916
917 8 ret = ff_iamfdec_read_descriptors(iamf, descriptor_pb, descriptors_size, c->fc);
918
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (ret < 0)
919 return ret;
920
921 8 metadata = st->metadata;
922 8 st->metadata = NULL;
923 8 start_time = st->start_time;
924 8 nb_frames = st->nb_frames;
925 8 duration = st->duration;
926 8 disposition = st->disposition;
927
928
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 for (int i = 0; i < iamf->nb_audio_elements; i++) {
929 8 IAMFAudioElement *audio_element = iamf->audio_elements[i];
930 const AVIAMFAudioElement *element;
931 AVStreamGroup *stg =
932 8 avformat_stream_group_create(c->fc, AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT, NULL);
933
934
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (!stg) {
935 ret = AVERROR(ENOMEM);
936 goto fail;
937 }
938
939 8 av_iamf_audio_element_free(&stg->params.iamf_audio_element);
940 8 stg->id = audio_element->audio_element_id;
941 /* Transfer ownership */
942 8 element = stg->params.iamf_audio_element = audio_element->element;
943 8 audio_element->element = NULL;
944
945
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 8 times.
44 for (int j = 0; j < audio_element->nb_substreams; j++) {
946 36 IAMFSubStream *substream = &audio_element->substreams[j];
947 AVStream *stream;
948
949
3/4
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 28 times.
36 if (!i && !j) {
950
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
8 if (audio_element->layers[0].substream_count != 1)
951 2 disposition &= ~AV_DISPOSITION_DEFAULT;
952 8 stream = st;
953 } else
954 28 stream = avformat_new_stream(c->fc, NULL);
955
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
36 if (!stream) {
956 ret = AVERROR(ENOMEM);
957 goto fail;
958 }
959
960 36 stream->start_time = start_time;
961 36 stream->nb_frames = nb_frames;
962 36 stream->duration = duration;
963 36 stream->disposition = disposition;
964
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 8 times.
36 if (stream != st) {
965 28 stream->priv_data = sc;
966 28 sc->refcount++;
967 }
968
969
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 28 times.
36 if (element->audio_element_type == AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE)
970 8 stream->disposition |= AV_DISPOSITION_DEPENDENT;
971
3/4
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 8 times.
36 if (i || j) {
972 28 stream->disposition |= AV_DISPOSITION_DEPENDENT;
973
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 6 times.
28 if (audio_element->layers[0].substream_count == 1)
974 22 stream->disposition &= ~AV_DISPOSITION_DEFAULT;
975 }
976
977 36 ret = avcodec_parameters_copy(stream->codecpar, substream->codecpar);
978
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
36 if (ret < 0)
979 goto fail;
980
981 36 stream->id = substream->audio_substream_id;
982
983 36 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
984
985 36 ret = avformat_stream_group_add_stream(stg, stream);
986
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
36 if (ret < 0)
987 goto fail;
988 }
989
990 8 ret = av_dict_copy(&stg->metadata, metadata, 0);
991
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (ret < 0)
992 goto fail;
993 }
994
995
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 for (int i = 0; i < iamf->nb_mix_presentations; i++) {
996 8 IAMFMixPresentation *mix_presentation = iamf->mix_presentations[i];
997 8 const AVIAMFMixPresentation *mix = mix_presentation->cmix;
998 AVStreamGroup *stg =
999 8 avformat_stream_group_create(c->fc, AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION, NULL);
1000
1001
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (!stg) {
1002 ret = AVERROR(ENOMEM);
1003 goto fail;
1004 }
1005
1006 8 av_iamf_mix_presentation_free(&stg->params.iamf_mix_presentation);
1007 8 stg->id = mix_presentation->mix_presentation_id;
1008 /* Transfer ownership */
1009 8 stg->params.iamf_mix_presentation = mix_presentation->mix;
1010 8 mix_presentation->mix = NULL;
1011
1012
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 8 times.
18 for (int j = 0; j < mix->nb_submixes; j++) {
1013 10 const AVIAMFSubmix *submix = mix->submixes[j];
1014
1015
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
20 for (int k = 0; k < submix->nb_elements; k++) {
1016 10 const AVIAMFSubmixElement *submix_element = submix->elements[k];
1017 10 const AVStreamGroup *audio_element = NULL;
1018
1019
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 for (int l = 0; l < c->fc->nb_stream_groups; l++)
1020
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if (c->fc->stream_groups[l]->type == AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT &&
1021
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 c->fc->stream_groups[l]->id == submix_element->audio_element_id) {
1022 10 audio_element = c->fc->stream_groups[l];
1023 10 break;
1024 }
1025
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 av_assert0(audio_element);
1026
1027
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 10 times.
48 for (int l = 0; l < audio_element->nb_streams; l++) {
1028 38 ret = avformat_stream_group_add_stream(stg, audio_element->streams[l]);
1029
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
38 if (ret < 0 && ret != AVERROR(EEXIST))
1030 goto fail;
1031 }
1032 }
1033 }
1034
1035 8 ret = av_dict_copy(&stg->metadata, metadata, 0);
1036
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (ret < 0)
1037 goto fail;
1038 }
1039
1040 8 ret = 0;
1041 8 fail:
1042 8 av_dict_free(&metadata);
1043
1044 8 return ret;
1045 }
1046 #endif
1047
1048 1 static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1049 {
1050 AVStream *st;
1051 AVPacketSideData *sd;
1052 enum AVAudioServiceType *ast;
1053 int eac3info, acmod, lfeon, bsmod;
1054 uint64_t mask;
1055
1056
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (c->fc->nb_streams < 1)
1057 return 0;
1058 1 st = c->fc->streams[c->fc->nb_streams-1];
1059
1060 1 sd = av_packet_side_data_new(&st->codecpar->coded_side_data,
1061 1 &st->codecpar->nb_coded_side_data,
1062 AV_PKT_DATA_AUDIO_SERVICE_TYPE,
1063 sizeof(*ast), 0);
1064
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!sd)
1065 return AVERROR(ENOMEM);
1066
1067 1 ast = (enum AVAudioServiceType*)sd->data;
1068
1069 /* No need to parse fields for additional independent substreams and its
1070 * associated dependent substreams since libavcodec's E-AC-3 decoder
1071 * does not support them yet. */
1072 1 avio_rb16(pb); /* data_rate and num_ind_sub */
1073 1 eac3info = avio_rb24(pb);
1074 1 bsmod = (eac3info >> 12) & 0x1f;
1075 1 acmod = (eac3info >> 9) & 0x7;
1076 1 lfeon = (eac3info >> 8) & 0x1;
1077
1078 1 mask = ff_ac3_channel_layout_tab[acmod];
1079
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (lfeon)
1080 mask |= AV_CH_LOW_FREQUENCY;
1081 1 av_channel_layout_uninit(&st->codecpar->ch_layout);
1082 1 av_channel_layout_from_mask(&st->codecpar->ch_layout, mask);
1083
1084 1 *ast = bsmod;
1085
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
1086 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
1087
1088 1 return 0;
1089 }
1090
1091 static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1092 {
1093 #define DDTS_SIZE 20
1094 uint8_t buf[DDTS_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
1095 AVStream *st = NULL;
1096 uint32_t frame_duration_code = 0;
1097 uint32_t channel_layout_code = 0;
1098 GetBitContext gb;
1099 int ret;
1100
1101 if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
1102 return ret;
1103
1104 init_get_bits(&gb, buf, 8 * DDTS_SIZE);
1105
1106 if (c->fc->nb_streams < 1) {
1107 return 0;
1108 }
1109 st = c->fc->streams[c->fc->nb_streams-1];
1110
1111 st->codecpar->sample_rate = get_bits_long(&gb, 32);
1112 if (st->codecpar->sample_rate <= 0) {
1113 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
1114 return AVERROR_INVALIDDATA;
1115 }
1116 skip_bits_long(&gb, 32); /* max bitrate */
1117 st->codecpar->bit_rate = get_bits_long(&gb, 32);
1118 st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
1119 frame_duration_code = get_bits(&gb, 2);
1120 skip_bits(&gb, 30); /* various fields */
1121 channel_layout_code = get_bits(&gb, 16);
1122
1123 st->codecpar->frame_size =
1124 (frame_duration_code == 0) ? 512 :
1125 (frame_duration_code == 1) ? 1024 :
1126 (frame_duration_code == 2) ? 2048 :
1127 (frame_duration_code == 3) ? 4096 : 0;
1128
1129 if (channel_layout_code > 0xff) {
1130 av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout\n");
1131 }
1132 av_channel_layout_uninit(&st->codecpar->ch_layout);
1133 av_channel_layout_from_mask(&st->codecpar->ch_layout,
1134 ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
1135 ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
1136 ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
1137 ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
1138 ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
1139 ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0));
1140
1141 return 0;
1142 }
1143
1144 50 static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1145 {
1146 AVStream *st;
1147
1148
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 50 times.
50 if (c->fc->nb_streams < 1)
1149 return 0;
1150 50 st = c->fc->streams[c->fc->nb_streams-1];
1151
1152
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 50 times.
50 if (atom.size < 16)
1153 return 0;
1154
1155 /* skip version and flags */
1156 50 avio_skip(pb, 4);
1157
1158 50 ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
1159
1160 50 return 0;
1161 }
1162
1163 5 static int mov_read_chnl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1164 {
1165 5 int64_t end = av_sat_add64(avio_tell(pb), atom.size);
1166 int version, flags;
1167 int ret;
1168 AVStream *st;
1169
1170
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (c->fc->nb_streams < 1)
1171 return 0;
1172 5 st = c->fc->streams[c->fc->nb_streams-1];
1173
1174 5 version = avio_r8(pb);
1175 5 flags = avio_rb24(pb);
1176
2/4
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
5 if (version != 0 || flags != 0) {
1177 av_log(c->fc, AV_LOG_ERROR,
1178 "Unsupported 'chnl' box with version %d, flags: %#x",
1179 version, flags);
1180 return AVERROR_INVALIDDATA;
1181 }
1182
1183 5 ret = ff_mov_read_chnl(c->fc, pb, st);
1184
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (ret < 0)
1185 return ret;
1186
1187
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
5 if (avio_tell(pb) != end) {
1188 av_log(c->fc, AV_LOG_WARNING, "skip %" PRId64 " bytes of unknown data inside chnl\n",
1189 end - avio_tell(pb));
1190 avio_seek(pb, end, SEEK_SET);
1191 }
1192 5 return ret;
1193 }
1194
1195 2 static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1196 {
1197 AVStream *st;
1198 int ret;
1199
1200
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (c->fc->nb_streams < 1)
1201 return 0;
1202 2 st = c->fc->streams[c->fc->nb_streams-1];
1203
1204
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
1205 av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
1206
1207 2 return ret;
1208 }
1209
1210 /* This atom overrides any previously set aspect ratio */
1211 65 static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1212 {
1213 65 const int num = avio_rb32(pb);
1214 65 const int den = avio_rb32(pb);
1215 AVStream *st;
1216
1217
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 65 times.
65 if (c->fc->nb_streams < 1)
1218 return 0;
1219 65 st = c->fc->streams[c->fc->nb_streams-1];
1220
1221
2/2
✓ Branch 0 taken 63 times.
✓ Branch 1 taken 2 times.
65 if (den != 0) {
1222 63 av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den,
1223 num, den, 32767);
1224 }
1225 65 return 0;
1226 }
1227
1228 /* this atom contains actual media data */
1229 855 static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1230 {
1231
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 855 times.
855 if (atom.size == 0) /* wrong one (MP4) */
1232 return 0;
1233 855 c->found_mdat=1;
1234 855 return 0; /* now go for moov */
1235 }
1236
1237 #define DRM_BLOB_SIZE 56
1238
1239 static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1240 {
1241 uint8_t intermediate_key[20];
1242 uint8_t intermediate_iv[20];
1243 uint8_t input[64];
1244 uint8_t output[64];
1245 uint8_t file_checksum[20];
1246 uint8_t calculated_checksum[20];
1247 char checksum_string[2 * sizeof(file_checksum) + 1];
1248 struct AVSHA *sha;
1249 int i;
1250 int ret = 0;
1251 uint8_t *activation_bytes = c->activation_bytes;
1252 uint8_t *fixed_key = c->audible_fixed_key;
1253
1254 c->aax_mode = 1;
1255
1256 sha = av_sha_alloc();
1257 if (!sha)
1258 return AVERROR(ENOMEM);
1259 av_free(c->aes_decrypt);
1260 c->aes_decrypt = av_aes_alloc();
1261 if (!c->aes_decrypt) {
1262 ret = AVERROR(ENOMEM);
1263 goto fail;
1264 }
1265
1266 /* drm blob processing */
1267 avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1268 avio_read(pb, input, DRM_BLOB_SIZE);
1269 avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1270 avio_read(pb, file_checksum, 20);
1271
1272 // required by external tools
1273 ff_data_to_hex(checksum_string, file_checksum, sizeof(file_checksum), 1);
1274 av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == %s\n", checksum_string);
1275
1276 /* verify activation data */
1277 if (!activation_bytes) {
1278 av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1279 ret = 0; /* allow ffprobe to continue working on .aax files */
1280 goto fail;
1281 }
1282 if (c->activation_bytes_size != 4) {
1283 av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1284 ret = AVERROR(EINVAL);
1285 goto fail;
1286 }
1287
1288 /* verify fixed key */
1289 if (c->audible_fixed_key_size != 16) {
1290 av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1291 ret = AVERROR(EINVAL);
1292 goto fail;
1293 }
1294
1295 /* AAX (and AAX+) key derivation */
1296 av_sha_init(sha, 160);
1297 av_sha_update(sha, fixed_key, 16);
1298 av_sha_update(sha, activation_bytes, 4);
1299 av_sha_final(sha, intermediate_key);
1300 av_sha_init(sha, 160);
1301 av_sha_update(sha, fixed_key, 16);
1302 av_sha_update(sha, intermediate_key, 20);
1303 av_sha_update(sha, activation_bytes, 4);
1304 av_sha_final(sha, intermediate_iv);
1305 av_sha_init(sha, 160);
1306 av_sha_update(sha, intermediate_key, 16);
1307 av_sha_update(sha, intermediate_iv, 16);
1308 av_sha_final(sha, calculated_checksum);
1309 if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1310 av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1311 ret = AVERROR_INVALIDDATA;
1312 goto fail;
1313 }
1314 av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1315 av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1316 for (i = 0; i < 4; i++) {
1317 // file data (in output) is stored in big-endian mode
1318 if (activation_bytes[i] != output[3 - i]) { // critical error
1319 av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1320 ret = AVERROR_INVALIDDATA;
1321 goto fail;
1322 }
1323 }
1324 memcpy(c->file_key, output + 8, 16);
1325 memcpy(input, output + 26, 16);
1326 av_sha_init(sha, 160);
1327 av_sha_update(sha, input, 16);
1328 av_sha_update(sha, c->file_key, 16);
1329 av_sha_update(sha, fixed_key, 16);
1330 av_sha_final(sha, c->file_iv);
1331
1332 fail:
1333 av_free(sha);
1334
1335 return ret;
1336 }
1337
1338 static int mov_aaxc_crypto(MOVContext *c)
1339 {
1340 if (c->audible_key_size != 16) {
1341 av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
1342 return AVERROR(EINVAL);
1343 }
1344
1345 if (c->audible_iv_size != 16) {
1346 av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
1347 return AVERROR(EINVAL);
1348 }
1349
1350 c->aes_decrypt = av_aes_alloc();
1351 if (!c->aes_decrypt) {
1352 return AVERROR(ENOMEM);
1353 }
1354
1355 memcpy(c->file_key, c->audible_key, 16);
1356 memcpy(c->file_iv, c->audible_iv, 16);
1357 c->aax_mode = 1;
1358
1359 return 0;
1360 }
1361
1362 // Audible AAX (and AAX+) bytestream decryption
1363 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1364 {
1365 int blocks = 0;
1366 unsigned char iv[16];
1367
1368 memcpy(iv, c->file_iv, 16); // iv is overwritten
1369 blocks = size >> 4; // trailing bytes are not encrypted!
1370 av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1371 av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1372
1373 return 0;
1374 }
1375
1376 /* read major brand, minor version and compatible brands and store them as metadata */
1377 434 static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1378 {
1379 uint32_t minor_ver;
1380 int comp_brand_size;
1381 char* comp_brands_str;
1382 434 uint8_t type[5] = {0};
1383 434 int ret = ffio_read_size(pb, type, 4);
1384
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 434 times.
434 if (ret < 0)
1385 return ret;
1386
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 434 times.
434 if (c->fc->nb_streams) {
1387 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT)
1388 return AVERROR_INVALIDDATA;
1389 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate FTYP\n");
1390 return 0;
1391 }
1392
1393
2/2
✓ Branch 0 taken 211 times.
✓ Branch 1 taken 223 times.
434 if (strcmp(type, "qt "))
1394 211 c->isom = 1;
1395 434 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1396 434 av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1397 434 minor_ver = avio_rb32(pb); /* minor version */
1398 434 av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1399
1400 434 comp_brand_size = atom.size - 8;
1401
2/4
✓ Branch 0 taken 434 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 434 times.
434 if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1402 return AVERROR_INVALIDDATA;
1403 434 comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1404
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 434 times.
434 if (!comp_brands_str)
1405 return AVERROR(ENOMEM);
1406
1407 434 ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1408
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 434 times.
434 if (ret < 0) {
1409 av_freep(&comp_brands_str);
1410 return ret;
1411 }
1412 434 comp_brands_str[comp_brand_size] = 0;
1413 434 av_dict_set(&c->fc->metadata, "compatible_brands",
1414 comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1415
1416 // Logic for handling Audible's .aaxc files
1417
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 434 times.
434 if (!strcmp(type, "aaxc")) {
1418 mov_aaxc_crypto(c);
1419 }
1420
1421 434 return 0;
1422 }
1423
1424 /* this atom should contain all header atoms */
1425 468 static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1426 {
1427 int ret;
1428
1429
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 468 times.
468 if (c->found_moov) {
1430 av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1431 avio_skip(pb, atom.size);
1432 return 0;
1433 }
1434
1435
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 468 times.
468 if ((ret = mov_read_default(c, pb, atom)) < 0)
1436 return ret;
1437 /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1438 /* so we don't parse the whole file if over a network */
1439 468 c->found_moov=1;
1440 468 return 0; /* now go for mdat */
1441 }
1442
1443 2869 static MOVFragmentStreamInfo * get_frag_stream_info(
1444 MOVFragmentIndex *frag_index,
1445 int index,
1446 int id)
1447 {
1448 int i;
1449 MOVFragmentIndexItem * item;
1450
1451
2/4
✓ Branch 0 taken 2869 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2869 times.
2869 if (index < 0 || index >= frag_index->nb_items)
1452 return NULL;
1453 2869 item = &frag_index->item[index];
1454
1/2
✓ Branch 0 taken 2993 times.
✗ Branch 1 not taken.
2993 for (i = 0; i < item->nb_stream_info; i++)
1455
2/2
✓ Branch 0 taken 2869 times.
✓ Branch 1 taken 124 times.
2993 if (item->stream_info[i].id == id)
1456 2869 return &item->stream_info[i];
1457
1458 // This shouldn't happen
1459 return NULL;
1460 }
1461
1462 388 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1463 {
1464 int i;
1465 MOVFragmentIndexItem * item;
1466
1467
1/2
✓ Branch 0 taken 388 times.
✗ Branch 1 not taken.
388 if (frag_index->current < 0 ||
1468
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 388 times.
388 frag_index->current >= frag_index->nb_items)
1469 return;
1470
1471 388 item = &frag_index->item[frag_index->current];
1472
1/2
✓ Branch 0 taken 394 times.
✗ Branch 1 not taken.
394 for (i = 0; i < item->nb_stream_info; i++)
1473
2/2
✓ Branch 0 taken 388 times.
✓ Branch 1 taken 6 times.
394 if (item->stream_info[i].id == id) {
1474 388 item->current = i;
1475 388 return;
1476 }
1477
1478 // id not found. This shouldn't happen.
1479 item->current = -1;
1480 }
1481
1482 1149 static MOVFragmentStreamInfo * get_current_frag_stream_info(
1483 MOVFragmentIndex *frag_index)
1484 {
1485 MOVFragmentIndexItem *item;
1486
1/2
✓ Branch 0 taken 1149 times.
✗ Branch 1 not taken.
1149 if (frag_index->current < 0 ||
1487
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1146 times.
1149 frag_index->current >= frag_index->nb_items)
1488 3 return NULL;
1489
1490 1146 item = &frag_index->item[frag_index->current];
1491
2/4
✓ Branch 0 taken 1146 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1146 times.
✗ Branch 3 not taken.
1146 if (item->current >= 0 && item->current < item->nb_stream_info)
1492 1146 return &item->stream_info[item->current];
1493
1494 // This shouldn't happen
1495 return NULL;
1496 }
1497
1498 798 static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
1499 {
1500 int a, b, m;
1501 int64_t moof_offset;
1502
1503 // Optimize for appending new entries
1504
2/2
✓ Branch 0 taken 788 times.
✓ Branch 1 taken 10 times.
798 if (!frag_index->nb_items ||
1505
2/2
✓ Branch 0 taken 383 times.
✓ Branch 1 taken 405 times.
788 frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1506 393 return frag_index->nb_items;
1507
1508 405 a = -1;
1509 405 b = frag_index->nb_items;
1510
1511
2/2
✓ Branch 0 taken 2655 times.
✓ Branch 1 taken 405 times.
3060 while (b - a > 1) {
1512 2655 m = (a + b) >> 1;
1513 2655 moof_offset = frag_index->item[m].moof_offset;
1514
2/2
✓ Branch 0 taken 732 times.
✓ Branch 1 taken 1923 times.
2655 if (moof_offset >= offset)
1515 732 b = m;
1516
2/2
✓ Branch 0 taken 2328 times.
✓ Branch 1 taken 327 times.
2655 if (moof_offset <= offset)
1517 2328 a = m;
1518 }
1519 405 return b;
1520 }
1521
1522 static int64_t get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
1523 {
1524 av_assert0(frag_stream_info);
1525 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1526 return frag_stream_info->sidx_pts;
1527 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1528 return frag_stream_info->first_tfra_pts;
1529 return frag_stream_info->tfdt_dts;
1530 }
1531
1532 219 static int64_t get_frag_time(AVFormatContext *s, AVStream *dst_st,
1533 MOVFragmentIndex *frag_index, int index)
1534 {
1535 MOVFragmentStreamInfo * frag_stream_info;
1536 219 MOVStreamContext *sc = dst_st->priv_data;
1537 int64_t timestamp;
1538 int i, j;
1539
1540 // If the stream is referenced by any sidx, limit the search
1541 // to fragments that referenced this stream in the sidx
1542
1/2
✓ Branch 0 taken 219 times.
✗ Branch 1 not taken.
219 if (sc->has_sidx) {
1543 219 frag_stream_info = get_frag_stream_info(frag_index, index, sc->id);
1544
1/2
✓ Branch 0 taken 219 times.
✗ Branch 1 not taken.
219 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1545 219 return frag_stream_info->sidx_pts;
1546 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1547 return frag_stream_info->first_tfra_pts;
1548 return frag_stream_info->sidx_pts;
1549 }
1550
1551 for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1552 AVStream *frag_stream = NULL;
1553 frag_stream_info = &frag_index->item[index].stream_info[i];
1554 for (j = 0; j < s->nb_streams; j++) {
1555 MOVStreamContext *sc2 = s->streams[j]->priv_data;
1556 if (sc2->id == frag_stream_info->id)
1557 frag_stream = s->streams[j];
1558 }
1559 if (!frag_stream) {
1560 av_log(s, AV_LOG_WARNING, "No stream matching sidx ID found.\n");
1561 continue;
1562 }
1563 timestamp = get_stream_info_time(frag_stream_info);
1564 if (timestamp != AV_NOPTS_VALUE)
1565 return av_rescale_q(timestamp, frag_stream->time_base, dst_st->time_base);
1566 }
1567 return AV_NOPTS_VALUE;
1568 }
1569
1570 26 static int search_frag_timestamp(AVFormatContext *s, MOVFragmentIndex *frag_index,
1571 AVStream *st, int64_t timestamp)
1572 {
1573 int a, b, m, m0;
1574 int64_t frag_time;
1575
1576 26 a = -1;
1577 26 b = frag_index->nb_items;
1578
1579
2/2
✓ Branch 0 taken 219 times.
✓ Branch 1 taken 26 times.
245 while (b - a > 1) {
1580 219 m0 = m = (a + b) >> 1;
1581
1582
2/4
✓ Branch 0 taken 219 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 219 times.
438 while (m < b &&
1583 219 (frag_time = get_frag_time(s, st, frag_index, m)) == AV_NOPTS_VALUE)
1584 m++;
1585
1586
3/4
✓ Branch 0 taken 219 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 93 times.
✓ Branch 3 taken 126 times.
219 if (m < b && frag_time <= timestamp)
1587 93 a = m;
1588 else
1589 126 b = m0;
1590 }
1591
1592 26 return a;
1593 }
1594
1595 756 static int update_frag_index(MOVContext *c, int64_t offset)
1596 {
1597 int index, i;
1598 MOVFragmentIndexItem * item;
1599 MOVFragmentStreamInfo * frag_stream_info;
1600
1601 // If moof_offset already exists in frag_index, return index to it
1602 756 index = search_frag_moof_offset(&c->frag_index, offset);
1603
2/2
✓ Branch 0 taken 367 times.
✓ Branch 1 taken 389 times.
756 if (index < c->frag_index.nb_items &&
1604
1/2
✓ Branch 0 taken 367 times.
✗ Branch 1 not taken.
367 c->frag_index.item[index].moof_offset == offset)
1605 367 return index;
1606
1607 // offset is not yet in frag index.
1608 // Insert new item at index (sorted by moof offset)
1609 389 item = av_fast_realloc(c->frag_index.item,
1610 389 &c->frag_index.allocated_size,
1611 389 (c->frag_index.nb_items + 1) *
1612 sizeof(*c->frag_index.item));
1613
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 389 times.
389 if (!item)
1614 return -1;
1615 389 c->frag_index.item = item;
1616
1617 389 frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1618 sizeof(*item->stream_info));
1619
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 389 times.
389 if (!frag_stream_info)
1620 return -1;
1621
1622
2/2
✓ Branch 0 taken 407 times.
✓ Branch 1 taken 389 times.
796 for (i = 0; i < c->fc->nb_streams; i++) {
1623 // Avoid building frag index if streams lack track id.
1624 407 MOVStreamContext *sc = c->fc->streams[i]->priv_data;
1625
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 407 times.
407 if (sc->id < 0) {
1626 av_free(frag_stream_info);
1627 return AVERROR_INVALIDDATA;
1628 }
1629
1630 407 frag_stream_info[i].id = sc->id;
1631 407 frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1632 407 frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1633 407 frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1634 407 frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1635 407 frag_stream_info[i].index_base = -1;
1636 407 frag_stream_info[i].index_entry = -1;
1637 407 frag_stream_info[i].encryption_index = NULL;
1638 407 frag_stream_info[i].stsd_id = -1;
1639 }
1640
1641
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 389 times.
389 if (index < c->frag_index.nb_items)
1642 memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1643 (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1644
1645 389 item = &c->frag_index.item[index];
1646 389 item->headers_read = 0;
1647 389 item->current = 0;
1648 389 item->nb_stream_info = c->fc->nb_streams;
1649 389 item->moof_offset = offset;
1650 389 item->stream_info = frag_stream_info;
1651 389 c->frag_index.nb_items++;
1652
1653 389 return index;
1654 }
1655
1656 388 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1657 int id, int entries)
1658 {
1659 int i;
1660 MOVFragmentStreamInfo * frag_stream_info;
1661
1662
1/2
✓ Branch 0 taken 388 times.
✗ Branch 1 not taken.
388 if (index < 0)
1663 388 return;
1664 for (i = index; i < frag_index->nb_items; i++) {
1665 frag_stream_info = get_frag_stream_info(frag_index, i, id);
1666 if (frag_stream_info && frag_stream_info->index_entry >= 0)
1667 frag_stream_info->index_entry += entries;
1668 }
1669 }
1670
1671 388 static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1672 {
1673 // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1674 388 c->fragment.found_tfhd = 0;
1675
1676
2/4
✓ Branch 0 taken 388 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 388 times.
388 if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1677 c->has_looked_for_mfra = 1;
1678 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1679 int ret;
1680 av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1681 "for a mfra\n");
1682 if ((ret = mov_read_mfra(c, pb)) < 0) {
1683 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1684 "read the mfra (may be a live ismv)\n");
1685 }
1686 } else {
1687 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1688 "seekable, can not look for mfra\n");
1689 }
1690 }
1691 388 c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1692 388 av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1693 388 c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1694 388 return mov_read_default(c, pb, atom);
1695 }
1696
1697 1036 static void mov_metadata_creation_time(MOVContext *c, AVIOContext *pb, AVDictionary **metadata, int version)
1698 {
1699 int64_t time;
1700
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 1025 times.
1036 if (version == 1) {
1701 11 time = avio_rb64(pb);
1702 11 avio_rb64(pb);
1703
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if (time < 0) {
1704 av_log(c->fc, AV_LOG_DEBUG, "creation_time is negative\n");
1705 return;
1706 }
1707 } else {
1708 1025 time = avio_rb32(pb);
1709 1025 avio_rb32(pb); /* modification time */
1710
4/4
✓ Branch 0 taken 509 times.
✓ Branch 1 taken 516 times.
✓ Branch 2 taken 48 times.
✓ Branch 3 taken 461 times.
1025 if (time > 0 && time < 2082844800) {
1711 48 av_log(c->fc, AV_LOG_WARNING, "Detected creation time before 1970, parsing as unix timestamp.\n");
1712 48 time += 2082844800;
1713 }
1714 }
1715
2/2
✓ Branch 0 taken 515 times.
✓ Branch 1 taken 521 times.
1036 if (time) {
1716 515 time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1717
1718
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 515 times.
515 if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1719 av_log(c->fc, AV_LOG_DEBUG, "creation_time is not representable\n");
1720 return;
1721 }
1722
1723 515 avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1724 }
1725 }
1726
1727 571 static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1728 {
1729 AVStream *st;
1730 MOVStreamContext *sc;
1731 int version;
1732 571 char language[4] = {0};
1733 unsigned lang;
1734
1735
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 571 times.
571 if (c->fc->nb_streams < 1)
1736 return 0;
1737 571 st = c->fc->streams[c->fc->nb_streams-1];
1738 571 sc = st->priv_data;
1739
1740
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 571 times.
571 if (sc->time_scale) {
1741 av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1742 return AVERROR_INVALIDDATA;
1743 }
1744
1745 571 version = avio_r8(pb);
1746
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 571 times.
571 if (version > 1) {
1747 avpriv_request_sample(c->fc, "Version %d", version);
1748 return AVERROR_PATCHWELCOME;
1749 }
1750 571 avio_rb24(pb); /* flags */
1751 571 mov_metadata_creation_time(c, pb, &st->metadata, version);
1752
1753 571 sc->time_scale = avio_rb32(pb);
1754
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 571 times.
571 if (sc->time_scale <= 0) {
1755 av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1756 sc->time_scale = 1;
1757 }
1758
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 562 times.
571 st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1759
1760
6/6
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 562 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 562 times.
✓ Branch 5 taken 4 times.
571 if ((version == 1 && st->duration == UINT64_MAX) ||
1761
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 562 times.
562 (version != 1 && st->duration == UINT32_MAX)) {
1762 5 st->duration = 0;
1763 }
1764
1765 571 lang = avio_rb16(pb); /* language */
1766
2/2
✓ Branch 1 taken 407 times.
✓ Branch 2 taken 164 times.
571 if (ff_mov_lang_to_iso639(lang, language))
1767 407 av_dict_set(&st->metadata, "language", language, 0);
1768 571 avio_rb16(pb); /* quality */
1769
1770 571 return 0;
1771 }
1772
1773 465 static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1774 {
1775 int i;
1776 465 int version = avio_r8(pb); /* version */
1777 465 avio_rb24(pb); /* flags */
1778
1779 465 mov_metadata_creation_time(c, pb, &c->fc->metadata, version);
1780 465 c->time_scale = avio_rb32(pb); /* time scale */
1781
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 465 times.
465 if (c->time_scale <= 0) {
1782 av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1783 c->time_scale = 1;
1784 }
1785 465 av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1786
1787
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 463 times.
465 c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1788 465 avio_rb32(pb); /* preferred scale */
1789
1790 465 avio_rb16(pb); /* preferred volume */
1791
1792 465 avio_skip(pb, 10); /* reserved */
1793
1794 /* movie display matrix, store it in main context and use it later on */
1795
2/2
✓ Branch 0 taken 1395 times.
✓ Branch 1 taken 465 times.
1860 for (i = 0; i < 3; i++) {
1796 1395 c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1797 1395 c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1798 1395 c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1799 }
1800
1801 465 avio_rb32(pb); /* preview time */
1802 465 avio_rb32(pb); /* preview duration */
1803 465 avio_rb32(pb); /* poster time */
1804 465 avio_rb32(pb); /* selection time */
1805 465 avio_rb32(pb); /* selection duration */
1806 465 avio_rb32(pb); /* current time */
1807 465 avio_rb32(pb); /* next track ID */
1808
1809 465 return 0;
1810 }
1811
1812 7 static void set_last_stream_little_endian(AVFormatContext *fc)
1813 {
1814 AVStream *st;
1815
1816
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (fc->nb_streams < 1)
1817 return;
1818 7 st = fc->streams[fc->nb_streams-1];
1819
1820
3/6
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
7 switch (st->codecpar->codec_id) {
1821 5 case AV_CODEC_ID_PCM_S16BE:
1822 5 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
1823 5 break;
1824 1 case AV_CODEC_ID_PCM_S24BE:
1825 1 st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE;
1826 1 break;
1827 case AV_CODEC_ID_PCM_S32BE:
1828 st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE;
1829 break;
1830 1 case AV_CODEC_ID_PCM_F32BE:
1831 1 st->codecpar->codec_id = AV_CODEC_ID_PCM_F32LE;
1832 1 break;
1833 case AV_CODEC_ID_PCM_F64BE:
1834 st->codecpar->codec_id = AV_CODEC_ID_PCM_F64LE;
1835 break;
1836 default:
1837 break;
1838 }
1839 }
1840
1841 5 static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1842 {
1843 5 int little_endian = avio_rb16(pb) & 0xFF;
1844 5 av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1845
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
5 if (little_endian == 1)
1846 1 set_last_stream_little_endian(c->fc);
1847 5 return 0;
1848 }
1849
1850 6 static int mov_read_pcmc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1851 {
1852 int format_flags;
1853 int version, flags;
1854 int pcm_sample_size;
1855 6 AVFormatContext *fc = c->fc;
1856 AVStream *st;
1857 MOVStreamContext *sc;
1858
1859
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (atom.size < 6) {
1860 av_log(c->fc, AV_LOG_ERROR, "Empty pcmC box\n");
1861 return AVERROR_INVALIDDATA;
1862 }
1863
1864 6 version = avio_r8(pb);
1865 6 flags = avio_rb24(pb);
1866
1867
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
6 if (version != 0 || flags != 0) {
1868 av_log(c->fc, AV_LOG_ERROR,
1869 "Unsupported 'pcmC' box with version %d, flags: %x",
1870 version, flags);
1871 return AVERROR_INVALIDDATA;
1872 }
1873
1874 6 format_flags = avio_r8(pb);
1875 6 pcm_sample_size = avio_r8(pb);
1876
1877
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (fc->nb_streams < 1)
1878 return AVERROR_INVALIDDATA;
1879
1880 6 st = fc->streams[fc->nb_streams - 1];
1881 6 sc = st->priv_data;
1882
1883
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
6 if (sc->format == MOV_MP4_FPCM_TAG) {
1884
1/3
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
1 switch (pcm_sample_size) {
1885 1 case 32:
1886 1 st->codecpar->codec_id = AV_CODEC_ID_PCM_F32BE;
1887 1 break;
1888 case 64:
1889 st->codecpar->codec_id = AV_CODEC_ID_PCM_F64BE;
1890 break;
1891 default:
1892 av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
1893 pcm_sample_size,
1894 av_fourcc2str(sc->format));
1895 return AVERROR_INVALIDDATA;
1896 }
1897
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 } else if (sc->format == MOV_MP4_IPCM_TAG) {
1898
1/4
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
5 switch (pcm_sample_size) {
1899 5 case 16:
1900 5 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16BE;
1901 5 break;
1902 case 24:
1903 st->codecpar->codec_id = AV_CODEC_ID_PCM_S24BE;
1904 break;
1905 case 32:
1906 st->codecpar->codec_id = AV_CODEC_ID_PCM_S32BE;
1907 break;
1908 default:
1909 av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
1910 pcm_sample_size,
1911 av_fourcc2str(sc->format));
1912 return AVERROR_INVALIDDATA;
1913 }
1914 } else {
1915 av_log(fc, AV_LOG_ERROR, "'pcmC' with invalid sample entry '%s'\n",
1916 av_fourcc2str(sc->format));
1917 return AVERROR_INVALIDDATA;
1918 }
1919
1920
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (format_flags & 1) // indicates little-endian format. If not present, big-endian format is used
1921 6 set_last_stream_little_endian(c->fc);
1922 6 st->codecpar->bits_per_coded_sample = av_get_bits_per_sample(st->codecpar->codec_id);
1923
1924 6 return 0;
1925 }
1926
1927 40 static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1928 {
1929 AVStream *st;
1930 40 char color_parameter_type[5] = { 0 };
1931 uint16_t color_primaries, color_trc, color_matrix;
1932 int ret;
1933
1934 40 st = get_curr_st(c);
1935
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
40 if (!st)
1936 return 0;
1937
1938 40 ret = ffio_read_size(pb, color_parameter_type, 4);
1939
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
40 if (ret < 0)
1940 return ret;
1941
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 10 times.
40 if (strncmp(color_parameter_type, "nclx", 4) &&
1942
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
30 strncmp(color_parameter_type, "nclc", 4) &&
1943 strncmp(color_parameter_type, "prof", 4)) {
1944 av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
1945 color_parameter_type);
1946 return 0;
1947 }
1948
1949
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
40 if (!strncmp(color_parameter_type, "prof", 4)) {
1950 AVPacketSideData *sd = av_packet_side_data_new(&st->codecpar->coded_side_data,
1951 &st->codecpar->nb_coded_side_data,
1952 AV_PKT_DATA_ICC_PROFILE,
1953 atom.size - 4, 0);
1954 if (!sd)
1955 return AVERROR(ENOMEM);
1956 ret = ffio_read_size(pb, sd->data, atom.size - 4);
1957 if (ret < 0)
1958 return ret;
1959 } else {
1960 40 color_primaries = avio_rb16(pb);
1961 40 color_trc = avio_rb16(pb);
1962 40 color_matrix = avio_rb16(pb);
1963
1964 40 av_log(c->fc, AV_LOG_TRACE,
1965 "%s: pri %d trc %d matrix %d",
1966 color_parameter_type, color_primaries, color_trc, color_matrix);
1967
1968
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 30 times.
40 if (!strncmp(color_parameter_type, "nclx", 4)) {
1969 10 uint8_t color_range = avio_r8(pb) >> 7;
1970 10 av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
1971
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if (color_range)
1972 st->codecpar->color_range = AVCOL_RANGE_JPEG;
1973 else
1974 10 st->codecpar->color_range = AVCOL_RANGE_MPEG;
1975 }
1976
1977
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 40 times.
40 if (!av_color_primaries_name(color_primaries))
1978 color_primaries = AVCOL_PRI_UNSPECIFIED;
1979
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 40 times.
40 if (!av_color_transfer_name(color_trc))
1980 color_trc = AVCOL_TRC_UNSPECIFIED;
1981
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 40 times.
40 if (!av_color_space_name(color_matrix))
1982 color_matrix = AVCOL_SPC_UNSPECIFIED;
1983
1984 40 st->codecpar->color_primaries = color_primaries;
1985 40 st->codecpar->color_trc = color_trc;
1986 40 st->codecpar->color_space = color_matrix;
1987 40 av_log(c->fc, AV_LOG_TRACE, "\n");
1988 }
1989 40 return 0;
1990 }
1991
1992 107 static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1993 {
1994 AVStream *st;
1995 unsigned mov_field_order;
1996 107 enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
1997
1998
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 107 times.
107 if (c->fc->nb_streams < 1) // will happen with jp2 files
1999 return 0;
2000 107 st = c->fc->streams[c->fc->nb_streams-1];
2001
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 107 times.
107 if (atom.size < 2)
2002 return AVERROR_INVALIDDATA;
2003 107 mov_field_order = avio_rb16(pb);
2004
2/2
✓ Branch 0 taken 95 times.
✓ Branch 1 taken 12 times.
107 if ((mov_field_order & 0xFF00) == 0x0100)
2005 95 decoded_field_order = AV_FIELD_PROGRESSIVE;
2006
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 else if ((mov_field_order & 0xFF00) == 0x0200) {
2007
3/5
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 10 times.
✗ Branch 4 not taken.
12 switch (mov_field_order & 0xFF) {
2008 1 case 0x01: decoded_field_order = AV_FIELD_TT;
2009 1 break;
2010 case 0x06: decoded_field_order = AV_FIELD_BB;
2011 break;
2012 1 case 0x09: decoded_field_order = AV_FIELD_TB;
2013 1 break;
2014 10 case 0x0E: decoded_field_order = AV_FIELD_BT;
2015 10 break;
2016 }
2017 }
2018
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 107 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
107 if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
2019 av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
2020 }
2021 107 st->codecpar->field_order = decoded_field_order;
2022
2023 107 return 0;
2024 }
2025
2026 65 static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
2027 {
2028 65 int err = 0;
2029 65 uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
2030
2/4
✓ Branch 0 taken 65 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 65 times.
65 if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
2031 return AVERROR_INVALIDDATA;
2032
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 65 times.
65 if ((err = av_reallocp(&par->extradata, size)) < 0) {
2033 par->extradata_size = 0;
2034 return err;
2035 }
2036 65 par->extradata_size = size - AV_INPUT_BUFFER_PADDING_SIZE;
2037 65 return 0;
2038 }
2039
2040 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
2041 65 static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
2042 AVCodecParameters *par, uint8_t *buf)
2043 {
2044 65 int64_t result = atom.size;
2045 int err;
2046
2047 65 AV_WB32(buf , atom.size + 8);
2048 65 AV_WL32(buf + 4, atom.type);
2049 65 err = ffio_read_size(pb, buf + 8, atom.size);
2050
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 65 times.
65 if (err < 0) {
2051 par->extradata_size -= atom.size;
2052 return err;
2053
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 65 times.
65 } else if (err < atom.size) {
2054 av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
2055 par->extradata_size -= atom.size - err;
2056 result = err;
2057 }
2058 65 memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
2059 65 return result;
2060 }
2061
2062 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
2063 58 static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
2064 enum AVCodecID codec_id)
2065 {
2066 AVStream *st;
2067 uint64_t original_size;
2068 int err;
2069
2070
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
58 if (c->fc->nb_streams < 1) // will happen with jp2 files
2071 return 0;
2072 58 st = c->fc->streams[c->fc->nb_streams-1];
2073
2074
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 39 times.
58 if (st->codecpar->codec_id != codec_id)
2075 19 return 0; /* unexpected codec_id - don't mess with extradata */
2076
2077 39 original_size = st->codecpar->extradata_size;
2078 39 err = mov_realloc_extradata(st->codecpar, atom);
2079
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
39 if (err)
2080 return err;
2081
2082 39 err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
2083
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
39 if (err < 0)
2084 return err;
2085 39 return 0; // Note: this is the original behavior to ignore truncation.
2086 }
2087
2088 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
2089 16 static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2090 {
2091 16 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
2092 }
2093
2094 static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2095 {
2096 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_CAVS);
2097 }
2098
2099 static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2100 {
2101 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
2102 }
2103
2104 static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2105 {
2106 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
2107 }
2108
2109 19 static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2110 {
2111 19 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
2112
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 if (!ret)
2113 19 ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
2114 19 return ret;
2115 }
2116
2117 static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2118 {
2119 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
2120
2121 if (!ret && c->fc->nb_streams >= 1) {
2122 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2123 if (par->extradata_size >= 40) {
2124 par->height = AV_RB16(&par->extradata[36]);
2125 par->width = AV_RB16(&par->extradata[38]);
2126 }
2127 }
2128 return ret;
2129 }
2130
2131 16 static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2132 {
2133
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 if (c->fc->nb_streams >= 1) {
2134 16 AVStream *const st = c->fc->streams[c->fc->nb_streams - 1];
2135 16 FFStream *const sti = ffstream(st);
2136 16 AVCodecParameters *par = st->codecpar;
2137
2138
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
2139 par->codec_id == AV_CODEC_ID_H264 &&
2140 atom.size > 11) {
2141 int cid;
2142 avio_skip(pb, 10);
2143 cid = avio_rb16(pb);
2144 /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
2145 if (cid == 0xd4d || cid == 0xd4e)
2146 par->width = 1440;
2147 return 0;
2148
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
2149
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
2150
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 3 times.
16 par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
2151
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 atom.size >= 24) {
2152 int num, den;
2153 13 avio_skip(pb, 12);
2154 13 num = avio_rb32(pb);
2155 13 den = avio_rb32(pb);
2156
2/4
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
13 if (num <= 0 || den <= 0)
2157 return 0;
2158
2/3
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
13 switch (avio_rb32(pb)) {
2159 12 case 2:
2160
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (den >= INT_MAX / 2)
2161 return 0;
2162 12 den *= 2;
2163 13 case 1:
2164 13 sti->display_aspect_ratio = (AVRational){ num, den };
2165 13 default:
2166 13 return 0;
2167 }
2168 }
2169 }
2170
2171 3 return mov_read_avid(c, pb, atom);
2172 }
2173
2174 26 static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2175 {
2176 26 int ret = 0;
2177 26 int length = 0;
2178 uint64_t original_size;
2179
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 if (c->fc->nb_streams >= 1) {
2180 26 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2181
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (par->codec_id == AV_CODEC_ID_H264)
2182 return 0;
2183
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 if (atom.size == 16) {
2184 26 original_size = par->extradata_size;
2185 26 ret = mov_realloc_extradata(par, atom);
2186
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 if (!ret) {
2187 26 length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
2188
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 if (length == atom.size) {
2189 26 const uint8_t range_value = par->extradata[original_size + 19];
2190
1/3
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
26 switch (range_value) {
2191 26 case 1:
2192 26 par->color_range = AVCOL_RANGE_MPEG;
2193 26 break;
2194 case 2:
2195 par->color_range = AVCOL_RANGE_JPEG;
2196 break;
2197 default:
2198 av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
2199 break;
2200 }
2201 ff_dlog(c->fc, "color_range: %d\n", par->color_range);
2202 } else {
2203 /* For some reason the whole atom was not added to the extradata */
2204 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
2205 }
2206 } else {
2207 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
2208 }
2209 } else {
2210 av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
2211 }
2212 }
2213
2214 26 return ret;
2215 }
2216
2217 4 static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2218 {
2219 4 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
2220 }
2221
2222 34 static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2223 {
2224 AVStream *st;
2225 int ret;
2226
2227
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 34 times.
34 if (c->fc->nb_streams < 1)
2228 return 0;
2229 34 st = c->fc->streams[c->fc->nb_streams-1];
2230
2231
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 34 times.
34 if ((uint64_t)atom.size > (1<<30))
2232 return AVERROR_INVALIDDATA;
2233
2234
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 2 times.
34 if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
2235
1/2
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
32 st->codecpar->codec_id == AV_CODEC_ID_QDMC ||
2236
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
32 st->codecpar->codec_id == AV_CODEC_ID_SPEEX) {
2237 // pass all frma atom to codec, needed at least for QDMC and QDM2
2238 2 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2239
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (ret < 0)
2240 return ret;
2241
1/2
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
32 } else if (atom.size > 8) { /* to read frma, esds atoms */
2242
3/4
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 22 times.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
32 if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
2243 uint64_t buffer;
2244 10 ret = ffio_ensure_seekback(pb, 8);
2245
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if (ret < 0)
2246 return ret;
2247 10 buffer = avio_rb64(pb);
2248 10 atom.size -= 8;
2249
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
2250
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 && buffer >> 32 <= atom.size
2251
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 && buffer >> 32 >= 8) {
2252 10 avio_skip(pb, -8);
2253 10 atom.size += 8;
2254 } else if (!st->codecpar->extradata_size) {
2255 #define ALAC_EXTRADATA_SIZE 36
2256 st->codecpar->extradata = av_mallocz(ALAC_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
2257 if (!st->codecpar->extradata)
2258 return AVERROR(ENOMEM);
2259 st->codecpar->extradata_size = ALAC_EXTRADATA_SIZE;
2260 AV_WB32(st->codecpar->extradata , ALAC_EXTRADATA_SIZE);
2261 AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
2262 AV_WB64(st->codecpar->extradata + 12, buffer);
2263 avio_read(pb, st->codecpar->extradata + 20, 16);
2264 avio_skip(pb, atom.size - 24);
2265 return 0;
2266 }
2267 }
2268
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
32 if ((ret = mov_read_default(c, pb, atom)) < 0)
2269 return ret;
2270 } else
2271 avio_skip(pb, atom.size);
2272 34 return 0;
2273 }
2274
2275 /**
2276 * This function reads atom content and puts data in extradata without tag
2277 * nor size unlike mov_read_extradata.
2278 */
2279 128 static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2280 {
2281 AVStream *st;
2282 int ret;
2283
2284 128 st = get_curr_st(c);
2285
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 128 times.
128 if (!st)
2286 return 0;
2287
2288
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 128 times.
128 if ((uint64_t)atom.size > (1<<30))
2289 return AVERROR_INVALIDDATA;
2290
2291
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 128 times.
128 if (atom.type == MKTAG('v','v','c','C')) {
2292 avio_skip(pb, 4);
2293 atom.size -= 4;
2294 }
2295
2296
2/2
✓ Branch 0 taken 124 times.
✓ Branch 1 taken 4 times.
128 if (atom.size >= 10) {
2297 // Broken files created by legacy versions of libavformat will
2298 // wrap a whole fiel atom inside of a glbl atom.
2299 124 unsigned size = avio_rb32(pb);
2300 124 unsigned type = avio_rl32(pb);
2301
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 124 times.
124 if (avio_feof(pb))
2302 return AVERROR_INVALIDDATA;
2303 124 avio_seek(pb, -8, SEEK_CUR);
2304
3/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 116 times.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
124 if (type == MKTAG('f','i','e','l') && size == atom.size)
2305 8 return mov_read_default(c, pb, atom);
2306 }
2307
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 120 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
120 if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
2308 av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
2309 return 0;
2310 }
2311 120 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2312
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 120 times.
120 if (ret < 0)
2313 return ret;
2314
3/4
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 90 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 30 times.
120 if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
2315 /* HEVC-based Dolby Vision derived from hvc1.
2316 Happens to match with an identifier
2317 previously utilized for DV. Thus, if we have
2318 the hvcC extradata box available as specified,
2319 set codec to HEVC */
2320 st->codecpar->codec_id = AV_CODEC_ID_HEVC;
2321
2322 120 return 0;
2323 }
2324
2325 2 static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2326 {
2327 AVStream *st;
2328 uint8_t profile_level;
2329 int ret;
2330
2331
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (c->fc->nb_streams < 1)
2332 return 0;
2333 2 st = c->fc->streams[c->fc->nb_streams-1];
2334
2335
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
2 if (atom.size >= (1<<28) || atom.size < 7)
2336 return AVERROR_INVALIDDATA;
2337
2338 2 profile_level = avio_r8(pb);
2339
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if ((profile_level & 0xf0) != 0xc0)
2340 return 0;
2341
2342 2 avio_seek(pb, 6, SEEK_CUR);
2343 2 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
2344
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (ret < 0)
2345 return ret;
2346
2347 2 return 0;
2348 }
2349
2350 /**
2351 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
2352 * but can have extradata appended at the end after the 40 bytes belonging
2353 * to the struct.
2354 */
2355 static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2356 {
2357 AVStream *st;
2358 int ret;
2359
2360 if (c->fc->nb_streams < 1)
2361 return 0;
2362 if (atom.size <= 40)
2363 return 0;
2364 st = c->fc->streams[c->fc->nb_streams-1];
2365
2366 if ((uint64_t)atom.size > (1<<30))
2367 return AVERROR_INVALIDDATA;
2368
2369 avio_skip(pb, 40);
2370 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2371 if (ret < 0)
2372 return ret;
2373
2374 return 0;
2375 }
2376
2377 571 static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2378 {
2379 AVStream *st;
2380 MOVStreamContext *sc;
2381 unsigned int i, entries;
2382
2383
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 571 times.
571 if (c->trak_index < 0) {
2384 av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2385 return 0;
2386 }
2387
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 571 times.
571 if (c->fc->nb_streams < 1)
2388 return 0;
2389 571 st = c->fc->streams[c->fc->nb_streams-1];
2390 571 sc = st->priv_data;
2391
2392 571 avio_r8(pb); /* version */
2393 571 avio_rb24(pb); /* flags */
2394
2395 // Clamp allocation size for `chunk_offsets` -- don't throw an error for an
2396 // invalid count since the EOF path doesn't throw either.
2397 571 entries = avio_rb32(pb);
2398 571 entries =
2399
2/2
✓ Branch 0 taken 566 times.
✓ Branch 1 taken 5 times.
571 FFMIN(entries,
2400 FFMAX(0, (atom.size - 8) /
2401 (atom.type == MKTAG('s', 't', 'c', 'o') ? 4 : 8)));
2402
2403
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 555 times.
571 if (!entries)
2404 16 return 0;
2405
2406
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 555 times.
555 if (sc->chunk_offsets) {
2407 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STCO atom\n");
2408 return 0;
2409 }
2410
2411 555 av_free(sc->chunk_offsets);
2412 555 sc->chunk_count = 0;
2413 555 sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2414
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 555 times.
555 if (!sc->chunk_offsets)
2415 return AVERROR(ENOMEM);
2416 555 sc->chunk_count = entries;
2417
2418
2/2
✓ Branch 0 taken 551 times.
✓ Branch 1 taken 4 times.
555 if (atom.type == MKTAG('s','t','c','o'))
2419
3/4
✓ Branch 0 taken 42725 times.
✓ Branch 1 taken 551 times.
✓ Branch 2 taken 42725 times.
✗ Branch 3 not taken.
43276 for (i = 0; i < entries && !pb->eof_reached; i++)
2420 42725 sc->chunk_offsets[i] = avio_rb32(pb);
2421
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 else if (atom.type == MKTAG('c','o','6','4'))
2422
3/4
✓ Branch 0 taken 136336 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 136336 times.
✗ Branch 3 not taken.
136340 for (i = 0; i < entries && !pb->eof_reached; i++) {
2423 136336 sc->chunk_offsets[i] = avio_rb64(pb);
2424
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 136336 times.
136336 if (sc->chunk_offsets[i] < 0) {
2425 av_log(c->fc, AV_LOG_WARNING, "Impossible chunk_offset\n");
2426 sc->chunk_offsets[i] = 0;
2427 }
2428 }
2429 else
2430 return AVERROR_INVALIDDATA;
2431
2432 555 sc->chunk_count = i;
2433
2434
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 555 times.
555 if (pb->eof_reached) {
2435 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2436 return AVERROR_EOF;
2437 }
2438
2439 555 return 0;
2440 }
2441
2442 604 static int mov_codec_id(AVStream *st, uint32_t format)
2443 {
2444 604 int id = ff_codec_get_id(ff_codec_movaudio_tags, format);
2445
2446
2/2
✓ Branch 0 taken 387 times.
✓ Branch 1 taken 217 times.
604 if (id <= 0 &&
2447
2/2
✓ Branch 0 taken 384 times.
✓ Branch 1 taken 3 times.
387 ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2448
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 384 times.
384 (format & 0xFFFF) == 'T' + ('S' << 8)))
2449 3 id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format) & 0xFFFF);
2450
2451
4/4
✓ Branch 0 taken 286 times.
✓ Branch 1 taken 318 times.
✓ Branch 2 taken 220 times.
✓ Branch 3 taken 66 times.
604 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2452 220 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2453
3/4
✓ Branch 0 taken 368 times.
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 368 times.
✗ Branch 3 not taken.
384 } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2454 /* skip old ASF MPEG-4 tag */
2455
2/2
✓ Branch 0 taken 364 times.
✓ Branch 1 taken 4 times.
368 format && format != MKTAG('m','p','4','s')) {
2456 364 id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2457
2/2
✓ Branch 0 taken 53 times.
✓ Branch 1 taken 311 times.
364 if (id <= 0)
2458 53 id = ff_codec_get_id(ff_codec_bmp_tags, format);
2459
2/2
✓ Branch 0 taken 315 times.
✓ Branch 1 taken 49 times.
364 if (id > 0)
2460 315 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
2461
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 45 times.
49 else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2462
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
4 (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE &&
2463
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2464 45 id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
2465
2/2
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 6 times.
45 if (id <= 0) {
2466
2/2
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 2 times.
76 id = (format == MOV_MP4_TTML_TAG || format == MOV_ISMV_TTML_TAG) ?
2467
2/2
✓ Branch 0 taken 37 times.
✓ Branch 1 taken 2 times.
76 AV_CODEC_ID_TTML : id;
2468 }
2469
2470
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 35 times.
45 if (id > 0)
2471 10 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
2472 else
2473 35 id = ff_codec_get_id(ff_codec_movdata_tags, format);
2474 }
2475 }
2476
2477 604 st->codecpar->codec_tag = format;
2478
2479 604 return id;
2480 }
2481
2482 296 static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
2483 AVStream *st, MOVStreamContext *sc)
2484 {
2485 296 uint8_t codec_name[32] = { 0 };
2486 int64_t stsd_start;
2487 unsigned int len;
2488 296 uint32_t id = 0;
2489
2490 /* The first 16 bytes of the video sample description are already
2491 * read in ff_mov_read_stsd_entries() */
2492 296 stsd_start = avio_tell(pb) - 16;
2493
2494 296 avio_rb16(pb); /* version */
2495 296 avio_rb16(pb); /* revision level */
2496 296 id = avio_rl32(pb); /* vendor */
2497 296 av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2498 296 avio_rb32(pb); /* temporal quality */
2499 296 avio_rb32(pb); /* spatial quality */
2500
2501 296 st->codecpar->width = avio_rb16(pb); /* width */
2502 296 st->codecpar->height = avio_rb16(pb); /* height */
2503
2504 296 avio_rb32(pb); /* horiz resolution */
2505 296 avio_rb32(pb); /* vert resolution */
2506 296 avio_rb32(pb); /* data size, always 0 */
2507 296 avio_rb16(pb); /* frames per samples */
2508
2509 296 len = avio_r8(pb); /* codec name, pascal string */
2510
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 295 times.
296 if (len > 31)
2511 1 len = 31;
2512 296 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2513
2/2
✓ Branch 0 taken 294 times.
✓ Branch 1 taken 2 times.
296 if (len < 31)
2514 294 avio_skip(pb, 31 - len);
2515
2516
2/2
✓ Branch 0 taken 237 times.
✓ Branch 1 taken 59 times.
296 if (codec_name[0])
2517 237 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2518
2519 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2520
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 296 times.
296 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2521 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2522 st->codecpar->width &= ~1;
2523 st->codecpar->height &= ~1;
2524 }
2525 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2526
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 296 times.
296 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2527 !strncmp(codec_name, "Sorenson H263", 13))
2528 st->codecpar->codec_id = AV_CODEC_ID_FLV1;
2529
2530 296 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2531
2532 296 avio_seek(pb, stsd_start, SEEK_SET);
2533
2534
2/2
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 278 times.
296 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2535 18 st->codecpar->bits_per_coded_sample &= 0x1F;
2536 18 sc->has_palette = 1;
2537 }
2538 296 }
2539
2540 236 static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
2541 AVStream *st, MOVStreamContext *sc)
2542 {
2543 int bits_per_sample, flags;
2544 236 uint16_t version = avio_rb16(pb);
2545 236 uint32_t id = 0;
2546 236 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2547 int channel_count;
2548
2549 236 avio_rb16(pb); /* revision level */
2550 236 id = avio_rl32(pb); /* vendor */
2551 236 av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2552
2553 236 channel_count = avio_rb16(pb);
2554
2555 236 st->codecpar->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
2556 236 st->codecpar->ch_layout.nb_channels = channel_count;
2557 236 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2558 236 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", channel_count);
2559
2560 236 sc->audio_cid = avio_rb16(pb);
2561 236 avio_rb16(pb); /* packet size = 0 */
2562
2563 236 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2564
2565 // Read QT version 1 fields. In version 0 these do not exist.
2566 236 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2567
3/4
✓ Branch 0 taken 151 times.
✓ Branch 1 taken 85 times.
✓ Branch 2 taken 151 times.
✗ Branch 3 not taken.
236 if (!c->isom ||
2568
1/2
✓ Branch 0 taken 151 times.
✗ Branch 1 not taken.
151 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2569
3/4
✓ Branch 0 taken 151 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 147 times.
151 (sc->stsd_version == 0 && version > 0)) {
2570
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 39 times.
89 if (version == 1) {
2571 50 sc->samples_per_frame = avio_rb32(pb);
2572 50 avio_rb32(pb); /* bytes per packet */
2573 50 sc->bytes_per_frame = avio_rb32(pb);
2574 50 avio_rb32(pb); /* bytes per sample */
2575
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 35 times.
39 } else if (version == 2) {
2576 4 avio_rb32(pb); /* sizeof struct only */
2577 4 st->codecpar->sample_rate = av_int2double(avio_rb64(pb));
2578 4 channel_count = avio_rb32(pb);
2579 4 st->codecpar->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
2580 4 st->codecpar->ch_layout.nb_channels = channel_count;
2581 4 avio_rb32(pb); /* always 0x7F000000 */
2582 4 st->codecpar->bits_per_coded_sample = avio_rb32(pb);
2583
2584 4 flags = avio_rb32(pb); /* lpcm format specific flag */
2585 4 sc->bytes_per_frame = avio_rb32(pb);
2586 4 sc->samples_per_frame = avio_rb32(pb);
2587
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2588 st->codecpar->codec_id =
2589 ff_mov_get_lpcm_codec_id(st->codecpar->bits_per_coded_sample,
2590 flags);
2591 }
2592
6/6
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 35 times.
✓ Branch 2 taken 50 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 24 times.
✓ Branch 5 taken 26 times.
89 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2593 /* can't correctly handle variable sized packet as audio unit */
2594
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 59 times.
59 switch (st->codecpar->codec_id) {
2595 case AV_CODEC_ID_MP2:
2596 case AV_CODEC_ID_MP3:
2597 ffstream(st)->need_parsing = AVSTREAM_PARSE_FULL;
2598 break;
2599 }
2600 }
2601 }
2602
2603
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 236 times.
236 if (sc->format == 0) {
2604 if (st->codecpar->bits_per_coded_sample == 8)
2605 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2606 else if (st->codecpar->bits_per_coded_sample == 16)
2607 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2608 }
2609
2610
7/7
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 19 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 194 times.
236 switch (st->codecpar->codec_id) {
2611 7 case AV_CODEC_ID_PCM_S8:
2612 case AV_CODEC_ID_PCM_U8:
2613
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (st->codecpar->bits_per_coded_sample == 16)
2614 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16BE;
2615 7 break;
2616 19 case AV_CODEC_ID_PCM_S16LE:
2617 case AV_CODEC_ID_PCM_S16BE:
2618
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 17 times.
19 if (st->codecpar->bits_per_coded_sample == 8)
2619 2 st->codecpar->codec_id = AV_CODEC_ID_PCM_S8;
2620
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 else if (st->codecpar->bits_per_coded_sample == 24)
2621 st->codecpar->codec_id =
2622 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2623 AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
2624
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 else if (st->codecpar->bits_per_coded_sample == 32)
2625 st->codecpar->codec_id =
2626 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2627 AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
2628 19 break;
2629 /* set values for old format before stsd version 1 appeared */
2630 2 case AV_CODEC_ID_MACE3:
2631 2 sc->samples_per_frame = 6;
2632 2 sc->bytes_per_frame = 2 * st->codecpar->ch_layout.nb_channels;
2633 2 break;
2634 8 case AV_CODEC_ID_MACE6:
2635 8 sc->samples_per_frame = 6;
2636 8 sc->bytes_per_frame = 1 * st->codecpar->ch_layout.nb_channels;
2637 8 break;
2638 5 case AV_CODEC_ID_ADPCM_IMA_QT:
2639 5 sc->samples_per_frame = 64;
2640 5 sc->bytes_per_frame = 34 * st->codecpar->ch_layout.nb_channels;
2641 5 break;
2642 1 case AV_CODEC_ID_GSM:
2643 1 sc->samples_per_frame = 160;
2644 1 sc->bytes_per_frame = 33;
2645 1 break;
2646 194 default:
2647 194 break;
2648 }
2649
2650 236 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2651
3/4
✓ Branch 0 taken 47 times.
✓ Branch 1 taken 189 times.
✓ Branch 2 taken 47 times.
✗ Branch 3 not taken.
236 if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->ch_layout.nb_channels <= INT_MAX) {
2652 47 st->codecpar->bits_per_coded_sample = bits_per_sample;
2653 47 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->ch_layout.nb_channels;
2654 }
2655 236 }
2656
2657 11 static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
2658 AVStream *st, MOVStreamContext *sc,
2659 int64_t size)
2660 {
2661 // ttxt stsd contains display flags, justification, background
2662 // color, fonts, and default styles, so fake an atom to read it
2663 11 MOVAtom fake_atom = { .size = size };
2664 // mp4s contains a regular esds atom, dfxp ISMV TTML has no content
2665 // in extradata unlike stpp MP4 TTML.
2666
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if (st->codecpar->codec_tag != AV_RL32("mp4s") &&
2667
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 2 times.
11 st->codecpar->codec_tag != MOV_ISMV_TTML_TAG)
2668 9 mov_read_glbl(c, pb, fake_atom);
2669 11 st->codecpar->width = sc->width;
2670 11 st->codecpar->height = sc->height;
2671 11 }
2672
2673 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2674 {
2675 uint8_t r, g, b;
2676 int y, cb, cr;
2677
2678 y = (ycbcr >> 16) & 0xFF;
2679 cr = (ycbcr >> 8) & 0xFF;
2680 cb = ycbcr & 0xFF;
2681
2682 b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
2683 g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
2684 r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
2685
2686 return (r << 16) | (g << 8) | b;
2687 }
2688
2689 static int mov_rewrite_dvd_sub_extradata(AVStream *st)
2690 {
2691 char buf[256] = {0};
2692 uint8_t *src = st->codecpar->extradata;
2693 int i, ret;
2694
2695 if (st->codecpar->extradata_size != 64)
2696 return 0;
2697
2698 if (st->codecpar->width > 0 && st->codecpar->height > 0)
2699 snprintf(buf, sizeof(buf), "size: %dx%d\n",
2700 st->codecpar->width, st->codecpar->height);
2701 av_strlcat(buf, "palette: ", sizeof(buf));
2702
2703 for (i = 0; i < 16; i++) {
2704 uint32_t yuv = AV_RB32(src + i * 4);
2705 uint32_t rgba = yuv_to_rgba(yuv);
2706
2707 av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2708 }
2709
2710 if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2711 return 0;
2712
2713 ret = ff_alloc_extradata(st->codecpar, strlen(buf));
2714 if (ret < 0)
2715 return ret;
2716 memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2717
2718 return 0;
2719 }
2720
2721 39 static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
2722 AVStream *st, MOVStreamContext *sc,
2723 int64_t size)
2724 {
2725 int ret;
2726
2727
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 20 times.
39 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2728
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
19 if ((int)size != size)
2729 return AVERROR(ENOMEM);
2730
2731 19 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2732
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
19 if (ret < 0)
2733 return ret;
2734
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 if (size > 16) {
2735 19 MOVStreamContext *tmcd_ctx = st->priv_data;
2736 int val;
2737 19 val = AV_RB32(st->codecpar->extradata + 4);
2738 19 tmcd_ctx->tmcd_flags = val;
2739 19 st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2740 19 st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2741 19 tmcd_ctx->tmcd_nb_frames = st->codecpar->extradata[16]; /* number of frames */
2742
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 15 times.
19 if (size > 30) {
2743 4 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2744 4 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2745
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2746 4 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2747
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 if (str_size > 0 && size >= (int)str_size + 30 &&
2748
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 st->codecpar->extradata[30] /* Don't add empty string */) {
2749 4 char *reel_name = av_malloc(str_size + 1);
2750
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!reel_name)
2751 return AVERROR(ENOMEM);
2752 4 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2753 4 reel_name[str_size] = 0; /* Add null terminator */
2754 4 av_dict_set(&st->metadata, "reel_name", reel_name,
2755 AV_DICT_DONT_STRDUP_VAL);
2756 }
2757 }
2758 }
2759 }
2760 } else {
2761 /* other codec type, just skip (rtp, mp4s ...) */
2762 20 avio_skip(pb, size);
2763 }
2764 39 return 0;
2765 }
2766
2767 571 static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
2768 AVStream *st, MOVStreamContext *sc)
2769 {
2770 571 FFStream *const sti = ffstream(st);
2771
2772
2/2
✓ Branch 0 taken 236 times.
✓ Branch 1 taken 335 times.
571 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2773
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 236 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
236 !st->codecpar->sample_rate && sc->time_scale > 1)
2774 st->codecpar->sample_rate = sc->time_scale;
2775
2776 /* special codec parameters handling */
2777
7/10
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 15 times.
✓ Branch 6 taken 16 times.
✓ Branch 7 taken 10 times.
✓ Branch 8 taken 65 times.
✓ Branch 9 taken 453 times.
571 switch (st->codecpar->codec_id) {
2778 #if CONFIG_DV_DEMUXER
2779 case AV_CODEC_ID_DVAUDIO:
2780 if (c->dv_fctx) {
2781 avpriv_request_sample(c->fc, "multiple DV audio streams");
2782 return AVERROR(ENOSYS);
2783 }
2784
2785 c->dv_fctx = avformat_alloc_context();
2786 if (!c->dv_fctx) {
2787 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2788 return AVERROR(ENOMEM);
2789 }
2790 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2791 if (!c->dv_demux) {
2792 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2793 return AVERROR(ENOMEM);
2794 }
2795 sc->dv_audio_container = 1;
2796 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
2797 break;
2798 #endif
2799 /* no ifdef since parameters are always those */
2800 case AV_CODEC_ID_QCELP:
2801 av_channel_layout_uninit(&st->codecpar->ch_layout);
2802 st->codecpar->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO;
2803 // force sample rate for qcelp when not stored in mov
2804 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2805 st->codecpar->sample_rate = 8000;
2806 // FIXME: Why is the following needed for some files?
2807 sc->samples_per_frame = 160;
2808 if (!sc->bytes_per_frame)
2809 sc->bytes_per_frame = 35;
2810 break;
2811 case AV_CODEC_ID_AMR_NB:
2812 av_channel_layout_uninit(&st->codecpar->ch_layout);
2813 st->codecpar->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO;
2814 /* force sample rate for amr, stsd in 3gp does not store sample rate */
2815 st->codecpar->sample_rate = 8000;
2816 break;
2817 11 case AV_CODEC_ID_AMR_WB:
2818 11 av_channel_layout_uninit(&st->codecpar->ch_layout);
2819 11 st->codecpar->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO;
2820 11 st->codecpar->sample_rate = 16000;
2821 11 break;
2822 1 case AV_CODEC_ID_MP2:
2823 case AV_CODEC_ID_MP3:
2824 /* force type after stsd for m1a hdlr */
2825 1 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2826 1 break;
2827 15 case AV_CODEC_ID_GSM:
2828 case AV_CODEC_ID_ADPCM_MS:
2829 case AV_CODEC_ID_ADPCM_IMA_WAV:
2830 case AV_CODEC_ID_ILBC:
2831 case AV_CODEC_ID_MACE3:
2832 case AV_CODEC_ID_MACE6:
2833 case AV_CODEC_ID_QDM2:
2834 15 st->codecpar->block_align = sc->bytes_per_frame;
2835 15 break;
2836 16 case AV_CODEC_ID_ALAC:
2837
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 if (st->codecpar->extradata_size == 36) {
2838 16 int channel_count = AV_RB8(st->codecpar->extradata + 21);
2839
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (st->codecpar->ch_layout.nb_channels != channel_count) {
2840 av_channel_layout_uninit(&st->codecpar->ch_layout);
2841 st->codecpar->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
2842 st->codecpar->ch_layout.nb_channels = channel_count;
2843 }
2844 16 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2845 }
2846 16 break;
2847 10 case AV_CODEC_ID_AC3:
2848 case AV_CODEC_ID_EAC3:
2849 case AV_CODEC_ID_MPEG1VIDEO:
2850 case AV_CODEC_ID_VC1:
2851 case AV_CODEC_ID_VP8:
2852 case AV_CODEC_ID_VP9:
2853 10 sti->need_parsing = AVSTREAM_PARSE_FULL;
2854 10 break;
2855 65 case AV_CODEC_ID_EVC:
2856 case AV_CODEC_ID_AV1:
2857 /* field_order detection of H264 requires parsing */
2858 case AV_CODEC_ID_H264:
2859 65 sti->need_parsing = AVSTREAM_PARSE_HEADERS;
2860 65 break;
2861 453 default:
2862 453 break;
2863 }
2864 571 return 0;
2865 }
2866
2867 582 static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
2868 int codec_tag, int format,
2869 int64_t size)
2870 {
2871
3/4
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 571 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
582 if (codec_tag &&
2872 (codec_tag != format &&
2873 // AVID 1:1 samples with differing data format and codec tag exist
2874 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
2875 // prores is allowed to have differing data format and codec tag
2876 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
2877 // so is dv (sigh)
2878 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
2879 (c->fc->video_codec_id ? ff_codec_get_id(ff_codec_movvideo_tags, format) != c->fc->video_codec_id
2880 : codec_tag != MKTAG('j','p','e','g')))) {
2881 /* Multiple fourcc, we skip JPEG. This is not correct, we should
2882 * export it as a separate AVStream but this needs a few changes
2883 * in the MOV demuxer, patch welcome. */
2884
2885 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
2886 avio_skip(pb, size);
2887 return 1;
2888 }
2889
2890 582 return 0;
2891 }
2892
2893 571 int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
2894 {
2895 AVStream *st;
2896 MOVStreamContext *sc;
2897 int pseudo_stream_id;
2898
2899
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 571 times.
571 av_assert0 (c->fc->nb_streams >= 1);
2900 571 st = c->fc->streams[c->fc->nb_streams-1];
2901 571 sc = st->priv_data;
2902
2903 571 for (pseudo_stream_id = 0;
2904
3/4
✓ Branch 0 taken 582 times.
✓ Branch 1 taken 571 times.
✓ Branch 2 taken 582 times.
✗ Branch 3 not taken.
1153 pseudo_stream_id < entries && !pb->eof_reached;
2905 582 pseudo_stream_id++) {
2906 //Parsing Sample description table
2907 enum AVCodecID id;
2908 582 int ret, dref_id = 1;
2909 582 MOVAtom a = { AV_RL32("stsd") };
2910 582 int64_t start_pos = avio_tell(pb);
2911 582 int64_t size = avio_rb32(pb); /* size */
2912 582 uint32_t format = avio_rl32(pb); /* data format */
2913
2914
1/2
✓ Branch 0 taken 582 times.
✗ Branch 1 not taken.
582 if (size >= 16) {
2915 582 avio_rb32(pb); /* reserved */
2916 582 avio_rb16(pb); /* reserved */
2917 582 dref_id = avio_rb16(pb);
2918 } else if (size <= 7) {
2919 av_log(c->fc, AV_LOG_ERROR,
2920 "invalid size %"PRId64" in stsd\n", size);
2921 return AVERROR_INVALIDDATA;
2922 }
2923
2924
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 582 times.
582 if (mov_skip_multiple_stsd(c, pb, st->codecpar->codec_tag, format,
2925 582 size - (avio_tell(pb) - start_pos))) {
2926 sc->stsd_count++;
2927 continue;
2928 }
2929
2930
2/2
✓ Branch 0 taken 571 times.
✓ Branch 1 taken 11 times.
582 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
2931 582 sc->dref_id= dref_id;
2932 582 sc->format = format;
2933
2934 582 id = mov_codec_id(st, format);
2935
2936 582 av_log(c->fc, AV_LOG_TRACE,
2937 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
2938 582 av_fourcc2str(format), st->codecpar->codec_type);
2939
2940 582 st->codecpar->codec_id = id;
2941
2/2
✓ Branch 0 taken 296 times.
✓ Branch 1 taken 286 times.
582 if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) {
2942 296 mov_parse_stsd_video(c, pb, st, sc);
2943
2/2
✓ Branch 0 taken 236 times.
✓ Branch 1 taken 50 times.
286 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
2944 236 mov_parse_stsd_audio(c, pb, st, sc);
2945
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 236 times.
236 if (st->codecpar->sample_rate < 0) {
2946 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
2947 return AVERROR_INVALIDDATA;
2948 }
2949
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 236 times.
236 if (st->codecpar->ch_layout.nb_channels < 0) {
2950 av_log(c->fc, AV_LOG_ERROR, "Invalid channels %d\n", st->codecpar->ch_layout.nb_channels);
2951 return AVERROR_INVALIDDATA;
2952 }
2953
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 39 times.
50 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
2954 11 mov_parse_stsd_subtitle(c, pb, st, sc,
2955 11 size - (avio_tell(pb) - start_pos));
2956 } else {
2957 39 ret = mov_parse_stsd_data(c, pb, st, sc,
2958 39 size - (avio_tell(pb) - start_pos));
2959
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
39 if (ret < 0)
2960 return ret;
2961 }
2962 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
2963 582 a.size = size - (avio_tell(pb) - start_pos);
2964
2/2
✓ Branch 0 taken 456 times.
✓ Branch 1 taken 126 times.
582 if (a.size > 8) {
2965
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 456 times.
456 if ((ret = mov_read_default(c, pb, a)) < 0)
2966 return ret;
2967
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 125 times.
126 } else if (a.size > 0)
2968 1 avio_skip(pb, a.size);
2969
2970
3/4
✓ Branch 0 taken 582 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 325 times.
✓ Branch 3 taken 257 times.
582 if (sc->extradata && st->codecpar->extradata) {
2971 325 int extra_size = st->codecpar->extradata_size;
2972
2973 /* Move the current stream extradata to the stream context one. */
2974 325 sc->extradata_size[pseudo_stream_id] = extra_size;
2975 325 sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
2976 325 st->codecpar->extradata = NULL;
2977 325 st->codecpar->extradata_size = 0;
2978 }
2979 582 sc->stsd_count++;
2980 }
2981
2982
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 571 times.
571 if (pb->eof_reached) {
2983 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
2984 return AVERROR_EOF;
2985 }
2986
2987 571 return 0;
2988 }
2989
2990 571 static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2991 {
2992 AVStream *st;
2993 MOVStreamContext *sc;
2994 int ret, entries;
2995
2996
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 571 times.
571 if (c->fc->nb_streams < 1)
2997 return 0;
2998 571 st = c->fc->streams[c->fc->nb_streams - 1];
2999 571 sc = st->priv_data;
3000
3001 571 sc->stsd_version = avio_r8(pb);
3002 571 avio_rb24(pb); /* flags */
3003 571 entries = avio_rb32(pb);
3004
3005 /* Each entry contains a size (4 bytes) and format (4 bytes). */
3006
3/6
✓ Branch 0 taken 571 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 571 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 571 times.
571 if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
3007 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
3008 return AVERROR_INVALIDDATA;
3009 }
3010
3011
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 571 times.
571 if (sc->extradata) {
3012 av_log(c->fc, AV_LOG_ERROR,
3013 "Duplicate stsd found in this track.\n");
3014 return AVERROR_INVALIDDATA;
3015 }
3016
3017 /* Prepare space for hosting multiple extradata. */
3018 571 sc->extradata = av_calloc(entries, sizeof(*sc->extradata));
3019
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 571 times.
571 if (!sc->extradata)
3020 return AVERROR(ENOMEM);
3021
3022 571 sc->extradata_size = av_calloc(entries, sizeof(*sc->extradata_size));
3023
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 571 times.
571 if (!sc->extradata_size) {
3024 ret = AVERROR(ENOMEM);
3025 goto fail;
3026 }
3027
3028 571 ret = ff_mov_read_stsd_entries(c, pb, entries);
3029
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 571 times.
571 if (ret < 0)
3030 goto fail;
3031
3032 /* Restore back the primary extradata. */
3033 571 av_freep(&st->codecpar->extradata);
3034 571 st->codecpar->extradata_size = sc->extradata_size[0];
3035
2/2
✓ Branch 0 taken 315 times.
✓ Branch 1 taken 256 times.
571 if (sc->extradata_size[0]) {
3036 315 st->codecpar->extradata = av_mallocz(sc->extradata_size[0] + AV_INPUT_BUFFER_PADDING_SIZE);
3037
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 315 times.
315 if (!st->codecpar->extradata)
3038 return AVERROR(ENOMEM);
3039 315 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
3040 }
3041
3042 571 return mov_finalize_stsd_codec(c, pb, st, sc);
3043 fail:
3044 if (sc->extradata) {
3045 int j;
3046 for (j = 0; j < sc->stsd_count; j++)
3047 av_freep(&sc->extradata[j]);
3048 }
3049
3050 av_freep(&sc->extradata);
3051 av_freep(&sc->extradata_size);
3052 return ret;
3053 }
3054
3055 571 static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3056 {
3057 AVStream *st;
3058 MOVStreamContext *sc;
3059 unsigned int i, entries;
3060
3061
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 571 times.
571 if (c->fc->nb_streams < 1)
3062 return 0;
3063 571 st = c->fc->streams[c->fc->nb_streams-1];
3064 571 sc = st->priv_data;
3065
3066 571 avio_r8(pb); /* version */
3067 571 avio_rb24(pb); /* flags */
3068
3069 571 entries = avio_rb32(pb);
3070
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 571 times.
571 if ((uint64_t)entries * 12 + 4 > atom.size)
3071 return AVERROR_INVALIDDATA;
3072
3073 571 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
3074
3075
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 556 times.
571 if (!entries)
3076 15 return 0;
3077
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 556 times.
556 if (sc->stsc_data) {
3078 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n");
3079 return 0;
3080 }
3081 556 av_free(sc->stsc_data);
3082 556 sc->stsc_count = 0;
3083 556 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
3084
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 556 times.
556 if (!sc->stsc_data)
3085 return AVERROR(ENOMEM);
3086
3087
3/4
✓ Branch 0 taken 3718 times.
✓ Branch 1 taken 556 times.
✓ Branch 2 taken 3718 times.
✗ Branch 3 not taken.
4274 for (i = 0; i < entries && !pb->eof_reached; i++) {
3088 3718 sc->stsc_data[i].first = avio_rb32(pb);
3089 3718 sc->stsc_data[i].count = avio_rb32(pb);
3090 3718 sc->stsc_data[i].id = avio_rb32(pb);
3091 }
3092
3093 556 sc->stsc_count = i;
3094
2/2
✓ Branch 0 taken 3718 times.
✓ Branch 1 taken 556 times.
4274 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
3095 3718 int64_t first_min = i + 1;
3096
5/6
✓ Branch 0 taken 3162 times.
✓ Branch 1 taken 556 times.
✓ Branch 2 taken 3162 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3162 times.
✓ Branch 5 taken 556 times.
3718 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
3097
1/2
✓ Branch 0 taken 3162 times.
✗ Branch 1 not taken.
3162 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
3098
1/2
✓ Branch 0 taken 3718 times.
✗ Branch 1 not taken.
3718 sc->stsc_data[i].first < first_min ||
3099
1/2
✓ Branch 0 taken 3718 times.
✗ Branch 1 not taken.
3718 sc->stsc_data[i].count < 1 ||
3100
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3718 times.
3718 sc->stsc_data[i].id < 1) {
3101 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);
3102 if (i+1 >= sc->stsc_count) {
3103 if (sc->stsc_data[i].count == 0 && i > 0) {
3104 sc->stsc_count --;
3105 continue;
3106 }
3107 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
3108 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
3109 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
3110 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
3111 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
3112 continue;
3113 }
3114 av_assert0(sc->stsc_data[i+1].first >= 2);
3115 // We replace this entry by the next valid
3116 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
3117 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
3118 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
3119 }
3120 }
3121
3122
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 556 times.
556 if (pb->eof_reached) {
3123 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
3124 return AVERROR_EOF;
3125 }
3126
3127 556 return 0;
3128 }
3129
3130 335795 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
3131 {
3132 335795 return index < count - 1;
3133 }
3134
3135 /* Compute the samples value for the stsc entry at the given index. */
3136 55378 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
3137 {
3138 int chunk_count;
3139
3140
2/2
✓ Branch 1 taken 55182 times.
✓ Branch 2 taken 196 times.
55378 if (mov_stsc_index_valid(index, sc->stsc_count))
3141 55182 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
3142 else {
3143 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
3144
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 196 times.
196 av_assert0(sc->stsc_data[index].first <= sc->chunk_count);
3145 196 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
3146 }
3147
3148 55378 return sc->stsc_data[index].count * (int64_t)chunk_count;
3149 }
3150
3151 static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3152 {
3153 AVStream *st;
3154 MOVStreamContext *sc;
3155 unsigned i, entries;
3156
3157 if (c->fc->nb_streams < 1)
3158 return 0;
3159 st = c->fc->streams[c->fc->nb_streams-1];
3160 sc = st->priv_data;
3161
3162 avio_rb32(pb); // version + flags
3163
3164 entries = avio_rb32(pb);
3165 if (sc->stps_data)
3166 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
3167 av_free(sc->stps_data);
3168 sc->stps_count = 0;
3169 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
3170 if (!sc->stps_data)
3171 return AVERROR(ENOMEM);
3172
3173 for (i = 0; i < entries && !pb->eof_reached; i++) {
3174 sc->stps_data[i] = avio_rb32(pb);
3175 }
3176
3177 sc->stps_count = i;
3178
3179 if (pb->eof_reached) {
3180 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
3181 return AVERROR_EOF;
3182 }
3183
3184 return 0;
3185 }
3186
3187 130 static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3188 {
3189 AVStream *st;
3190 FFStream *sti;
3191 MOVStreamContext *sc;
3192 unsigned int i, entries;
3193
3194
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 130 times.
130 if (c->fc->nb_streams < 1)
3195 return 0;
3196 130 st = c->fc->streams[c->fc->nb_streams-1];
3197 130 sti = ffstream(st);
3198 130 sc = st->priv_data;
3199
3200 130 avio_r8(pb); /* version */
3201 130 avio_rb24(pb); /* flags */
3202
3203 130 entries = avio_rb32(pb);
3204
3205 130 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
3206
3207
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 126 times.
130 if (!entries) {
3208 4 sc->keyframe_absent = 1;
3209
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4 if (!sti->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
3210 sti->need_parsing = AVSTREAM_PARSE_HEADERS;
3211 4 return 0;
3212 }
3213
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 126 times.
126 if (sc->keyframes)
3214 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
3215
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 126 times.
126 if (entries >= UINT_MAX / sizeof(int))
3216 return AVERROR_INVALIDDATA;
3217 126 av_freep(&sc->keyframes);
3218 126 sc->keyframe_count = 0;
3219 126 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
3220
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 126 times.
126 if (!sc->keyframes)
3221 return AVERROR(ENOMEM);
3222
3223
3/4
✓ Branch 0 taken 5680 times.
✓ Branch 1 taken 126 times.
✓ Branch 2 taken 5680 times.
✗ Branch 3 not taken.
5806 for (i = 0; i < entries && !pb->eof_reached; i++) {
3224 5680 sc->keyframes[i] = avio_rb32(pb);
3225 }
3226
3227 126 sc->keyframe_count = i;
3228
3229
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 126 times.
126 if (pb->eof_reached) {
3230 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
3231 return AVERROR_EOF;
3232 }
3233
3234 126 return 0;
3235 }
3236
3237 571 static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3238 {
3239 AVStream *st;
3240 MOVStreamContext *sc;
3241 unsigned int i, entries, sample_size, field_size, num_bytes;
3242 GetBitContext gb;
3243 unsigned char* buf;
3244 int ret;
3245
3246
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 571 times.
571 if (c->fc->nb_streams < 1)
3247 return 0;
3248 571 st = c->fc->streams[c->fc->nb_streams-1];
3249 571 sc = st->priv_data;
3250
3251 571 avio_r8(pb); /* version */
3252 571 avio_rb24(pb); /* flags */
3253
3254
1/2
✓ Branch 0 taken 571 times.
✗ Branch 1 not taken.
571 if (atom.type == MKTAG('s','t','s','z')) {
3255 571 sample_size = avio_rb32(pb);
3256
2/2
✓ Branch 0 taken 531 times.
✓ Branch 1 taken 40 times.
571 if (!sc->sample_size) /* do not overwrite value computed in stsd */
3257 531 sc->sample_size = sample_size;
3258 571 sc->stsz_sample_size = sample_size;
3259 571 field_size = 32;
3260 } else {
3261 sample_size = 0;
3262 avio_rb24(pb); /* reserved */
3263 field_size = avio_r8(pb);
3264 }
3265 571 entries = avio_rb32(pb);
3266
3267 571 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
3268
3269 571 sc->sample_count = entries;
3270
2/2
✓ Branch 0 taken 191 times.
✓ Branch 1 taken 380 times.
571 if (sample_size)
3271 191 return 0;
3272
3273
4/8
✓ Branch 0 taken 380 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 380 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 380 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 380 times.
380 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
3274 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
3275 return AVERROR_INVALIDDATA;
3276 }
3277
3278
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 364 times.
380 if (!entries)
3279 16 return 0;
3280
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 364 times.
364 if (entries >= (INT_MAX - 4 - 8 * AV_INPUT_BUFFER_PADDING_SIZE) / field_size)
3281 return AVERROR_INVALIDDATA;
3282
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 364 times.
364 if (sc->sample_sizes)
3283 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
3284 364 av_free(sc->sample_sizes);
3285 364 sc->sample_count = 0;
3286 364 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
3287
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 364 times.
364 if (!sc->sample_sizes)
3288 return AVERROR(ENOMEM);
3289
3290 364 num_bytes = (entries*field_size+4)>>3;
3291
3292 364 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
3293
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 364 times.
364 if (!buf) {
3294 av_freep(&sc->sample_sizes);
3295 return AVERROR(ENOMEM);
3296 }
3297
3298 364 ret = ffio_read_size(pb, buf, num_bytes);
3299
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 364 times.
364 if (ret < 0) {
3300 av_freep(&sc->sample_sizes);
3301 av_free(buf);
3302 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
3303 return 0;
3304 }
3305
3306 364 init_get_bits(&gb, buf, 8*num_bytes);
3307
3308
2/2
✓ Branch 0 taken 222617 times.
✓ Branch 1 taken 364 times.
222981 for (i = 0; i < entries; i++) {
3309 222617 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
3310
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 222617 times.
222617 if (sc->sample_sizes[i] < 0) {
3311 av_free(buf);
3312 av_log(c->fc, AV_LOG_ERROR, "Invalid sample size %d\n", sc->sample_sizes[i]);
3313 return AVERROR_INVALIDDATA;
3314 }
3315 222617 sc->data_size += sc->sample_sizes[i];
3316 }
3317
3318 364 sc->sample_count = i;
3319
3320 364 av_free(buf);
3321
3322 364 return 0;
3323 }
3324
3325 571 static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3326 {
3327 AVStream *st;
3328 MOVStreamContext *sc;
3329 571 unsigned int i, entries, alloc_size = 0;
3330 571 int64_t duration = 0;
3331 571 int64_t total_sample_count = 0;
3332 571 int64_t current_dts = 0;
3333 571 int64_t corrected_dts = 0;
3334
3335
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 571 times.
571 if (c->fc->nb_streams < 1)
3336 return 0;
3337 571 st = c->fc->streams[c->fc->nb_streams-1];
3338 571 sc = st->priv_data;
3339
3340 571 avio_r8(pb); /* version */
3341 571 avio_rb24(pb); /* flags */
3342 571 entries = avio_rb32(pb);
3343
3344 571 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
3345 571 c->fc->nb_streams-1, entries);
3346
3347
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 571 times.
571 if (sc->stts_data)
3348 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
3349 571 av_freep(&sc->stts_data);
3350 571 sc->stts_count = 0;
3351
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 571 times.
571 if (entries >= INT_MAX / sizeof(*sc->stts_data))
3352 return AVERROR(ENOMEM);
3353
3354
3/4
✓ Branch 0 taken 2916 times.
✓ Branch 1 taken 571 times.
✓ Branch 2 taken 2916 times.
✗ Branch 3 not taken.
3487 for (i = 0; i < entries && !pb->eof_reached; i++) {
3355 unsigned int sample_duration;
3356 unsigned int sample_count;
3357 2916 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
3358 2916 MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
3359 min_entries * sizeof(*sc->stts_data));
3360
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2916 times.
2916 if (!stts_data) {
3361 av_freep(&sc->stts_data);
3362 sc->stts_count = 0;
3363 return AVERROR(ENOMEM);
3364 }
3365 2916 sc->stts_count = min_entries;
3366 2916 sc->stts_data = stts_data;
3367
3368 2916 sample_count = avio_rb32(pb);
3369 2916 sample_duration = avio_rb32(pb);
3370
3371 2916 sc->stts_data[i].count= sample_count;
3372 2916 sc->stts_data[i].duration= sample_duration;
3373
3374 2916 av_log(c->fc, AV_LOG_TRACE, "sample_count=%u, sample_duration=%u\n",
3375 sample_count, sample_duration);
3376
3377 /* STTS sample offsets are uint32 but some files store it as int32
3378 * with negative values used to correct DTS delays.
3379 There may be abnormally large values as well. */
3380
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2915 times.
2916 if (sample_duration > c->max_stts_delta) {
3381 // assume high delta is a correction if negative when cast as int32
3382 1 int32_t delta_magnitude = (int32_t)sample_duration;
3383 1 av_log(c->fc, AV_LOG_WARNING, "Too large sample offset %u in stts entry %u with count %u in st:%d. Clipping to 1.\n",
3384 sample_duration, i, sample_count, st->index);
3385 1 sc->stts_data[i].duration = 1;
3386
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 corrected_dts += (delta_magnitude < 0 ? (int64_t)delta_magnitude : 1) * sample_count;
3387 } else {
3388 2915 corrected_dts += sample_duration * sample_count;
3389 }
3390
3391 2916 current_dts += sc->stts_data[i].duration * sample_count;
3392
3393
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 2894 times.
2916 if (current_dts > corrected_dts) {
3394 22 int64_t drift = (current_dts - corrected_dts)/FFMAX(sample_count, 1);
3395
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 1 times.
22 uint32_t correction = (sc->stts_data[i].duration > drift) ? drift : sc->stts_data[i].duration - 1;
3396 22 current_dts -= correction * sample_count;
3397 22 sc->stts_data[i].duration -= correction;
3398 }
3399
3400 2916 duration+=(int64_t)sc->stts_data[i].duration*(uint64_t)sc->stts_data[i].count;
3401 2916 total_sample_count+=sc->stts_data[i].count;
3402 }
3403
3404 571 sc->stts_count = i;
3405
3406
2/2
✓ Branch 0 taken 555 times.
✓ Branch 1 taken 16 times.
571 if (duration > 0 &&
3407
1/2
✓ Branch 0 taken 555 times.
✗ Branch 1 not taken.
555 duration <= INT64_MAX - sc->duration_for_fps &&
3408
1/2
✓ Branch 0 taken 555 times.
✗ Branch 1 not taken.
555 total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
3409 555 sc->duration_for_fps += duration;
3410 555 sc->nb_frames_for_fps += total_sample_count;
3411 }
3412
3413
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 571 times.
571 if (pb->eof_reached) {
3414 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
3415 return AVERROR_EOF;
3416 }
3417
3418 571 st->nb_frames= total_sample_count;
3419
2/2
✓ Branch 0 taken 555 times.
✓ Branch 1 taken 16 times.
571 if (duration)
3420 555 st->duration= FFMIN(st->duration, duration);
3421
3422 // All samples have zero duration. They have higher chance be chose by
3423 // mov_find_next_sample, which leads to seek again and again.
3424 //
3425 // It's AVERROR_INVALIDDATA actually, but such files exist in the wild.
3426 // So only mark data stream as discarded for safety.
3427
3/4
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 555 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 16 times.
571 if (!duration && sc->stts_count &&
3428 st->codecpar->codec_type == AVMEDIA_TYPE_DATA) {
3429 av_log(c->fc, AV_LOG_WARNING,
3430 "All samples in data stream index:id [%d:%d] have zero "
3431 "duration, stream set to be discarded by default. Override "
3432 "using AVStream->discard or -discard for ffmpeg command.\n",
3433 st->index, sc->id);
3434 st->discard = AVDISCARD_ALL;
3435 }
3436 571 sc->track_end = duration;
3437 571 return 0;
3438 }
3439
3440 41 static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3441 {
3442 AVStream *st;
3443 MOVStreamContext *sc;
3444 int64_t i, entries;
3445
3446
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 41 times.
41 if (c->fc->nb_streams < 1)
3447 return 0;
3448 41 st = c->fc->streams[c->fc->nb_streams - 1];
3449 41 sc = st->priv_data;
3450
3451 41 avio_r8(pb); /* version */
3452 41 avio_rb24(pb); /* flags */
3453 41 entries = atom.size - 4;
3454
3455 41 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3456 41 c->fc->nb_streams - 1, entries);
3457
3458
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 33 times.
41 if (sc->sdtp_data)
3459 8 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3460 41 av_freep(&sc->sdtp_data);
3461 41 sc->sdtp_count = 0;
3462
3463 41 sc->sdtp_data = av_malloc(entries);
3464
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 41 times.
41 if (!sc->sdtp_data)
3465 return AVERROR(ENOMEM);
3466
3467
3/4
✓ Branch 0 taken 3774 times.
✓ Branch 1 taken 41 times.
✓ Branch 2 taken 3774 times.
✗ Branch 3 not taken.
3815 for (i = 0; i < entries && !pb->eof_reached; i++)
3468 3774 sc->sdtp_data[i] = avio_r8(pb);
3469 41 sc->sdtp_count = i;
3470
3471 41 return 0;
3472 }
3473
3474 10778 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3475 {
3476
2/2
✓ Branch 0 taken 1128 times.
✓ Branch 1 taken 9650 times.
10778 if (duration < 0) {
3477
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1128 times.
1128 if (duration == INT_MIN) {
3478 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3479 duration++;
3480 }
3481 1128 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3482 }
3483 10778 }
3484
3485 59 static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3486 {
3487 AVStream *st;
3488 MOVStreamContext *sc;
3489 59 unsigned int i, entries, ctts_count = 0;
3490
3491
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 59 times.
59 if (c->fc->nb_streams < 1)
3492 return 0;
3493 59 st = c->fc->streams[c->fc->nb_streams-1];
3494 59 sc = st->priv_data;
3495
3496 59 avio_r8(pb); /* version */
3497 59 avio_rb24(pb); /* flags */
3498 59 entries = avio_rb32(pb);
3499
3500 59 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3501
3502
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 55 times.
59 if (!entries)
3503 4 return 0;
3504
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 55 times.
55 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3505 return AVERROR_INVALIDDATA;
3506 55 av_freep(&sc->ctts_data);
3507 55 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3508
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 55 times.
55 if (!sc->ctts_data)
3509 return AVERROR(ENOMEM);
3510
3511
3/4
✓ Branch 0 taken 4817 times.
✓ Branch 1 taken 55 times.
✓ Branch 2 taken 4817 times.
✗ Branch 3 not taken.
4872 for (i = 0; i < entries && !pb->eof_reached; i++) {
3512 4817 int count = avio_rb32(pb);
3513 4817 int duration = avio_rb32(pb);
3514
3515
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4817 times.
4817 if (count <= 0) {
3516 av_log(c->fc, AV_LOG_TRACE,
3517 "ignoring CTTS entry with count=%d duration=%d\n",
3518 count, duration);
3519 continue;
3520 }
3521
3522 4817 add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3523 count, duration);
3524
3525 4817 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3526 count, duration);
3527
3528
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4817 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4817 if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3529 av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3530 av_freep(&sc->ctts_data);
3531 sc->ctts_count = 0;
3532 return 0;
3533 }
3534
3535
2/2
✓ Branch 0 taken 4712 times.
✓ Branch 1 taken 105 times.
4817 if (i+2<entries)
3536 4712 mov_update_dts_shift(sc, duration, c->fc);
3537 }
3538
3539 55 sc->ctts_count = ctts_count;
3540
3541
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 55 times.
55 if (pb->eof_reached) {
3542 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3543 return AVERROR_EOF;
3544 }
3545
3546 55 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3547
3548 55 return 0;
3549 }
3550
3551 24 static int mov_read_sgpd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3552 {
3553 AVStream *st;
3554 MOVStreamContext *sc;
3555 uint8_t version;
3556 uint32_t grouping_type;
3557 uint32_t default_length;
3558 av_unused uint32_t default_group_description_index;
3559 uint32_t entry_count;
3560
3561
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
24 if (c->fc->nb_streams < 1)
3562 return 0;
3563 24 st = c->fc->streams[c->fc->nb_streams - 1];
3564 24 sc = st->priv_data;
3565
3566 24 version = avio_r8(pb); /* version */
3567 24 avio_rb24(pb); /* flags */
3568 24 grouping_type = avio_rl32(pb);
3569
3570 /*
3571 * This function only supports "sync" boxes, but the code is able to parse
3572 * other boxes (such as "tscl", "tsas" and "stsa")
3573 */
3574
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 3 times.
24 if (grouping_type != MKTAG('s','y','n','c'))
3575 21 return 0;
3576
3577
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 default_length = version >= 1 ? avio_rb32(pb) : 0;
3578
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 default_group_description_index = version >= 2 ? avio_rb32(pb) : 0;
3579 3 entry_count = avio_rb32(pb);
3580
3581 3 av_freep(&sc->sgpd_sync);
3582 3 sc->sgpd_sync_count = entry_count;
3583 3 sc->sgpd_sync = av_calloc(entry_count, sizeof(*sc->sgpd_sync));
3584
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!sc->sgpd_sync)
3585 return AVERROR(ENOMEM);
3586
3587
3/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
9 for (uint32_t i = 0; i < entry_count && !pb->eof_reached; i++) {
3588 6 uint32_t description_length = default_length;
3589
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
6 if (version >= 1 && default_length == 0)
3590 description_length = avio_rb32(pb);
3591
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (grouping_type == MKTAG('s','y','n','c')) {
3592 6 const uint8_t nal_unit_type = avio_r8(pb) & 0x3f;
3593 6 sc->sgpd_sync[i] = nal_unit_type;
3594 6 description_length -= 1;
3595 }
3596 6 avio_skip(pb, description_length);
3597 }
3598
3599
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (pb->eof_reached) {
3600 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SGPD atom\n");
3601 return AVERROR_EOF;
3602 }
3603
3604 3 return 0;
3605 }
3606
3607 21 static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3608 {
3609 AVStream *st;
3610 MOVStreamContext *sc;
3611 unsigned int i, entries;
3612 uint8_t version;
3613 uint32_t grouping_type;
3614 MOVSbgp *table, **tablep;
3615 int *table_count;
3616
3617
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (c->fc->nb_streams < 1)
3618 return 0;
3619 21 st = c->fc->streams[c->fc->nb_streams-1];
3620 21 sc = st->priv_data;
3621
3622 21 version = avio_r8(pb); /* version */
3623 21 avio_rb24(pb); /* flags */
3624 21 grouping_type = avio_rl32(pb);
3625
3626
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 20 times.
21 if (grouping_type == MKTAG('r','a','p',' ')) {
3627 1 tablep = &sc->rap_group;
3628 1 table_count = &sc->rap_group_count;
3629
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 17 times.
20 } else if (grouping_type == MKTAG('s','y','n','c')) {
3630 3 tablep = &sc->sync_group;
3631 3 table_count = &sc->sync_group_count;
3632 } else {
3633 17 return 0;
3634 }
3635
3636
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (version == 1)
3637 avio_rb32(pb); /* grouping_type_parameter */
3638
3639 4 entries = avio_rb32(pb);
3640
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!entries)
3641 return 0;
3642
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (*tablep)
3643 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP %s atom\n", av_fourcc2str(grouping_type));
3644 4 av_freep(tablep);
3645 4 table = av_malloc_array(entries, sizeof(*table));
3646
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!table)
3647 return AVERROR(ENOMEM);
3648 4 *tablep = table;
3649
3650
3/4
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
32 for (i = 0; i < entries && !pb->eof_reached; i++) {
3651 28 table[i].count = avio_rb32(pb); /* sample_count */
3652 28 table[i].index = avio_rb32(pb); /* group_description_index */
3653 }
3654
3655 4 *table_count = i;
3656
3657
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (pb->eof_reached) {
3658 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3659 return AVERROR_EOF;
3660 }
3661
3662 4 return 0;
3663 }
3664
3665 /**
3666 * Get ith edit list entry (media time, duration).
3667 */
3668 859 static int get_edit_list_entry(MOVContext *mov,
3669 const MOVStreamContext *msc,
3670 unsigned int edit_list_index,
3671 int64_t *edit_list_media_time,
3672 int64_t *edit_list_duration,
3673 int64_t global_timescale)
3674 {
3675
2/2
✓ Branch 0 taken 416 times.
✓ Branch 1 taken 443 times.
859 if (edit_list_index == msc->elst_count) {
3676 416 return 0;
3677 }
3678 443 *edit_list_media_time = msc->elst_data[edit_list_index].time;
3679 443 *edit_list_duration = msc->elst_data[edit_list_index].duration;
3680
3681 /* duration is in global timescale units;convert to msc timescale */
3682
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 443 times.
443 if (global_timescale == 0) {
3683 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3684 return 0;
3685 }
3686 443 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3687 global_timescale);
3688 443 return 1;
3689 }
3690
3691 /**
3692 * Find the closest previous frame to the timestamp_pts, in e_old index
3693 * entries. Searching for just any frame / just key frames can be controlled by
3694 * last argument 'flag'.
3695 * Note that if ctts_data is not NULL, we will always search for a key frame
3696 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3697 * return the first frame of the video.
3698 *
3699 * Here the timestamp_pts is considered to be a presentation timestamp and
3700 * the timestamp of index entries are considered to be decoding timestamps.
3701 *
3702 * Returns 0 if successful in finding a frame, else returns -1.
3703 * Places the found index corresponding output arg.
3704 *
3705 * If ctts_old is not NULL, then refines the searched entry by searching
3706 * backwards from the found timestamp, to find the frame with correct PTS.
3707 *
3708 * Places the found ctts_index and ctts_sample in corresponding output args.
3709 */
3710 442 static int find_prev_closest_index(AVStream *st,
3711 AVIndexEntry *e_old,
3712 int nb_old,
3713 MOVCtts* ctts_data,
3714 int64_t ctts_count,
3715 int64_t timestamp_pts,
3716 int flag,
3717 int64_t* index,
3718 int64_t* ctts_index,
3719 int64_t* ctts_sample)
3720 {
3721 442 MOVStreamContext *msc = st->priv_data;
3722 442 FFStream *const sti = ffstream(st);
3723 442 AVIndexEntry *e_keep = sti->index_entries;
3724 442 int nb_keep = sti->nb_index_entries;
3725 442 int64_t i = 0;
3726 int64_t index_ctts_count;
3727
3728
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 442 times.
442 av_assert0(index);
3729
3730 // If dts_shift > 0, then all the index timestamps will have to be offset by
3731 // at least dts_shift amount to obtain PTS.
3732 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3733
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 435 times.
442 if (msc->dts_shift > 0) {
3734 7 timestamp_pts -= msc->dts_shift;
3735 }
3736
3737 442 sti->index_entries = e_old;
3738 442 sti->nb_index_entries = nb_old;
3739 442 *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3740
3741 // Keep going backwards in the index entries until the timestamp is the same.
3742
2/2
✓ Branch 0 taken 441 times.
✓ Branch 1 taken 1 times.
442 if (*index >= 0) {
3743
3/4
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 417 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 24 times.
441 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3744 i--) {
3745 if ((flag & AVSEEK_FLAG_ANY) ||
3746 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3747 *index = i - 1;
3748 }
3749 }
3750 }
3751
3752 // If we have CTTS then refine the search, by searching backwards over PTS
3753 // computed by adding corresponding CTTS durations to index timestamps.
3754
4/4
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 382 times.
✓ Branch 2 taken 59 times.
✓ Branch 3 taken 1 times.
442 if (ctts_data && *index >= 0) {
3755
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 59 times.
59 av_assert0(ctts_index);
3756
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 59 times.
59 av_assert0(ctts_sample);
3757 // Find out the ctts_index for the found frame.
3758 59 *ctts_index = 0;
3759 59 *ctts_sample = 0;
3760
2/2
✓ Branch 0 taken 175 times.
✓ Branch 1 taken 59 times.
234 for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3761
1/2
✓ Branch 0 taken 175 times.
✗ Branch 1 not taken.
175 if (*ctts_index < ctts_count) {
3762 175 (*ctts_sample)++;
3763
1/2
✓ Branch 0 taken 175 times.
✗ Branch 1 not taken.
175 if (ctts_data[*ctts_index].count == *ctts_sample) {
3764 175 (*ctts_index)++;
3765 175 *ctts_sample = 0;
3766 }
3767 }
3768 }
3769
3770
4/6
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 66 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 66 times.
✗ Branch 5 not taken.
71 while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3771 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3772 // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3773 // compensated by dts_shift above.
3774
2/2
✓ Branch 0 taken 58 times.
✓ Branch 1 taken 8 times.
66 if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3775
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 4 times.
58 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3776 54 break;
3777 }
3778
3779 12 (*index)--;
3780
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if (*ctts_sample == 0) {
3781 12 (*ctts_index)--;
3782
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 5 times.
12 if (*ctts_index >= 0)
3783 7 *ctts_sample = ctts_data[*ctts_index].count - 1;
3784 } else {
3785 (*ctts_sample)--;
3786 }
3787 }
3788 }
3789
3790 /* restore AVStream state*/
3791 442 sti->index_entries = e_keep;
3792 442 sti->nb_index_entries = nb_keep;
3793
2/2
✓ Branch 0 taken 436 times.
✓ Branch 1 taken 6 times.
442 return *index >= 0 ? 0 : -1;
3794 }
3795
3796 /**
3797 * Add index entry with the given values, to the end of ffstream(st)->index_entries.
3798 * Returns the new size ffstream(st)->index_entries if successful, else returns -1.
3799 *
3800 * This function is similar to ff_add_index_entry in libavformat/utils.c
3801 * except that here we are always unconditionally adding an index entry to
3802 * the end, instead of searching the entries list and skipping the add if
3803 * there is an existing entry with the same timestamp.
3804 * This is needed because the mov_fix_index calls this func with the same
3805 * unincremented timestamp for successive discarded frames.
3806 */
3807 344104 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3808 int size, int distance, int flags)
3809 {
3810 344104 FFStream *const sti = ffstream(st);
3811 AVIndexEntry *entries, *ie;
3812 344104 int64_t index = -1;
3813 344104 const size_t min_size_needed = (sti->nb_index_entries + 1) * sizeof(AVIndexEntry);
3814
3815 // Double the allocation each time, to lower memory fragmentation.
3816 // Another difference from ff_add_index_entry function.
3817 344104 const size_t requested_size =
3818 344104 min_size_needed > sti->index_entries_allocated_size ?
3819
2/2
✓ Branch 0 taken 1882 times.
✓ Branch 1 taken 342222 times.
344104 FFMAX(min_size_needed, 2 * sti->index_entries_allocated_size) :
3820 min_size_needed;
3821
3822
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 344104 times.
344104 if (sti->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
3823 return -1;
3824
3825 344104 entries = av_fast_realloc(sti->index_entries,
3826 &sti->index_entries_allocated_size,
3827 requested_size);
3828
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 344104 times.
344104 if (!entries)
3829 return -1;
3830
3831 344104 sti->index_entries = entries;
3832
3833 344104 index = sti->nb_index_entries++;
3834 344104 ie= &entries[index];
3835
3836 344104 ie->pos = pos;
3837 344104 ie->timestamp = timestamp;
3838 344104 ie->min_distance= distance;
3839 344104 ie->size= size;
3840 344104 ie->flags = flags;
3841 344104 return index;
3842 }
3843
3844 /**
3845 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3846 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3847 */
3848 23 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3849 int64_t* frame_duration_buffer,
3850 int frame_duration_buffer_size) {
3851 23 FFStream *const sti = ffstream(st);
3852 23 int i = 0;
3853
2/4
✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 23 times.
23 av_assert0(end_index >= 0 && end_index <= sti->nb_index_entries);
3854
2/2
✓ Branch 0 taken 130 times.
✓ Branch 1 taken 23 times.
153 for (i = 0; i < frame_duration_buffer_size; i++) {
3855 130 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3856 130 sti->index_entries[end_index - 1 - i].timestamp = end_ts;
3857 }
3858 23 }
3859
3860 /**
3861 * Append a new ctts entry to ctts_data.
3862 * Returns the new ctts_count if successful, else returns -1.
3863 */
3864 282521 static int64_t add_ctts_entry(MOVCtts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3865 int count, int duration)
3866 {
3867 MOVCtts *ctts_buf_new;
3868 282521 const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVCtts);
3869 282521 const size_t requested_size =
3870 282521 min_size_needed > *allocated_size ?
3871
2/2
✓ Branch 0 taken 204 times.
✓ Branch 1 taken 282317 times.
282521 FFMAX(min_size_needed, 2 * (*allocated_size)) :
3872 min_size_needed;
3873
3874
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 282521 times.
282521 if ((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVCtts) - 1)
3875 return -1;
3876
3877 282521 ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3878
3879
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 282521 times.
282521 if (!ctts_buf_new)
3880 return -1;
3881
3882 282521 *ctts_data = ctts_buf_new;
3883
3884 282521 ctts_buf_new[*ctts_count].count = count;
3885 282521 ctts_buf_new[*ctts_count].duration = duration;
3886
3887 282521 *ctts_count = (*ctts_count) + 1;
3888 282521 return *ctts_count;
3889 }
3890
3891 #define MAX_REORDER_DELAY 16
3892 574 static void mov_estimate_video_delay(MOVContext *c, AVStream* st)
3893 {
3894 574 MOVStreamContext *msc = st->priv_data;
3895 574 FFStream *const sti = ffstream(st);
3896 574 int ctts_ind = 0;
3897 574 int ctts_sample = 0;
3898 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3899 574 int buf_start = 0;
3900 int j, r, num_swaps;
3901
3902
2/2
✓ Branch 0 taken 9758 times.
✓ Branch 1 taken 574 times.
10332 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3903 9758 pts_buf[j] = INT64_MIN;
3904
3905
3/4
✓ Branch 0 taken 574 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 55 times.
✓ Branch 3 taken 519 times.
574 if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3906
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 13 times.
55 st->codecpar->codec_id == AV_CODEC_ID_H264) {
3907 42 st->codecpar->video_delay = 0;
3908
3/4
✓ Branch 0 taken 138229 times.
✓ Branch 1 taken 42 times.
✓ Branch 2 taken 138229 times.
✗ Branch 3 not taken.
138271 for (int ind = 0; ind < sti->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3909 // Point j to the last elem of the buffer and insert the current pts there.
3910 138229 j = buf_start;
3911 138229 buf_start = (buf_start + 1);
3912
2/2
✓ Branch 0 taken 8109 times.
✓ Branch 1 taken 130120 times.
138229 if (buf_start == MAX_REORDER_DELAY + 1)
3913 8109 buf_start = 0;
3914
3915 138229 pts_buf[j] = sti->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3916
3917 // The timestamps that are already in the sorted buffer, and are greater than the
3918 // current pts, are exactly the timestamps that need to be buffered to output PTS
3919 // in correct sorted order.
3920 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3921 // can be computed as the maximum no. of swaps any particular timestamp needs to
3922 // go through, to keep this buffer in sorted order.
3923 138229 num_swaps = 0;
3924
2/2
✓ Branch 0 taken 142192 times.
✓ Branch 1 taken 4 times.
142196 while (j != buf_start) {
3925 142192 r = j - 1;
3926
2/2
✓ Branch 0 taken 8384 times.
✓ Branch 1 taken 133808 times.
142192 if (r < 0) r = MAX_REORDER_DELAY;
3927
2/2
✓ Branch 0 taken 3967 times.
✓ Branch 1 taken 138225 times.
142192 if (pts_buf[j] < pts_buf[r]) {
3928 3967 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3929 3967 ++num_swaps;
3930 } else {
3931 138225 break;
3932 }
3933 3967 j = r;
3934 }
3935 138229 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3936
3937 138229 ctts_sample++;
3938
1/2
✓ Branch 0 taken 138229 times.
✗ Branch 1 not taken.
138229 if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3939 138229 ctts_ind++;
3940 138229 ctts_sample = 0;
3941 }
3942 }
3943 42 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3944 42 st->codecpar->video_delay, st->index);
3945 }
3946 574 }
3947
3948 98910 static void mov_current_sample_inc(MOVStreamContext *sc)
3949 {
3950 98910 sc->current_sample++;
3951 98910 sc->current_index++;
3952
2/2
✓ Branch 0 taken 56984 times.
✓ Branch 1 taken 41926 times.
98910 if (sc->index_ranges &&
3953
2/2
✓ Branch 0 taken 404 times.
✓ Branch 1 taken 56580 times.
56984 sc->current_index >= sc->current_index_range->end &&
3954
1/2
✓ Branch 0 taken 404 times.
✗ Branch 1 not taken.
404 sc->current_index_range->end) {
3955 404 sc->current_index_range++;
3956 404 sc->current_index = sc->current_index_range->start;
3957 }
3958 98910 }
3959
3960 static void mov_current_sample_dec(MOVStreamContext *sc)
3961 {
3962 sc->current_sample--;
3963 sc->current_index--;
3964 if (sc->index_ranges &&
3965 sc->current_index < sc->current_index_range->start &&
3966 sc->current_index_range > sc->index_ranges) {
3967 sc->current_index_range--;
3968 sc->current_index = sc->current_index_range->end - 1;
3969 }
3970 }
3971
3972 335 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3973 {
3974 int64_t range_size;
3975
3976 335 sc->current_sample = current_sample;
3977 335 sc->current_index = current_sample;
3978
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 309 times.
335 if (!sc->index_ranges) {
3979 26 return;
3980 }
3981
3982 309 for (sc->current_index_range = sc->index_ranges;
3983
1/2
✓ Branch 0 taken 309 times.
✗ Branch 1 not taken.
309 sc->current_index_range->end;
3984 sc->current_index_range++) {
3985 309 range_size = sc->current_index_range->end - sc->current_index_range->start;
3986
1/2
✓ Branch 0 taken 309 times.
✗ Branch 1 not taken.
309 if (range_size > current_sample) {
3987 309 sc->current_index = sc->current_index_range->start + current_sample;
3988 309 break;
3989 }
3990 current_sample -= range_size;
3991 }
3992 }
3993
3994 /**
3995 * Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries
3996 * which are needed to decode them) that fall in the edit list time ranges.
3997 * Also fixes the timestamps of the index entries to match the timeline
3998 * specified the edit lists.
3999 */
4000 574 static void mov_fix_index(MOVContext *mov, AVStream *st)
4001 {
4002 574 MOVStreamContext *msc = st->priv_data;
4003 574 FFStream *const sti = ffstream(st);
4004 574 AVIndexEntry *e_old = sti->index_entries;
4005 574 int nb_old = sti->nb_index_entries;
4006 574 const AVIndexEntry *e_old_end = e_old + nb_old;
4007 574 const AVIndexEntry *current = NULL;
4008 574 MOVCtts *ctts_data_old = msc->ctts_data;
4009 574 int64_t ctts_index_old = 0;
4010 574 int64_t ctts_sample_old = 0;
4011 574 int64_t ctts_count_old = msc->ctts_count;
4012 574 int64_t edit_list_media_time = 0;
4013 574 int64_t edit_list_duration = 0;
4014 574 int64_t frame_duration = 0;
4015 574 int64_t edit_list_dts_counter = 0;
4016 574 int64_t edit_list_dts_entry_end = 0;
4017 574 int64_t edit_list_start_ctts_sample = 0;
4018 int64_t curr_cts;
4019 574 int64_t curr_ctts = 0;
4020 574 int64_t empty_edits_sum_duration = 0;
4021 574 int64_t edit_list_index = 0;
4022 int64_t index;
4023 int flags;
4024 574 int64_t start_dts = 0;
4025 574 int64_t edit_list_start_encountered = 0;
4026 574 int64_t search_timestamp = 0;
4027 574 int64_t* frame_duration_buffer = NULL;
4028 574 int num_discarded_begin = 0;
4029 574 int first_non_zero_audio_edit = -1;
4030 574 int packet_skip_samples = 0;
4031 574 MOVIndexRange *current_index_range = NULL;
4032 574 int found_keyframe_after_edit = 0;
4033 574 int found_non_empty_edit = 0;
4034
4035
4/6
✓ Branch 0 taken 416 times.
✓ Branch 1 taken 158 times.
✓ Branch 2 taken 416 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 416 times.
574 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
4036 158 return;
4037 }
4038
4039 // allocate the index ranges array
4040 416 msc->index_ranges = av_malloc_array(msc->elst_count + 1,
4041 sizeof(msc->index_ranges[0]));
4042
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 416 times.
416 if (!msc->index_ranges) {
4043 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
4044 return;
4045 }
4046 416 msc->current_index_range = msc->index_ranges;
4047
4048 // Clean AVStream from traces of old index
4049 416 sti->index_entries = NULL;
4050 416 sti->index_entries_allocated_size = 0;
4051 416 sti->nb_index_entries = 0;
4052
4053 // Clean ctts fields of MOVStreamContext
4054 416 msc->ctts_data = NULL;
4055 416 msc->ctts_count = 0;
4056 416 msc->ctts_index = 0;
4057 416 msc->ctts_sample = 0;
4058 416 msc->ctts_allocated_size = 0;
4059
4060 // Reinitialize min_corrected_pts so that it can be computed again.
4061 416 msc->min_corrected_pts = -1;
4062
4063 // If the dts_shift is positive (in case of negative ctts values in mov),
4064 // then negate the DTS by dts_shift
4065
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 409 times.
416 if (msc->dts_shift > 0) {
4066 7 edit_list_dts_entry_end -= msc->dts_shift;
4067 7 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
4068 }
4069
4070 416 start_dts = edit_list_dts_entry_end;
4071
4072
2/2
✓ Branch 0 taken 443 times.
✓ Branch 1 taken 416 times.
1275 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
4073 859 &edit_list_duration, mov->time_scale)) {
4074 443 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
4075 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
4076 443 edit_list_index++;
4077 443 edit_list_dts_counter = edit_list_dts_entry_end;
4078 443 edit_list_dts_entry_end += edit_list_duration;
4079 443 num_discarded_begin = 0;
4080
4/4
✓ Branch 0 taken 420 times.
✓ Branch 1 taken 23 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 416 times.
443 if (!found_non_empty_edit && edit_list_media_time == -1) {
4081 4 empty_edits_sum_duration += edit_list_duration;
4082 4 continue;
4083 }
4084 439 found_non_empty_edit = 1;
4085
4086 // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
4087 // according to the edit list below.
4088
2/2
✓ Branch 0 taken 123 times.
✓ Branch 1 taken 316 times.
439 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4089
1/2
✓ Branch 0 taken 123 times.
✗ Branch 1 not taken.
123 if (first_non_zero_audio_edit < 0) {
4090 123 first_non_zero_audio_edit = 1;
4091 } else {
4092 first_non_zero_audio_edit = 0;
4093 }
4094
4095
1/2
✓ Branch 0 taken 123 times.
✗ Branch 1 not taken.
123 if (first_non_zero_audio_edit > 0)
4096 123 sti->skip_samples = msc->start_pad = 0;
4097 }
4098
4099 // While reordering frame index according to edit list we must handle properly
4100 // the scenario when edit list entry starts from none key frame.
4101 // We find closest previous key frame and preserve it and consequent frames in index.
4102 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
4103 439 search_timestamp = edit_list_media_time;
4104
2/2
✓ Branch 0 taken 123 times.
✓ Branch 1 taken 316 times.
439 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4105 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
4106 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
4107 // edit_list_media_time to cover the decoder delay.
4108 123 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
4109 }
4110
4111
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 436 times.
439 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
4112 &index, &ctts_index_old, &ctts_sample_old) < 0) {
4113 3 av_log(mov->fc, AV_LOG_WARNING,
4114 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
4115 st->index, edit_list_index, search_timestamp);
4116
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
4117 &index, &ctts_index_old, &ctts_sample_old) < 0) {
4118 3 av_log(mov->fc, AV_LOG_WARNING,
4119 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
4120 st->index, edit_list_index, search_timestamp);
4121 3 index = 0;
4122 3 ctts_index_old = 0;
4123 3 ctts_sample_old = 0;
4124 }
4125 }
4126 439 current = e_old + index;
4127 439 edit_list_start_ctts_sample = ctts_sample_old;
4128
4129 // Iterate over index and arrange it according to edit list
4130 439 edit_list_start_encountered = 0;
4131 439 found_keyframe_after_edit = 0;
4132
2/2
✓ Branch 0 taken 344104 times.
✓ Branch 1 taken 105 times.
344209 for (; current < e_old_end; current++, index++) {
4133 // check if frame outside edit list mark it for discard
4134 688208 frame_duration = (current + 1 < e_old_end) ?
4135
2/2
✓ Branch 0 taken 343692 times.
✓ Branch 1 taken 412 times.
344104 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
4136
4137 344104 flags = current->flags;
4138
4139 // frames (pts) before or after edit list
4140 344104 curr_cts = current->timestamp + msc->dts_shift;
4141 344104 curr_ctts = 0;
4142
4143
3/4
✓ Branch 0 taken 138770 times.
✓ Branch 1 taken 205334 times.
✓ Branch 2 taken 138770 times.
✗ Branch 3 not taken.
344104 if (ctts_data_old && ctts_index_old < ctts_count_old) {
4144 138770 curr_ctts = ctts_data_old[ctts_index_old].duration;
4145 138770 av_log(mov->fc, AV_LOG_TRACE, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
4146 curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
4147 138770 curr_cts += curr_ctts;
4148 138770 ctts_sample_old++;
4149
1/2
✓ Branch 0 taken 138770 times.
✗ Branch 1 not taken.
138770 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
4150
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 138770 times.
138770 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
4151 &msc->ctts_allocated_size,
4152 138770 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
4153 138770 ctts_data_old[ctts_index_old].duration) == -1) {
4154 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
4155 ctts_index_old,
4156 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
4157 ctts_data_old[ctts_index_old].duration);
4158 break;
4159 }
4160 138770 ctts_index_old++;
4161 138770 ctts_sample_old = 0;
4162 138770 edit_list_start_ctts_sample = 0;
4163 }
4164 }
4165
4166
4/4
✓ Branch 0 taken 343961 times.
✓ Branch 1 taken 143 times.
✓ Branch 2 taken 130 times.
✓ Branch 3 taken 343831 times.
344104 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
4167
4/4
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 202 times.
✓ Branch 2 taken 25 times.
✓ Branch 3 taken 46 times.
273 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
4168
4/6
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 16 times.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
25 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
4169 first_non_zero_audio_edit > 0) {
4170 9 packet_skip_samples = edit_list_media_time - curr_cts;
4171 9 sti->skip_samples += packet_skip_samples;
4172
4173 // Shift the index entry timestamp by packet_skip_samples to be correct.
4174 9 edit_list_dts_counter -= packet_skip_samples;
4175
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if (edit_list_start_encountered == 0) {
4176 9 edit_list_start_encountered = 1;
4177 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
4178 // discarded packets.
4179
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 5 times.
9 if (frame_duration_buffer) {
4180 4 fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4181 frame_duration_buffer, num_discarded_begin);
4182 4 av_freep(&frame_duration_buffer);
4183 }
4184 }
4185
4186 9 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
4187 } else {
4188 264 flags |= AVINDEX_DISCARD_FRAME;
4189 264 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
4190
4191
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 132 times.
264 if (edit_list_start_encountered == 0) {
4192 132 num_discarded_begin++;
4193 132 frame_duration_buffer = av_realloc(frame_duration_buffer,
4194 num_discarded_begin * sizeof(int64_t));
4195
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 132 times.
132 if (!frame_duration_buffer) {
4196 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
4197 break;
4198 }
4199 132 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
4200
4201 // Increment skip_samples for the first non-zero audio edit list
4202
3/4
✓ Branch 0 taken 62 times.
✓ Branch 1 taken 70 times.
✓ Branch 2 taken 62 times.
✗ Branch 3 not taken.
132 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4203
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 46 times.
62 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
4204 16 sti->skip_samples += frame_duration;
4205 }
4206 }
4207 }
4208 } else {
4209
2/2
✓ Branch 0 taken 415 times.
✓ Branch 1 taken 343416 times.
343831 if (msc->min_corrected_pts < 0) {
4210 415 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
4211 } else {
4212 343416 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
4213 }
4214
2/2
✓ Branch 0 taken 428 times.
✓ Branch 1 taken 343403 times.
343831 if (edit_list_start_encountered == 0) {
4215 428 edit_list_start_encountered = 1;
4216 // Make timestamps strictly monotonically increasing by rewriting timestamps for
4217 // discarded packets.
4218
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 409 times.
428 if (frame_duration_buffer) {
4219 19 fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4220 frame_duration_buffer, num_discarded_begin);
4221 19 av_freep(&frame_duration_buffer);
4222 }
4223 }
4224 }
4225
4226
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 344104 times.
344104 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
4227 344104 current->min_distance, flags) == -1) {
4228 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
4229 break;
4230 }
4231
4232 // Update the index ranges array
4233
4/4
✓ Branch 0 taken 343688 times.
✓ Branch 1 taken 416 times.
✓ Branch 2 taken 21 times.
✓ Branch 3 taken 343667 times.
344104 if (!current_index_range || index != current_index_range->end) {
4234 437 current_index_range = current_index_range ? current_index_range + 1
4235
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 416 times.
437 : msc->index_ranges;
4236 437 current_index_range->start = index;
4237 }
4238 344104 current_index_range->end = index + 1;
4239
4240 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
4241
2/2
✓ Branch 0 taken 343972 times.
✓ Branch 1 taken 132 times.
344104 if (edit_list_start_encountered > 0) {
4242 343972 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
4243 }
4244
4245 // Break when found first key frame after edit entry completion
4246
2/2
✓ Branch 0 taken 592 times.
✓ Branch 1 taken 343512 times.
344104 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
4247
3/4
✓ Branch 0 taken 246 times.
✓ Branch 1 taken 346 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 246 times.
592 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
4248
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 325 times.
346 if (ctts_data_old) {
4249 // If we have CTTS and this is the first keyframe after edit elist,
4250 // wait for one more, because there might be trailing B-frames after this I-frame
4251 // that do belong to the edit.
4252
3/4
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 9 times.
21 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
4253 12 found_keyframe_after_edit = 1;
4254 12 continue;
4255 }
4256
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (ctts_sample_old != 0) {
4257 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
4258 &msc->ctts_allocated_size,
4259 ctts_sample_old - edit_list_start_ctts_sample,
4260 ctts_data_old[ctts_index_old].duration) == -1) {
4261 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
4262 ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
4263 ctts_data_old[ctts_index_old].duration);
4264 break;
4265 }
4266 }
4267 }
4268 334 break;
4269 }
4270 }
4271 }
4272 // If there are empty edits, then msc->min_corrected_pts might be positive
4273 // intentionally. So we subtract the sum duration of emtpy edits here.
4274 416 msc->min_corrected_pts -= empty_edits_sum_duration;
4275
4276 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
4277 // dts by that amount to make the first pts zero.
4278
2/2
✓ Branch 0 taken 253 times.
✓ Branch 1 taken 163 times.
416 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4279
2/2
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 214 times.
253 if (msc->min_corrected_pts > 0) {
4280 39 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
4281
2/2
✓ Branch 0 taken 2768 times.
✓ Branch 1 taken 39 times.
2807 for (int i = 0; i < sti->nb_index_entries; ++i)
4282 2768 sti->index_entries[i].timestamp -= msc->min_corrected_pts;
4283 }
4284 }
4285 // Start time should be equal to zero or the duration of any empty edits.
4286 416 st->start_time = empty_edits_sum_duration;
4287
4288 // Update av stream length, if it ends up shorter than the track's media duration
4289 416 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
4290 416 msc->start_pad = sti->skip_samples;
4291
4292 // Free the old index and the old CTTS structures
4293 416 av_free(e_old);
4294 416 av_free(ctts_data_old);
4295 416 av_freep(&frame_duration_buffer);
4296
4297 // Null terminate the index ranges array
4298 416 current_index_range = current_index_range ? current_index_range + 1
4299
1/2
✓ Branch 0 taken 416 times.
✗ Branch 1 not taken.
416 : msc->index_ranges;
4300 416 current_index_range->start = 0;
4301 416 current_index_range->end = 0;
4302 416 msc->current_index = msc->index_ranges[0].start;
4303 }
4304
4305 3 static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
4306 {
4307
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 for (uint32_t i = 0; i < sc->sgpd_sync_count; i++)
4308
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (sc->sgpd_sync[i] == HEVC_NAL_CRA_NUT)
4309 3 return i + 1;
4310 return 0;
4311 }
4312
4313 590 static int build_open_gop_key_points(AVStream *st)
4314 {
4315 int k;
4316 590 int sample_id = 0;
4317 uint32_t cra_index;
4318 590 MOVStreamContext *sc = st->priv_data;
4319
4320
4/4
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 562 times.
✓ Branch 2 taken 25 times.
✓ Branch 3 taken 3 times.
590 if (st->codecpar->codec_id != AV_CODEC_ID_HEVC || !sc->sync_group_count)
4321 587 return 0;
4322
4323 /* Build an unrolled index of the samples */
4324 3 sc->sample_offsets_count = 0;
4325
2/2
✓ Branch 0 taken 300 times.
✓ Branch 1 taken 3 times.
303 for (uint32_t i = 0; i < sc->ctts_count; i++) {
4326
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 300 times.
300 if (sc->ctts_data[i].count > INT_MAX - sc->sample_offsets_count)
4327 return AVERROR(ENOMEM);
4328 300 sc->sample_offsets_count += sc->ctts_data[i].count;
4329 }
4330 3 av_freep(&sc->sample_offsets);
4331 3 sc->sample_offsets = av_calloc(sc->sample_offsets_count, sizeof(*sc->sample_offsets));
4332
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!sc->sample_offsets)
4333 return AVERROR(ENOMEM);
4334 3 k = 0;
4335
2/2
✓ Branch 0 taken 300 times.
✓ Branch 1 taken 3 times.
303 for (uint32_t i = 0; i < sc->ctts_count; i++)
4336
2/2
✓ Branch 0 taken 300 times.
✓ Branch 1 taken 300 times.
600 for (int j = 0; j < sc->ctts_data[i].count; j++)
4337 300 sc->sample_offsets[k++] = sc->ctts_data[i].duration;
4338
4339 /* The following HEVC NAL type reveal the use of open GOP sync points
4340 * (TODO: BLA types may also be concerned) */
4341 3 cra_index = get_sgpd_sync_index(sc, HEVC_NAL_CRA_NUT); /* Clean Random Access */
4342
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!cra_index)
4343 return 0;
4344
4345 /* Build a list of open-GOP key samples */
4346 3 sc->open_key_samples_count = 0;
4347
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 3 times.
27 for (uint32_t i = 0; i < sc->sync_group_count; i++)
4348
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 15 times.
24 if (sc->sync_group[i].index == cra_index) {
4349
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (sc->sync_group[i].count > INT_MAX - sc->open_key_samples_count)
4350 return AVERROR(ENOMEM);
4351 9 sc->open_key_samples_count += sc->sync_group[i].count;
4352 }
4353 3 av_freep(&sc->open_key_samples);
4354 3 sc->open_key_samples = av_calloc(sc->open_key_samples_count, sizeof(*sc->open_key_samples));
4355
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!sc->open_key_samples)
4356 return AVERROR(ENOMEM);
4357 3 k = 0;
4358
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 3 times.
27 for (uint32_t i = 0; i < sc->sync_group_count; i++) {
4359 24 const MOVSbgp *sg = &sc->sync_group[i];
4360
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 15 times.
24 if (sg->index == cra_index)
4361
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 9 times.
18 for (uint32_t j = 0; j < sg->count; j++)
4362 9 sc->open_key_samples[k++] = sample_id;
4363
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
24 if (sg->count > INT_MAX - sample_id)
4364 return AVERROR_PATCHWELCOME;
4365 24 sample_id += sg->count;
4366 }
4367
4368 /* Identify the minimal time step between samples */
4369 3 sc->min_sample_duration = UINT_MAX;
4370
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
12 for (uint32_t i = 0; i < sc->stts_count; i++)
4371 9 sc->min_sample_duration = FFMIN(sc->min_sample_duration, sc->stts_data[i].duration);
4372
4373 3 return 0;
4374 }
4375
4376 590 static void mov_build_index(MOVContext *mov, AVStream *st)
4377 {
4378 590 MOVStreamContext *sc = st->priv_data;
4379 590 FFStream *const sti = ffstream(st);
4380 int64_t current_offset;
4381 590 int64_t current_dts = 0;
4382 590 unsigned int stts_index = 0;
4383 590 unsigned int stsc_index = 0;
4384 590 unsigned int stss_index = 0;
4385 590 unsigned int stps_index = 0;
4386 unsigned int i, j;
4387 590 uint64_t stream_size = 0;
4388 590 MOVCtts *ctts_data_old = sc->ctts_data;
4389 590 unsigned int ctts_count_old = sc->ctts_count;
4390
4391 590 int ret = build_open_gop_key_points(st);
4392
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 590 times.
590 if (ret < 0)
4393 return;
4394
4395
2/2
✓ Branch 0 taken 418 times.
✓ Branch 1 taken 172 times.
590 if (sc->elst_count) {
4396 418 int i, edit_start_index = 0, multiple_edits = 0;
4397 418 int64_t empty_duration = 0; // empty duration of the first edit list entry
4398 418 int64_t start_time = 0; // start time of the media
4399
4400
2/2
✓ Branch 0 taken 445 times.
✓ Branch 1 taken 418 times.
863 for (i = 0; i < sc->elst_count; i++) {
4401 445 const MOVElst *e = &sc->elst_data[i];
4402
4/4
✓ Branch 0 taken 418 times.
✓ Branch 1 taken 27 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 414 times.
445 if (i == 0 && e->time == -1) {
4403 /* if empty, the first entry is the start time of the stream
4404 * relative to the presentation itself */
4405 4 empty_duration = e->duration;
4406 4 edit_start_index = 1;
4407
3/4
✓ Branch 0 taken 418 times.
✓ Branch 1 taken 23 times.
✓ Branch 2 taken 418 times.
✗ Branch 3 not taken.
441 } else if (i == edit_start_index && e->time >= 0) {
4408 418 start_time = e->time;
4409 } else {
4410 23 multiple_edits = 1;
4411 }
4412 }
4413
4414
3/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 412 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
418 if (multiple_edits && !mov->advanced_editlist) {
4415 if (mov->advanced_editlist_autodisabled)
4416 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4417 "not supported in fragmented MP4 files\n");
4418 else
4419 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4420 "Use -advanced_editlist to correctly decode otherwise "
4421 "a/v desync might occur\n");
4422 }
4423
4424 /* adjust first dts according to edit list */
4425
5/6
✓ Branch 0 taken 414 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 63 times.
✓ Branch 3 taken 351 times.
✓ Branch 4 taken 67 times.
✗ Branch 5 not taken.
418 if ((empty_duration || start_time) && mov->time_scale > 0) {
4426
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 63 times.
67 if (empty_duration)
4427 4 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
4428
4429
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 67 times.
67 if (av_sat_sub64(start_time, empty_duration) != start_time - (uint64_t)empty_duration)
4430 av_log(mov->fc, AV_LOG_WARNING, "start_time - empty_duration is not representable\n");
4431
4432 67 sc->time_offset = start_time - (uint64_t)empty_duration;
4433 67 sc->min_corrected_pts = start_time;
4434
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 66 times.
67 if (!mov->advanced_editlist)
4435 1 current_dts = -sc->time_offset;
4436 }
4437
4438
4/4
✓ Branch 0 taken 412 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 410 times.
418 if (!multiple_edits && !mov->advanced_editlist &&
4439
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 st->codecpar->codec_id == AV_CODEC_ID_AAC && start_time > 0)
4440 sc->start_pad = start_time;
4441 }
4442
4443 /* only use old uncompressed audio chunk demuxing when stts specifies it */
4444
2/2
✓ Branch 0 taken 236 times.
✓ Branch 1 taken 354 times.
590 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4445
4/4
✓ Branch 0 taken 185 times.
✓ Branch 1 taken 51 times.
✓ Branch 2 taken 120 times.
✓ Branch 3 taken 65 times.
745 sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
4446 525 unsigned int current_sample = 0;
4447 525 unsigned int stts_sample = 0;
4448 unsigned int sample_size;
4449 525 unsigned int distance = 0;
4450 525 unsigned int rap_group_index = 0;
4451 525 unsigned int rap_group_sample = 0;
4452
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 524 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
525 int rap_group_present = sc->rap_group_count && sc->rap_group;
4453
4/8
✓ Branch 0 taken 126 times.
✓ Branch 1 taken 399 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 126 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 399 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
525 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
4454
4455 525 current_dts -= sc->dts_shift;
4456
4457
3/4
✓ Branch 0 taken 509 times.
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 509 times.
525 if (!sc->sample_count || sti->nb_index_entries)
4458 16 return;
4459
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 509 times.
509 if (sc->sample_count >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4460 return;
4461
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 509 times.
509 if (av_reallocp_array(&sti->index_entries,
4462 509 sti->nb_index_entries + sc->sample_count,
4463 sizeof(*sti->index_entries)) < 0) {
4464 sti->nb_index_entries = 0;
4465 return;
4466 }
4467 509 sti->index_entries_allocated_size = (sti->nb_index_entries + sc->sample_count) * sizeof(*sti->index_entries);
4468
4469
2/2
✓ Branch 0 taken 55 times.
✓ Branch 1 taken 454 times.
509 if (ctts_data_old) {
4470 // Expand ctts entries such that we have a 1-1 mapping with samples
4471
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 55 times.
55 if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
4472 return;
4473 55 sc->ctts_count = 0;
4474 55 sc->ctts_allocated_size = 0;
4475 110 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size,
4476 55 sc->sample_count * sizeof(*sc->ctts_data));
4477
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 55 times.
55 if (!sc->ctts_data) {
4478 av_free(ctts_data_old);
4479 return;
4480 }
4481
4482 55 memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
4483
4484
2/2
✓ Branch 0 taken 4817 times.
✓ Branch 1 taken 55 times.
4872 for (i = 0; i < ctts_count_old &&
4485
1/2
✓ Branch 0 taken 4817 times.
✗ Branch 1 not taken.
9634 sc->ctts_count < sc->sample_count; i++)
4486
2/2
✓ Branch 0 taken 138934 times.
✓ Branch 1 taken 4817 times.
143751 for (j = 0; j < ctts_data_old[i].count &&
4487
1/2
✓ Branch 0 taken 138934 times.
✗ Branch 1 not taken.
277868 sc->ctts_count < sc->sample_count; j++)
4488 138934 add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
4489 &sc->ctts_allocated_size, 1,
4490 138934 ctts_data_old[i].duration);
4491 55 av_free(ctts_data_old);
4492 }
4493
4494
2/2
✓ Branch 0 taken 173659 times.
✓ Branch 1 taken 509 times.
174168 for (i = 0; i < sc->chunk_count; i++) {
4495
2/2
✓ Branch 0 taken 173150 times.
✓ Branch 1 taken 509 times.
173659 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
4496 173659 current_offset = sc->chunk_offsets[i];
4497
2/2
✓ Branch 1 taken 8777 times.
✓ Branch 2 taken 167388 times.
176165 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4498
2/2
✓ Branch 0 taken 2506 times.
✓ Branch 1 taken 6271 times.
8777 i + 1 == sc->stsc_data[stsc_index + 1].first)
4499 2506 stsc_index++;
4500
4501
4/6
✓ Branch 0 taken 173659 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7268 times.
✓ Branch 3 taken 166391 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 7268 times.
173659 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
4502 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
4503 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
4504 sc->stsz_sample_size = sc->sample_size;
4505 }
4506
3/4
✓ Branch 0 taken 7268 times.
✓ Branch 1 taken 166391 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 7268 times.
173659 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
4507 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
4508 sc->stsz_sample_size = sc->sample_size;
4509 }
4510
4511
2/2
✓ Branch 0 taken 231420 times.
✓ Branch 1 taken 173659 times.
405079 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
4512 231420 int keyframe = 0;
4513
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 231420 times.
231420 if (current_sample >= sc->sample_count) {
4514 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
4515 return;
4516 }
4517
4518
6/6
✓ Branch 0 taken 230546 times.
✓ Branch 1 taken 874 times.
✓ Branch 2 taken 152280 times.
✓ Branch 3 taken 78266 times.
✓ Branch 4 taken 5680 times.
✓ Branch 5 taken 146600 times.
231420 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
4519 83946 keyframe = 1;
4520
2/2
✓ Branch 0 taken 5554 times.
✓ Branch 1 taken 78392 times.
83946 if (stss_index + 1 < sc->keyframe_count)
4521 5554 stss_index++;
4522
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 147474 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
147474 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
4523 keyframe = 1;
4524 if (stps_index + 1 < sc->stps_count)
4525 stps_index++;
4526 }
4527
3/4
✓ Branch 0 taken 188 times.
✓ Branch 1 taken 231232 times.
✓ Branch 2 taken 188 times.
✗ Branch 3 not taken.
231420 if (rap_group_present && rap_group_index < sc->rap_group_count) {
4528
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 186 times.
188 if (sc->rap_group[rap_group_index].index > 0)
4529 2 keyframe = 1;
4530
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 184 times.
188 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
4531 4 rap_group_sample = 0;
4532 4 rap_group_index++;
4533 }
4534 }
4535
2/2
✓ Branch 0 taken 874 times.
✓ Branch 1 taken 230546 times.
231420 if (sc->keyframe_absent
4536
1/2
✓ Branch 0 taken 874 times.
✗ Branch 1 not taken.
874 && !sc->stps_count
4537
1/2
✓ Branch 0 taken 874 times.
✗ Branch 1 not taken.
874 && !rap_group_present
4538
5/6
✓ Branch 0 taken 874 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 50 times.
✓ Branch 3 taken 824 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 48 times.
874 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
4539 2 keyframe = 1;
4540
2/2
✓ Branch 0 taken 83948 times.
✓ Branch 1 taken 147472 times.
231420 if (keyframe)
4541 83948 distance = 0;
4542
2/2
✓ Branch 0 taken 8784 times.
✓ Branch 1 taken 222636 times.
231420 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
4543
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 231420 times.
231420 if (current_offset > INT64_MAX - sample_size) {
4544 av_log(mov->fc, AV_LOG_ERROR, "Current offset %"PRId64" or sample size %u is too large\n",
4545 current_offset,
4546 sample_size);
4547 return;
4548 }
4549
4550
2/2
✓ Branch 0 taken 231339 times.
✓ Branch 1 taken 81 times.
231420 if (sc->pseudo_stream_id == -1 ||
4551
1/2
✓ Branch 0 taken 231339 times.
✗ Branch 1 not taken.
231339 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
4552 AVIndexEntry *e;
4553
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 231420 times.
231420 if (sample_size > 0x3FFFFFFF) {
4554 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
4555 return;
4556 }
4557 231420 e = &sti->index_entries[sti->nb_index_entries++];
4558 231420 e->pos = current_offset;
4559 231420 e->timestamp = current_dts;
4560 231420 e->size = sample_size;
4561 231420 e->min_distance = distance;
4562 231420 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
4563 231420 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
4564 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
4565 current_offset, current_dts, sample_size, distance, keyframe);
4566
4/4
✓ Branch 0 taken 154424 times.
✓ Branch 1 taken 76996 times.
✓ Branch 2 taken 9791 times.
✓ Branch 3 taken 144633 times.
231420 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sti->nb_index_entries < 100)
4567 9791 ff_rfps_add_frame(mov->fc, st, current_dts);
4568 }
4569
4570 231420 current_offset += sample_size;
4571 231420 stream_size += sample_size;
4572
4573 231420 current_dts += sc->stts_data[stts_index].duration;
4574
4575 231420 distance++;
4576 231420 stts_sample++;
4577 231420 current_sample++;
4578
4/4
✓ Branch 0 taken 19542 times.
✓ Branch 1 taken 211878 times.
✓ Branch 2 taken 2361 times.
✓ Branch 3 taken 17181 times.
231420 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
4579 2361 stts_sample = 0;
4580 2361 stts_index++;
4581 }
4582 }
4583 }
4584
2/2
✓ Branch 0 taken 490 times.
✓ Branch 1 taken 19 times.
509 if (st->duration > 0)
4585 490 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
4586 } else {
4587 65 unsigned chunk_samples, total = 0;
4588
4589
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 65 times.
65 if (!sc->chunk_count)
4590 return;
4591
4592 // compute total chunk count
4593
2/2
✓ Branch 0 taken 721 times.
✓ Branch 1 taken 65 times.
786 for (i = 0; i < sc->stsc_count; i++) {
4594 unsigned count, chunk_count;
4595
4596 721 chunk_samples = sc->stsc_data[i].count;
4597
2/2
✓ Branch 0 taken 656 times.
✓ Branch 1 taken 65 times.
721 if (i != sc->stsc_count - 1 &&
4598
3/4
✓ Branch 0 taken 594 times.
✓ Branch 1 taken 62 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 594 times.
656 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
4599 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
4600 return;
4601 }
4602
4603
2/2
✓ Branch 0 taken 75 times.
✓ Branch 1 taken 646 times.
721 if (sc->samples_per_frame >= 160) { // gsm
4604 75 count = chunk_samples / sc->samples_per_frame;
4605
2/2
✓ Branch 0 taken 531 times.
✓ Branch 1 taken 115 times.
646 } else if (sc->samples_per_frame > 1) {
4606 531 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4607 531 count = (chunk_samples+samples-1) / samples;
4608 } else {
4609 115 count = (chunk_samples+1023) / 1024;
4610 }
4611
4612
2/2
✓ Branch 1 taken 656 times.
✓ Branch 2 taken 65 times.
721 if (mov_stsc_index_valid(i, sc->stsc_count))
4613 656 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4614 else
4615 65 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4616 721 total += chunk_count * count;
4617 }
4618
4619 65 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4620
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 65 times.
65 if (total >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4621 return;
4622
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 65 times.
65 if (av_reallocp_array(&sti->index_entries,
4623 65 sti->nb_index_entries + total,
4624 sizeof(*sti->index_entries)) < 0) {
4625 sti->nb_index_entries = 0;
4626 return;
4627 }
4628 65 sti->index_entries_allocated_size = (sti->nb_index_entries + total) * sizeof(*sti->index_entries);
4629
4630 // populate index
4631
2/2
✓ Branch 0 taken 5421 times.
✓ Branch 1 taken 65 times.
5486 for (i = 0; i < sc->chunk_count; i++) {
4632 5421 current_offset = sc->chunk_offsets[i];
4633
2/2
✓ Branch 1 taken 5280 times.
✓ Branch 2 taken 141 times.
5421 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4634
2/2
✓ Branch 0 taken 656 times.
✓ Branch 1 taken 4624 times.
5280 i + 1 == sc->stsc_data[stsc_index + 1].first)
4635 656 stsc_index++;
4636 5421 chunk_samples = sc->stsc_data[stsc_index].count;
4637
4638
2/2
✓ Branch 0 taken 162488 times.
✓ Branch 1 taken 5421 times.
167909 while (chunk_samples > 0) {
4639 AVIndexEntry *e;
4640 unsigned size, samples;
4641
4642
3/4
✓ Branch 0 taken 23921 times.
✓ Branch 1 taken 138567 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 23921 times.
162488 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4643 avpriv_request_sample(mov->fc,
4644 "Zero bytes per frame, but %d samples per frame",
4645 sc->samples_per_frame);
4646 return;
4647 }
4648
4649
2/2
✓ Branch 0 taken 14358 times.
✓ Branch 1 taken 148130 times.
162488 if (sc->samples_per_frame >= 160) { // gsm
4650 14358 samples = sc->samples_per_frame;
4651 14358 size = sc->bytes_per_frame;
4652 } else {
4653
2/2
✓ Branch 0 taken 9563 times.
✓ Branch 1 taken 138567 times.
148130 if (sc->samples_per_frame > 1) {
4654 9563 samples = FFMIN((1024 / sc->samples_per_frame)*
4655 sc->samples_per_frame, chunk_samples);
4656 9563 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
4657 } else {
4658 138567 samples = FFMIN(1024, chunk_samples);
4659 138567 size = samples * sc->sample_size;
4660 }
4661 }
4662
4663
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 162488 times.
162488 if (sti->nb_index_entries >= total) {
4664 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4665 return;
4666 }
4667
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 162488 times.
162488 if (size > 0x3FFFFFFF) {
4668 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4669 return;
4670 }
4671 162488 e = &sti->index_entries[sti->nb_index_entries++];
4672 162488 e->pos = current_offset;
4673 162488 e->timestamp = current_dts;
4674 162488 e->size = size;
4675 162488 e->min_distance = 0;
4676 162488 e->flags = AVINDEX_KEYFRAME;
4677 162488 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4678 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4679 size, samples);
4680
4681 162488 current_offset += size;
4682 162488 current_dts += samples;
4683 162488 chunk_samples -= samples;
4684 }
4685 }
4686 }
4687
4688
2/4
✓ Branch 0 taken 574 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 574 times.
✗ Branch 3 not taken.
574 if (!mov->ignore_editlist && mov->advanced_editlist) {
4689 // Fix index according to edit lists.
4690 574 mov_fix_index(mov, st);
4691 }
4692
4693 // Update start time of the stream.
4694
5/6
✓ Branch 0 taken 158 times.
✓ Branch 1 taken 416 times.
✓ Branch 2 taken 42 times.
✓ Branch 3 taken 116 times.
✓ Branch 4 taken 42 times.
✗ Branch 5 not taken.
574 if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sti->nb_index_entries > 0) {
4695 42 st->start_time = sti->index_entries[0].timestamp + sc->dts_shift;
4696
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 39 times.
42 if (sc->ctts_data) {
4697 3 st->start_time += sc->ctts_data[0].duration;
4698 }
4699 }
4700
4701 574 mov_estimate_video_delay(mov, st);
4702 }
4703
4704 static int test_same_origin(const char *src, const char *ref) {
4705 char src_proto[64];
4706 char ref_proto[64];
4707 char src_auth[256];
4708 char ref_auth[256];
4709 char src_host[256];
4710 char ref_host[256];
4711 int src_port=-1;
4712 int ref_port=-1;
4713
4714 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4715 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4716
4717 if (strlen(src) == 0) {
4718 return -1;
4719 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4720 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4721 strlen(src_host) + 1 >= sizeof(src_host) ||
4722 strlen(ref_host) + 1 >= sizeof(ref_host)) {
4723 return 0;
4724 } else if (strcmp(src_proto, ref_proto) ||
4725 strcmp(src_auth, ref_auth) ||
4726 strcmp(src_host, ref_host) ||
4727 src_port != ref_port) {
4728 return 0;
4729 } else
4730 return 1;
4731 }
4732
4733 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4734 {
4735 /* try relative path, we do not try the absolute because it can leak information about our
4736 system to an attacker */
4737 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4738 char filename[1025];
4739 const char *src_path;
4740 int i, l;
4741
4742 /* find a source dir */
4743 src_path = strrchr(src, '/');
4744 if (src_path)
4745 src_path++;
4746 else
4747 src_path = src;
4748
4749 /* find a next level down to target */
4750 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4751 if (ref->path[l] == '/') {
4752 if (i == ref->nlvl_to - 1)
4753 break;
4754 else
4755 i++;
4756 }
4757
4758 /* compose filename if next level down to target was found */
4759 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4760 memcpy(filename, src, src_path - src);
4761 filename[src_path - src] = 0;
4762
4763 for (i = 1; i < ref->nlvl_from; i++)
4764 av_strlcat(filename, "../", sizeof(filename));
4765
4766 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4767 if (!c->use_absolute_path) {
4768 int same_origin = test_same_origin(src, filename);
4769
4770 if (!same_origin) {
4771 av_log(c->fc, AV_LOG_ERROR,
4772 "Reference with mismatching origin, %s not tried for security reasons, "
4773 "set demuxer option use_absolute_path to allow it anyway\n",
4774 ref->path);
4775 return AVERROR(ENOENT);
4776 }
4777
4778 if (strstr(ref->path + l + 1, "..") ||
4779 strstr(ref->path + l + 1, ":") ||
4780 (ref->nlvl_from > 1 && same_origin < 0) ||
4781 (filename[0] == '/' && src_path == src))
4782 return AVERROR(ENOENT);
4783 }
4784
4785 if (strlen(filename) + 1 == sizeof(filename))
4786 return AVERROR(ENOENT);
4787 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4788 return 0;
4789 }
4790 } else if (c->use_absolute_path) {
4791 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4792 "this is a possible security issue\n");
4793 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4794 return 0;
4795 } else {
4796 av_log(c->fc, AV_LOG_ERROR,
4797 "Absolute path %s not tried for security reasons, "
4798 "set demuxer option use_absolute_path to allow absolute paths\n",
4799 ref->path);
4800 }
4801
4802 return AVERROR(ENOENT);
4803 }
4804
4805 1203 static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
4806 {
4807
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 1189 times.
1203 if (sc->time_scale <= 0) {
4808 14 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4809 14 sc->time_scale = c->time_scale;
4810
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (sc->time_scale <= 0)
4811 sc->time_scale = 1;
4812 }
4813 1203 }
4814
4815 #if CONFIG_IAMFDEC
4816 8 static int mov_update_iamf_streams(MOVContext *c, const AVStream *st)
4817 {
4818 8 const MOVStreamContext *sc = st->priv_data;
4819 8 const IAMFContext *iamf = &sc->iamf->iamf;
4820
4821
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 for (int i = 0; i < iamf->nb_audio_elements; i++) {
4822 8 const AVStreamGroup *stg = NULL;
4823
4824
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 8 times.
24 for (int j = 0; j < c->fc->nb_stream_groups; j++)
4825
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 if (c->fc->stream_groups[j]->id == iamf->audio_elements[i]->audio_element_id)
4826 8 stg = c->fc->stream_groups[j];
4827
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 av_assert0(stg);
4828
4829
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 8 times.
44 for (int j = 0; j < stg->nb_streams; j++) {
4830 36 const FFStream *sti = cffstream(st);
4831 36 AVStream *out = stg->streams[j];
4832 36 FFStream *out_sti = ffstream(stg->streams[j]);
4833
4834 36 out->codecpar->bit_rate = 0;
4835
4836
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 28 times.
36 if (out == st)
4837 8 continue;
4838
4839 28 out->time_base = st->time_base;
4840 28 out->start_time = st->start_time;
4841 28 out->duration = st->duration;
4842 28 out->nb_frames = st->nb_frames;
4843 28 out->discard = st->discard;
4844
4845
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
28 av_assert0(!out_sti->index_entries);
4846 28 out_sti->index_entries = av_malloc(sti->index_entries_allocated_size);
4847
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
28 if (!out_sti->index_entries)
4848 return AVERROR(ENOMEM);
4849
4850 28 out_sti->index_entries_allocated_size = sti->index_entries_allocated_size;
4851 28 out_sti->nb_index_entries = sti->nb_index_entries;
4852 28 out_sti->skip_samples = sti->skip_samples;
4853 28 memcpy(out_sti->index_entries, sti->index_entries, sti->index_entries_allocated_size);
4854 }
4855 }
4856
4857 8 return 0;
4858 }
4859 #endif
4860
4861 571 static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4862 {
4863 AVStream *st;
4864 MOVStreamContext *sc;
4865 int ret;
4866
4867 571 st = avformat_new_stream(c->fc, NULL);
4868
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 571 times.
571 if (!st) return AVERROR(ENOMEM);
4869 571 st->id = -1;
4870 571 sc = av_mallocz(sizeof(MOVStreamContext));
4871
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 571 times.
571 if (!sc) return AVERROR(ENOMEM);
4872
4873 571 st->priv_data = sc;
4874 571 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
4875 571 sc->ffindex = st->index;
4876 571 c->trak_index = st->index;
4877 571 sc->refcount = 1;
4878
4879
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 571 times.
571 if ((ret = mov_read_default(c, pb, atom)) < 0)
4880 return ret;
4881
4882 571 c->trak_index = -1;
4883
4884 // Here stsc refers to a chunk not described in stco. This is technically invalid,
4885 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4886
5/6
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 555 times.
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 15 times.
571 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4887 1 sc->stsc_count = 0;
4888 1 av_freep(&sc->stsc_data);
4889 }
4890
4891 /* sanity checks */
4892
4/6
✓ Branch 0 taken 555 times.
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 555 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 555 times.
✗ Branch 5 not taken.
571 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4893
3/4
✓ Branch 0 taken 364 times.
✓ Branch 1 taken 191 times.
✓ Branch 2 taken 364 times.
✗ Branch 3 not taken.
555 (!sc->sample_size && !sc->sample_count))) ||
4894
3/4
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 555 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 16 times.
571 (!sc->chunk_count && sc->sample_count)) {
4895 av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4896 st->index);
4897 return 0;
4898 }
4899
3/4
✓ Branch 0 taken 555 times.
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 555 times.
571 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4900 av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4901 st->index);
4902 return AVERROR_INVALIDDATA;
4903 }
4904
4905 571 fix_timescale(c, sc);
4906
4907 571 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4908
4909 /*
4910 * Advanced edit list support does not work with fragemented MP4s, which
4911 * have stsc, stsz, stco, and stts with zero entries in the moov atom.
4912 * In these files, trun atoms may be streamed in.
4913 */
4914
4/4
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 555 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 4 times.
571 if (!sc->stts_count && c->advanced_editlist) {
4915
4916 12 av_log(c->fc, AV_LOG_VERBOSE, "advanced_editlist does not work with fragmented "
4917 "MP4. disabling.\n");
4918 12 c->advanced_editlist = 0;
4919 12 c->advanced_editlist_autodisabled = 1;
4920 }
4921
4922 571 mov_build_index(c, st);
4923
4924 #if CONFIG_IAMFDEC
4925
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 563 times.
571 if (sc->iamf) {
4926 8 ret = mov_update_iamf_streams(c, st);
4927
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (ret < 0)
4928 return ret;
4929 }
4930 #endif
4931
4932
3/4
✓ Branch 0 taken 570 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 570 times.
571 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4933 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4934 if (c->enable_drefs) {
4935 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4936 av_log(c->fc, AV_LOG_ERROR,
4937 "stream %d, error opening alias: path='%s', dir='%s', "
4938 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4939 st->index, dref->path, dref->dir, dref->filename,
4940 dref->volume, dref->nlvl_from, dref->nlvl_to);
4941 } else {
4942 av_log(c->fc, AV_LOG_WARNING,
4943 "Skipped opening external track: "
4944 "stream %d, alias: path='%s', dir='%s', "
4945 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4946 "Set enable_drefs to allow this.\n",
4947 st->index, dref->path, dref->dir, dref->filename,
4948 dref->volume, dref->nlvl_from, dref->nlvl_to);
4949 }
4950 } else {
4951 571 sc->pb = c->fc->pb;
4952 571 sc->pb_is_copied = 1;
4953 }
4954
4955
2/2
✓ Branch 0 taken 286 times.
✓ Branch 1 taken 285 times.
571 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4956
4/6
✓ Branch 0 taken 226 times.
✓ Branch 1 taken 60 times.
✓ Branch 2 taken 226 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 226 times.
✗ Branch 5 not taken.
286 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4957
2/4
✓ Branch 0 taken 226 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 226 times.
✗ Branch 3 not taken.
226 sc->height && sc->width &&
4958
2/4
✓ Branch 0 taken 226 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 226 times.
226 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4959 st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4960 ((double)st->codecpar->width * sc->height), INT_MAX);
4961 }
4962
4963 #if FF_API_R_FRAME_RATE
4964
6/6
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 251 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 23 times.
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 1 times.
286 if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4965 262 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
4966 262 sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4967 #endif
4968 }
4969
4970 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4971
3/4
✓ Branch 0 taken 256 times.
✓ Branch 1 taken 315 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 256 times.
571 if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4972 TAG_IS_AVCI(st->codecpar->codec_tag)) {
4973 ret = ff_generate_avci_extradata(st);
4974 if (ret < 0)
4975 return ret;
4976 }
4977
4978
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 552 times.
571 switch (st->codecpar->codec_id) {
4979 #if CONFIG_H261_DECODER
4980 19 case AV_CODEC_ID_H261:
4981 #endif
4982 #if CONFIG_H263_DECODER
4983 case AV_CODEC_ID_H263:
4984 #endif
4985 #if CONFIG_MPEG4_DECODER
4986 case AV_CODEC_ID_MPEG4:
4987 #endif
4988 19 st->codecpar->width = 0; /* let decoder init width/height */
4989 19 st->codecpar->height= 0;
4990 19 break;
4991 }
4992
4993 // If the duration of the mp3 packets is not constant, then they could need a parser
4994
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 570 times.
571 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4995
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 && sc->stts_count > 3
4996 && sc->stts_count*10 > st->nb_frames
4997 && sc->time_scale == st->codecpar->sample_rate) {
4998 ffstream(st)->need_parsing = AVSTREAM_PARSE_FULL;
4999 }
5000 /* Do not need those anymore. */
5001 571 av_freep(&sc->chunk_offsets);
5002 571 av_freep(&sc->sample_sizes);
5003 571 av_freep(&sc->keyframes);
5004 571 av_freep(&sc->stts_data);
5005 571 av_freep(&sc->stps_data);
5006 571 av_freep(&sc->elst_data);
5007 571 av_freep(&sc->rap_group);
5008 571 av_freep(&sc->sync_group);
5009 571 av_freep(&sc->sgpd_sync);
5010
5011 571 return 0;
5012 }
5013
5014 118 static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5015 {
5016 int ret;
5017 118 c->itunes_metadata = 1;
5018 118 ret = mov_read_default(c, pb, atom);
5019 118 c->itunes_metadata = 0;
5020 118 return ret;
5021 }
5022
5023 9 static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5024 {
5025 uint32_t count;
5026 uint32_t i;
5027
5028
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (atom.size < 8)
5029 return 0;
5030
5031 9 avio_skip(pb, 4);
5032 9 count = avio_rb32(pb);
5033 9 atom.size -= 8;
5034
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (count >= UINT_MAX / sizeof(*c->meta_keys)) {
5035 av_log(c->fc, AV_LOG_ERROR,
5036 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
5037 return AVERROR_INVALIDDATA;
5038 }
5039
5040 9 c->meta_keys_count = count + 1;
5041 9 c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
5042
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (!c->meta_keys)
5043 return AVERROR(ENOMEM);
5044
5045
2/2
✓ Branch 0 taken 44 times.
✓ Branch 1 taken 9 times.
53 for (i = 1; i <= count; ++i) {
5046 44 uint32_t key_size = avio_rb32(pb);
5047 44 uint32_t type = avio_rl32(pb);
5048
2/4
✓ Branch 0 taken 44 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 44 times.
44 if (key_size < 8 || key_size > atom.size) {
5049 av_log(c->fc, AV_LOG_ERROR,
5050 "The key# %"PRIu32" in meta has invalid size:"
5051 "%"PRIu32"\n", i, key_size);
5052 return AVERROR_INVALIDDATA;
5053 }
5054 44 atom.size -= key_size;
5055 44 key_size -= 8;
5056
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 44 times.
44 if (type != MKTAG('m','d','t','a')) {
5057 avio_skip(pb, key_size);
5058 continue;
5059 }
5060 44 c->meta_keys[i] = av_mallocz(key_size + 1);
5061
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 44 times.
44 if (!c->meta_keys[i])
5062 return AVERROR(ENOMEM);
5063 44 avio_read(pb, c->meta_keys[i], key_size);
5064 }
5065
5066 9 return 0;
5067 }
5068
5069 65 static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5070 {
5071 65 int64_t end = av_sat_add64(avio_tell(pb), atom.size);
5072 65 uint8_t *key = NULL, *val = NULL, *mean = NULL;
5073 int i;
5074 65 int ret = 0;
5075 AVStream *st;
5076 MOVStreamContext *sc;
5077
5078
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 65 times.
65 if (c->fc->nb_streams < 1)
5079 return 0;
5080 65 st = c->fc->streams[c->fc->nb_streams-1];
5081 65 sc = st->priv_data;
5082
5083
2/2
✓ Branch 0 taken 195 times.
✓ Branch 1 taken 65 times.
260 for (i = 0; i < 3; i++) {
5084 uint8_t **p;
5085 uint32_t len, tag;
5086
5087
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 195 times.
195 if (end - avio_tell(pb) <= 12)
5088 break;
5089
5090 195 len = avio_rb32(pb);
5091 195 tag = avio_rl32(pb);
5092 195 avio_skip(pb, 4); // flags
5093
5094
2/4
✓ Branch 0 taken 195 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 195 times.
✗ Branch 4 not taken.
195 if (len < 12 || len - 12 > end - avio_tell(pb))
5095 break;
5096 195 len -= 12;
5097
5098
2/2
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 130 times.
195 if (tag == MKTAG('m', 'e', 'a', 'n'))
5099 65 p = &mean;
5100
2/2
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 65 times.
130 else if (tag == MKTAG('n', 'a', 'm', 'e'))
5101 65 p = &key;
5102
2/4
✓ Branch 0 taken 65 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 65 times.
✗ Branch 3 not taken.
65 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
5103 65 avio_skip(pb, 4);
5104 65 len -= 4;
5105 65 p = &val;
5106 } else
5107 break;
5108
5109
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 195 times.
195 if (*p)
5110 break;
5111
5112 195 *p = av_malloc(len + 1);
5113
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 195 times.
195 if (!*p) {
5114 ret = AVERROR(ENOMEM);
5115 break;
5116 }
5117 195 ret = ffio_read_size(pb, *p, len);
5118
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 195 times.
195 if (ret < 0) {
5119 av_freep(p);
5120 break;
5121 }
5122 195 (*p)[len] = 0;
5123 }
5124
5125
3/6
✓ Branch 0 taken 65 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 65 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 65 times.
✗ Branch 5 not taken.
65 if (mean && key && val) {
5126
2/2
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 32 times.
65 if (strcmp(key, "iTunSMPB") == 0) {
5127 int priming, remainder, samples;
5128
1/2
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
33 if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
5129
2/4
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 33 times.
✗ Branch 3 not taken.
33 if(priming>0 && priming<16384)
5130 33 sc->start_pad = priming;
5131 }
5132 }
5133
2/2
✓ Branch 0 taken 55 times.
✓ Branch 1 taken 10 times.
120 if (strcmp(key, "cdec") != 0) {
5134 55 av_dict_set(&c->fc->metadata, key, val,
5135 AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
5136 55 key = val = NULL;
5137 }
5138 } else {
5139 av_log(c->fc, AV_LOG_VERBOSE,
5140 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
5141 }
5142
5143 65 avio_seek(pb, end, SEEK_SET);
5144 65 av_freep(&key);
5145 65 av_freep(&val);
5146 65 av_freep(&mean);
5147 65 return ret;
5148 }
5149
5150 19 static int heif_add_stream(MOVContext *c, HEIFItem *item)
5151 {
5152 MOVStreamContext *sc;
5153 AVStream *st;
5154
5155 19 st = avformat_new_stream(c->fc, NULL);
5156
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
19 if (!st)
5157 return AVERROR(ENOMEM);
5158 19 sc = av_mallocz(sizeof(MOVStreamContext));
5159
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
19 if (!sc)
5160 return AVERROR(ENOMEM);
5161
5162 19 item->st = st;
5163 19 st->id = item->item_id;
5164 19 st->priv_data = sc;
5165 19 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
5166 19 st->codecpar->codec_id = mov_codec_id(st, item->type);
5167 19 sc->id = st->id;
5168 19 sc->ffindex = st->index;
5169 19 st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
5170 19 st->time_base.num = st->time_base.den = 1;
5171 19 st->nb_frames = 1;
5172 19 sc->time_scale = 1;
5173 19 sc->pb = c->fc->pb;
5174 19 sc->pb_is_copied = 1;
5175 19 sc->refcount = 1;
5176
5177
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 if (item->name)
5178 19 av_dict_set(&st->metadata, "title", item->name, 0);
5179
5180 // Populate the necessary fields used by mov_build_index.
5181 19 sc->stsc_count = 1;
5182 19 sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
5183
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
19 if (!sc->stsc_data)
5184 return AVERROR(ENOMEM);
5185 19 sc->stsc_data[0].first = 1;
5186 19 sc->stsc_data[0].count = 1;
5187 19 sc->stsc_data[0].id = 1;
5188 19 sc->chunk_count = 1;
5189 19 sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
5190
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
19 if (!sc->chunk_offsets)
5191 return AVERROR(ENOMEM);
5192 19 sc->sample_count = 1;
5193 19 sc->sample_sizes = av_malloc_array(1, sizeof(*sc->sample_sizes));
5194
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
19 if (!sc->sample_sizes)
5195 return AVERROR(ENOMEM);
5196 19 sc->stts_count = 1;
5197 19 sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
5198
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
19 if (!sc->stts_data)
5199 return AVERROR(ENOMEM);
5200 19 sc->stts_data[0].count = 1;
5201 // Not used for still images. But needed by mov_build_index.
5202 19 sc->stts_data[0].duration = 0;
5203
5204 19 return 0;
5205 }
5206
5207 130 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5208 {
5209
1/2
✓ Branch 0 taken 378 times.
✗ Branch 1 not taken.
378 while (atom.size > 8) {
5210 uint32_t tag;
5211
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 378 times.
378 if (avio_feof(pb))
5212 return AVERROR_EOF;
5213 378 tag = avio_rl32(pb);
5214 378 atom.size -= 4;
5215
2/2
✓ Branch 0 taken 130 times.
✓ Branch 1 taken 248 times.
378 if (tag == MKTAG('h','d','l','r')) {
5216 130 avio_seek(pb, -8, SEEK_CUR);
5217 130 atom.size += 8;
5218 130 return mov_read_default(c, pb, atom);
5219 }
5220 }
5221 return 0;
5222 }
5223
5224 // return 1 when matrix is identity, 0 otherwise
5225 #define IS_MATRIX_IDENT(matrix) \
5226 ( (matrix)[0][0] == (1 << 16) && \
5227 (matrix)[1][1] == (1 << 16) && \
5228 (matrix)[2][2] == (1 << 30) && \
5229 !(matrix)[0][1] && !(matrix)[0][2] && \
5230 !(matrix)[1][0] && !(matrix)[1][2] && \
5231 !(matrix)[2][0] && !(matrix)[2][1])
5232
5233 571 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5234 {
5235 int i, j, e;
5236 int width;
5237 int height;
5238 int display_matrix[3][3];
5239 571 int res_display_matrix[3][3] = { { 0 } };
5240 AVStream *st;
5241 MOVStreamContext *sc;
5242 int version;
5243 int flags;
5244
5245
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 571 times.
571 if (c->fc->nb_streams < 1)
5246 return 0;
5247 571 st = c->fc->streams[c->fc->nb_streams-1];
5248 571 sc = st->priv_data;
5249
5250 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
5251 // avoids corrupting AVStreams mapped to an earlier tkhd.
5252
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 571 times.
571 if (st->id != -1)
5253 return AVERROR_INVALIDDATA;
5254
5255 571 version = avio_r8(pb);
5256 571 flags = avio_rb24(pb);
5257 571 st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
5258
5259
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 562 times.
571 if (version == 1) {
5260 9 avio_rb64(pb);
5261 9 avio_rb64(pb);
5262 } else {
5263 562 avio_rb32(pb); /* creation time */
5264 562 avio_rb32(pb); /* modification time */
5265 }
5266 571 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
5267 571 sc->id = st->id;
5268 571 avio_rb32(pb); /* reserved */
5269
5270 /* highlevel (considering edits) duration in movie timebase */
5271
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 562 times.
571 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
5272 571 avio_rb32(pb); /* reserved */
5273 571 avio_rb32(pb); /* reserved */
5274
5275 571 avio_rb16(pb); /* layer */
5276 571 avio_rb16(pb); /* alternate group */
5277 571 avio_rb16(pb); /* volume */
5278 571 avio_rb16(pb); /* reserved */
5279
5280 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
5281 // they're kept in fixed point format through all calculations
5282 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
5283 // side data, but the scale factor is not needed to calculate aspect ratio
5284
2/2
✓ Branch 0 taken 1713 times.
✓ Branch 1 taken 571 times.
2284 for (i = 0; i < 3; i++) {
5285 1713 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
5286 1713 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
5287 1713 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
5288 }
5289
5290 571 width = avio_rb32(pb); // 16.16 fixed point track width
5291 571 height = avio_rb32(pb); // 16.16 fixed point track height
5292 571 sc->width = width >> 16;
5293 571 sc->height = height >> 16;
5294
5295 // apply the moov display matrix (after the tkhd one)
5296
2/2
✓ Branch 0 taken 1713 times.
✓ Branch 1 taken 571 times.
2284 for (i = 0; i < 3; i++) {
5297 1713 const int sh[3] = { 16, 16, 30 };
5298
2/2
✓ Branch 0 taken 5139 times.
✓ Branch 1 taken 1713 times.
6852 for (j = 0; j < 3; j++) {
5299
2/2
✓ Branch 0 taken 15417 times.
✓ Branch 1 taken 5139 times.
20556 for (e = 0; e < 3; e++) {
5300 15417 res_display_matrix[i][j] +=
5301 15417 ((int64_t) display_matrix[i][e] *
5302 15417 c->movie_display_matrix[e][j]) >> sh[e];
5303 }
5304 }
5305 }
5306
5307 // save the matrix when it is not the default identity
5308
10/18
✓ Branch 0 taken 562 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 562 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 562 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 562 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 562 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 562 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 562 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 562 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 562 times.
571 if (!IS_MATRIX_IDENT(res_display_matrix)) {
5309 9 av_freep(&sc->display_matrix);
5310 9 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
5311
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (!sc->display_matrix)
5312 return AVERROR(ENOMEM);
5313
5314
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 9 times.
36 for (i = 0; i < 3; i++)
5315
2/2
✓ Branch 0 taken 81 times.
✓ Branch 1 taken 27 times.
108 for (j = 0; j < 3; j++)
5316 81 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
5317 }
5318
5319 // transform the display width/height according to the matrix
5320 // to keep the same scale, use [width height 1<<16]
5321
5/6
✓ Branch 0 taken 296 times.
✓ Branch 1 taken 275 times.
✓ Branch 2 taken 296 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 8 times.
✓ Branch 5 taken 288 times.
571 if (width && height && sc->display_matrix) {
5322 double disp_transform[2];
5323
5324
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 8 times.
24 for (i = 0; i < 2; i++)
5325 16 disp_transform[i] = hypot(sc->display_matrix[0 + i],
5326 16 sc->display_matrix[3 + i]);
5327
5328
2/4
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
8 if (disp_transform[0] > 1 && disp_transform[1] > 1 &&
5329
2/4
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
8 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
5330
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 5 times.
8 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
5331 3 st->sample_aspect_ratio = av_d2q(
5332 3 disp_transform[0] / disp_transform[1],
5333 INT_MAX);
5334 }
5335 571 return 0;
5336 }
5337
5338 388 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5339 {
5340 388 MOVFragment *frag = &c->fragment;
5341 388 MOVTrackExt *trex = NULL;
5342 int flags, track_id, i;
5343 MOVFragmentStreamInfo * frag_stream_info;
5344
5345 388 avio_r8(pb); /* version */
5346 388 flags = avio_rb24(pb);
5347
5348 388 track_id = avio_rb32(pb);
5349
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 388 times.
388 if (!track_id)
5350 return AVERROR_INVALIDDATA;
5351
1/2
✓ Branch 0 taken 394 times.
✗ Branch 1 not taken.
394 for (i = 0; i < c->trex_count; i++)
5352
2/2
✓ Branch 0 taken 388 times.
✓ Branch 1 taken 6 times.
394 if (c->trex_data[i].track_id == track_id) {
5353 388 trex = &c->trex_data[i];
5354 388 break;
5355 }
5356
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 388 times.
388 if (!trex) {
5357 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
5358 return 0;
5359 }
5360 388 c->fragment.found_tfhd = 1;
5361 388 frag->track_id = track_id;
5362 388 set_frag_stream(&c->frag_index, track_id);
5363
5364 776 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
5365
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 388 times.
776 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
5366
2/2
✓ Branch 0 taken 367 times.
✓ Branch 1 taken 21 times.
388 frag->moof_offset : frag->implicit_offset;
5367
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 385 times.
388 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
5368
5369 776 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
5370
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 383 times.
388 avio_rb32(pb) : trex->duration;
5371 776 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
5372
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 382 times.
388 avio_rb32(pb) : trex->size;
5373 776 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
5374
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 365 times.
388 avio_rb32(pb) : trex->flags;
5375 388 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
5376
5377 388 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5378
1/2
✓ Branch 0 taken 388 times.
✗ Branch 1 not taken.
388 if (frag_stream_info) {
5379 388 frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
5380 388 frag_stream_info->stsd_id = frag->stsd_id;
5381 }
5382 388 return 0;
5383 }
5384
5385 2 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5386 {
5387 unsigned i, num;
5388 void *new_tracks;
5389
5390 2 num = atom.size / 4;
5391
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
5392 return AVERROR(ENOMEM);
5393
5394 2 av_free(c->chapter_tracks);
5395 2 c->chapter_tracks = new_tracks;
5396 2 c->nb_chapter_tracks = num;
5397
5398
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
4 for (i = 0; i < num && !pb->eof_reached; i++)
5399 2 c->chapter_tracks[i] = avio_rb32(pb);
5400
5401 2 c->nb_chapter_tracks = i;
5402
5403 2 return 0;
5404 }
5405
5406 15 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5407 {
5408 MOVTrackExt *trex;
5409 int err;
5410
5411
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
5412 return AVERROR_INVALIDDATA;
5413
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 15 times.
15 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
5414 sizeof(*c->trex_data))) < 0) {
5415 c->trex_count = 0;
5416 return err;
5417 }
5418
5419 15 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
5420
5421 15 trex = &c->trex_data[c->trex_count++];
5422 15 avio_r8(pb); /* version */
5423 15 avio_rb24(pb); /* flags */
5424 15 trex->track_id = avio_rb32(pb);
5425 15 trex->stsd_id = avio_rb32(pb);
5426 15 trex->duration = avio_rb32(pb);
5427 15 trex->size = avio_rb32(pb);
5428 15 trex->flags = avio_rb32(pb);
5429 15 return 0;
5430 }
5431
5432 367 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5433 {
5434 367 MOVFragment *frag = &c->fragment;
5435 367 AVStream *st = NULL;
5436 MOVStreamContext *sc;
5437 int version, i;
5438 MOVFragmentStreamInfo * frag_stream_info;
5439 int64_t base_media_decode_time;
5440
5441
1/2
✓ Branch 0 taken 367 times.
✗ Branch 1 not taken.
367 for (i = 0; i < c->fc->nb_streams; i++) {
5442 367 sc = c->fc->streams[i]->priv_data;
5443
1/2
✓ Branch 0 taken 367 times.
✗ Branch 1 not taken.
367 if (sc->id == frag->track_id) {
5444 367 st = c->fc->streams[i];
5445 367 break;
5446 }
5447 }
5448
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 367 times.
367 if (!st) {
5449 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5450 return 0;
5451 }
5452 367 sc = st->priv_data;
5453
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 365 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
367 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5454 return 0;
5455 367 version = avio_r8(pb);
5456 367 avio_rb24(pb); /* flags */
5457
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 367 times.
367 if (version) {
5458 base_media_decode_time = avio_rb64(pb);
5459 } else {
5460 367 base_media_decode_time = avio_rb32(pb);
5461 }
5462
5463 367 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5464
1/2
✓ Branch 0 taken 367 times.
✗ Branch 1 not taken.
367 if (frag_stream_info)
5465 367 frag_stream_info->tfdt_dts = base_media_decode_time;
5466 367 sc->track_end = base_media_decode_time;
5467
5468 367 return 0;
5469 }
5470
5471 388 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5472 {
5473 388 MOVFragment *frag = &c->fragment;
5474 388 AVStream *st = NULL;
5475 388 FFStream *sti = NULL;
5476 MOVStreamContext *sc;
5477 MOVCtts *ctts_data;
5478 uint64_t offset;
5479 388 int64_t dts, pts = AV_NOPTS_VALUE;
5480 388 int data_offset = 0;
5481 388 unsigned entries, first_sample_flags = frag->flags;
5482 int flags, distance, i;
5483 388 int64_t prev_dts = AV_NOPTS_VALUE;
5484 388 int next_frag_index = -1, index_entry_pos;
5485 size_t requested_size;
5486 size_t old_ctts_allocated_size;
5487 AVIndexEntry *new_entries;
5488 MOVFragmentStreamInfo * frag_stream_info;
5489
5490
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 388 times.
388 if (!frag->found_tfhd) {
5491 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
5492 return AVERROR_INVALIDDATA;
5493 }
5494
5495
1/2
✓ Branch 0 taken 394 times.
✗ Branch 1 not taken.
394 for (i = 0; i < c->fc->nb_streams; i++) {
5496 394 sc = c->fc->streams[i]->priv_data;
5497
2/2
✓ Branch 0 taken 388 times.
✓ Branch 1 taken 6 times.
394 if (sc->id == frag->track_id) {
5498 388 st = c->fc->streams[i];
5499 388 sti = ffstream(st);
5500 388 break;
5501 }
5502 }
5503
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 388 times.
388 if (!st) {
5504 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5505 return 0;
5506 }
5507 388 sc = st->priv_data;
5508
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 386 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
388 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5509 return 0;
5510
5511 // Find the next frag_index index that has a valid index_entry for
5512 // the current track_id.
5513 //
5514 // A valid index_entry means the trun for the fragment was read
5515 // and it's samples are in index_entries at the given position.
5516 // New index entries will be inserted before the index_entry found.
5517 388 index_entry_pos = sti->nb_index_entries;
5518
2/2
✓ Branch 0 taken 1621 times.
✓ Branch 1 taken 388 times.
2009 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
5519 1621 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
5520
2/4
✓ Branch 0 taken 1621 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1621 times.
1621 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
5521 next_frag_index = i;
5522 index_entry_pos = frag_stream_info->index_entry;
5523 break;
5524 }
5525 }
5526
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 388 times.
388 av_assert0(index_entry_pos <= sti->nb_index_entries);
5527
5528 388 avio_r8(pb); /* version */
5529 388 flags = avio_rb24(pb);
5530 388 entries = avio_rb32(pb);
5531 388 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
5532
5533
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 388 times.
388 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
5534 return AVERROR_INVALIDDATA;
5535
1/2
✓ Branch 0 taken 388 times.
✗ Branch 1 not taken.
388 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
5536
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 367 times.
388 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
5537
5538 388 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5539
1/2
✓ Branch 0 taken 388 times.
✗ Branch 1 not taken.
388 if (frag_stream_info) {
5540
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 388 times.
388 if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
5541 dts = frag_stream_info->next_trun_dts - sc->time_offset;
5542
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 388 times.
388 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
5543 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
5544 pts = frag_stream_info->first_tfra_pts;
5545 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
5546 ", using it for pts\n", pts);
5547
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 388 times.
388 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
5548 c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
5549 dts = frag_stream_info->first_tfra_pts;
5550 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
5551 ", using it for dts\n", pts);
5552 } else {
5553 388 int has_tfdt = frag_stream_info->tfdt_dts != AV_NOPTS_VALUE;
5554 388 int has_sidx = frag_stream_info->sidx_pts != AV_NOPTS_VALUE;
5555
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 388 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
388 int fallback_tfdt = !c->use_tfdt && !has_sidx && has_tfdt;
5556
4/6
✓ Branch 0 taken 388 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
✓ Branch 3 taken 367 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 21 times.
388 int fallback_sidx = c->use_tfdt && !has_tfdt && has_sidx;
5557
5558
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 388 times.
388 if (fallback_sidx) {
5559 av_log(c->fc, AV_LOG_DEBUG, "use_tfdt set but no tfdt found, using sidx instead\n");
5560 }
5561
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 388 times.
388 if (fallback_tfdt) {
5562 av_log(c->fc, AV_LOG_DEBUG, "use_tfdt not set but no sidx found, using tfdt instead\n");
5563 }
5564
5565
4/6
✓ Branch 0 taken 367 times.
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 367 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 21 times.
388 if (has_tfdt && c->use_tfdt || fallback_tfdt) {
5566 367 dts = frag_stream_info->tfdt_dts - sc->time_offset;
5567 367 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
5568 ", using it for dts\n", dts);
5569
2/6
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 21 times.
21 } else if (has_sidx && !c->use_tfdt || fallback_sidx) {
5570 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
5571 // pts = frag_stream_info->sidx_pts;
5572 dts = frag_stream_info->sidx_pts - sc->time_offset;
5573 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
5574 ", using it for dts\n", frag_stream_info->sidx_pts);
5575 } else {
5576 21 dts = sc->track_end - sc->time_offset;
5577 21 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
5578 ", using it for dts\n", dts);
5579 }
5580 }
5581 } else {
5582 dts = sc->track_end - sc->time_offset;
5583 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
5584 ", using it for dts\n", dts);
5585 }
5586 388 offset = frag->base_data_offset + data_offset;
5587 388 distance = 0;
5588 388 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
5589
5590 // realloc space for new index entries
5591
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 388 times.
388 if ((uint64_t)sti->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
5592 entries = UINT_MAX / sizeof(AVIndexEntry) - sti->nb_index_entries;
5593 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
5594 }
5595
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 388 times.
388 if (entries == 0)
5596 return 0;
5597
5598 388 requested_size = (sti->nb_index_entries + entries) * sizeof(AVIndexEntry);
5599 388 new_entries = av_fast_realloc(sti->index_entries,
5600 &sti->index_entries_allocated_size,
5601 requested_size);
5602
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 388 times.
388 if (!new_entries)
5603 return AVERROR(ENOMEM);
5604 388 sti->index_entries= new_entries;
5605
5606 388 requested_size = (sti->nb_index_entries + entries) * sizeof(*sc->ctts_data);
5607 388 old_ctts_allocated_size = sc->ctts_allocated_size;
5608 388 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
5609 requested_size);
5610
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 388 times.
388 if (!ctts_data)
5611 return AVERROR(ENOMEM);
5612 388 sc->ctts_data = ctts_data;
5613
5614 // In case there were samples without ctts entries, ensure they get
5615 // zero valued entries. This ensures clips which mix boxes with and
5616 // without ctts entries don't pickup uninitialized data.
5617 388 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
5618 388 sc->ctts_allocated_size - old_ctts_allocated_size);
5619
5620
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 388 times.
388 if (index_entry_pos < sti->nb_index_entries) {
5621 // Make hole in index_entries and ctts_data for new samples
5622 memmove(sti->index_entries + index_entry_pos + entries,
5623 sti->index_entries + index_entry_pos,
5624 sizeof(*sti->index_entries) *
5625 (sti->nb_index_entries - index_entry_pos));
5626 memmove(sc->ctts_data + index_entry_pos + entries,
5627 sc->ctts_data + index_entry_pos,
5628 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
5629 if (index_entry_pos < sc->current_sample) {
5630 sc->current_sample += entries;
5631 }
5632 }
5633
5634 388 sti->nb_index_entries += entries;
5635 388 sc->ctts_count = sti->nb_index_entries;
5636
5637 // Record the index_entry position in frag_index of this fragment
5638
1/2
✓ Branch 0 taken 388 times.
✗ Branch 1 not taken.
388 if (frag_stream_info) {
5639 388 frag_stream_info->index_entry = index_entry_pos;
5640
1/2
✓ Branch 0 taken 388 times.
✗ Branch 1 not taken.
388 if (frag_stream_info->index_base < 0)
5641 388 frag_stream_info->index_base = index_entry_pos;
5642 }
5643
5644
2/2
✓ Branch 0 taken 374 times.
✓ Branch 1 taken 14 times.
388 if (index_entry_pos > 0)
5645 374 prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
5646
5647
3/4
✓ Branch 0 taken 6066 times.
✓ Branch 1 taken 388 times.
✓ Branch 2 taken 6066 times.
✗ Branch 3 not taken.
6454 for (i = 0; i < entries && !pb->eof_reached; i++) {
5648 6066 unsigned sample_size = frag->size;
5649
2/2
✓ Branch 0 taken 5678 times.
✓ Branch 1 taken 388 times.
6066 int sample_flags = i ? frag->flags : first_sample_flags;
5650 6066 unsigned sample_duration = frag->duration;
5651 6066 unsigned ctts_duration = 0;
5652 6066 int keyframe = 0;
5653 6066 int index_entry_flags = 0;
5654
5655
2/2
✓ Branch 0 taken 472 times.
✓ Branch 1 taken 5594 times.
6066 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
5656
2/2
✓ Branch 0 taken 6034 times.
✓ Branch 1 taken 32 times.
6066 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
5657
2/2
✓ Branch 0 taken 933 times.
✓ Branch 1 taken 5133 times.
6066 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
5658
2/2
✓ Branch 0 taken 5400 times.
✓ Branch 1 taken 666 times.
6066 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
5659
5660 6066 mov_update_dts_shift(sc, ctts_duration, c->fc);
5661
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6066 times.
6066 if (pts != AV_NOPTS_VALUE) {
5662 dts = pts - sc->dts_shift;
5663 if (flags & MOV_TRUN_SAMPLE_CTS) {
5664 dts -= ctts_duration;
5665 } else {
5666 dts -= sc->time_offset;
5667 }
5668 av_log(c->fc, AV_LOG_DEBUG,
5669 "pts %"PRId64" calculated dts %"PRId64
5670 " sc->dts_shift %d ctts.duration %d"
5671 " sc->time_offset %"PRId64
5672 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
5673 pts, dts,
5674 sc->dts_shift, ctts_duration,
5675 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
5676 pts = AV_NOPTS_VALUE;
5677 }
5678
5679
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 6034 times.
6066 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
5680 32 keyframe = 1;
5681 else
5682 6034 keyframe =
5683 6034 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
5684 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
5685
2/2
✓ Branch 0 taken 400 times.
✓ Branch 1 taken 5666 times.
6066 if (keyframe) {
5686 400 distance = 0;
5687 400 index_entry_flags |= AVINDEX_KEYFRAME;
5688 }
5689 // Fragments can overlap in time. Discard overlapping frames after
5690 // decoding.
5691
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 6042 times.
6066 if (prev_dts >= dts)
5692 24 index_entry_flags |= AVINDEX_DISCARD_FRAME;
5693
5694 6066 sti->index_entries[index_entry_pos].pos = offset;
5695 6066 sti->index_entries[index_entry_pos].timestamp = dts;
5696 6066 sti->index_entries[index_entry_pos].size = sample_size;
5697 6066 sti->index_entries[index_entry_pos].min_distance = distance;
5698 6066 sti->index_entries[index_entry_pos].flags = index_entry_flags;
5699
5700 6066 sc->ctts_data[index_entry_pos].count = 1;
5701 6066 sc->ctts_data[index_entry_pos].duration = ctts_duration;
5702 6066 index_entry_pos++;
5703
5704 6066 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
5705 "size %u, distance %d, keyframe %d\n", st->index,
5706 index_entry_pos, offset, dts, sample_size, distance, keyframe);
5707 6066 distance++;
5708
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6066 times.
6066 if (av_sat_add64(dts, sample_duration) != dts + (uint64_t)sample_duration)
5709 return AVERROR_INVALIDDATA;
5710
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6066 times.
6066 if (!sample_size)
5711 return AVERROR_INVALIDDATA;
5712 6066 dts += sample_duration;
5713 6066 offset += sample_size;
5714 6066 sc->data_size += sample_size;
5715
5716
1/2
✓ Branch 0 taken 6066 times.
✗ Branch 1 not taken.
6066 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
5717
1/2
✓ Branch 0 taken 6066 times.
✗ Branch 1 not taken.
6066 1 <= INT_MAX - sc->nb_frames_for_fps
5718 ) {
5719 6066 sc->duration_for_fps += sample_duration;
5720 6066 sc->nb_frames_for_fps ++;
5721 }
5722 }
5723
1/2
✓ Branch 0 taken 388 times.
✗ Branch 1 not taken.
388 if (frag_stream_info)
5724 388 frag_stream_info->next_trun_dts = dts + sc->time_offset;
5725
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 388 times.
388 if (i < entries) {
5726 // EOF found before reading all entries. Fix the hole this would
5727 // leave in index_entries and ctts_data
5728 int gap = entries - i;
5729 memmove(sti->index_entries + index_entry_pos,
5730 sti->index_entries + index_entry_pos + gap,
5731 sizeof(*sti->index_entries) *
5732 (sti->nb_index_entries - (index_entry_pos + gap)));
5733 memmove(sc->ctts_data + index_entry_pos,
5734 sc->ctts_data + index_entry_pos + gap,
5735 sizeof(*sc->ctts_data) *
5736 (sc->ctts_count - (index_entry_pos + gap)));
5737
5738 sti->nb_index_entries -= gap;
5739 sc->ctts_count -= gap;
5740 if (index_entry_pos < sc->current_sample) {
5741 sc->current_sample -= gap;
5742 }
5743 entries = i;
5744 }
5745
5746 // The end of this new fragment may overlap in time with the start
5747 // of the next fragment in index_entries. Mark the samples in the next
5748 // fragment that overlap with AVINDEX_DISCARD_FRAME
5749 388 prev_dts = AV_NOPTS_VALUE;
5750
1/2
✓ Branch 0 taken 388 times.
✗ Branch 1 not taken.
388 if (index_entry_pos > 0)
5751 388 prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
5752
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 388 times.
388 for (int i = index_entry_pos; i < sti->nb_index_entries; i++) {
5753 if (prev_dts < sti->index_entries[i].timestamp)
5754 break;
5755 sti->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
5756 }
5757
5758 // If a hole was created to insert the new index_entries into,
5759 // the index_entry recorded for all subsequent moof must
5760 // be incremented by the number of entries inserted.
5761 388 fix_frag_index_entries(&c->frag_index, next_frag_index,
5762 388 frag->track_id, entries);
5763
5764
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 388 times.
388 if (pb->eof_reached) {
5765 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
5766 return AVERROR_EOF;
5767 }
5768
5769 388 frag->implicit_offset = offset;
5770
5771 388 sc->track_end = dts + sc->time_offset;
5772
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 379 times.
388 if (st->duration < sc->track_end)
5773 9 st->duration = sc->track_end;
5774
5775 388 return 0;
5776 }
5777
5778 43 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5779 {
5780 43 int64_t stream_size = avio_size(pb);
5781 43 int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
5782 uint8_t version, is_complete;
5783 int64_t offadd;
5784 unsigned i, j, track_id, item_count;
5785 43 AVStream *st = NULL;
5786 43 AVStream *ref_st = NULL;
5787 43 MOVStreamContext *sc, *ref_sc = NULL;
5788 AVRational timescale;
5789
5790 43 version = avio_r8(pb);
5791
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 43 times.
43 if (version > 1) {
5792 avpriv_request_sample(c->fc, "sidx version %u", version);
5793 return 0;
5794 }
5795
5796 43 avio_rb24(pb); // flags
5797
5798 43 track_id = avio_rb32(pb); // Reference ID
5799
1/2
✓ Branch 0 taken 43 times.
✗ Branch 1 not taken.
43 for (i = 0; i < c->fc->nb_streams; i++) {
5800 43 sc = c->fc->streams[i]->priv_data;
5801
1/2
✓ Branch 0 taken 43 times.
✗ Branch 1 not taken.
43 if (sc->id == track_id) {
5802 43 st = c->fc->streams[i];
5803 43 break;
5804 }
5805 }
5806
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 43 times.
43 if (!st) {
5807 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5808 return 0;
5809 }
5810
5811 43 sc = st->priv_data;
5812
5813 43 timescale = av_make_q(1, avio_rb32(pb));
5814
5815
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 43 times.
43 if (timescale.den <= 0) {
5816 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5817 return AVERROR_INVALIDDATA;
5818 }
5819
5820
1/2
✓ Branch 0 taken 43 times.
✗ Branch 1 not taken.
43 if (version == 0) {
5821 43 pts = avio_rb32(pb);
5822 43 offadd= avio_rb32(pb);
5823 } else {
5824 pts = avio_rb64(pb);
5825 offadd= avio_rb64(pb);
5826 }
5827
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 43 times.
43 if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
5828 return AVERROR_INVALIDDATA;
5829
5830 43 offset += (uint64_t)offadd;
5831
5832 43 avio_rb16(pb); // reserved
5833
5834 43 item_count = avio_rb16(pb);
5835
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 43 times.
43 if (item_count == 0)
5836 return AVERROR_INVALIDDATA;
5837
5838
2/2
✓ Branch 0 taken 368 times.
✓ Branch 1 taken 43 times.
411 for (i = 0; i < item_count; i++) {
5839 int index;
5840 MOVFragmentStreamInfo * frag_stream_info;
5841 368 uint32_t size = avio_rb32(pb);
5842 368 uint32_t duration = avio_rb32(pb);
5843
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 368 times.
368 if (size & 0x80000000) {
5844 avpriv_request_sample(c->fc, "sidx reference_type 1");
5845 return AVERROR_PATCHWELCOME;
5846 }
5847 368 avio_rb32(pb); // sap_flags
5848 368 timestamp = av_rescale_q(pts, timescale, st->time_base);
5849
5850 368 index = update_frag_index(c, offset);
5851 368 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5852
1/2
✓ Branch 0 taken 368 times.
✗ Branch 1 not taken.
368 if (frag_stream_info)
5853 368 frag_stream_info->sidx_pts = timestamp;
5854
5855
1/2
✓ Branch 1 taken 368 times.
✗ Branch 2 not taken.
368 if (av_sat_add64(offset, size) != offset + (uint64_t)size ||
5856
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 368 times.
368 av_sat_add64(pts, duration) != pts + (uint64_t)duration
5857 )
5858 return AVERROR_INVALIDDATA;
5859 368 offset += size;
5860 368 pts += duration;
5861 }
5862
5863 43 st->duration = sc->track_end = pts;
5864
5865 43 sc->has_sidx = 1;
5866
5867 // See if the remaining bytes are just an mfra which we can ignore.
5868 43 is_complete = offset == stream_size;
5869
4/6
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 38 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 38 times.
✗ Branch 5 not taken.
43 if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL) && stream_size > 0 ) {
5870 int64_t ret;
5871 38 int64_t original_pos = avio_tell(pb);
5872
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 35 times.
38 if (!c->have_read_mfra_size) {
5873
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
5874 return ret;
5875 3 c->mfra_size = avio_rb32(pb);
5876 3 c->have_read_mfra_size = 1;
5877
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
5878 return ret;
5879 }
5880
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 if (offset == stream_size - c->mfra_size)
5881 is_complete = 1;
5882 }
5883
5884
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 38 times.
43 if (is_complete) {
5885 // Find first entry in fragment index that came from an sidx.
5886 // This will pretty much always be the first entry.
5887
2/2
✓ Branch 0 taken 368 times.
✓ Branch 1 taken 5 times.
373 for (i = 0; i < c->frag_index.nb_items; i++) {
5888 368 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5889
3/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 363 times.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
368 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5890 MOVFragmentStreamInfo * si;
5891 5 si = &item->stream_info[j];
5892
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if (si->sidx_pts != AV_NOPTS_VALUE) {
5893 5 ref_st = c->fc->streams[j];
5894 5 ref_sc = ref_st->priv_data;
5895 5 break;
5896 }
5897 }
5898 }
5899
3/4
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 5 times.
10 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5900 5 st = c->fc->streams[i];
5901 5 sc = st->priv_data;
5902
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (!sc->has_sidx) {
5903 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5904 }
5905 }
5906
5907 5 c->frag_index.complete = 1;
5908 }
5909
5910 43 return 0;
5911 }
5912
5913 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5914 /* like the files created with Adobe Premiere 5.0, for samples see */
5915 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5916 258 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5917 {
5918 int err;
5919
5920
1/2
✓ Branch 0 taken 258 times.
✗ Branch 1 not taken.
258 if (atom.size < 8)
5921 258 return 0; /* continue */
5922 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5923 avio_skip(pb, atom.size - 4);
5924 return 0;
5925 }
5926 atom.type = avio_rl32(pb);
5927 atom.size -= 8;
5928 if (atom.type != MKTAG('m','d','a','t')) {
5929 avio_skip(pb, atom.size);
5930 return 0;
5931 }
5932 err = mov_read_mdat(c, pb, atom);
5933 return err;
5934 }
5935
5936 3 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5937 {
5938 #if CONFIG_ZLIB
5939 FFIOContext ctx;
5940 uint8_t *cmov_data;
5941 uint8_t *moov_data; /* uncompressed data */
5942 long cmov_len, moov_len;
5943 3 int ret = -1;
5944
5945 3 avio_rb32(pb); /* dcom atom */
5946
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5947 return AVERROR_INVALIDDATA;
5948
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5949 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5950 return AVERROR_INVALIDDATA;
5951 }
5952 3 avio_rb32(pb); /* cmvd atom */
5953
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5954 return AVERROR_INVALIDDATA;
5955 3 moov_len = avio_rb32(pb); /* uncompressed size */
5956 3 cmov_len = atom.size - 6 * 4;
5957
5958 3 cmov_data = av_malloc(cmov_len);
5959
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!cmov_data)
5960 return AVERROR(ENOMEM);
5961 3 moov_data = av_malloc(moov_len);
5962
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!moov_data) {
5963 av_free(cmov_data);
5964 return AVERROR(ENOMEM);
5965 }
5966 3 ret = ffio_read_size(pb, cmov_data, cmov_len);
5967
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (ret < 0)
5968 goto free_and_return;
5969
5970 3 ret = AVERROR_INVALIDDATA;
5971
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5972 goto free_and_return;
5973 3 ffio_init_read_context(&ctx, moov_data, moov_len);
5974 3 ctx.pub.seekable = AVIO_SEEKABLE_NORMAL;
5975 3 atom.type = MKTAG('m','o','o','v');
5976 3 atom.size = moov_len;
5977 3 ret = mov_read_default(c, &ctx.pub, atom);
5978 3 free_and_return:
5979 3 av_free(moov_data);
5980 3 av_free(cmov_data);
5981 3 return ret;
5982 #else
5983 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5984 return AVERROR(ENOSYS);
5985 #endif
5986 }
5987
5988 /* edit list atom */
5989 418 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5990 {
5991 MOVStreamContext *sc;
5992 int i, edit_count, version;
5993 int64_t elst_entry_size;
5994
5995
2/4
✓ Branch 0 taken 418 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 418 times.
418 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5996 return 0;
5997 418 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5998
5999 418 version = avio_r8(pb); /* version */
6000 418 avio_rb24(pb); /* flags */
6001 418 edit_count = avio_rb32(pb); /* entries */
6002 418 atom.size -= 8;
6003
6004
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 418 times.
418 elst_entry_size = version == 1 ? 20 : 12;
6005
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 417 times.
418 if (atom.size != edit_count * elst_entry_size) {
6006
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6007 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
6008 edit_count, atom.size + 8);
6009 return AVERROR_INVALIDDATA;
6010 } else {
6011 1 edit_count = atom.size / elst_entry_size;
6012
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (edit_count * elst_entry_size != atom.size) {
6013 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
6014 }
6015 }
6016 }
6017
6018
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 418 times.
418 if (!edit_count)
6019 return 0;
6020
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 418 times.
418 if (sc->elst_data)
6021 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
6022 418 av_free(sc->elst_data);
6023 418 sc->elst_count = 0;
6024 418 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
6025
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 418 times.
418 if (!sc->elst_data)
6026 return AVERROR(ENOMEM);
6027
6028 418 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
6029
4/6
✓ Branch 0 taken 445 times.
✓ Branch 1 taken 418 times.
✓ Branch 2 taken 445 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 445 times.
✗ Branch 5 not taken.
863 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
6030 445 MOVElst *e = &sc->elst_data[i];
6031
6032
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 445 times.
445 if (version == 1) {
6033 e->duration = avio_rb64(pb);
6034 e->time = avio_rb64(pb);
6035 atom.size -= 16;
6036 } else {
6037 445 e->duration = avio_rb32(pb); /* segment duration */
6038 445 e->time = (int32_t)avio_rb32(pb); /* media time */
6039 445 atom.size -= 8;
6040 }
6041 445 e->rate = avio_rb32(pb) / 65536.0;
6042 445 atom.size -= 4;
6043 445 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
6044 445 e->duration, e->time, e->rate);
6045
6046
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 441 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
445 if (e->time < 0 && e->time != -1 &&
6047 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6048 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
6049 c->fc->nb_streams-1, i, e->time);
6050 return AVERROR_INVALIDDATA;
6051 }
6052 }
6053 418 sc->elst_count = i;
6054
6055 418 return 0;
6056 }
6057
6058 18 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6059 {
6060 MOVStreamContext *sc;
6061
6062
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if (c->fc->nb_streams < 1)
6063 return AVERROR_INVALIDDATA;
6064 18 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6065 18 sc->timecode_track = avio_rb32(pb);
6066 18 return 0;
6067 }
6068
6069 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6070 {
6071 AVStream *st;
6072 int version, color_range, color_primaries, color_trc, color_space;
6073
6074 if (c->fc->nb_streams < 1)
6075 return 0;
6076 st = c->fc->streams[c->fc->nb_streams - 1];
6077
6078 if (atom.size < 5) {
6079 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
6080 return AVERROR_INVALIDDATA;
6081 }
6082
6083 version = avio_r8(pb);
6084 if (version != 1) {
6085 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
6086 return 0;
6087 }
6088 avio_skip(pb, 3); /* flags */
6089
6090 avio_skip(pb, 2); /* profile + level */
6091 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
6092 color_primaries = avio_r8(pb);
6093 color_trc = avio_r8(pb);
6094 color_space = avio_r8(pb);
6095 if (avio_rb16(pb)) /* codecIntializationDataSize */
6096 return AVERROR_INVALIDDATA;
6097
6098 if (!av_color_primaries_name(color_primaries))
6099 color_primaries = AVCOL_PRI_UNSPECIFIED;
6100 if (!av_color_transfer_name(color_trc))
6101 color_trc = AVCOL_TRC_UNSPECIFIED;
6102 if (!av_color_space_name(color_space))
6103 color_space = AVCOL_SPC_UNSPECIFIED;
6104
6105 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
6106 st->codecpar->color_primaries = color_primaries;
6107 st->codecpar->color_trc = color_trc;
6108 st->codecpar->color_space = color_space;
6109
6110 return 0;
6111 }
6112
6113 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6114 {
6115 MOVStreamContext *sc;
6116 int i, version;
6117
6118 if (c->fc->nb_streams < 1)
6119 return AVERROR_INVALIDDATA;
6120
6121 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6122
6123 if (atom.size < 5) {
6124 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
6125 return AVERROR_INVALIDDATA;
6126 }
6127
6128 version = avio_r8(pb);
6129 if (version) {
6130 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
6131 return 0;
6132 }
6133 if (sc->mastering) {
6134 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Metadata\n");
6135 return 0;
6136 }
6137
6138 avio_skip(pb, 3); /* flags */
6139
6140 sc->mastering = av_mastering_display_metadata_alloc();
6141 if (!sc->mastering)
6142 return AVERROR(ENOMEM);
6143
6144 for (i = 0; i < 3; i++) {
6145 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
6146 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
6147 }
6148 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
6149 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
6150
6151 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
6152 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
6153
6154 sc->mastering->has_primaries = 1;
6155 sc->mastering->has_luminance = 1;
6156
6157 return 0;
6158 }
6159
6160 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6161 {
6162 MOVStreamContext *sc;
6163 const int mapping[3] = {1, 2, 0};
6164 const int chroma_den = 50000;
6165 const int luma_den = 10000;
6166 int i;
6167
6168 if (c->fc->nb_streams < 1)
6169 return AVERROR_INVALIDDATA;
6170
6171 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6172
6173 if (atom.size < 24) {
6174 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
6175 return AVERROR_INVALIDDATA;
6176 }
6177
6178 if (sc->mastering) {
6179 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Color Volume\n");
6180 return 0;
6181 }
6182
6183 sc->mastering = av_mastering_display_metadata_alloc();
6184 if (!sc->mastering)
6185 return AVERROR(ENOMEM);
6186
6187 for (i = 0; i < 3; i++) {
6188 const int j = mapping[i];
6189 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
6190 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
6191 }
6192 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
6193 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
6194
6195 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
6196 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
6197
6198 sc->mastering->has_luminance = 1;
6199 sc->mastering->has_primaries = 1;
6200
6201 return 0;
6202 }
6203
6204 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6205 {
6206 MOVStreamContext *sc;
6207 int version;
6208
6209 if (c->fc->nb_streams < 1)
6210 return AVERROR_INVALIDDATA;
6211
6212 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6213
6214 if (atom.size < 5) {
6215 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
6216 return AVERROR_INVALIDDATA;
6217 }
6218
6219 version = avio_r8(pb);
6220 if (version) {
6221 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
6222 return 0;
6223 }
6224 avio_skip(pb, 3); /* flags */
6225
6226 if (sc->coll){
6227 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate COLL\n");
6228 return 0;
6229 }
6230
6231 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
6232 if (!sc->coll)
6233 return AVERROR(ENOMEM);
6234
6235 sc->coll->MaxCLL = avio_rb16(pb);
6236 sc->coll->MaxFALL = avio_rb16(pb);
6237
6238 return 0;
6239 }
6240
6241 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6242 {
6243 MOVStreamContext *sc;
6244
6245 if (c->fc->nb_streams < 1)
6246 return AVERROR_INVALIDDATA;
6247
6248 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6249
6250 if (atom.size < 4) {
6251 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
6252 return AVERROR_INVALIDDATA;
6253 }
6254
6255 if (sc->coll){
6256 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate CLLI/COLL\n");
6257 return 0;
6258 }
6259
6260 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
6261 if (!sc->coll)
6262 return AVERROR(ENOMEM);
6263
6264 sc->coll->MaxCLL = avio_rb16(pb);
6265 sc->coll->MaxFALL = avio_rb16(pb);
6266
6267 return 0;
6268 }
6269
6270 4 static int mov_read_amve(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6271 {
6272 MOVStreamContext *sc;
6273 4 const int illuminance_den = 10000;
6274 4 const int ambient_den = 50000;
6275
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (c->fc->nb_streams < 1)
6276 return AVERROR_INVALIDDATA;
6277 4 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6278
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (atom.size < 6) {
6279 av_log(c->fc, AV_LOG_ERROR, "Empty Ambient Viewing Environment Info box\n");
6280 return AVERROR_INVALIDDATA;
6281 }
6282
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (sc->ambient){
6283 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate AMVE\n");
6284 return 0;
6285 }
6286 4 sc->ambient = av_ambient_viewing_environment_alloc(&sc->ambient_size);
6287
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!sc->ambient)
6288 return AVERROR(ENOMEM);
6289 4 sc->ambient->ambient_illuminance = av_make_q(avio_rb32(pb), illuminance_den);
6290 4 sc->ambient->ambient_light_x = av_make_q(avio_rb16(pb), ambient_den);
6291 4 sc->ambient->ambient_light_y = av_make_q(avio_rb16(pb), ambient_den);
6292 4 return 0;
6293 }
6294
6295 1 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6296 {
6297 AVStream *st;
6298 MOVStreamContext *sc;
6299 enum AVStereo3DType type;
6300 int mode;
6301
6302
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (c->fc->nb_streams < 1)
6303 return 0;
6304
6305 1 st = c->fc->streams[c->fc->nb_streams - 1];
6306 1 sc = st->priv_data;
6307
6308
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (atom.size < 5) {
6309 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
6310 return AVERROR_INVALIDDATA;
6311 }
6312
6313
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (sc->stereo3d)
6314 return AVERROR_INVALIDDATA;
6315
6316 1 avio_skip(pb, 4); /* version + flags */
6317
6318 1 mode = avio_r8(pb);
6319
1/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 switch (mode) {
6320 1 case 0:
6321 1 type = AV_STEREO3D_2D;
6322 1 break;
6323 case 1:
6324 type = AV_STEREO3D_TOPBOTTOM;
6325 break;
6326 case 2:
6327 type = AV_STEREO3D_SIDEBYSIDE;
6328 break;
6329 default:
6330 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
6331 return 0;
6332 }
6333
6334 1 sc->stereo3d = av_stereo3d_alloc();
6335
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!sc->stereo3d)
6336 return AVERROR(ENOMEM);
6337
6338 1 sc->stereo3d->type = type;
6339 1 return 0;
6340 }
6341
6342 1 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6343 {
6344 AVStream *st;
6345 MOVStreamContext *sc;
6346 int size, version, layout;
6347 int32_t yaw, pitch, roll;
6348 1 uint32_t l = 0, t = 0, r = 0, b = 0;
6349 1 uint32_t tag, padding = 0;
6350 enum AVSphericalProjection projection;
6351
6352
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (c->fc->nb_streams < 1)
6353 return 0;
6354
6355 1 st = c->fc->streams[c->fc->nb_streams - 1];
6356 1 sc = st->priv_data;
6357
6358
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (atom.size < 8) {
6359 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
6360 return AVERROR_INVALIDDATA;
6361 }
6362
6363 1 size = avio_rb32(pb);
6364
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if (size <= 12 || size > atom.size)
6365 return AVERROR_INVALIDDATA;
6366
6367 1 tag = avio_rl32(pb);
6368
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (tag != MKTAG('s','v','h','d')) {
6369 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
6370 return 0;
6371 }
6372 1 version = avio_r8(pb);
6373
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (version != 0) {
6374 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6375 version);
6376 return 0;
6377 }
6378 1 avio_skip(pb, 3); /* flags */
6379 1 avio_skip(pb, size - 12); /* metadata_source */
6380
6381 1 size = avio_rb32(pb);
6382
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (size > atom.size)
6383 return AVERROR_INVALIDDATA;
6384
6385 1 tag = avio_rl32(pb);
6386
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (tag != MKTAG('p','r','o','j')) {
6387 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
6388 return 0;
6389 }
6390
6391 1 size = avio_rb32(pb);
6392
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (size > atom.size)
6393 return AVERROR_INVALIDDATA;
6394
6395 1 tag = avio_rl32(pb);
6396
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (tag != MKTAG('p','r','h','d')) {
6397 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
6398 return 0;
6399 }
6400 1 version = avio_r8(pb);
6401
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (version != 0) {
6402 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6403 version);
6404 return 0;
6405 }
6406 1 avio_skip(pb, 3); /* flags */
6407
6408 /* 16.16 fixed point */
6409 1 yaw = avio_rb32(pb);
6410 1 pitch = avio_rb32(pb);
6411 1 roll = avio_rb32(pb);
6412
6413 1 size = avio_rb32(pb);
6414
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (size > atom.size)
6415 return AVERROR_INVALIDDATA;
6416
6417 1 tag = avio_rl32(pb);
6418 1 version = avio_r8(pb);
6419
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (version != 0) {
6420 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6421 version);
6422 return 0;
6423 }
6424 1 avio_skip(pb, 3); /* flags */
6425
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 switch (tag) {
6426 case MKTAG('c','b','m','p'):
6427 layout = avio_rb32(pb);
6428 if (layout) {
6429 av_log(c->fc, AV_LOG_WARNING,
6430 "Unsupported cubemap layout %d\n", layout);
6431 return 0;
6432 }
6433 projection = AV_SPHERICAL_CUBEMAP;
6434 padding = avio_rb32(pb);
6435 break;
6436 1 case MKTAG('e','q','u','i'):
6437 1 t = avio_rb32(pb);
6438 1 b = avio_rb32(pb);
6439 1 l = avio_rb32(pb);
6440 1 r = avio_rb32(pb);
6441
6442
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
6443 av_log(c->fc, AV_LOG_ERROR,
6444 "Invalid bounding rectangle coordinates "
6445 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
6446 return AVERROR_INVALIDDATA;
6447 }
6448
6449
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
1 if (l || t || r || b)
6450 1 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
6451 else
6452 projection = AV_SPHERICAL_EQUIRECTANGULAR;
6453 1 break;
6454 default:
6455 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
6456 return 0;
6457 }
6458
6459 1 sc->spherical = av_spherical_alloc(&sc->spherical_size);
6460
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!sc->spherical)
6461 return AVERROR(ENOMEM);
6462
6463 1 sc->spherical->projection = projection;
6464
6465 1 sc->spherical->yaw = yaw;
6466 1 sc->spherical->pitch = pitch;
6467 1 sc->spherical->roll = roll;
6468
6469 1 sc->spherical->padding = padding;
6470
6471 1 sc->spherical->bound_left = l;
6472 1 sc->spherical->bound_top = t;
6473 1 sc->spherical->bound_right = r;
6474 1 sc->spherical->bound_bottom = b;
6475
6476 1 return 0;
6477 }
6478
6479 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
6480 {
6481 int ret = 0;
6482 uint8_t *buffer = av_malloc(len + 1);
6483 const char *val;
6484
6485 if (!buffer)
6486 return AVERROR(ENOMEM);
6487 buffer[len] = '\0';
6488
6489 ret = ffio_read_size(pb, buffer, len);
6490 if (ret < 0)
6491 goto out;
6492
6493 /* Check for mandatory keys and values, try to support XML as best-effort */
6494 if (!sc->spherical &&
6495 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
6496 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
6497 av_stristr(val, "true") &&
6498 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
6499 av_stristr(val, "true") &&
6500 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
6501 av_stristr(val, "equirectangular")) {
6502 sc->spherical = av_spherical_alloc(&sc->spherical_size);
6503 if (!sc->spherical)
6504 goto out;
6505
6506 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
6507
6508 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
6509 enum AVStereo3DType mode;
6510
6511 if (av_stristr(buffer, "left-right"))
6512 mode = AV_STEREO3D_SIDEBYSIDE;
6513 else if (av_stristr(buffer, "top-bottom"))
6514 mode = AV_STEREO3D_TOPBOTTOM;
6515 else
6516 mode = AV_STEREO3D_2D;
6517
6518 sc->stereo3d = av_stereo3d_alloc();
6519 if (!sc->stereo3d)
6520 goto out;
6521
6522 sc->stereo3d->type = mode;
6523 }
6524
6525 /* orientation */
6526 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
6527 if (val)
6528 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
6529 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
6530 if (val)
6531 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
6532 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
6533 if (val)
6534 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
6535 }
6536
6537 out:
6538 av_free(buffer);
6539 return ret;
6540 }
6541
6542 15 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6543 {
6544 AVStream *st;
6545 MOVStreamContext *sc;
6546 int64_t ret;
6547 AVUUID uuid;
6548 static const AVUUID uuid_isml_manifest = {
6549 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
6550 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
6551 };
6552 static const AVUUID uuid_xmp = {
6553 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
6554 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
6555 };
6556 static const AVUUID uuid_spherical = {
6557 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
6558 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
6559 };
6560
6561
2/4
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 15 times.
15 if (atom.size < AV_UUID_LEN || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
6562 return AVERROR_INVALIDDATA;
6563
6564
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 14 times.
15 if (c->fc->nb_streams < 1)
6565 1 return 0;
6566 14 st = c->fc->streams[c->fc->nb_streams - 1];
6567 14 sc = st->priv_data;
6568
6569 14 ret = ffio_read_size(pb, uuid, AV_UUID_LEN);
6570
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (ret < 0)
6571 return ret;
6572
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
14 if (av_uuid_equal(uuid, uuid_isml_manifest)) {
6573 uint8_t *buffer, *ptr;
6574 char *endptr;
6575 size_t len = atom.size - AV_UUID_LEN;
6576
6577 if (len < 4) {
6578 return AVERROR_INVALIDDATA;
6579 }
6580 ret = avio_skip(pb, 4); // zeroes
6581 len -= 4;
6582
6583 buffer = av_mallocz(len + 1);
6584 if (!buffer) {
6585 return AVERROR(ENOMEM);
6586 }
6587 ret = ffio_read_size(pb, buffer, len);
6588 if (ret < 0) {
6589 av_free(buffer);
6590 return ret;
6591 }
6592
6593 ptr = buffer;
6594 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
6595 ptr += sizeof("systemBitrate=\"") - 1;
6596 c->bitrates_count++;
6597 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
6598 if (!c->bitrates) {
6599 c->bitrates_count = 0;
6600 av_free(buffer);
6601 return AVERROR(ENOMEM);
6602 }
6603 errno = 0;
6604 ret = strtol(ptr, &endptr, 10);
6605 if (ret < 0 || errno || *endptr != '"') {
6606 c->bitrates[c->bitrates_count - 1] = 0;
6607 } else {
6608 c->bitrates[c->bitrates_count - 1] = ret;
6609 }
6610 }
6611
6612 av_free(buffer);
6613
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
14 } else if (av_uuid_equal(uuid, uuid_xmp)) {
6614 uint8_t *buffer;
6615 size_t len = atom.size - AV_UUID_LEN;
6616 if (c->export_xmp) {
6617 buffer = av_mallocz(len + 1);
6618 if (!buffer) {
6619 return AVERROR(ENOMEM);
6620 }
6621 ret = ffio_read_size(pb, buffer, len);
6622 if (ret < 0) {
6623 av_free(buffer);
6624 return ret;
6625 }
6626 buffer[len] = '\0';
6627 av_dict_set(&c->fc->metadata, "xmp",
6628 buffer, AV_DICT_DONT_STRDUP_VAL);
6629 } else {
6630 // skip all uuid atom, which makes it fast for long uuid-xmp file
6631 ret = avio_skip(pb, len);
6632 if (ret < 0)
6633 return ret;
6634 }
6635
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
14 } else if (av_uuid_equal(uuid, uuid_spherical)) {
6636 size_t len = atom.size - AV_UUID_LEN;
6637 ret = mov_parse_uuid_spherical(sc, pb, len);
6638 if (ret < 0)
6639 return ret;
6640 if (!sc->spherical)
6641 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
6642 }
6643
6644 14 return 0;
6645 }
6646
6647 183 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6648 {
6649 int ret;
6650 uint8_t content[16];
6651
6652
2/2
✓ Branch 0 taken 87 times.
✓ Branch 1 taken 96 times.
183 if (atom.size < 8)
6653 87 return 0;
6654
6655 96 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
6656
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96 times.
96 if (ret < 0)
6657 return ret;
6658
6659
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 55 times.
96 if ( !c->found_moov
6660
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 23 times.
41 && !c->found_mdat
6661
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 && !memcmp(content, "Anevia\x1A\x1A", 8)
6662 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
6663 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
6664 }
6665
6666 96 return 0;
6667 }
6668
6669 35 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6670 {
6671 35 uint32_t format = avio_rl32(pb);
6672 MOVStreamContext *sc;
6673 enum AVCodecID id;
6674 AVStream *st;
6675
6676
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35 times.
35 if (c->fc->nb_streams < 1)
6677 return 0;
6678 35 st = c->fc->streams[c->fc->nb_streams - 1];
6679 35 sc = st->priv_data;
6680
6681
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 32 times.
35 switch (sc->format)
6682 {
6683 3 case MKTAG('e','n','c','v'): // encrypted video
6684 case MKTAG('e','n','c','a'): // encrypted audio
6685 3 id = mov_codec_id(st, format);
6686
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
6687 st->codecpar->codec_id != id) {
6688 av_log(c->fc, AV_LOG_WARNING,
6689 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
6690 (char*)&format, st->codecpar->codec_id);
6691 break;
6692 }
6693
6694 3 st->codecpar->codec_id = id;
6695 3 sc->format = format;
6696 3 break;
6697
6698 32 default:
6699
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
32 if (format != sc->format) {
6700 av_log(c->fc, AV_LOG_WARNING,
6701 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
6702 (char*)&format, (char*)&sc->format);
6703 }
6704 32 break;
6705 }
6706
6707 35 return 0;
6708 }
6709
6710 /**
6711 * Gets the current encryption info and associated current stream context. If
6712 * we are parsing a track fragment, this will return the specific encryption
6713 * info for this fragment; otherwise this will return the global encryption
6714 * info for the current stream.
6715 */
6716 6 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
6717 {
6718 MOVFragmentStreamInfo *frag_stream_info;
6719 AVStream *st;
6720 int i;
6721
6722 6 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
6723
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (frag_stream_info) {
6724
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 for (i = 0; i < c->fc->nb_streams; i++) {
6725 3 *sc = c->fc->streams[i]->priv_data;
6726
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if ((*sc)->id == frag_stream_info->id) {
6727 3 st = c->fc->streams[i];
6728 3 break;
6729 }
6730 }
6731
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (i == c->fc->nb_streams)
6732 return 0;
6733 3 *sc = st->priv_data;
6734
6735
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 if (!frag_stream_info->encryption_index) {
6736 // If this stream isn't encrypted, don't create the index.
6737
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!(*sc)->cenc.default_encrypted_sample)
6738 return 0;
6739 1 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
6740
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!frag_stream_info->encryption_index)
6741 return AVERROR(ENOMEM);
6742 }
6743 3 *encryption_index = frag_stream_info->encryption_index;
6744 3 return 1;
6745 } else {
6746 // No current track fragment, using stream level encryption info.
6747
6748
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (c->fc->nb_streams < 1)
6749 return 0;
6750 3 st = c->fc->streams[c->fc->nb_streams - 1];
6751 3 *sc = st->priv_data;
6752
6753
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!(*sc)->cenc.encryption_index) {
6754 // If this stream isn't encrypted, don't create the index.
6755 if (!(*sc)->cenc.default_encrypted_sample)
6756 return 0;
6757 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
6758 if (!(*sc)->cenc.encryption_index)
6759 return AVERROR(ENOMEM);
6760 }
6761
6762 3 *encryption_index = (*sc)->cenc.encryption_index;
6763 3 return 1;
6764 }
6765 }
6766
6767 72 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
6768 {
6769 int i, ret;
6770 unsigned int subsample_count;
6771 AVSubsampleEncryptionInfo *subsamples;
6772
6773
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
72 if (!sc->cenc.default_encrypted_sample) {
6774 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
6775 return AVERROR_INVALIDDATA;
6776 }
6777
6778
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
72 if (sc->cenc.per_sample_iv_size || use_subsamples) {
6779 72 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
6780
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
72 if (!*sample)
6781 return AVERROR(ENOMEM);
6782 } else
6783 *sample = NULL;
6784
6785
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 if (sc->cenc.per_sample_iv_size != 0) {
6786
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 72 times.
72 if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
6787 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
6788 av_encryption_info_free(*sample);
6789 *sample = NULL;
6790 return ret;
6791 }
6792 }
6793
6794
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 if (use_subsamples) {
6795 72 subsample_count = avio_rb16(pb);
6796 72 av_free((*sample)->subsamples);
6797 72 (*sample)->subsamples = av_calloc(subsample_count, sizeof(*subsamples));
6798
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
72 if (!(*sample)->subsamples) {
6799 av_encryption_info_free(*sample);
6800 *sample = NULL;
6801 return AVERROR(ENOMEM);
6802 }
6803
6804
3/4
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 72 times.
✗ Branch 3 not taken.
144 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
6805 72 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
6806 72 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
6807 }
6808
6809
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
72 if (pb->eof_reached) {
6810 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
6811 av_encryption_info_free(*sample);
6812 *sample = NULL;
6813 return AVERROR_INVALIDDATA;
6814 }
6815 72 (*sample)->subsample_count = subsample_count;
6816 }
6817
6818 72 return 0;
6819 }
6820
6821 2 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6822 {
6823 AVEncryptionInfo **encrypted_samples;
6824 MOVEncryptionIndex *encryption_index;
6825 MOVStreamContext *sc;
6826 int use_subsamples, ret;
6827 2 unsigned int sample_count, i, alloc_size = 0;
6828
6829 2 ret = get_current_encryption_info(c, &encryption_index, &sc);
6830
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (ret != 1)
6831 return ret;
6832
6833
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (encryption_index->nb_encrypted_samples) {
6834 // This can happen if we have both saio/saiz and senc atoms.
6835 1 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6836 1 return 0;
6837 }
6838
6839 1 avio_r8(pb); /* version */
6840 1 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6841
6842 1 sample_count = avio_rb32(pb);
6843
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6844 return AVERROR(ENOMEM);
6845
6846
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 1 times.
49 for (i = 0; i < sample_count; i++) {
6847 48 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6848 48 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6849 min_samples * sizeof(*encrypted_samples));
6850
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 if (encrypted_samples) {
6851 48 encryption_index->encrypted_samples = encrypted_samples;
6852
6853 48 ret = mov_read_sample_encryption_info(
6854 48 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6855 } else {
6856 ret = AVERROR(ENOMEM);
6857 }
6858
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 if (pb->eof_reached) {
6859 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6860 if (ret >= 0)
6861 av_encryption_info_free(encryption_index->encrypted_samples[i]);
6862 ret = AVERROR_INVALIDDATA;
6863 }
6864
6865
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 if (ret < 0) {
6866 for (; i > 0; i--)
6867 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6868 av_freep(&encryption_index->encrypted_samples);
6869 return ret;
6870 }
6871 }
6872 1 encryption_index->nb_encrypted_samples = sample_count;
6873
6874 1 return 0;
6875 }
6876
6877 1 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6878 {
6879 AVEncryptionInfo **sample, **encrypted_samples;
6880 int64_t prev_pos;
6881 size_t sample_count, sample_info_size, i;
6882 1 int ret = 0;
6883 1 unsigned int alloc_size = 0;
6884
6885
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (encryption_index->nb_encrypted_samples)
6886 return 0;
6887 1 sample_count = encryption_index->auxiliary_info_sample_count;
6888
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (encryption_index->auxiliary_offsets_count != 1) {
6889 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6890 return AVERROR_PATCHWELCOME;
6891 }
6892
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6893 return AVERROR(ENOMEM);
6894
6895 1 prev_pos = avio_tell(pb);
6896
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6897
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6898 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6899 goto finish;
6900 }
6901
6902
3/4
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
25 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6903 24 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6904 24 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6905 min_samples * sizeof(*encrypted_samples));
6906
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
24 if (!encrypted_samples) {
6907 ret = AVERROR(ENOMEM);
6908 goto finish;
6909 }
6910 24 encryption_index->encrypted_samples = encrypted_samples;
6911
6912 24 sample = &encryption_index->encrypted_samples[i];
6913 48 sample_info_size = encryption_index->auxiliary_info_default_size
6914 24 ? encryption_index->auxiliary_info_default_size
6915
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 : encryption_index->auxiliary_info_sizes[i];
6916
6917 24 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6918
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
24 if (ret < 0)
6919 goto finish;
6920 }
6921
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (pb->eof_reached) {
6922 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6923 ret = AVERROR_INVALIDDATA;
6924 } else {
6925 1 encryption_index->nb_encrypted_samples = sample_count;
6926 }
6927
6928 1 finish:
6929 1 avio_seek(pb, prev_pos, SEEK_SET);
6930
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (ret < 0) {
6931 for (; i > 0; i--) {
6932 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6933 }
6934 av_freep(&encryption_index->encrypted_samples);
6935 }
6936 1 return ret;
6937 }
6938
6939 2 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6940 {
6941 MOVEncryptionIndex *encryption_index;
6942 MOVStreamContext *sc;
6943 int ret;
6944 unsigned int sample_count, aux_info_type, aux_info_param;
6945
6946 2 ret = get_current_encryption_info(c, &encryption_index, &sc);
6947
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (ret != 1)
6948 return ret;
6949
6950
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (encryption_index->nb_encrypted_samples) {
6951 // This can happen if we have both saio/saiz and senc atoms.
6952 1 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6953 1 return 0;
6954 }
6955
6956
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (encryption_index->auxiliary_info_sample_count) {
6957 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6958 return AVERROR_INVALIDDATA;
6959 }
6960
6961 1 avio_r8(pb); /* version */
6962
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (avio_rb24(pb) & 0x01) { /* flags */
6963 aux_info_type = avio_rb32(pb);
6964 aux_info_param = avio_rb32(pb);
6965 if (sc->cenc.default_encrypted_sample) {
6966 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6967 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6968 return 0;
6969 }
6970 if (aux_info_param != 0) {
6971 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6972 return 0;
6973 }
6974 } else {
6975 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6976 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6977 aux_info_type == MKBETAG('c','e','n','s') ||
6978 aux_info_type == MKBETAG('c','b','c','1') ||
6979 aux_info_type == MKBETAG('c','b','c','s')) &&
6980 aux_info_param == 0) {
6981 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6982 return AVERROR_INVALIDDATA;
6983 } else {
6984 return 0;
6985 }
6986 }
6987
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 } else if (!sc->cenc.default_encrypted_sample) {
6988 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6989 return 0;
6990 }
6991
6992 1 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6993 1 sample_count = avio_rb32(pb);
6994
6995
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (encryption_index->auxiliary_info_default_size == 0) {
6996 if (sample_count == 0)
6997 return AVERROR_INVALIDDATA;
6998
6999 encryption_index->auxiliary_info_sizes = av_malloc(sample_count);
7000 if (!encryption_index->auxiliary_info_sizes)
7001 return AVERROR(ENOMEM);
7002
7003 ret = avio_read(pb, encryption_index->auxiliary_info_sizes, sample_count);
7004 if (ret != sample_count) {
7005 av_freep(&encryption_index->auxiliary_info_sizes);
7006
7007 if (ret >= 0)
7008 ret = AVERROR_INVALIDDATA;
7009 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info, %s\n",
7010 av_err2str(ret));
7011 return ret;
7012 }
7013 }
7014 1 encryption_index->auxiliary_info_sample_count = sample_count;
7015
7016
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (encryption_index->auxiliary_offsets_count) {
7017 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
7018 }
7019
7020 1 return 0;
7021 }
7022
7023 2 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
7024 {
7025 uint64_t *auxiliary_offsets;
7026 MOVEncryptionIndex *encryption_index;
7027 MOVStreamContext *sc;
7028 int i, ret;
7029 unsigned int version, entry_count, aux_info_type, aux_info_param;
7030 2 unsigned int alloc_size = 0;
7031
7032 2 ret = get_current_encryption_info(c, &encryption_index, &sc);
7033
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (ret != 1)
7034 return ret;
7035
7036
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (encryption_index->nb_encrypted_samples) {
7037 // This can happen if we have both saio/saiz and senc atoms.
7038 1 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
7039 1 return 0;
7040 }
7041
7042
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (encryption_index->auxiliary_offsets_count) {
7043 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
7044 return AVERROR_INVALIDDATA;
7045 }
7046
7047 1 version = avio_r8(pb); /* version */
7048
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (avio_rb24(pb) & 0x01) { /* flags */
7049 aux_info_type = avio_rb32(pb);
7050 aux_info_param = avio_rb32(pb);
7051 if (sc->cenc.default_encrypted_sample) {
7052 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
7053 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
7054 return 0;
7055 }
7056 if (aux_info_param != 0) {
7057 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
7058 return 0;
7059 }
7060 } else {
7061 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7062 if ((aux_info_type == MKBETAG('c','e','n','c') ||
7063 aux_info_type == MKBETAG('c','e','n','s') ||
7064 aux_info_type == MKBETAG('c','b','c','1') ||
7065 aux_info_type == MKBETAG('c','b','c','s')) &&
7066 aux_info_param == 0) {
7067 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
7068 return AVERROR_INVALIDDATA;
7069 } else {
7070 return 0;
7071 }
7072 }
7073
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 } else if (!sc->cenc.default_encrypted_sample) {
7074 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7075 return 0;
7076 }
7077
7078 1 entry_count = avio_rb32(pb);
7079
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
7080 return AVERROR(ENOMEM);
7081
7082
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
7083
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
7084 1 auxiliary_offsets = av_fast_realloc(
7085 1 encryption_index->auxiliary_offsets, &alloc_size,
7086 min_offsets * sizeof(*auxiliary_offsets));
7087
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!auxiliary_offsets) {
7088 av_freep(&encryption_index->auxiliary_offsets);
7089 return AVERROR(ENOMEM);
7090 }
7091 1 encryption_index->auxiliary_offsets = auxiliary_offsets;
7092
7093
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (version == 0) {
7094 1 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
7095 } else {
7096 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
7097 }
7098
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (c->frag_index.current >= 0) {
7099 1 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
7100 }
7101 }
7102
7103
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (pb->eof_reached) {
7104 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
7105 av_freep(&encryption_index->auxiliary_offsets);
7106 return AVERROR_INVALIDDATA;
7107 }
7108
7109 1 encryption_index->auxiliary_offsets_count = entry_count;
7110
7111
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (encryption_index->auxiliary_info_sample_count) {
7112 1 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
7113 }
7114
7115 return 0;
7116 }
7117
7118 2 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
7119 {
7120 AVEncryptionInitInfo *info, *old_init_info;
7121 uint8_t **key_ids;
7122 AVStream *st;
7123 const AVPacketSideData *old_side_data;
7124 uint8_t *side_data, *extra_data;
7125 size_t side_data_size;
7126 2 int ret = 0;
7127 2 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
7128
7129
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (c->fc->nb_streams < 1)
7130 return 0;
7131 2 st = c->fc->streams[c->fc->nb_streams-1];
7132
7133 2 version = avio_r8(pb); /* version */
7134 2 avio_rb24(pb); /* flags */
7135
7136 2 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
7137 /* key_id_size */ 16, /* data_size */ 0);
7138
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!info)
7139 return AVERROR(ENOMEM);
7140
7141
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
7142 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
7143 goto finish;
7144 }
7145
7146
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (version > 0) {
7147 2 kid_count = avio_rb32(pb);
7148
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
7149 ret = AVERROR(ENOMEM);
7150 goto finish;
7151 }
7152
7153
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
4 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
7154 2 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
7155 2 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
7156 min_kid_count * sizeof(*key_ids));
7157
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!key_ids) {
7158 ret = AVERROR(ENOMEM);
7159 goto finish;
7160 }
7161 2 info->key_ids = key_ids;
7162
7163 2 info->key_ids[i] = av_mallocz(16);
7164
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!info->key_ids[i]) {
7165 ret = AVERROR(ENOMEM);
7166 goto finish;
7167 }
7168 2 info->num_key_ids = i + 1;
7169
7170
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
7171 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
7172 goto finish;
7173 }
7174 }
7175
7176
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (pb->eof_reached) {
7177 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
7178 ret = AVERROR_INVALIDDATA;
7179 goto finish;
7180 }
7181 }
7182
7183 2 extra_data_size = avio_rb32(pb);
7184 2 extra_data = av_malloc(extra_data_size);
7185
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!extra_data) {
7186 ret = AVERROR(ENOMEM);
7187 goto finish;
7188 }
7189 2 ret = avio_read(pb, extra_data, extra_data_size);
7190
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (ret != extra_data_size) {
7191 av_free(extra_data);
7192
7193 if (ret >= 0)
7194 ret = AVERROR_INVALIDDATA;
7195 goto finish;
7196 }
7197
7198 2 av_freep(&info->data); // malloc(0) may still allocate something.
7199 2 info->data = extra_data;
7200 2 info->data_size = extra_data_size;
7201
7202 // If there is existing initialization data, append to the list.
7203 2 old_side_data = av_packet_side_data_get(st->codecpar->coded_side_data, st->codecpar->nb_coded_side_data,
7204 AV_PKT_DATA_ENCRYPTION_INIT_INFO);
7205
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (old_side_data) {
7206 old_init_info = av_encryption_init_info_get_side_data(old_side_data->data, old_side_data->size);
7207 if (old_init_info) {
7208 // Append to the end of the list.
7209 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
7210 if (!cur->next) {
7211 cur->next = info;
7212 break;
7213 }
7214 }
7215 info = old_init_info;
7216 } else {
7217 // Assume existing side-data will be valid, so the only error we could get is OOM.
7218 ret = AVERROR(ENOMEM);
7219 goto finish;
7220 }
7221 }
7222
7223 2 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
7224
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!side_data) {
7225 ret = AVERROR(ENOMEM);
7226 goto finish;
7227 }
7228
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (!av_packet_side_data_add(&st->codecpar->coded_side_data,
7229 2 &st->codecpar->nb_coded_side_data,
7230 AV_PKT_DATA_ENCRYPTION_INIT_INFO,
7231 side_data, side_data_size, 0))
7232 av_free(side_data);
7233
7234 2 finish:
7235 2 av_encryption_init_info_free(info);
7236 2 return ret;
7237 }
7238
7239 3 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
7240 {
7241 AVStream *st;
7242 MOVStreamContext *sc;
7243
7244
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (c->fc->nb_streams < 1)
7245 return 0;
7246 3 st = c->fc->streams[c->fc->nb_streams-1];
7247 3 sc = st->priv_data;
7248
7249
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (sc->pseudo_stream_id != 0) {
7250 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
7251 return AVERROR_PATCHWELCOME;
7252 }
7253
7254
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (atom.size < 8)
7255 return AVERROR_INVALIDDATA;
7256
7257 3 avio_rb32(pb); /* version and flags */
7258
7259
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (!sc->cenc.default_encrypted_sample) {
7260 3 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
7261
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!sc->cenc.default_encrypted_sample) {
7262 return AVERROR(ENOMEM);
7263 }
7264 }
7265
7266 3 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
7267 3 return 0;
7268 }
7269
7270 3 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
7271 {
7272 AVStream *st;
7273 MOVStreamContext *sc;
7274 unsigned int version, pattern, is_protected, iv_size;
7275
7276
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (c->fc->nb_streams < 1)
7277 return 0;
7278 3 st = c->fc->streams[c->fc->nb_streams-1];
7279 3 sc = st->priv_data;
7280
7281
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (sc->pseudo_stream_id != 0) {
7282 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
7283 return AVERROR_PATCHWELCOME;
7284 }
7285
7286
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!sc->cenc.default_encrypted_sample) {
7287 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
7288 if (!sc->cenc.default_encrypted_sample) {
7289 return AVERROR(ENOMEM);
7290 }
7291 }
7292
7293
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (atom.size < 20)
7294 return AVERROR_INVALIDDATA;
7295
7296 3 version = avio_r8(pb); /* version */
7297 3 avio_rb24(pb); /* flags */
7298
7299 3 avio_r8(pb); /* reserved */
7300 3 pattern = avio_r8(pb);
7301
7302
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (version > 0) {
7303 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
7304 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
7305 }
7306
7307 3 is_protected = avio_r8(pb);
7308
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
3 if (is_protected && !sc->cenc.encryption_index) {
7309 // The whole stream should be by-default encrypted.
7310 3 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
7311
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!sc->cenc.encryption_index)
7312 return AVERROR(ENOMEM);
7313 }
7314 3 sc->cenc.per_sample_iv_size = avio_r8(pb);
7315
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
3 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
7316 sc->cenc.per_sample_iv_size != 16) {
7317 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
7318 return AVERROR_INVALIDDATA;
7319 }
7320
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
7321 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
7322 return AVERROR_INVALIDDATA;
7323 }
7324
7325
3/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 2 times.
3 if (is_protected && !sc->cenc.per_sample_iv_size) {
7326 1 iv_size = avio_r8(pb);
7327
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 if (iv_size != 8 && iv_size != 16) {
7328 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
7329 return AVERROR_INVALIDDATA;
7330 }
7331
7332
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
7333 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
7334 return AVERROR_INVALIDDATA;
7335 }
7336 }
7337
7338 3 return 0;
7339 }
7340
7341 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
7342 {
7343 AVStream *st;
7344 int last, type, size, ret;
7345 uint8_t buf[4];
7346
7347 if (c->fc->nb_streams < 1)
7348 return 0;
7349 st = c->fc->streams[c->fc->nb_streams-1];
7350
7351 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
7352 return AVERROR_INVALIDDATA;
7353
7354 /* Check FlacSpecificBox version. */
7355 if (avio_r8(pb) != 0)
7356 return AVERROR_INVALIDDATA;
7357
7358 avio_rb24(pb); /* Flags */
7359
7360 if (avio_read(pb, buf, sizeof(buf)) != sizeof(buf)) {
7361 av_log(c->fc, AV_LOG_ERROR, "failed to read FLAC metadata block header\n");
7362 return pb->error < 0 ? pb->error : AVERROR_INVALIDDATA;
7363 }
7364 flac_parse_block_header(buf, &last, &type, &size);
7365
7366 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
7367 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
7368 return AVERROR_INVALIDDATA;
7369 }
7370
7371 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
7372 if (ret < 0)
7373 return ret;
7374
7375 if (!last)
7376 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
7377
7378 return 0;
7379 }
7380
7381 146 static int cenc_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
7382 {
7383 int i, ret;
7384 int bytes_of_protected_data;
7385
7386
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 143 times.
146 if (!sc->cenc.aes_ctr) {
7387 /* initialize the cipher */
7388 3 sc->cenc.aes_ctr = av_aes_ctr_alloc();
7389
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!sc->cenc.aes_ctr) {
7390 return AVERROR(ENOMEM);
7391 }
7392
7393 3 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
7394
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (ret < 0) {
7395 return ret;
7396 }
7397 }
7398
7399 146 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
7400
7401
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 98 times.
146 if (!sample->subsample_count) {
7402 /* decrypt the whole packet */
7403 48 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
7404 48 return 0;
7405 }
7406
7407
2/2
✓ Branch 0 taken 98 times.
✓ Branch 1 taken 98 times.
196 for (i = 0; i < sample->subsample_count; i++) {
7408
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 98 times.
98 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
7409 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
7410 return AVERROR_INVALIDDATA;
7411 }
7412
7413 /* skip the clear bytes */
7414 98 input += sample->subsamples[i].bytes_of_clear_data;
7415 98 size -= sample->subsamples[i].bytes_of_clear_data;
7416
7417 /* decrypt the encrypted bytes */
7418
7419 98 bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data;
7420 98 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, bytes_of_protected_data);
7421
7422 98 input += bytes_of_protected_data;
7423 98 size -= bytes_of_protected_data;
7424 }
7425
7426
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 98 times.
98 if (size > 0) {
7427 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
7428 return AVERROR_INVALIDDATA;
7429 }
7430
7431 98 return 0;
7432 }
7433
7434 static int cbc1_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
7435 {
7436 int i, ret;
7437 int num_of_encrypted_blocks;
7438 uint8_t iv[16];
7439
7440 if (!sc->cenc.aes_ctx) {
7441 /* initialize the cipher */
7442 sc->cenc.aes_ctx = av_aes_alloc();
7443 if (!sc->cenc.aes_ctx) {
7444 return AVERROR(ENOMEM);
7445 }
7446
7447 ret = av_aes_init(sc->cenc.aes_ctx, c->decryption_key, 16 * 8, 1);
7448 if (ret < 0) {
7449 return ret;
7450 }
7451 }
7452
7453 memcpy(iv, sample->iv, 16);
7454
7455 /* whole-block full sample encryption */
7456 if (!sample->subsample_count) {
7457 /* decrypt the whole packet */
7458 av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
7459 return 0;
7460 }
7461
7462 for (i = 0; i < sample->subsample_count; i++) {
7463 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
7464 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
7465 return AVERROR_INVALIDDATA;
7466 }
7467
7468 if (sample->subsamples[i].bytes_of_protected_data % 16) {
7469 av_log(c->fc, AV_LOG_ERROR, "subsample BytesOfProtectedData is not a multiple of 16\n");
7470 return AVERROR_INVALIDDATA;
7471 }
7472
7473 /* skip the clear bytes */
7474 input += sample->subsamples[i].bytes_of_clear_data;
7475 size -= sample->subsamples[i].bytes_of_clear_data;
7476
7477 /* decrypt the encrypted bytes */
7478 num_of_encrypted_blocks = sample->subsamples[i].bytes_of_protected_data/16;
7479 if (num_of_encrypted_blocks > 0) {
7480 av_aes_crypt(sc->cenc.aes_ctx, input, input, num_of_encrypted_blocks, iv, 1);
7481 }
7482 input += sample->subsamples[i].bytes_of_protected_data;
7483 size -= sample->subsamples[i].bytes_of_protected_data;
7484 }
7485
7486 if (size > 0) {
7487 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
7488 return AVERROR_INVALIDDATA;
7489 }
7490
7491 return 0;
7492 }
7493
7494 static int cens_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
7495 {
7496 int i, ret, rem_bytes;
7497 uint8_t *data;
7498
7499 if (!sc->cenc.aes_ctr) {
7500 /* initialize the cipher */
7501 sc->cenc.aes_ctr = av_aes_ctr_alloc();
7502 if (!sc->cenc.aes_ctr) {
7503 return AVERROR(ENOMEM);
7504 }
7505
7506 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
7507 if (ret < 0) {
7508 return ret;
7509 }
7510 }
7511
7512 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
7513
7514 /* whole-block full sample encryption */
7515 if (!sample->subsample_count) {
7516 /* decrypt the whole packet */
7517 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
7518 return 0;
7519 } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
7520 av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cens' scheme\n");
7521 return AVERROR_INVALIDDATA;
7522 }
7523
7524 for (i = 0; i < sample->subsample_count; i++) {
7525 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
7526 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
7527 return AVERROR_INVALIDDATA;
7528 }
7529
7530 /* skip the clear bytes */
7531 input += sample->subsamples[i].bytes_of_clear_data;
7532 size -= sample->subsamples[i].bytes_of_clear_data;
7533
7534 /* decrypt the encrypted bytes */
7535 data = input;
7536 rem_bytes = sample->subsamples[i].bytes_of_protected_data;
7537 while (rem_bytes > 0) {
7538 if (rem_bytes < 16*sample->crypt_byte_block) {
7539 break;
7540 }
7541 av_aes_ctr_crypt(sc->cenc.aes_ctr, data, data, 16*sample->crypt_byte_block);
7542 data += 16*sample->crypt_byte_block;
7543 rem_bytes -= 16*sample->crypt_byte_block;
7544 data += FFMIN(16*sample->skip_byte_block, rem_bytes);
7545 rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
7546 }
7547 input += sample->subsamples[i].bytes_of_protected_data;
7548 size -= sample->subsamples[i].bytes_of_protected_data;
7549 }
7550
7551 if (size > 0) {
7552 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
7553 return AVERROR_INVALIDDATA;
7554 }
7555
7556 return 0;
7557 }
7558
7559 static int cbcs_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
7560 {
7561 int i, ret, rem_bytes;
7562 uint8_t iv[16];
7563 uint8_t *data;
7564
7565 if (!sc->cenc.aes_ctx) {
7566 /* initialize the cipher */
7567 sc->cenc.aes_ctx = av_aes_alloc();
7568 if (!sc->cenc.aes_ctx) {
7569 return AVERROR(ENOMEM);
7570 }
7571
7572 ret = av_aes_init(sc->cenc.aes_ctx, c->decryption_key, 16 * 8, 1);
7573 if (ret < 0) {
7574 return ret;
7575 }
7576 }
7577
7578 /* whole-block full sample encryption */
7579 if (!sample->subsample_count) {
7580 /* decrypt the whole packet */
7581 memcpy(iv, sample->iv, 16);
7582 av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
7583 return 0;
7584 } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
7585 av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cbcs' scheme\n");
7586 return AVERROR_INVALIDDATA;
7587 }
7588
7589 for (i = 0; i < sample->subsample_count; i++) {
7590 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
7591 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
7592 return AVERROR_INVALIDDATA;
7593 }
7594
7595 /* skip the clear bytes */
7596 input += sample->subsamples[i].bytes_of_clear_data;
7597 size -= sample->subsamples[i].bytes_of_clear_data;
7598
7599 /* decrypt the encrypted bytes */
7600 memcpy(iv, sample->iv, 16);
7601 data = input;
7602 rem_bytes = sample->subsamples[i].bytes_of_protected_data;
7603 while (rem_bytes > 0) {
7604 if (rem_bytes < 16*sample->crypt_byte_block) {
7605 break;
7606 }
7607 av_aes_crypt(sc->cenc.aes_ctx, data, data, sample->crypt_byte_block, iv, 1);
7608 data += 16*sample->crypt_byte_block;
7609 rem_bytes -= 16*sample->crypt_byte_block;
7610 data += FFMIN(16*sample->skip_byte_block, rem_bytes);
7611 rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
7612 }
7613 input += sample->subsamples[i].bytes_of_protected_data;
7614 size -= sample->subsamples[i].bytes_of_protected_data;
7615 }
7616
7617 if (size > 0) {
7618 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
7619 return AVERROR_INVALIDDATA;
7620 }
7621
7622 return 0;
7623 }
7624
7625 146 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
7626 {
7627
3/6
✓ Branch 0 taken 146 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 146 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 146 times.
✗ Branch 5 not taken.
146 if (sample->scheme == MKBETAG('c','e','n','c') && !sample->crypt_byte_block && !sample->skip_byte_block) {
7628 146 return cenc_scheme_decrypt(c, sc, sample, input, size);
7629 } else if (sample->scheme == MKBETAG('c','b','c','1') && !sample->crypt_byte_block && !sample->skip_byte_block) {
7630 return cbc1_scheme_decrypt(c, sc, sample, input, size);
7631 } else if (sample->scheme == MKBETAG('c','e','n','s')) {
7632 return cens_scheme_decrypt(c, sc, sample, input, size);
7633 } else if (sample->scheme == MKBETAG('c','b','c','s')) {
7634 return cbcs_scheme_decrypt(c, sc, sample, input, size);
7635 } else {
7636 av_log(c->fc, AV_LOG_ERROR, "invalid encryption scheme\n");
7637 return AVERROR_INVALIDDATA;
7638 }
7639 }
7640
7641 92038 static MOVFragmentStreamInfo *get_frag_stream_info_from_pkt(MOVFragmentIndex *frag_index, AVPacket *pkt, int id)
7642 {
7643 92038 int current = frag_index->current;
7644
7645
2/2
✓ Branch 0 taken 91377 times.
✓ Branch 1 taken 661 times.
92038 if (!frag_index->nb_items)
7646 91377 return NULL;
7647
7648 // Check frag_index->current is the right one for pkt. It can out of sync.
7649
2/4
✓ Branch 0 taken 661 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 661 times.
✗ Branch 3 not taken.
661 if (current >= 0 && current < frag_index->nb_items) {
7650
2/2
✓ Branch 0 taken 639 times.
✓ Branch 1 taken 22 times.
661 if (frag_index->item[current].moof_offset < pkt->pos &&
7651
2/2
✓ Branch 0 taken 413 times.
✓ Branch 1 taken 226 times.
639 (current + 1 == frag_index->nb_items ||
7652
2/2
✓ Branch 0 taken 388 times.
✓ Branch 1 taken 25 times.
413 frag_index->item[current + 1].moof_offset > pkt->pos))
7653 614 return get_frag_stream_info(frag_index, current, id);
7654 }
7655
7656
7657
2/2
✓ Branch 0 taken 3955 times.
✓ Branch 1 taken 4 times.
3959 for (int i = 0; i < frag_index->nb_items; i++) {
7658
2/2
✓ Branch 0 taken 43 times.
✓ Branch 1 taken 3912 times.
3955 if (frag_index->item[i].moof_offset > pkt->pos)
7659 43 break;
7660 3912 current = i;
7661 }
7662 47 frag_index->current = current;
7663 47 return get_frag_stream_info(frag_index, current, id);
7664 }
7665
7666 92038 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
7667 {
7668 MOVFragmentStreamInfo *frag_stream_info;
7669 MOVEncryptionIndex *encryption_index;
7670 AVEncryptionInfo *encrypted_sample;
7671 int encrypted_index, ret;
7672
7673 92038 frag_stream_info = get_frag_stream_info_from_pkt(&mov->frag_index, pkt, sc->id);
7674 92038 encrypted_index = current_index;
7675 92038 encryption_index = NULL;
7676
2/2
✓ Branch 0 taken 661 times.
✓ Branch 1 taken 91377 times.
92038 if (frag_stream_info) {
7677 // Note this only supports encryption info in the first sample descriptor.
7678
2/2
✓ Branch 0 taken 637 times.
✓ Branch 1 taken 24 times.
661 if (frag_stream_info->stsd_id == 1) {
7679
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 613 times.
637 if (frag_stream_info->encryption_index) {
7680 24 encrypted_index = current_index - frag_stream_info->index_base;
7681 24 encryption_index = frag_stream_info->encryption_index;
7682 } else {
7683 613 encryption_index = sc->cenc.encryption_index;
7684 }
7685 }
7686 } else {
7687 91377 encryption_index = sc->cenc.encryption_index;
7688 }
7689
7690
2/2
✓ Branch 0 taken 146 times.
✓ Branch 1 taken 91892 times.
92038 if (encryption_index) {
7691
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 122 times.
146 if (encryption_index->auxiliary_info_sample_count &&
7692
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
24 !encryption_index->nb_encrypted_samples) {
7693 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
7694 return AVERROR_INVALIDDATA;
7695 }
7696
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 122 times.
146 if (encryption_index->auxiliary_offsets_count &&
7697
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
24 !encryption_index->nb_encrypted_samples) {
7698 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
7699 return AVERROR_INVALIDDATA;
7700 }
7701
7702
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 98 times.
146 if (!encryption_index->nb_encrypted_samples) {
7703 // Full-sample encryption with default settings.
7704 48 encrypted_sample = sc->cenc.default_encrypted_sample;
7705
2/4
✓ Branch 0 taken 98 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 98 times.
✗ Branch 3 not taken.
98 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
7706 // Per-sample setting override.
7707 98 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
7708
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 98 times.
98 if (!encrypted_sample)
7709 encrypted_sample = sc->cenc.default_encrypted_sample;
7710 } else {
7711 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
7712 return AVERROR_INVALIDDATA;
7713 }
7714
7715
1/2
✓ Branch 0 taken 146 times.
✗ Branch 1 not taken.
146 if (mov->decryption_key) {
7716 146 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
7717 } else {
7718 size_t size;
7719 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
7720 if (!side_data)
7721 return AVERROR(ENOMEM);
7722 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
7723 if (ret < 0)
7724 av_free(side_data);
7725 return ret;
7726 }
7727 }
7728
7729 91892 return 0;
7730 }
7731
7732 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
7733 {
7734 const int OPUS_SEEK_PREROLL_MS = 80;
7735 int ret;
7736 AVStream *st;
7737 size_t size;
7738 uint16_t pre_skip;
7739
7740 if (c->fc->nb_streams < 1)
7741 return 0;
7742 st = c->fc->streams[c->fc->nb_streams-1];
7743
7744 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
7745 return AVERROR_INVALIDDATA;
7746
7747 /* Check OpusSpecificBox version. */
7748 if (avio_r8(pb) != 0) {
7749 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
7750 return AVERROR_INVALIDDATA;
7751 }
7752
7753 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
7754 size = atom.size + 8;
7755
7756 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
7757 return ret;
7758
7759 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
7760 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
7761 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
7762 avio_read(pb, st->codecpar->extradata + 9, size - 9);
7763
7764 /* OpusSpecificBox is stored in big-endian, but OpusHead is
7765 little-endian; aside from the preceeding magic and version they're
7766 otherwise currently identical. Data after output gain at offset 16
7767 doesn't need to be bytewapped. */
7768 pre_skip = AV_RB16(st->codecpar->extradata + 10);
7769 AV_WL16(st->codecpar->extradata + 10, pre_skip);
7770 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
7771 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
7772
7773 st->codecpar->initial_padding = pre_skip;
7774 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
7775 (AVRational){1, 1000},
7776 (AVRational){1, 48000});
7777
7778 return 0;
7779 }
7780
7781 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
7782 {
7783 AVStream *st;
7784 unsigned format_info;
7785 int channel_assignment, channel_assignment1, channel_assignment2;
7786 int ratebits;
7787 uint64_t chmask;
7788
7789 if (c->fc->nb_streams < 1)
7790 return 0;
7791 st = c->fc->streams[c->fc->nb_streams-1];
7792
7793 if (atom.size < 10)
7794 return AVERROR_INVALIDDATA;
7795
7796 format_info = avio_rb32(pb);
7797
7798 ratebits = (format_info >> 28) & 0xF;
7799 channel_assignment1 = (format_info >> 15) & 0x1F;
7800 channel_assignment2 = format_info & 0x1FFF;
7801 if (channel_assignment2)
7802 channel_assignment = channel_assignment2;
7803 else
7804 channel_assignment = channel_assignment1;
7805
7806 st->codecpar->frame_size = 40 << (ratebits & 0x7);
7807 st->codecpar->sample_rate = mlp_samplerate(ratebits);
7808
7809 av_channel_layout_uninit(&st->codecpar->ch_layout);
7810 chmask = truehd_layout(channel_assignment);
7811 av_channel_layout_from_mask(&st->codecpar->ch_layout, chmask);
7812
7813 return 0;
7814 }
7815
7816 4 static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
7817 {
7818 AVStream *st;
7819 uint8_t buf[ISOM_DVCC_DVVC_SIZE];
7820 int ret;
7821 4 int64_t read_size = atom.size;
7822
7823
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (c->fc->nb_streams < 1)
7824 return 0;
7825 4 st = c->fc->streams[c->fc->nb_streams-1];
7826
7827 // At most 24 bytes
7828 4 read_size = FFMIN(read_size, ISOM_DVCC_DVVC_SIZE);
7829
7830
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 if ((ret = ffio_read_size(pb, buf, read_size)) < 0)
7831 return ret;
7832
7833 4 return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size);
7834 }
7835
7836 4 static int mov_read_kind(MOVContext *c, AVIOContext *pb, MOVAtom atom)
7837 {
7838 4 AVFormatContext *ctx = c->fc;
7839 4 AVStream *st = NULL;
7840 AVBPrint scheme_buf, value_buf;
7841 4 int64_t scheme_str_len = 0, value_str_len = 0;
7842 4 int version, flags, ret = AVERROR_BUG;
7843 4 int64_t size = atom.size;
7844
7845
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (atom.size < 6)
7846 // 4 bytes for version + flags, 2x 1 byte for null
7847 return AVERROR_INVALIDDATA;
7848
7849
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (c->fc->nb_streams < 1)
7850 return 0;
7851 4 st = c->fc->streams[c->fc->nb_streams-1];
7852
7853 4 version = avio_r8(pb);
7854 4 flags = avio_rb24(pb);
7855 4 size -= 4;
7856
7857
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
4 if (version != 0 || flags != 0) {
7858 av_log(ctx, AV_LOG_ERROR,
7859 "Unsupported 'kind' box with version %d, flags: %x",
7860 version, flags);
7861 return AVERROR_INVALIDDATA;
7862 }
7863
7864 4 av_bprint_init(&scheme_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
7865 4 av_bprint_init(&value_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
7866
7867
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 if ((scheme_str_len = ff_read_string_to_bprint_overwrite(pb, &scheme_buf,
7868 size)) < 0) {
7869 ret = scheme_str_len;
7870 goto cleanup;
7871 }
7872
7873
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (scheme_str_len + 1 >= size) {
7874 // we need to have another string, even if nullptr.
7875 // we check with + 1 since we expect that if size was not hit,
7876 // an additional null was read.
7877 ret = AVERROR_INVALIDDATA;
7878 goto cleanup;
7879 }
7880
7881 4 size -= scheme_str_len + 1;
7882
7883
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 if ((value_str_len = ff_read_string_to_bprint_overwrite(pb, &value_buf,
7884 size)) < 0) {
7885 ret = value_str_len;
7886 goto cleanup;
7887 }
7888
7889
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (value_str_len == size) {
7890 // in case of no trailing null, box is not valid.
7891 ret = AVERROR_INVALIDDATA;
7892 goto cleanup;
7893 }
7894
7895 4 av_log(ctx, AV_LOG_TRACE,
7896 "%s stream %d KindBox(scheme: %s, value: %s)\n",
7897 4 av_get_media_type_string(st->codecpar->codec_type),
7898 st->index,
7899 scheme_buf.str, value_buf.str);
7900
7901
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
7902 4 const struct MP4TrackKindMapping map = ff_mov_track_kind_table[i];
7903
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 if (!av_strstart(scheme_buf.str, map.scheme_uri, NULL))
7904 continue;
7905
7906
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 4 times.
24 for (int j = 0; map.value_maps[j].disposition; j++) {
7907 20 const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
7908
2/2
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 4 times.
20 if (!av_strstart(value_buf.str, value_map.value, NULL))
7909 16 continue;
7910
7911 4 st->disposition |= value_map.disposition;
7912 }
7913 }
7914
7915 4 ret = 0;
7916
7917 4 cleanup:
7918
7919 4 av_bprint_finalize(&scheme_buf, NULL);
7920 4 av_bprint_finalize(&value_buf, NULL);
7921
7922 4 return ret;
7923 }
7924
7925 static int mov_read_SA3D(MOVContext *c, AVIOContext *pb, MOVAtom atom)
7926 {
7927 AVStream *st;
7928 int i, version, type;
7929 int ambisonic_order, channel_order, normalization, channel_count;
7930
7931 if (c->fc->nb_streams < 1)
7932 return 0;
7933
7934 st = c->fc->streams[c->fc->nb_streams - 1];
7935
7936 if (atom.size < 16) {
7937 av_log(c->fc, AV_LOG_ERROR, "SA3D audio box too small\n");
7938 return AVERROR_INVALIDDATA;
7939 }
7940
7941 version = avio_r8(pb);
7942 if (version) {
7943 av_log(c->fc, AV_LOG_WARNING, "Unsupported SA3D box version %d\n", version);
7944 return 0;
7945 }
7946
7947 type = avio_r8(pb);
7948 if (type) {
7949 av_log(c->fc, AV_LOG_WARNING,
7950 "Unsupported ambisonic type %d\n", type);
7951 return 0;
7952 }
7953
7954 ambisonic_order = avio_rb32(pb);
7955
7956 channel_order = avio_r8(pb);
7957 if (channel_order) {
7958 av_log(c->fc, AV_LOG_WARNING,
7959 "Unsupported channel_order %d\n", channel_order);
7960 return 0;
7961 }
7962
7963 normalization = avio_r8(pb);
7964 if (normalization) {
7965 av_log(c->fc, AV_LOG_WARNING,
7966 "Unsupported normalization %d\n", normalization);
7967 return 0;
7968 }
7969
7970 channel_count = avio_rb32(pb);
7971 if (ambisonic_order < 0 || channel_count != (ambisonic_order + 1LL) * (ambisonic_order + 1LL)) {
7972 av_log(c->fc, AV_LOG_ERROR,
7973 "Invalid number of channels (%d / %d)\n",
7974 channel_count, ambisonic_order);
7975 return 0;
7976 }
7977
7978 for (i = 0; i < channel_count; i++) {
7979 if (i != avio_rb32(pb)) {
7980 av_log(c->fc, AV_LOG_WARNING,
7981 "Ambisonic channel reordering is not supported\n");
7982 return 0;
7983 }
7984 }
7985
7986 av_channel_layout_uninit(&st->codecpar->ch_layout);
7987 st->codecpar->ch_layout.order = AV_CHANNEL_ORDER_AMBISONIC;
7988 st->codecpar->ch_layout.nb_channels = channel_count;
7989
7990 return 0;
7991 }
7992
7993 static int mov_read_SAND(MOVContext *c, AVIOContext *pb, MOVAtom atom)
7994 {
7995 AVStream *st;
7996 int version;
7997
7998 if (c->fc->nb_streams < 1)
7999 return 0;
8000
8001 st = c->fc->streams[c->fc->nb_streams - 1];
8002
8003 if (atom.size < 5) {
8004 av_log(c->fc, AV_LOG_ERROR, "Empty SAND audio box\n");
8005 return AVERROR_INVALIDDATA;
8006 }
8007
8008 version = avio_r8(pb);
8009 if (version) {
8010 av_log(c->fc, AV_LOG_WARNING, "Unsupported SAND box version %d\n", version);
8011 return 0;
8012 }
8013
8014 st->disposition |= AV_DISPOSITION_NON_DIEGETIC;
8015
8016 return 0;
8017 }
8018
8019 78 static int rb_size(AVIOContext *pb, uint64_t* value, int size)
8020 {
8021
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 77 times.
78 if (size == 0)
8022 1 *value = 0;
8023
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 77 times.
77 else if (size == 1)
8024 *value = avio_r8(pb);
8025
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 77 times.
77 else if (size == 2)
8026 *value = avio_rb16(pb);
8027
1/2
✓ Branch 0 taken 77 times.
✗ Branch 1 not taken.
77 else if (size == 4)
8028 77 *value = avio_rb32(pb);
8029 else if (size == 8)
8030 *value = avio_rb64(pb);
8031 else
8032 return -1;
8033 78 return size;
8034 }
8035
8036 10 static int mov_read_pitm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
8037 {
8038 10 avio_rb32(pb); // version & flags.
8039 10 c->primary_item_id = avio_rb16(pb);
8040 10 av_log(c->fc, AV_LOG_TRACE, "pitm: primary_item_id %d\n", c->primary_item_id);
8041 10 return atom.size;
8042 }
8043
8044 6 static int mov_read_idat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
8045 {
8046 6 c->idat_offset = avio_tell(pb);
8047 6 return 0;
8048 }
8049
8050 10 static int mov_read_iloc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
8051 {
8052 HEIFItem *heif_item;
8053 int version, offset_size, length_size, base_offset_size, index_size;
8054 int item_count, extent_count;
8055 int64_t base_offset, extent_offset, extent_length;
8056 uint8_t value;
8057
8058
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if (c->found_iloc) {
8059 av_log(c->fc, AV_LOG_INFO, "Duplicate iloc box found\n");
8060 return 0;
8061 }
8062
8063 10 version = avio_r8(pb);
8064 10 avio_rb24(pb); // flags.
8065
8066 10 value = avio_r8(pb);
8067 10 offset_size = (value >> 4) & 0xF;
8068 10 length_size = value & 0xF;
8069 10 value = avio_r8(pb);
8070 10 base_offset_size = (value >> 4) & 0xF;
8071
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 4 times.
10 index_size = !version ? 0 : (value & 0xF);
8072
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if (index_size) {
8073 avpriv_report_missing_feature(c->fc, "iloc: index_size != 0");
8074 return AVERROR_PATCHWELCOME;
8075 }
8076
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
8077
8078 10 heif_item = av_realloc_array(c->heif_item, FFMAX(item_count, c->nb_heif_item), sizeof(*c->heif_item));
8079
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if (!heif_item)
8080 return AVERROR(ENOMEM);
8081 10 c->heif_item = heif_item;
8082
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if (item_count > c->nb_heif_item)
8083 10 memset(c->heif_item + c->nb_heif_item, 0,
8084 10 sizeof(*c->heif_item) * (item_count - c->nb_heif_item));
8085 10 c->nb_heif_item = FFMAX(c->nb_heif_item, item_count);
8086
8087 10 av_log(c->fc, AV_LOG_TRACE, "iloc: item_count %d\n", item_count);
8088
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 10 times.
36 for (int i = 0; i < item_count; i++) {
8089
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
8090
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 6 times.
26 int offset_type = (version > 0) ? avio_rb16(pb) & 0xf : 0;
8091
8092
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 26 times.
26 if (avio_feof(pb))
8093 return AVERROR_INVALIDDATA;
8094
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (offset_type > 1) {
8095 avpriv_report_missing_feature(c->fc, "iloc offset type %d", offset_type);
8096 return AVERROR_PATCHWELCOME;
8097 }
8098 26 c->heif_item[i].item_id = item_id;
8099
8100 26 avio_rb16(pb); // data_reference_index.
8101
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 26 times.
26 if (rb_size(pb, &base_offset, base_offset_size) < 0)
8102 return AVERROR_INVALIDDATA;
8103 26 extent_count = avio_rb16(pb);
8104
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (extent_count > 1) {
8105 // For still AVIF images, we only support one extent item.
8106 avpriv_report_missing_feature(c->fc, "iloc: extent_count > 1");
8107 return AVERROR_PATCHWELCOME;
8108 }
8109
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 26 times.
52 for (int j = 0; j < extent_count; j++) {
8110
2/4
✓ Branch 1 taken 26 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 26 times.
52 if (rb_size(pb, &extent_offset, offset_size) < 0 ||
8111 26 rb_size(pb, &extent_length, length_size) < 0)
8112 return AVERROR_INVALIDDATA;
8113
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 20 times.
26 if (offset_type == 1)
8114 6 c->heif_item[i].is_idat_relative = 1;
8115 26 c->heif_item[i].extent_length = extent_length;
8116 26 c->heif_item[i].extent_offset = base_offset + extent_offset;
8117 26 av_log(c->fc, AV_LOG_TRACE, "iloc: item_idx %d, offset_type %d, "
8118 "extent_offset %"PRId64", extent_length %"PRId64"\n",
8119 26 i, offset_type, c->heif_item[i].extent_offset, c->heif_item[i].extent_length);
8120 }
8121 }
8122
8123 10 c->found_iloc = 1;
8124 10 return atom.size;
8125 }
8126
8127 26 static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom, int idx)
8128 {
8129 AVBPrint item_name;
8130 26 int64_t size = atom.size;
8131 uint32_t item_type;
8132 int item_id;
8133 int version, ret;
8134
8135 26 version = avio_r8(pb);
8136 26 avio_rb24(pb); // flags.
8137 26 size -= 4;
8138
8139
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (version < 2) {
8140 avpriv_report_missing_feature(c->fc, "infe version < 2");
8141 return 1;
8142 }
8143
8144
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 item_id = version > 2 ? avio_rb32(pb) : avio_rb16(pb);
8145 26 avio_rb16(pb); // item_protection_index
8146 26 item_type = avio_rl32(pb);
8147 26 size -= 8;
8148
8149 26 av_bprint_init(&item_name, 0, AV_BPRINT_SIZE_UNLIMITED);
8150 26 ret = ff_read_string_to_bprint_overwrite(pb, &item_name, size);
8151
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (ret < 0) {
8152 av_bprint_finalize(&item_name, NULL);
8153 return ret;
8154 }
8155
8156 26 av_log(c->fc, AV_LOG_TRACE, "infe: item_id %d, item_type %s, item_name %s\n",
8157 26 item_id, av_fourcc2str(item_type), item_name.str);
8158
8159 26 size -= ret + 1;
8160
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (size > 0)
8161 avio_skip(pb, size);
8162
8163
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 1 times.
26 if (ret)
8164 25 av_bprint_finalize(&item_name, &c->heif_item[idx].name);
8165 26 c->heif_item[idx].item_id = item_id;
8166 26 c->heif_item[idx].type = item_type;
8167
8168
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 7 times.
26 switch (item_type) {
8169 19 case MKTAG('a','v','0','1'):
8170 case MKTAG('h','v','c','1'):
8171 19 ret = heif_add_stream(c, &c->heif_item[idx]);
8172
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
19 if (ret < 0)
8173 return ret;
8174 19 break;
8175 }
8176
8177 26 return 0;
8178 }
8179
8180 10 static int mov_read_iinf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
8181 {
8182 HEIFItem *heif_item;
8183 int entry_count;
8184 int version, ret;
8185
8186
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if (c->found_iinf) {
8187 av_log(c->fc, AV_LOG_WARNING, "Duplicate iinf box found\n");
8188 return 0;
8189 }
8190
8191 10 version = avio_r8(pb);
8192 10 avio_rb24(pb); // flags.
8193
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 entry_count = version ? avio_rb32(pb) : avio_rb16(pb);
8194
8195 10 heif_item = av_realloc_array(c->heif_item, FFMAX(entry_count, c->nb_heif_item), sizeof(*c->heif_item));
8196
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if (!heif_item)
8197 return AVERROR(ENOMEM);
8198 10 c->heif_item = heif_item;
8199
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if (entry_count > c->nb_heif_item)
8200 memset(c->heif_item + c->nb_heif_item, 0,
8201 sizeof(*c->heif_item) * (entry_count - c->nb_heif_item));
8202 10 c->nb_heif_item = FFMAX(c->nb_heif_item, entry_count);
8203
8204
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 10 times.
36 for (int i = 0; i < entry_count; i++) {
8205 MOVAtom infe;
8206
8207 26 infe.size = avio_rb32(pb) - 8;
8208 26 infe.type = avio_rl32(pb);
8209 26 ret = mov_read_infe(c, pb, infe, i);
8210
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (ret < 0)
8211 return ret;
8212
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (ret)
8213 return 0;
8214 }
8215
8216 10 c->found_iinf = 1;
8217 10 return 0;
8218 }
8219
8220 6 static int mov_read_iref_dimg(MOVContext *c, AVIOContext *pb, int version)
8221 {
8222 6 HEIFItem *item = NULL;
8223 HEIFGrid *grid;
8224 int entries, i;
8225
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
8226
8227
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 for (int i = 0; i < c->nb_heif_grid; i++) {
8228 if (c->heif_grid[i].item->item_id == from_item_id) {
8229 av_log(c->fc, AV_LOG_ERROR, "More than one 'dimg' box "
8230 "referencing the same Derived Image item\n");
8231 return AVERROR_INVALIDDATA;
8232 }
8233 }
8234
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 for (int i = 0; i < c->nb_heif_item; i++) {
8235
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 6 times.
20 if (c->heif_item[i].item_id != from_item_id)
8236 14 continue;
8237 6 item = &c->heif_item[i];
8238
8239
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 switch (item->type) {
8240 6 case MKTAG('g','r','i','d'):
8241 case MKTAG('i','o','v','l'):
8242 6 break;
8243 default:
8244 avpriv_report_missing_feature(c->fc, "Derived Image item of type %s",
8245 av_fourcc2str(item->type));
8246 return 0;
8247 }
8248 6 break;
8249 }
8250
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!item) {
8251 av_log(c->fc, AV_LOG_ERROR, "Missing grid information\n");
8252 return AVERROR_INVALIDDATA;
8253 }
8254
8255 6 grid = av_realloc_array(c->heif_grid, c->nb_heif_grid + 1U,
8256 sizeof(*c->heif_grid));
8257
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!grid)
8258 return AVERROR(ENOMEM);
8259 6 c->heif_grid = grid;
8260 6 grid = &grid[c->nb_heif_grid++];
8261
8262 6 entries = avio_rb16(pb);
8263 6 grid->tile_id_list = av_malloc_array(entries, sizeof(*grid->tile_id_list));
8264 6 grid->tile_item_list = av_calloc(entries, sizeof(*grid->tile_item_list));
8265
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
6 if (!grid->tile_id_list || !grid->tile_item_list)
8266 return AVERROR(ENOMEM);
8267 /* 'to' item ids */
8268
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 6 times.
22 for (i = 0; i < entries; i++)
8269
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 grid->tile_id_list[i] = version ? avio_rb32(pb) : avio_rb16(pb);
8270 6 grid->nb_tiles = entries;
8271 6 grid->item = item;
8272
8273 6 av_log(c->fc, AV_LOG_TRACE, "dimg: from_item_id %d, entries %d\n",
8274 from_item_id, entries);
8275
8276 6 return 0;
8277 }
8278
8279 static int mov_read_iref_thmb(MOVContext *c, AVIOContext *pb, int version)
8280 {
8281 int entries;
8282 int to_item_id, from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
8283
8284 entries = avio_rb16(pb);
8285 if (entries > 1) {
8286 avpriv_request_sample(c->fc, "thmb in iref referencing several items");
8287 return AVERROR_PATCHWELCOME;
8288 }
8289 /* 'to' item ids */
8290 to_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
8291
8292 if (to_item_id != c->primary_item_id)
8293 return 0;
8294
8295 c->thmb_item_id = from_item_id;
8296
8297 av_log(c->fc, AV_LOG_TRACE, "thmb: from_item_id %d, entries %d\n",
8298 from_item_id, entries);
8299
8300 return 0;
8301 }
8302
8303 6 static int mov_read_iref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
8304 {
8305 6 int version = avio_r8(pb);
8306 6 avio_rb24(pb); // flags
8307 6 atom.size -= 4;
8308
8309
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (version > 1) {
8310 av_log(c->fc, AV_LOG_WARNING, "Unknown iref box version %d\n", version);
8311 return 0;
8312 }
8313
8314
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 while (atom.size) {
8315 6 uint32_t type, size = avio_rb32(pb);
8316 6 int64_t next = avio_tell(pb);
8317
8318
3/6
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
6 if (size < 14 || next < 0 || next > INT64_MAX - size)
8319 return AVERROR_INVALIDDATA;
8320
8321 6 next += size - 4;
8322 6 type = avio_rl32(pb);
8323
1/3
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
6 switch (type) {
8324 6 case MKTAG('d','i','m','g'):
8325 6 mov_read_iref_dimg(c, pb, version);
8326 6 break;
8327 case MKTAG('t','h','m','b'):
8328 mov_read_iref_thmb(c, pb, version);
8329 break;
8330 default:
8331 av_log(c->fc, AV_LOG_DEBUG, "Unknown iref type %s size %"PRIu32"\n",
8332 av_fourcc2str(type), size);
8333 }
8334
8335 6 atom.size -= size;
8336 6 avio_seek(pb, next, SEEK_SET);
8337 }
8338 6 return 0;
8339 }
8340
8341 25 static int mov_read_ispe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
8342 {
8343 uint32_t width, height;
8344
8345 25 avio_r8(pb); /* version */
8346 25 avio_rb24(pb); /* flags */
8347 25 width = avio_rb32(pb);
8348 25 height = avio_rb32(pb);
8349
8350 25 av_log(c->fc, AV_LOG_TRACE, "ispe: item_id %d, width %u, height %u\n",
8351 c->cur_item_id, width, height);
8352
8353
1/2
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
54 for (int i = 0; i < c->nb_heif_item; i++) {
8354
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 29 times.
54 if (c->heif_item[i].item_id == c->cur_item_id) {
8355 25 c->heif_item[i].width = width;
8356 25 c->heif_item[i].height = height;
8357 25 break;
8358 }
8359 }
8360
8361 25 return 0;
8362 }
8363
8364 10 static int mov_read_iprp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
8365 {
8366 typedef struct MOVAtoms {
8367 FFIOContext b;
8368 uint32_t type;
8369 int64_t size;
8370 uint8_t *data;
8371 } MOVAtoms;
8372 10 MOVAtoms *atoms = NULL;
8373 MOVAtom a;
8374 unsigned count;
8375 10 int nb_atoms = 0;
8376 int version, flags;
8377 int ret;
8378
8379 10 a.size = avio_rb32(pb);
8380 10 a.type = avio_rl32(pb);
8381
8382
2/4
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
10 if (a.size < 8 || a.type != MKTAG('i','p','c','o'))
8383 return AVERROR_INVALIDDATA;
8384
8385 10 a.size -= 8;
8386
2/2
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 10 times.
43 while (a.size >= 8) {
8387 33 MOVAtoms *ref = av_dynarray2_add((void**)&atoms, &nb_atoms, sizeof(MOVAtoms), NULL);
8388
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 33 times.
33 if (!ref) {
8389 ret = AVERROR(ENOMEM);
8390 goto fail;
8391 }
8392 33 ref->data = NULL;
8393 33 ref->size = avio_rb32(pb);
8394 33 ref->type = avio_rl32(pb);
8395
2/4
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 33 times.
✗ Branch 3 not taken.
33 if (ref->size > a.size || ref->size < 8)
8396 break;
8397 33 ref->data = av_malloc(ref->size);
8398
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 33 times.
33 if (!ref->data) {
8399 ret = AVERROR_INVALIDDATA;
8400 goto fail;
8401 }
8402 33 av_log(c->fc, AV_LOG_TRACE, "ipco: index %d, box type %s\n", nb_atoms, av_fourcc2str(ref->type));
8403 33 avio_seek(pb, -8, SEEK_CUR);
8404
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 33 times.
33 if (avio_read(pb, ref->data, ref->size) != ref->size) {
8405 ret = AVERROR_INVALIDDATA;
8406 goto fail;
8407 }
8408 33 ffio_init_read_context(&ref->b, ref->data, ref->size);
8409 33 a.size -= ref->size;
8410 }
8411
8412
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if (a.size) {
8413 ret = AVERROR_INVALIDDATA;
8414 goto fail;
8415 }
8416
8417 10 a.size = avio_rb32(pb);
8418 10 a.type = avio_rl32(pb);
8419
8420
2/4
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
10 if (a.size < 8 || a.type != MKTAG('i','p','m','a')) {
8421 ret = AVERROR_INVALIDDATA;
8422 goto fail;
8423 }
8424
8425 10 version = avio_r8(pb);
8426 10 flags = avio_rb24(pb);
8427 10 count = avio_rb32(pb);
8428
8429
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 10 times.
35 for (int i = 0; i < count; i++) {
8430
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
25 int item_id = version ? avio_rb32(pb) : avio_rb16(pb);
8431 25 int assoc_count = avio_r8(pb);
8432
8433
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 25 times.
73 for (int j = 0; j < assoc_count; j++) {
8434 MOVAtoms *ref;
8435 48 int index = avio_r8(pb) & 0x7f;
8436
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 if (flags & 1) {
8437 index <<= 8;
8438 index |= avio_r8(pb);
8439 }
8440
2/4
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 48 times.
48 if (index > nb_atoms || index <= 0) {
8441 ret = AVERROR_INVALIDDATA;
8442 goto fail;
8443 }
8444 48 ref = &atoms[--index];
8445
8446 48 av_log(c->fc, AV_LOG_TRACE, "ipma: property_index %d, item_id %d, item_type %s\n",
8447 48 index + 1, item_id, av_fourcc2str(ref->type));
8448
8449 48 c->cur_item_id = item_id;
8450
8451 48 ret = mov_read_default(c, &ref->b.pub,
8452 48 (MOVAtom) { .size = ref->size,
8453 .type = MKTAG('i','p','c','o') });
8454
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 if (ret < 0)
8455 goto fail;
8456 48 ffio_init_read_context(&ref->b, ref->data, ref->size);
8457 }
8458 }
8459
8460 10 ret = 0;
8461 10 fail:
8462 10 c->cur_item_id = -1;
8463
2/2
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 10 times.
43 for (int i = 0; i < nb_atoms; i++)
8464 33 av_free(atoms[i].data);
8465 10 av_free(atoms);
8466
8467 10 return ret;
8468 }
8469
8470 static const MOVParseTableEntry mov_default_parse_table[] = {
8471 { MKTAG('A','C','L','R'), mov_read_aclr },
8472 { MKTAG('A','P','R','G'), mov_read_avid },
8473 { MKTAG('A','A','L','P'), mov_read_avid },
8474 { MKTAG('A','R','E','S'), mov_read_ares },
8475 { MKTAG('a','v','s','s'), mov_read_avss },
8476 { MKTAG('a','v','1','C'), mov_read_glbl },
8477 { MKTAG('c','h','p','l'), mov_read_chpl },
8478 { MKTAG('c','o','6','4'), mov_read_stco },
8479 { MKTAG('c','o','l','r'), mov_read_colr },
8480 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
8481 { MKTAG('d','i','n','f'), mov_read_default },
8482 { MKTAG('D','p','x','E'), mov_read_dpxe },
8483 { MKTAG('d','r','e','f'), mov_read_dref },
8484 { MKTAG('e','d','t','s'), mov_read_default },
8485 { MKTAG('e','l','s','t'), mov_read_elst },
8486 { MKTAG('e','n','d','a'), mov_read_enda },
8487 { MKTAG('f','i','e','l'), mov_read_fiel },
8488 { MKTAG('a','d','r','m'), mov_read_adrm },
8489 { MKTAG('f','t','y','p'), mov_read_ftyp },
8490 { MKTAG('g','l','b','l'), mov_read_glbl },
8491 { MKTAG('h','d','l','r'), mov_read_hdlr },
8492 { MKTAG('i','l','s','t'), mov_read_ilst },
8493 { MKTAG('j','p','2','h'), mov_read_jp2h },
8494 { MKTAG('m','d','a','t'), mov_read_mdat },
8495 { MKTAG('m','d','h','d'), mov_read_mdhd },
8496 { MKTAG('m','d','i','a'), mov_read_default },
8497 { MKTAG('m','e','t','a'), mov_read_meta },
8498 { MKTAG('m','i','n','f'), mov_read_default },
8499 { MKTAG('m','o','o','f'), mov_read_moof },
8500 { MKTAG('m','o','o','v'), mov_read_moov },
8501 { MKTAG('m','v','e','x'), mov_read_default },
8502 { MKTAG('m','v','h','d'), mov_read_mvhd },
8503 { MKTAG('S','M','I',' '), mov_read_svq3 },
8504 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
8505 { MKTAG('a','v','c','C'), mov_read_glbl },
8506 { MKTAG('p','a','s','p'), mov_read_pasp },
8507 { MKTAG('s','i','d','x'), mov_read_sidx },
8508 { MKTAG('s','t','b','l'), mov_read_default },
8509 { MKTAG('s','t','c','o'), mov_read_stco },
8510 { MKTAG('s','t','p','s'), mov_read_stps },
8511 { MKTAG('s','t','r','f'), mov_read_strf },
8512 { MKTAG('s','t','s','c'), mov_read_stsc },
8513 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
8514 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
8515 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
8516 { MKTAG('s','t','t','s'), mov_read_stts },
8517 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
8518 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
8519 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
8520 { MKTAG('t','f','d','t'), mov_read_tfdt },
8521 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
8522 { MKTAG('t','r','a','k'), mov_read_trak },
8523 { MKTAG('t','r','a','f'), mov_read_default },
8524 { MKTAG('t','r','e','f'), mov_read_default },
8525 { MKTAG('t','m','c','d'), mov_read_tmcd },
8526 { MKTAG('c','h','a','p'), mov_read_chap },
8527 { MKTAG('t','r','e','x'), mov_read_trex },
8528 { MKTAG('t','r','u','n'), mov_read_trun },
8529 { MKTAG('u','d','t','a'), mov_read_default },
8530 { MKTAG('w','a','v','e'), mov_read_wave },
8531 { MKTAG('e','s','d','s'), mov_read_esds },
8532 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
8533 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
8534 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
8535 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
8536 { MKTAG('w','f','e','x'), mov_read_wfex },
8537 { MKTAG('c','m','o','v'), mov_read_cmov },
8538 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout from quicktime */
8539 { MKTAG('c','h','n','l'), mov_read_chnl }, /* channel layout from ISO-14496-12 */
8540 { MKTAG('d','v','c','1'), mov_read_dvc1 },
8541 { MKTAG('s','g','p','d'), mov_read_sgpd },
8542 { MKTAG('s','b','g','p'), mov_read_sbgp },
8543 { MKTAG('h','v','c','C'), mov_read_glbl },
8544 { MKTAG('v','v','c','C'), mov_read_glbl },
8545 { MKTAG('u','u','i','d'), mov_read_uuid },
8546 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
8547 { MKTAG('f','r','e','e'), mov_read_free },
8548 { MKTAG('-','-','-','-'), mov_read_custom },
8549 { MKTAG('s','i','n','f'), mov_read_default },
8550 { MKTAG('f','r','m','a'), mov_read_frma },
8551 { MKTAG('s','e','n','c'), mov_read_senc },
8552 { MKTAG('s','a','i','z'), mov_read_saiz },
8553 { MKTAG('s','a','i','o'), mov_read_saio },
8554 { MKTAG('p','s','s','h'), mov_read_pssh },
8555 { MKTAG('s','c','h','m'), mov_read_schm },
8556 { MKTAG('s','c','h','i'), mov_read_default },
8557 { MKTAG('t','e','n','c'), mov_read_tenc },
8558 { MKTAG('d','f','L','a'), mov_read_dfla },
8559 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
8560 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
8561 { MKTAG('d','O','p','s'), mov_read_dops },
8562 { MKTAG('d','m','l','p'), mov_read_dmlp },
8563 { MKTAG('S','m','D','m'), mov_read_smdm },
8564 { MKTAG('C','o','L','L'), mov_read_coll },
8565 { MKTAG('v','p','c','C'), mov_read_vpcc },
8566 { MKTAG('m','d','c','v'), mov_read_mdcv },
8567 { MKTAG('c','l','l','i'), mov_read_clli },
8568 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
8569 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
8570 { MKTAG('d','v','w','C'), mov_read_dvcc_dvvc },
8571 { MKTAG('k','i','n','d'), mov_read_kind },
8572 { MKTAG('S','A','3','D'), mov_read_SA3D }, /* ambisonic audio box */
8573 { MKTAG('S','A','N','D'), mov_read_SAND }, /* non diegetic audio box */
8574 { MKTAG('i','l','o','c'), mov_read_iloc },
8575 { MKTAG('p','c','m','C'), mov_read_pcmc }, /* PCM configuration box */
8576 { MKTAG('p','i','t','m'), mov_read_pitm },
8577 { MKTAG('e','v','c','C'), mov_read_glbl },
8578 { MKTAG('i','d','a','t'), mov_read_idat },
8579 { MKTAG('i','r','e','f'), mov_read_iref },
8580 { MKTAG('i','s','p','e'), mov_read_ispe },
8581 { MKTAG('i','p','r','p'), mov_read_iprp },
8582 { MKTAG('i','i','n','f'), mov_read_iinf },
8583 { MKTAG('a','m','v','e'), mov_read_amve }, /* ambient viewing environment box */
8584 #if CONFIG_IAMFDEC
8585 { MKTAG('i','a','c','b'), mov_read_iacb },
8586 #endif
8587 { 0, NULL }
8588 };
8589
8590 6081 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
8591 {
8592 6081 int64_t total_size = 0;
8593 MOVAtom a;
8594 int i;
8595
8596
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6081 times.
6081 if (c->atom_depth > 10) {
8597 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
8598 return AVERROR_INVALIDDATA;
8599 }
8600 6081 c->atom_depth ++;
8601
8602
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6081 times.
6081 if (atom.size < 0)
8603 atom.size = INT64_MAX;
8604
2/2
✓ Branch 0 taken 17463 times.
✓ Branch 1 taken 5616 times.
23079 while (total_size <= atom.size - 8) {
8605 17463 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
8606 17463 a.size = avio_rb32(pb);
8607 17463 a.type = avio_rl32(pb);
8608
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 17459 times.
17463 if (avio_feof(pb))
8609 4 break;
8610
3/4
✓ Branch 0 taken 183 times.
✓ Branch 1 taken 17276 times.
✓ Branch 2 taken 183 times.
✗ Branch 3 not taken.
17459 if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
8611
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17459 times.
17459 a.type == MKTAG('h','o','o','v')) &&
8612 a.size >= 8 &&
8613 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
8614 uint32_t type;
8615 avio_skip(pb, 4);
8616 type = avio_rl32(pb);
8617 if (avio_feof(pb))
8618 break;
8619 avio_seek(pb, -8, SEEK_CUR);
8620 if (type == MKTAG('m','v','h','d') ||
8621 type == MKTAG('c','m','o','v')) {
8622 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
8623 a.type = MKTAG('m','o','o','v');
8624 }
8625 }
8626
2/2
✓ Branch 0 taken 14837 times.
✓ Branch 1 taken 2622 times.
17459 if (atom.type != MKTAG('r','o','o','t') &&
8627
2/2
✓ Branch 0 taken 13488 times.
✓ Branch 1 taken 1349 times.
14837 atom.type != MKTAG('m','o','o','v')) {
8628
1/2
✓ Branch 0 taken 13488 times.
✗ Branch 1 not taken.
13488 if (a.type == MKTAG('t','r','a','k') ||
8629
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13488 times.
13488 a.type == MKTAG('m','d','a','t')) {
8630 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
8631 avio_skip(pb, -8);
8632 c->atom_depth --;
8633 461 return 0;
8634 }
8635 }
8636 17459 total_size += 8;
8637
3/4
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 17438 times.
✓ Branch 2 taken 21 times.
✗ Branch 3 not taken.
17459 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
8638 21 a.size = avio_rb64(pb) - 8;
8639 21 total_size += 8;
8640 }
8641 17459 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
8642 17459 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
8643
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 17454 times.
17459 if (a.size == 0) {
8644 5 a.size = atom.size - total_size + 8;
8645 }
8646
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17459 times.
17459 if (a.size < 0)
8647 break;
8648 17459 a.size -= 8;
8649
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17459 times.
17459 if (a.size < 0)
8650 break;
8651 17459 a.size = FFMIN(a.size, atom.size - total_size);
8652
8653
2/2
✓ Branch 0 taken 764030 times.
✓ Branch 1 taken 1780 times.
765810 for (i = 0; mov_default_parse_table[i].type; i++)
8654
2/2
✓ Branch 0 taken 15679 times.
✓ Branch 1 taken 748351 times.
764030 if (mov_default_parse_table[i].type == a.type) {
8655 15679 parse = mov_default_parse_table[i].parse;
8656 15679 break;
8657 }
8658
8659 // container is user data
8660
4/4
✓ Branch 0 taken 1780 times.
✓ Branch 1 taken 15679 times.
✓ Branch 2 taken 1608 times.
✓ Branch 3 taken 172 times.
17459 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
8661
2/2
✓ Branch 0 taken 276 times.
✓ Branch 1 taken 1332 times.
1608 atom.type == MKTAG('i','l','s','t')))
8662 448 parse = mov_read_udta_string;
8663
8664 // Supports parsing the QuickTime Metadata Keys.
8665 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
8666
4/4
✓ Branch 0 taken 1332 times.
✓ Branch 1 taken 16127 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 1323 times.
17459 if (!parse && c->found_hdlr_mdta &&
8667
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 atom.type == MKTAG('m','e','t','a') &&
8668
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 a.type == MKTAG('k','e','y','s') &&
8669
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 c->meta_keys_count == 0) {
8670 9 parse = mov_read_keys;
8671 }
8672
8673
2/2
✓ Branch 0 taken 1323 times.
✓ Branch 1 taken 16136 times.
17459 if (!parse) { /* skip leaf atoms data */
8674 1323 avio_skip(pb, a.size);
8675 } else {
8676 16136 int64_t start_pos = avio_tell(pb);
8677 int64_t left;
8678 16136 int err = parse(c, pb, a);
8679
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16136 times.
16136 if (err < 0) {
8680 c->atom_depth --;
8681 return err;
8682 }
8683
5/6
✓ Branch 0 taken 3061 times.
✓ Branch 1 taken 13075 times.
✓ Branch 2 taken 2765 times.
✓ Branch 3 taken 296 times.
✓ Branch 4 taken 2765 times.
✗ Branch 5 not taken.
16136 if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
8684
6/8
✓ Branch 0 taken 2765 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2765 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2757 times.
✓ Branch 5 taken 8 times.
✓ Branch 6 taken 453 times.
✓ Branch 7 taken 2304 times.
5522 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
8685 2757 start_pos + a.size == avio_size(pb))) {
8686
4/6
✓ Branch 0 taken 461 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 461 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 8 times.
✓ Branch 5 taken 453 times.
461 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
8687 8 c->next_root_atom = start_pos + a.size;
8688 461 c->atom_depth --;
8689 461 return 0;
8690 }
8691 15675 left = a.size - avio_tell(pb) + start_pos;
8692
2/2
✓ Branch 0 taken 1268 times.
✓ Branch 1 taken 14407 times.
15675 if (left > 0) /* skip garbage at atom end */
8693 1268 avio_skip(pb, left);
8694
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 14405 times.
14407 else if (left < 0) {
8695 2 av_log(c->fc, AV_LOG_WARNING,
8696 "overread end of atom '%s' by %"PRId64" bytes\n",
8697 2 av_fourcc2str(a.type), -left);
8698 2 avio_seek(pb, left, SEEK_CUR);
8699 }
8700 }
8701
8702 16998 total_size += a.size;
8703 }
8704
8705
4/4
✓ Branch 0 taken 104 times.
✓ Branch 1 taken 5516 times.
✓ Branch 2 taken 100 times.
✓ Branch 3 taken 4 times.
5620 if (total_size < atom.size && atom.size < 0x7ffff)
8706 100 avio_skip(pb, atom.size - total_size);
8707
8708 5620 c->atom_depth --;
8709 5620 return 0;
8710 }
8711
8712 7128 static int mov_probe(const AVProbeData *p)
8713 {
8714 int64_t offset;
8715 uint32_t tag;
8716 7128 int score = 0;
8717 7128 int moov_offset = -1;
8718
8719 /* check file header */
8720 7128 offset = 0;
8721 8758 for (;;) {
8722 int64_t size;
8723 15886 int minsize = 8;
8724 /* ignore invalid offset */
8725
2/2
✓ Branch 0 taken 7128 times.
✓ Branch 1 taken 8758 times.
15886 if ((offset + 8ULL) > (unsigned int)p->buf_size)
8726 7128 break;
8727 8758 size = AV_RB32(p->buf + offset);
8728
3/4
✓ Branch 0 taken 501 times.
✓ Branch 1 taken 8257 times.
✓ Branch 2 taken 501 times.
✗ Branch 3 not taken.
8758 if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
8729 501 size = AV_RB64(p->buf+offset + 8);
8730 501 minsize = 16;
8731
2/2
✓ Branch 0 taken 55 times.
✓ Branch 1 taken 8202 times.
8257 } else if (size == 0) {
8732 55 size = p->buf_size - offset;
8733 }
8734
2/2
✓ Branch 0 taken 388 times.
✓ Branch 1 taken 8370 times.
8758 if (size < minsize) {
8735 388 offset += 4;
8736 388 continue;
8737 }
8738 8370 tag = AV_RL32(p->buf + offset + 4);
8739
5/6
✓ Branch 0 taken 121 times.
✓ Branch 1 taken 798 times.
✓ Branch 2 taken 339 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 7111 times.
8370 switch(tag) {
8740 /* check for obvious tags */
8741 121 case MKTAG('m','o','o','v'):
8742 121 moov_offset = offset + 4;
8743 919 case MKTAG('m','d','a','t'):
8744 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
8745 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
8746 case MKTAG('f','t','y','p'):
8747
2/2
✓ Branch 0 taken 416 times.
✓ Branch 1 taken 503 times.
919 if (tag == MKTAG('f','t','y','p') &&
8748
1/2
✓ Branch 0 taken 416 times.
✗ Branch 1 not taken.
416 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
8749
1/2
✓ Branch 0 taken 416 times.
✗ Branch 1 not taken.
416 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
8750
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 410 times.
416 || AV_RL32(p->buf + offset + 8) == MKTAG('j','x','l',' ')
8751 )) {
8752 6 score = FFMAX(score, 5);
8753 } else {
8754 913 score = AVPROBE_SCORE_MAX;
8755 }
8756 919 break;
8757 /* those are more common words, so rate then a bit less */
8758 339 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
8759 case MKTAG('w','i','d','e'):
8760 case MKTAG('f','r','e','e'):
8761 case MKTAG('j','u','n','k'):
8762 case MKTAG('p','i','c','t'):
8763 339 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
8764 339 break;
8765 case MKTAG(0x82,0x82,0x7f,0x7d):
8766 score = FFMAX(score, AVPROBE_SCORE_EXTENSION - 5);
8767 break;
8768 1 case MKTAG('s','k','i','p'):
8769 case MKTAG('u','u','i','d'):
8770 case MKTAG('p','r','f','l'):
8771 /* if we only find those cause probedata is too small at least rate them */
8772 1 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
8773 1 break;
8774 }
8775
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8370 times.
8370 if (size > INT64_MAX - offset)
8776 break;
8777 8370 offset += size;
8778 }
8779
4/4
✓ Branch 0 taken 447 times.
✓ Branch 1 taken 6681 times.
✓ Branch 2 taken 121 times.
✓ Branch 3 taken 326 times.
7128 if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
8780 /* moov atom in the header - we should make sure that this is not a
8781 * MOV-packed MPEG-PS */
8782 121 offset = moov_offset;
8783
8784
2/2
✓ Branch 0 taken 118604 times.
✓ Branch 1 taken 121 times.
118725 while (offset < (p->buf_size - 16)) { /* Sufficient space */
8785 /* We found an actual hdlr atom */
8786
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 118472 times.
118604 if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
8787
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 111 times.
132 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
8788
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
8789 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
8790 /* We found a media handler reference atom describing an
8791 * MPEG-PS-in-MOV, return a
8792 * low score to force expanding the probe window until
8793 * mpegps_probe finds what it needs */
8794 return 5;
8795 } else {
8796 /* Keep looking */
8797 118604 offset += 2;
8798 }
8799 }
8800 }
8801
8802 7128 return score;
8803 }
8804
8805 // must be done after parsing all trak because there's no order requirement
8806 2 static void mov_read_chapters(AVFormatContext *s)
8807 {
8808 2 MOVContext *mov = s->priv_data;
8809 MOVStreamContext *sc;
8810 int64_t cur_pos;
8811 int i, j;
8812 int chapter_track;
8813
8814
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 for (j = 0; j < mov->nb_chapter_tracks; j++) {
8815 2 AVStream *st = NULL;
8816 2 FFStream *sti = NULL;
8817 2 chapter_track = mov->chapter_tracks[j];
8818
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 for (i = 0; i < s->nb_streams; i++) {
8819 4 sc = mov->fc->streams[i]->priv_data;
8820
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (sc->id == chapter_track) {
8821 2 st = s->streams[i];
8822 2 break;
8823 }
8824 }
8825
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!st) {
8826 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
8827 continue;
8828 }
8829 2 sti = ffstream(st);
8830
8831 2 sc = st->priv_data;
8832 2 cur_pos = avio_tell(sc->pb);
8833
8834
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
8835 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
8836 if (!st->attached_pic.data && sti->nb_index_entries) {
8837 // Retrieve the first frame, if possible
8838 AVIndexEntry *sample = &sti->index_entries[0];
8839 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
8840 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
8841 goto finish;
8842 }
8843
8844 if (ff_add_attached_pic(s, st, sc->pb, NULL, sample->size) < 0)
8845 goto finish;
8846 }
8847 } else {
8848 2 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
8849 2 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
8850 2 st->discard = AVDISCARD_ALL;
8851
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 2 times.
10 for (int i = 0; i < sti->nb_index_entries; i++) {
8852 8 AVIndexEntry *sample = &sti->index_entries[i];
8853
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
8 int64_t end = i+1 < sti->nb_index_entries ? sti->index_entries[i+1].timestamp : st->duration;
8854 uint8_t *title;
8855 uint16_t ch;
8856 int len, title_len;
8857
8858
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (end < sample->timestamp) {
8859 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
8860 end = AV_NOPTS_VALUE;
8861 }
8862
8863
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
8864 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
8865 goto finish;
8866 }
8867
8868 // the first two bytes are the length of the title
8869 8 len = avio_rb16(sc->pb);
8870
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (len > sample->size-2)
8871 continue;
8872 8 title_len = 2*len + 1;
8873
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 if (!(title = av_mallocz(title_len)))
8874 goto finish;
8875
8876 // The samples could theoretically be in any encoding if there's an encd
8877 // atom following, but in practice are only utf-8 or utf-16, distinguished
8878 // instead by the presence of a BOM
8879
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (!len) {
8880 title[0] = 0;
8881 } else {
8882 8 ch = avio_rb16(sc->pb);
8883
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (ch == 0xfeff)
8884 avio_get_str16be(sc->pb, len, title, title_len);
8885
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 else if (ch == 0xfffe)
8886 avio_get_str16le(sc->pb, len, title, title_len);
8887 else {
8888 8 AV_WB16(title, ch);
8889
2/4
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
8 if (len == 1 || len == 2)
8890 title[len] = 0;
8891 else
8892 8 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
8893 }
8894 }
8895
8896 8 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
8897 8 av_freep(&title);
8898 }
8899 }
8900 2 finish:
8901 2 avio_seek(sc->pb, cur_pos, SEEK_SET);
8902 }
8903 2 }
8904
8905 19 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
8906 int64_t value, int flags)
8907 {
8908 AVTimecode tc;
8909 char buf[AV_TIMECODE_STR_SIZE];
8910 19 AVRational rate = st->avg_frame_rate;
8911 19 int ret = av_timecode_init(&tc, rate, flags, 0, s);
8912
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
19 if (ret < 0)
8913 return ret;
8914 19 av_dict_set(&st->metadata, "timecode",
8915 19 av_timecode_make_string(&tc, buf, value), 0);
8916 19 return 0;
8917 }
8918
8919 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
8920 {
8921 MOVStreamContext *sc = st->priv_data;
8922 FFStream *const sti = ffstream(st);
8923 char buf[AV_TIMECODE_STR_SIZE];
8924 int64_t cur_pos = avio_tell(sc->pb);
8925 int hh, mm, ss, ff, drop;
8926
8927 if (!sti->nb_index_entries)
8928 return -1;
8929
8930 avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
8931 avio_skip(s->pb, 13);
8932 hh = avio_r8(s->pb);
8933 mm = avio_r8(s->pb);
8934 ss = avio_r8(s->pb);
8935 drop = avio_r8(s->pb);
8936 ff = avio_r8(s->pb);
8937 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
8938 hh, mm, ss, drop ? ';' : ':', ff);
8939 av_dict_set(&st->metadata, "timecode", buf, 0);
8940
8941 avio_seek(sc->pb, cur_pos, SEEK_SET);
8942 return 0;
8943 }
8944
8945 19 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
8946 {
8947 19 MOVStreamContext *sc = st->priv_data;
8948 19 FFStream *const sti = ffstream(st);
8949 19 int flags = 0;
8950 19 int64_t cur_pos = avio_tell(sc->pb);
8951 int64_t value;
8952 19 AVRational tc_rate = st->avg_frame_rate;
8953 19 int tmcd_nb_frames = sc->tmcd_nb_frames;
8954 int rounded_tc_rate;
8955
8956
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
19 if (!sti->nb_index_entries)
8957 return -1;
8958
8959
3/6
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 19 times.
19 if (!tc_rate.num || !tc_rate.den || !tmcd_nb_frames)
8960 return -1;
8961
8962 19 avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
8963 19 value = avio_rb32(s->pb);
8964
8965
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 13 times.
19 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
8966
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 18 times.
19 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
8967
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 18 times.
19 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
8968
8969 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
8970 * not the case) and thus assume "frame number format" instead of QT one.
8971 * No sample with tmcd track can be found with a QT timecode at the moment,
8972 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
8973 * format). */
8974
8975 /* 60 fps content have tmcd_nb_frames set to 30 but tc_rate set to 60, so
8976 * we multiply the frame number with the quotient.
8977 * See tickets #9492, #9710. */
8978 19 rounded_tc_rate = (tc_rate.num + tc_rate.den / 2LL) / tc_rate.den;
8979 /* Work around files where tmcd_nb_frames is rounded down from frame rate
8980 * instead of up. See ticket #5978. */
8981
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 9 times.
19 if (tmcd_nb_frames == tc_rate.num / tc_rate.den &&
8982
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 s->strict_std_compliance < FF_COMPLIANCE_STRICT)
8983 10 tmcd_nb_frames = rounded_tc_rate;
8984 19 value = av_rescale(value, rounded_tc_rate, tmcd_nb_frames);
8985
8986 19 parse_timecode_in_framenum_format(s, st, value, flags);
8987
8988 19 avio_seek(sc->pb, cur_pos, SEEK_SET);
8989 19 return 0;
8990 }
8991
8992 1011 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
8993 int i;
8994
3/4
✓ Branch 0 taken 1011 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1007 times.
✓ Branch 3 taken 4 times.
1011 if (!index || !*index) return;
8995
2/2
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 4 times.
76 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
8996 72 av_encryption_info_free((*index)->encrypted_samples[i]);
8997 }
8998 4 av_freep(&(*index)->encrypted_samples);
8999 4 av_freep(&(*index)->auxiliary_info_sizes);
9000 4 av_freep(&(*index)->auxiliary_offsets);
9001 4 av_freep(index);
9002 }
9003
9004 632 static void mov_free_stream_context(AVFormatContext *s, AVStream *st)
9005 {
9006 632 MOVStreamContext *sc = st->priv_data;
9007
9008
3/4
✓ Branch 0 taken 632 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 604 times.
632 if (!sc || --sc->refcount) {
9009 28 st->priv_data = NULL;
9010 28 return;
9011 }
9012
9013 604 av_freep(&sc->ctts_data);
9014
2/2
✓ Branch 0 taken 571 times.
✓ Branch 1 taken 604 times.
1175 for (int i = 0; i < sc->drefs_count; i++) {
9015 571 av_freep(&sc->drefs[i].path);
9016 571 av_freep(&sc->drefs[i].dir);
9017 }
9018 604 av_freep(&sc->drefs);
9019
9020 604 sc->drefs_count = 0;
9021
9022
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 590 times.
604 if (!sc->pb_is_copied)
9023 14 ff_format_io_close(s, &sc->pb);
9024
9025 604 sc->pb = NULL;
9026 604 av_freep(&sc->chunk_offsets);
9027 604 av_freep(&sc->stsc_data);
9028 604 av_freep(&sc->sample_sizes);
9029 604 av_freep(&sc->keyframes);
9030 604 av_freep(&sc->stts_data);
9031 604 av_freep(&sc->sdtp_data);
9032 604 av_freep(&sc->stps_data);
9033 604 av_freep(&sc->elst_data);
9034 604 av_freep(&sc->rap_group);
9035 604 av_freep(&sc->sync_group);
9036 604 av_freep(&sc->sgpd_sync);
9037 604 av_freep(&sc->sample_offsets);
9038 604 av_freep(&sc->open_key_samples);
9039 604 av_freep(&sc->display_matrix);
9040 604 av_freep(&sc->index_ranges);
9041
9042
2/2
✓ Branch 0 taken 571 times.
✓ Branch 1 taken 33 times.
604 if (sc->extradata)
9043
2/2
✓ Branch 0 taken 582 times.
✓ Branch 1 taken 571 times.
1153 for (int i = 0; i < sc->stsd_count; i++)
9044 582 av_free(sc->extradata[i]);
9045 604 av_freep(&sc->extradata);
9046 604 av_freep(&sc->extradata_size);
9047
9048 604 mov_free_encryption_index(&sc->cenc.encryption_index);
9049 604 av_encryption_info_free(sc->cenc.default_encrypted_sample);
9050 604 av_aes_ctr_free(sc->cenc.aes_ctr);
9051
9052 604 av_freep(&sc->stereo3d);
9053 604 av_freep(&sc->spherical);
9054 604 av_freep(&sc->mastering);
9055 604 av_freep(&sc->coll);
9056 604 av_freep(&sc->ambient);
9057
9058 #if CONFIG_IAMFDEC
9059
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 596 times.
604 if (sc->iamf)
9060 8 ff_iamf_read_deinit(sc->iamf);
9061 #endif
9062 604 av_freep(&sc->iamf);
9063 }
9064
9065 475 static int mov_read_close(AVFormatContext *s)
9066 {
9067 475 MOVContext *mov = s->priv_data;
9068 int i, j;
9069
9070
2/2
✓ Branch 0 taken 632 times.
✓ Branch 1 taken 475 times.
1107 for (i = 0; i < s->nb_streams; i++) {
9071 632 AVStream *st = s->streams[i];
9072
9073 632 mov_free_stream_context(s, st);
9074 }
9075
9076 475 av_freep(&mov->dv_demux);
9077 475 avformat_free_context(mov->dv_fctx);
9078 475 mov->dv_fctx = NULL;
9079
9080
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 466 times.
475 if (mov->meta_keys) {
9081
2/2
✓ Branch 0 taken 44 times.
✓ Branch 1 taken 9 times.
53 for (i = 1; i < mov->meta_keys_count; i++) {
9082 44 av_freep(&mov->meta_keys[i]);
9083 }
9084 9 av_freep(&mov->meta_keys);
9085 }
9086
9087 475 av_freep(&mov->trex_data);
9088 475 av_freep(&mov->bitrates);
9089
9090
2/2
✓ Branch 0 taken 389 times.
✓ Branch 1 taken 475 times.
864 for (i = 0; i < mov->frag_index.nb_items; i++) {
9091 389 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
9092
2/2
✓ Branch 0 taken 407 times.
✓ Branch 1 taken 389 times.
796 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
9093 407 mov_free_encryption_index(&frag[j].encryption_index);
9094 }
9095 389 av_freep(&mov->frag_index.item[i].stream_info);
9096 }
9097 475 av_freep(&mov->frag_index.item);
9098
9099 475 av_freep(&mov->aes_decrypt);
9100 475 av_freep(&mov->chapter_tracks);
9101
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 475 times.
501 for (i = 0; i < mov->nb_heif_item; i++)
9102 26 av_freep(&mov->heif_item[i].name);
9103 475 av_freep(&mov->heif_item);
9104
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 475 times.
481 for (i = 0; i < mov->nb_heif_grid; i++) {
9105 6 av_freep(&mov->heif_grid[i].tile_id_list);
9106 6 av_freep(&mov->heif_grid[i].tile_item_list);
9107 }
9108 475 av_freep(&mov->heif_grid);
9109
9110 475 return 0;
9111 }
9112
9113 16 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
9114 {
9115 int i;
9116
9117
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 2 times.
26 for (i = 0; i < s->nb_streams; i++) {
9118 24 AVStream *st = s->streams[i];
9119 24 MOVStreamContext *sc = st->priv_data;
9120
9121
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 8 times.
24 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
9122
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 2 times.
16 sc->timecode_track == tmcd_id)
9123 14 return 1;
9124 }
9125 2 return 0;
9126 }
9127
9128 /* look for a tmcd track not referenced by any video track, and export it globally */
9129 475 static void export_orphan_timecode(AVFormatContext *s)
9130 {
9131 int i;
9132
9133
2/2
✓ Branch 0 taken 629 times.
✓ Branch 1 taken 473 times.
1102 for (i = 0; i < s->nb_streams; i++) {
9134 629 AVStream *st = s->streams[i];
9135
9136
4/4
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 613 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 14 times.
645 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
9137 16 !tmcd_is_referenced(s, i + 1)) {
9138 2 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
9139
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (tcr) {
9140 2 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
9141 2 break;
9142 }
9143 }
9144 }
9145 475 }
9146
9147 static int read_tfra(MOVContext *mov, AVIOContext *f)
9148 {
9149 int version, fieldlength, i, j;
9150 int64_t pos = avio_tell(f);
9151 uint32_t size = avio_rb32(f);
9152 unsigned track_id, item_count;
9153
9154 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
9155 return 1;
9156 }
9157 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
9158
9159 version = avio_r8(f);
9160 avio_rb24(f);
9161 track_id = avio_rb32(f);
9162 fieldlength = avio_rb32(f);
9163 item_count = avio_rb32(f);
9164 for (i = 0; i < item_count; i++) {
9165 int64_t time, offset;
9166 int index;
9167 MOVFragmentStreamInfo * frag_stream_info;
9168
9169 if (avio_feof(f)) {
9170 return AVERROR_INVALIDDATA;
9171 }
9172
9173 if (version == 1) {
9174 time = avio_rb64(f);
9175 offset = avio_rb64(f);
9176 } else {
9177 time = avio_rb32(f);
9178 offset = avio_rb32(f);
9179 }
9180
9181 // The first sample of each stream in a fragment is always a random
9182 // access sample. So it's entry in the tfra can be used as the
9183 // initial PTS of the fragment.
9184 index = update_frag_index(mov, offset);
9185 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
9186 if (frag_stream_info &&
9187 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
9188 frag_stream_info->first_tfra_pts = time;
9189
9190 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
9191 avio_r8(f);
9192 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
9193 avio_r8(f);
9194 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
9195 avio_r8(f);
9196 }
9197
9198 avio_seek(f, pos + size, SEEK_SET);
9199 return 0;
9200 }
9201
9202 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
9203 {
9204 int64_t stream_size = avio_size(f);
9205 int64_t original_pos = avio_tell(f);
9206 int64_t seek_ret;
9207 int ret = -1;
9208 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
9209 ret = seek_ret;
9210 goto fail;
9211 }
9212 c->mfra_size = avio_rb32(f);
9213 c->have_read_mfra_size = 1;
9214 if (!c->mfra_size || c->mfra_size > stream_size) {
9215 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
9216 goto fail;
9217 }
9218 if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
9219 ret = seek_ret;
9220 goto fail;
9221 }
9222 if (avio_rb32(f) != c->mfra_size) {
9223 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
9224 goto fail;
9225 }
9226 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
9227 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
9228 goto fail;
9229 }
9230 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
9231 do {
9232 ret = read_tfra(c, f);
9233 if (ret < 0)
9234 goto fail;
9235 } while (!ret);
9236 ret = 0;
9237 c->frag_index.complete = 1;
9238 fail:
9239 seek_ret = avio_seek(f, original_pos, SEEK_SET);
9240 if (seek_ret < 0) {
9241 av_log(c->fc, AV_LOG_ERROR,
9242 "failed to seek back after looking for mfra\n");
9243 ret = seek_ret;
9244 }
9245 return ret;
9246 }
9247
9248 2 static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid,
9249 AVStreamGroupTileGrid *tile_grid)
9250 {
9251 2 MOVContext *c = s->priv_data;
9252 2 const HEIFItem *item = grid->item;
9253 2 int64_t offset = 0, pos = avio_tell(s->pb);
9254 2 int x = 0, y = 0, i = 0;
9255 int tile_rows, tile_cols;
9256 int flags, size;
9257
9258
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
9259 av_log(c->fc, AV_LOG_INFO, "grid box with non seekable input\n");
9260 return AVERROR_PATCHWELCOME;
9261 }
9262
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (item->is_idat_relative) {
9263
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!c->idat_offset) {
9264 av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image grid\n");
9265 return AVERROR_INVALIDDATA;
9266 }
9267 2 offset = c->idat_offset;
9268 }
9269
9270 2 avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
9271
9272 2 avio_r8(s->pb); /* version */
9273 2 flags = avio_r8(s->pb);
9274
9275 2 tile_rows = avio_r8(s->pb) + 1;
9276 2 tile_cols = avio_r8(s->pb) + 1;
9277 /* actual width and height of output image */
9278
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 tile_grid->width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
9279
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 tile_grid->height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
9280
9281 2 av_log(c->fc, AV_LOG_TRACE, "grid: grid_rows %d grid_cols %d output_width %d output_height %d\n",
9282 tile_rows, tile_cols, tile_grid->width, tile_grid->height);
9283
9284 2 avio_seek(s->pb, pos, SEEK_SET);
9285
9286 2 size = tile_rows * tile_cols;
9287 2 tile_grid->nb_tiles = grid->nb_tiles;
9288
9289
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (tile_grid->nb_tiles != size)
9290 return AVERROR_INVALIDDATA;
9291
9292
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 for (int i = 0; i < tile_cols; i++)
9293 4 tile_grid->coded_width += grid->tile_item_list[i]->width;
9294
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 for (int i = 0; i < size; i += tile_cols)
9295 4 tile_grid->coded_height += grid->tile_item_list[i]->height;
9296
9297 2 tile_grid->offsets = av_calloc(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
9298
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!tile_grid->offsets)
9299 return AVERROR(ENOMEM);
9300
9301
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 while (y < tile_grid->coded_height) {
9302 4 int left_col = i;
9303
9304
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
12 while (x < tile_grid->coded_width) {
9305
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (i == tile_grid->nb_tiles)
9306 return AVERROR_INVALIDDATA;
9307
9308 8 tile_grid->offsets[i].idx = i;
9309 8 tile_grid->offsets[i].horizontal = x;
9310 8 tile_grid->offsets[i].vertical = y;
9311
9312 8 x += grid->tile_item_list[i++]->width;
9313 }
9314
9315
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (x > tile_grid->coded_width) {
9316 av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
9317 return AVERROR_INVALIDDATA;
9318 }
9319
9320 4 x = 0;
9321 4 y += grid->tile_item_list[left_col]->height;
9322 }
9323
9324
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
2 if (y > tile_grid->coded_height || i != tile_grid->nb_tiles) {
9325 av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
9326 return AVERROR_INVALIDDATA;
9327 }
9328
9329 2 return 0;
9330 }
9331
9332 4 static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid,
9333 AVStreamGroupTileGrid *tile_grid)
9334 {
9335 4 MOVContext *c = s->priv_data;
9336 4 const HEIFItem *item = grid->item;
9337 uint16_t canvas_fill_value[4];
9338 4 int64_t offset = 0, pos = avio_tell(s->pb);
9339 4 int ret = 0, flags;
9340
9341
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
9342 av_log(c->fc, AV_LOG_INFO, "iovl box with non seekable input\n");
9343 return AVERROR_PATCHWELCOME;
9344 }
9345
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (item->is_idat_relative) {
9346
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!c->idat_offset) {
9347 av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image overlay\n");
9348 return AVERROR_INVALIDDATA;
9349 }
9350 4 offset = c->idat_offset;
9351 }
9352
9353 4 avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
9354
9355 4 avio_r8(s->pb); /* version */
9356 4 flags = avio_r8(s->pb);
9357
9358
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 4 times.
20 for (int i = 0; i < 4; i++)
9359 16 canvas_fill_value[i] = avio_rb16(s->pb);
9360 4 av_log(c->fc, AV_LOG_TRACE, "iovl: canvas_fill_value { %u, %u, %u, %u }\n",
9361 4 canvas_fill_value[0], canvas_fill_value[1],
9362 4 canvas_fill_value[2], canvas_fill_value[3]);
9363
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 4 times.
20 for (int i = 0; i < 4; i++)
9364 16 tile_grid->background[i] = canvas_fill_value[i];
9365
9366 /* actual width and height of output image */
9367 4 tile_grid->width =
9368
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 tile_grid->coded_width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
9369 4 tile_grid->height =
9370
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 tile_grid->coded_height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
9371 4 av_log(c->fc, AV_LOG_TRACE, "iovl: output_width %d, output_height %d\n",
9372 tile_grid->width, tile_grid->height);
9373
9374 4 tile_grid->nb_tiles = grid->nb_tiles;
9375 4 tile_grid->offsets = av_malloc_array(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
9376
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!tile_grid->offsets) {
9377 ret = AVERROR(ENOMEM);
9378 goto fail;
9379 }
9380
9381
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
12 for (int i = 0; i < tile_grid->nb_tiles; i++) {
9382 8 tile_grid->offsets[i].idx = grid->tile_item_list[i]->st->index;
9383
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 tile_grid->offsets[i].horizontal = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
9384
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 tile_grid->offsets[i].vertical = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
9385 8 av_log(c->fc, AV_LOG_TRACE, "iovl: stream_idx[%d] %u, "
9386 "horizontal_offset[%d] %d, vertical_offset[%d] %d\n",
9387 8 i, tile_grid->offsets[i].idx,
9388 8 i, tile_grid->offsets[i].horizontal, i, tile_grid->offsets[i].vertical);
9389 }
9390
9391 4 fail:
9392 4 avio_seek(s->pb, pos, SEEK_SET);
9393
9394 4 return ret;
9395 }
9396
9397 6 static int mov_parse_tiles(AVFormatContext *s)
9398 {
9399 6 MOVContext *mov = s->priv_data;
9400
9401
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 for (int i = 0; i < mov->nb_heif_grid; i++) {
9402 6 AVStreamGroup *stg = avformat_stream_group_create(s, AV_STREAM_GROUP_PARAMS_TILE_GRID, NULL);
9403 AVStreamGroupTileGrid *tile_grid;
9404 6 const HEIFGrid *grid = &mov->heif_grid[i];
9405 6 int err, loop = 1;
9406
9407
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!stg)
9408 return AVERROR(ENOMEM);
9409
9410 6 stg->id = grid->item->item_id;
9411 6 tile_grid = stg->params.tile_grid;
9412
9413
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 6 times.
22 for (int j = 0; j < grid->nb_tiles; j++) {
9414 16 int tile_id = grid->tile_id_list[j];
9415 int k;
9416
9417
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 for (k = 0; k < mov->nb_heif_item; k++) {
9418 30 HEIFItem *item = &mov->heif_item[k];
9419 30 AVStream *st = item->st;
9420
9421
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 16 times.
30 if (item->item_id != tile_id)
9422 14 continue;
9423
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (!st) {
9424 av_log(s, AV_LOG_WARNING, "HEIF item id %d from grid id %d doesn't "
9425 "reference a stream\n",
9426 tile_id, grid->item->item_id);
9427 ff_remove_stream_group(s, stg);
9428 loop = 0;
9429 break;
9430 }
9431
9432 16 grid->tile_item_list[j] = item;
9433
9434 16 err = avformat_stream_group_add_stream(stg, st);
9435
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
16 if (err < 0 && err != AVERROR(EEXIST))
9436 return err;
9437
9438
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 6 times.
16 if (item->item_id != mov->primary_item_id)
9439 10 st->disposition |= AV_DISPOSITION_DEPENDENT;
9440 16 break;
9441 }
9442
9443
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (k == grid->nb_tiles) {
9444 av_log(s, AV_LOG_WARNING, "HEIF item id %d referenced by grid id %d doesn't "
9445 "exist\n",
9446 tile_id, grid->item->item_id);
9447 ff_remove_stream_group(s, stg);
9448 loop = 0;
9449 }
9450
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (!loop)
9451 break;
9452 }
9453
9454
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!loop)
9455 continue;
9456
9457
2/3
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
6 switch (grid->item->type) {
9458 2 case MKTAG('g','r','i','d'):
9459 2 err = read_image_grid(s, grid, tile_grid);
9460 2 break;
9461 4 case MKTAG('i','o','v','l'):
9462 4 err = read_image_iovl(s, grid, tile_grid);
9463 4 break;
9464 default:
9465 av_assert0(0);
9466 }
9467
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (err < 0)
9468 return err;
9469
9470
9471
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (grid->item->name)
9472 6 av_dict_set(&stg->metadata, "title", grid->item->name, 0);
9473
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
6 if (grid->item->item_id == mov->primary_item_id)
9474 2 stg->disposition |= AV_DISPOSITION_DEFAULT;
9475 }
9476
9477 6 return 0;
9478 }
9479
9480 475 static int mov_read_header(AVFormatContext *s)
9481 {
9482 475 MOVContext *mov = s->priv_data;
9483 475 AVIOContext *pb = s->pb;
9484 int j, err;
9485 475 MOVAtom atom = { AV_RL32("root") };
9486 int i;
9487
9488
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 472 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
475 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
9489 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
9490 mov->decryption_key_len, AES_CTR_KEY_SIZE);
9491 return AVERROR(EINVAL);
9492 }
9493
9494 475 mov->fc = s;
9495 475 mov->trak_index = -1;
9496 475 mov->thmb_item_id = -1;
9497 475 mov->primary_item_id = -1;
9498 475 mov->cur_item_id = -1;
9499 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
9500
1/2
✓ Branch 0 taken 475 times.
✗ Branch 1 not taken.
475 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
9501 475 atom.size = avio_size(pb);
9502 else
9503 atom.size = INT64_MAX;
9504
9505 /* check MOV header */
9506 do {
9507
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 475 times.
475 if (mov->moov_retry)
9508 avio_seek(pb, 0, SEEK_SET);
9509
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 475 times.
475 if ((err = mov_read_default(mov, pb, atom)) < 0) {
9510 av_log(s, AV_LOG_ERROR, "error reading header\n");
9511 return err;
9512 }
9513 950 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) &&
9514
5/10
✓ Branch 0 taken 475 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 465 times.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 10 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
475 !mov->found_moov && (!mov->found_iloc || !mov->found_iinf) && !mov->moov_retry++);
9515
3/6
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 465 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
475 if (!mov->found_moov && !mov->found_iloc && !mov->found_iinf) {
9516 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
9517 return AVERROR_INVALIDDATA;
9518 }
9519 475 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
9520
9521
3/4
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 465 times.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
475 if (mov->found_iloc && mov->found_iinf) {
9522
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 10 times.
36 for (i = 0; i < mov->nb_heif_item; i++) {
9523 26 HEIFItem *item = &mov->heif_item[i];
9524 MOVStreamContext *sc;
9525 AVStream *st;
9526 26 int64_t offset = 0;
9527
9528
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 19 times.
26 if (!item->st) {
9529
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (item->item_id == mov->thmb_item_id) {
9530 av_log(s, AV_LOG_ERROR, "HEIF thumbnail doesn't reference a stream\n");
9531 return AVERROR_INVALIDDATA;
9532 }
9533 7 continue;
9534 }
9535
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
19 if (item->is_idat_relative) {
9536 if (!mov->idat_offset) {
9537 av_log(s, AV_LOG_ERROR, "Missing idat box for item %d\n", item->item_id);
9538 return AVERROR_INVALIDDATA;
9539 }
9540 offset = mov->idat_offset;
9541 }
9542
9543 19 st = item->st;
9544 19 sc = st->priv_data;
9545 19 st->codecpar->width = item->width;
9546 19 st->codecpar->height = item->height;
9547
9548 19 sc->sample_sizes[0] = item->extent_length;
9549 19 sc->chunk_offsets[0] = item->extent_offset + offset;
9550
9551
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 11 times.
19 if (item->item_id == mov->primary_item_id)
9552 8 st->disposition |= AV_DISPOSITION_DEFAULT;
9553
9554 19 mov_build_index(mov, st);
9555 }
9556
9557
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 4 times.
10 if (mov->nb_heif_grid) {
9558 6 err = mov_parse_tiles(s);
9559
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (err < 0)
9560 return err;
9561 }
9562 }
9563
9564
1/2
✓ Branch 0 taken 475 times.
✗ Branch 1 not taken.
475 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
9565
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 473 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
475 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
9566 2 mov_read_chapters(s);
9567
2/2
✓ Branch 0 taken 632 times.
✓ Branch 1 taken 475 times.
1107 for (i = 0; i < s->nb_streams; i++)
9568
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 613 times.
632 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
9569 19 mov_read_timecode_track(s, s->streams[i]);
9570
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 613 times.
613 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
9571 mov_read_rtmd_track(s, s->streams[i]);
9572 }
9573 }
9574
9575 /* copy timecode metadata from tmcd tracks to the related video streams */
9576
2/2
✓ Branch 0 taken 632 times.
✓ Branch 1 taken 475 times.
1107 for (i = 0; i < s->nb_streams; i++) {
9577 632 AVStream *st = s->streams[i];
9578 632 MOVStreamContext *sc = st->priv_data;
9579
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 614 times.
632 if (sc->timecode_track > 0) {
9580 AVDictionaryEntry *tcr;
9581 18 int tmcd_st_id = -1;
9582
9583
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 18 times.
66 for (j = 0; j < s->nb_streams; j++) {
9584 48 MOVStreamContext *sc2 = s->streams[j]->priv_data;
9585
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 30 times.
48 if (sc2->id == sc->timecode_track)
9586 18 tmcd_st_id = j;
9587 }
9588
9589
2/4
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 18 times.
18 if (tmcd_st_id < 0 || tmcd_st_id == i)
9590 continue;
9591 18 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
9592
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 2 times.
18 if (tcr)
9593 16 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
9594 }
9595 }
9596 475 export_orphan_timecode(s);
9597
9598
2/2
✓ Branch 0 taken 632 times.
✓ Branch 1 taken 475 times.
1107 for (i = 0; i < s->nb_streams; i++) {
9599 632 AVStream *st = s->streams[i];
9600 632 FFStream *const sti = ffstream(st);
9601 632 MOVStreamContext *sc = st->priv_data;
9602 632 fix_timescale(mov, sc);
9603
2/2
✓ Branch 0 taken 264 times.
✓ Branch 1 taken 368 times.
632 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
9604
2/2
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 150 times.
264 st->codecpar->codec_id == AV_CODEC_ID_AAC) {
9605 114 sti->skip_samples = sc->start_pad;
9606 }
9607
5/6
✓ Branch 0 taken 319 times.
✓ Branch 1 taken 313 times.
✓ Branch 2 taken 286 times.
✓ Branch 3 taken 33 times.
✓ Branch 4 taken 286 times.
✗ Branch 5 not taken.
632 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
9608 286 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
9609 286 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
9610
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 624 times.
632 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
9611
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
8 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
9612 4 st->codecpar->width = sc->width;
9613 4 st->codecpar->height = sc->height;
9614 }
9615
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
9616 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
9617 return err;
9618 }
9619 }
9620
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 632 times.
632 if (mov->handbrake_version &&
9621 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
9622 st->codecpar->codec_id == AV_CODEC_ID_MP3) {
9623 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
9624 sti->need_parsing = AVSTREAM_PARSE_FULL;
9625 }
9626 }
9627
9628
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 464 times.
475 if (mov->trex_data) {
9629
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 11 times.
26 for (i = 0; i < s->nb_streams; i++) {
9630 15 AVStream *st = s->streams[i];
9631 15 MOVStreamContext *sc = st->priv_data;
9632
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 3 times.
15 if (st->duration > 0) {
9633 /* Akin to sc->data_size * 8 * sc->time_scale / st->duration but accounting for overflows. */
9634 12 st->codecpar->bit_rate = av_rescale(sc->data_size, ((int64_t) sc->time_scale) * 8, st->duration);
9635
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (st->codecpar->bit_rate == INT64_MIN) {
9636 av_log(s, AV_LOG_WARNING, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
9637 sc->data_size, sc->time_scale);
9638 st->codecpar->bit_rate = 0;
9639 if (s->error_recognition & AV_EF_EXPLODE)
9640 return AVERROR_INVALIDDATA;
9641 }
9642 }
9643 }
9644 }
9645
9646
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 475 times.
475 if (mov->use_mfra_for > 0) {
9647 for (i = 0; i < s->nb_streams; i++) {
9648 AVStream *st = s->streams[i];
9649 MOVStreamContext *sc = st->priv_data;
9650 if (sc->duration_for_fps > 0) {
9651 /* Akin to sc->data_size * 8 * sc->time_scale / sc->duration_for_fps but accounting for overflows. */
9652 st->codecpar->bit_rate = av_rescale(sc->data_size, ((int64_t) sc->time_scale) * 8, sc->duration_for_fps);
9653 if (st->codecpar->bit_rate == INT64_MIN) {
9654 av_log(s, AV_LOG_WARNING, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
9655 sc->data_size, sc->time_scale);
9656 st->codecpar->bit_rate = 0;
9657 if (s->error_recognition & AV_EF_EXPLODE)
9658 return AVERROR_INVALIDDATA;
9659 }
9660 }
9661 }
9662 }
9663
9664
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 475 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
475 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
9665 if (mov->bitrates[i]) {
9666 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
9667 }
9668 }
9669
9670 475 ff_rfps_calculate(s);
9671
9672
2/2
✓ Branch 0 taken 632 times.
✓ Branch 1 taken 475 times.
1107 for (i = 0; i < s->nb_streams; i++) {
9673 632 AVStream *st = s->streams[i];
9674 632 MOVStreamContext *sc = st->priv_data;
9675
9676
3/3
✓ Branch 0 taken 264 times.
✓ Branch 1 taken 319 times.
✓ Branch 2 taken 49 times.
632 switch (st->codecpar->codec_type) {
9677 264 case AVMEDIA_TYPE_AUDIO:
9678 264 err = ff_replaygain_export(st, s->metadata);
9679
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 264 times.
264 if (err < 0)
9680 return err;
9681 264 break;
9682 319 case AVMEDIA_TYPE_VIDEO:
9683
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 311 times.
319 if (sc->display_matrix) {
9684
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (!av_packet_side_data_add(&st->codecpar->coded_side_data, &st->codecpar->nb_coded_side_data,
9685 AV_PKT_DATA_DISPLAYMATRIX,
9686 8 (uint8_t*)sc->display_matrix, sizeof(int32_t) * 9, 0))
9687 return AVERROR(ENOMEM);
9688
9689 8 sc->display_matrix = NULL;
9690 }
9691
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 318 times.
319 if (sc->stereo3d) {
9692
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!av_packet_side_data_add(&st->codecpar->coded_side_data, &st->codecpar->nb_coded_side_data,
9693 AV_PKT_DATA_STEREO3D,
9694 1 (uint8_t *)sc->stereo3d, sizeof(*sc->stereo3d), 0))
9695 return AVERROR(ENOMEM);
9696
9697 1 sc->stereo3d = NULL;
9698 }
9699
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 318 times.
319 if (sc->spherical) {
9700
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!av_packet_side_data_add(&st->codecpar->coded_side_data, &st->codecpar->nb_coded_side_data,
9701 AV_PKT_DATA_SPHERICAL,
9702 1 (uint8_t *)sc->spherical, sc->spherical_size, 0))
9703 return AVERROR(ENOMEM);
9704
9705 1 sc->spherical = NULL;
9706 }
9707
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 319 times.
319 if (sc->mastering) {
9708 if (!av_packet_side_data_add(&st->codecpar->coded_side_data, &st->codecpar->nb_coded_side_data,
9709 AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
9710 (uint8_t *)sc->mastering, sizeof(*sc->mastering), 0))
9711 return AVERROR(ENOMEM);
9712
9713 sc->mastering = NULL;
9714 }
9715
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 319 times.
319 if (sc->coll) {
9716 if (!av_packet_side_data_add(&st->codecpar->coded_side_data, &st->codecpar->nb_coded_side_data,
9717 AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
9718 (uint8_t *)sc->coll, sc->coll_size, 0))
9719 return AVERROR(ENOMEM);
9720
9721 sc->coll = NULL;
9722 }
9723
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 315 times.
319 if (sc->ambient) {
9724
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!av_packet_side_data_add(&st->codecpar->coded_side_data, &st->codecpar->nb_coded_side_data,
9725 AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT,
9726 4 (uint8_t *) sc->ambient, sc->ambient_size, 0))
9727 return AVERROR(ENOMEM);
9728
9729 4 sc->ambient = NULL;
9730 }
9731 319 break;
9732 }
9733 }
9734 475 ff_configure_buffers_for_index(s, AV_TIME_BASE);
9735
9736
2/2
✓ Branch 0 taken 389 times.
✓ Branch 1 taken 475 times.
864 for (i = 0; i < mov->frag_index.nb_items; i++)
9737
2/2
✓ Branch 0 taken 385 times.
✓ Branch 1 taken 4 times.
389 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
9738 385 mov->frag_index.item[i].headers_read = 1;
9739
9740 475 return 0;
9741 }
9742
9743 99415 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
9744 {
9745 99415 AVIndexEntry *sample = NULL;
9746 99415 int64_t best_dts = INT64_MAX;
9747 int i;
9748 99415 MOVContext *mov = s->priv_data;
9749
2/4
✓ Branch 0 taken 99415 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 99415 times.
99415 int no_interleave = !mov->interleaved_read || !(s->pb->seekable & AVIO_SEEKABLE_NORMAL);
9750
2/2
✓ Branch 0 taken 128473 times.
✓ Branch 1 taken 99415 times.
227888 for (i = 0; i < s->nb_streams; i++) {
9751 128473 AVStream *avst = s->streams[i];
9752 128473 FFStream *const avsti = ffstream(avst);
9753 128473 MOVStreamContext *msc = avst->priv_data;
9754
4/4
✓ Branch 0 taken 120235 times.
✓ Branch 1 taken 8238 times.
✓ Branch 2 taken 117008 times.
✓ Branch 3 taken 3227 times.
128473 if (msc->pb && msc->current_sample < avsti->nb_index_entries) {
9755 117008 AVIndexEntry *current_sample = &avsti->index_entries[msc->current_sample];
9756 117008 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
9757
2/2
✓ Branch 0 taken 103871 times.
✓ Branch 1 taken 13137 times.
117008 uint64_t dtsdiff = best_dts > dts ? best_dts - (uint64_t)dts : ((uint64_t)dts - best_dts);
9758 117008 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
9759
3/6
✓ Branch 0 taken 18063 times.
✓ Branch 1 taken 98945 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 18063 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
117008 if (!sample || (no_interleave && current_sample->pos < sample->pos) ||
9760
1/2
✓ Branch 0 taken 18063 times.
✗ Branch 1 not taken.
18063 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
9761
5/10
✗ Branch 0 not taken.
✓ Branch 1 taken 18063 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 18063 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 18063 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15958 times.
✓ Branch 9 taken 2105 times.
18063 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
9762
4/4
✓ Branch 0 taken 7952 times.
✓ Branch 1 taken 8006 times.
✓ Branch 2 taken 2105 times.
✓ Branch 3 taken 7952 times.
18063 ((dtsdiff <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
9763
2/2
✓ Branch 0 taken 713 times.
✓ Branch 1 taken 1392 times.
2105 (dtsdiff > AV_TIME_BASE && dts < best_dts)))))) {
9764 107664 sample = current_sample;
9765 107664 best_dts = dts;
9766 107664 *st = avst;
9767 }
9768 }
9769 }
9770 99415 return sample;
9771 }
9772
9773 9 static int should_retry(AVIOContext *pb, int error_code) {
9774
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
9 if (error_code == AVERROR_EOF || avio_feof(pb))
9775 9 return 0;
9776
9777 return 1;
9778 }
9779
9780 42 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
9781 {
9782 int ret;
9783 42 MOVContext *mov = s->priv_data;
9784
9785
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
42 if (index >= 0 && index < mov->frag_index.nb_items)
9786 target = mov->frag_index.item[index].moof_offset;
9787
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 42 times.
42 if (avio_seek(s->pb, target, SEEK_SET) != target) {
9788 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
9789 return AVERROR_INVALIDDATA;
9790 }
9791
9792 42 mov->next_root_atom = 0;
9793
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
42 if (index < 0 || index >= mov->frag_index.nb_items)
9794 42 index = search_frag_moof_offset(&mov->frag_index, target);
9795
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 4 times.
42 if (index < mov->frag_index.nb_items &&
9796
1/2
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
38 mov->frag_index.item[index].moof_offset == target) {
9797
2/2
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 3 times.
38 if (index + 1 < mov->frag_index.nb_items)
9798 35 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
9799
2/2
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 3 times.
38 if (mov->frag_index.item[index].headers_read)
9800 35 return 0;
9801 3 mov->frag_index.item[index].headers_read = 1;
9802 }
9803
9804 7 mov->found_mdat = 0;
9805
9806 7 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
9807
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (ret < 0)
9808 return ret;
9809
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 3 times.
7 if (avio_feof(s->pb))
9810 4 return AVERROR_EOF;
9811 3 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
9812
9813 3 return 1;
9814 }
9815
9816 16 static int mov_change_extradata(AVStream *st, AVPacket *pkt)
9817 {
9818 16 MOVStreamContext *sc = st->priv_data;
9819 uint8_t *side, *extradata;
9820 int extradata_size;
9821
9822 /* Save the current index. */
9823 16 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
9824
9825 /* Notify the decoder that extradata changed. */
9826 16 extradata_size = sc->extradata_size[sc->last_stsd_index];
9827 16 extradata = sc->extradata[sc->last_stsd_index];
9828
4/6
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
16 if (st->discard != AVDISCARD_ALL && extradata_size > 0 && extradata) {
9829 13 side = av_packet_new_side_data(pkt,
9830 AV_PKT_DATA_NEW_EXTRADATA,
9831 extradata_size);
9832
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if (!side)
9833 return AVERROR(ENOMEM);
9834 13 memcpy(side, extradata, extradata_size);
9835 }
9836
9837 16 return 0;
9838 }
9839
9840 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int size)
9841 {
9842 int new_size, ret;
9843
9844 if (size <= 8)
9845 return AVERROR_INVALIDDATA;
9846 new_size = ((size - 8) / 2) * 3;
9847 ret = av_new_packet(pkt, new_size);
9848 if (ret < 0)
9849 return ret;
9850
9851 avio_skip(pb, 8);
9852 for (int j = 0; j < new_size; j += 3) {
9853 pkt->data[j] = 0xFC;
9854 pkt->data[j+1] = avio_r8(pb);
9855 pkt->data[j+2] = avio_r8(pb);
9856 }
9857
9858 return 0;
9859 }
9860
9861 98901 static int mov_finalize_packet(AVFormatContext *s, AVStream *st, AVIndexEntry *sample,
9862 int64_t current_index, AVPacket *pkt)
9863 {
9864 98901 MOVStreamContext *sc = st->priv_data;
9865
9866 98901 pkt->stream_index = sc->ffindex;
9867 98901 pkt->dts = sample->timestamp;
9868
2/2
✓ Branch 0 taken 230 times.
✓ Branch 1 taken 98671 times.
98901 if (sample->flags & AVINDEX_DISCARD_FRAME) {
9869 230 pkt->flags |= AV_PKT_FLAG_DISCARD;
9870 }
9871
3/4
✓ Branch 0 taken 3605 times.
✓ Branch 1 taken 95296 times.
✓ Branch 2 taken 3605 times.
✗ Branch 3 not taken.
98901 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
9872 3605 pkt->pts = av_sat_add64(pkt->dts, av_sat_add64(sc->dts_shift, sc->ctts_data[sc->ctts_index].duration));
9873 /* update ctts context */
9874 3605 sc->ctts_sample++;
9875
1/2
✓ Branch 0 taken 3605 times.
✗ Branch 1 not taken.
3605 if (sc->ctts_index < sc->ctts_count &&
9876
1/2
✓ Branch 0 taken 3605 times.
✗ Branch 1 not taken.
3605 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
9877 3605 sc->ctts_index++;
9878 3605 sc->ctts_sample = 0;
9879 }
9880 } else {
9881 95296 int64_t next_dts = (sc->current_sample < ffstream(st)->nb_index_entries) ?
9882
2/2
✓ Branch 0 taken 94818 times.
✓ Branch 1 taken 478 times.
95296 ffstream(st)->index_entries[sc->current_sample].timestamp : st->duration;
9883
9884
2/2
✓ Branch 0 taken 95270 times.
✓ Branch 1 taken 26 times.
95296 if (next_dts >= pkt->dts)
9885 95270 pkt->duration = next_dts - pkt->dts;
9886 95296 pkt->pts = pkt->dts;
9887 }
9888
9889
4/4
✓ Branch 0 taken 1010 times.
✓ Branch 1 taken 97891 times.
✓ Branch 2 taken 878 times.
✓ Branch 3 taken 132 times.
98901 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
9890 878 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
9891 878 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
9892
2/2
✓ Branch 0 taken 302 times.
✓ Branch 1 taken 576 times.
878 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
9893 }
9894 98901 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
9895 98901 pkt->pos = sample->pos;
9896
9897 /* Multiple stsd handling. */
9898
2/2
✓ Branch 0 taken 98110 times.
✓ Branch 1 taken 791 times.
98901 if (sc->stsc_data) {
9899
1/2
✓ Branch 0 taken 98110 times.
✗ Branch 1 not taken.
98110 if (sc->stsc_data[sc->stsc_index].id > 0 &&
9900
2/2
✓ Branch 0 taken 98091 times.
✓ Branch 1 taken 19 times.
98110 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
9901
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 98075 times.
98091 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
9902 16 int ret = mov_change_extradata(st, pkt);
9903
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (ret < 0)
9904 return ret;
9905 }
9906
9907 /* Update the stsc index for the next sample */
9908 98110 sc->stsc_sample++;
9909
2/2
✓ Branch 1 taken 54997 times.
✓ Branch 2 taken 43113 times.
98110 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
9910
2/2
✓ Branch 1 taken 1167 times.
✓ Branch 2 taken 53830 times.
54997 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
9911 1167 sc->stsc_index++;
9912 1167 sc->stsc_sample = 0;
9913 }
9914 }
9915
9916 98901 return 0;
9917 }
9918
9919 92558 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
9920 {
9921 92558 MOVContext *mov = s->priv_data;
9922 MOVStreamContext *sc;
9923 AVIndexEntry *sample;
9924 92558 AVStream *st = NULL;
9925 int64_t current_index;
9926 int ret;
9927 92558 mov->fc = s;
9928 6857 retry:
9929 99415 sample = mov_find_next_sample(s, &st);
9930
6/6
✓ Branch 0 taken 98945 times.
✓ Branch 1 taken 470 times.
✓ Branch 2 taken 472 times.
✓ Branch 3 taken 98473 times.
✓ Branch 4 taken 35 times.
✓ Branch 5 taken 437 times.
99415 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
9931
2/2
✓ Branch 0 taken 463 times.
✓ Branch 1 taken 42 times.
505 if (!mov->next_root_atom)
9932 463 return AVERROR_EOF;
9933
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 38 times.
42 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
9934 4 return ret;
9935 38 goto retry;
9936 }
9937 98910 sc = st->priv_data;
9938 /* must be done just before reading, to avoid infinite loop on sample */
9939 98910 current_index = sc->current_index;
9940 98910 mov_current_sample_inc(sc);
9941
9942
2/2
✓ Branch 0 taken 437 times.
✓ Branch 1 taken 98473 times.
98910 if (mov->next_root_atom) {
9943 437 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
9944 437 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
9945 }
9946
9947
2/2
✓ Branch 0 taken 92091 times.
✓ Branch 1 taken 6819 times.
98910 if (st->discard != AVDISCARD_ALL) {
9948 92091 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
9949
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 92084 times.
92091 if (ret64 != sample->pos) {
9950 7 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
9951 sc->ffindex, sample->pos);
9952
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
7 if (should_retry(sc->pb, ret64)) {
9953 mov_current_sample_dec(sc);
9954
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 } else if (ret64 < 0) {
9955 7 return (int)ret64;
9956 }
9957 return AVERROR_INVALIDDATA;
9958 }
9959
9960
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 92084 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
92084 if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
9961 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
9962 goto retry;
9963 }
9964
9965
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 92084 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
92084 if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
9966 ret = get_eia608_packet(sc->pb, pkt, sample->size);
9967 #if CONFIG_IAMFDEC
9968
2/2
✓ Branch 0 taken 44 times.
✓ Branch 1 taken 92040 times.
92084 else if (sc->iamf) {
9969 int64_t pts, dts, pos, duration;
9970 44 int flags, size = sample->size;
9971 44 ret = mov_finalize_packet(s, st, sample, current_index, pkt);
9972 44 pts = pkt->pts; dts = pkt->dts;
9973 44 pos = pkt->pos; flags = pkt->flags;
9974 44 duration = pkt->duration;
9975
3/4
✓ Branch 0 taken 242 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 198 times.
✓ Branch 3 taken 44 times.
242 while (!ret && size > 0) {
9976 198 ret = ff_iamf_read_packet(s, sc->iamf, sc->pb, size, pkt);
9977
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 198 times.
198 if (ret < 0) {
9978 if (should_retry(sc->pb, ret))
9979 mov_current_sample_dec(sc);
9980 return ret;
9981 }
9982 198 size -= ret;
9983 198 pkt->pts = pts; pkt->dts = dts;
9984 198 pkt->pos = pos; pkt->flags |= flags;
9985 198 pkt->duration = duration;
9986 198 ret = ff_buffer_packet(s, pkt);
9987 }
9988
1/2
✓ Branch 0 taken 44 times.
✗ Branch 1 not taken.
44 if (!ret)
9989 44 return FFERROR_REDO;
9990 }
9991 #endif
9992 else
9993 92040 ret = av_get_packet(sc->pb, pkt, sample->size);
9994
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 92038 times.
92040 if (ret < 0) {
9995
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if (should_retry(sc->pb, ret)) {
9996 mov_current_sample_dec(sc);
9997 }
9998 2 return ret;
9999 }
10000 #if CONFIG_DV_DEMUXER
10001
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 92038 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
92038 if (mov->dv_demux && sc->dv_audio_container) {
10002 ret = avpriv_dv_produce_packet(mov->dv_demux, NULL, pkt->data, pkt->size, pkt->pos);
10003 av_packet_unref(pkt);
10004 if (ret < 0)
10005 return ret;
10006 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
10007 if (ret < 0)
10008 return ret;
10009 }
10010 #endif
10011
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 92020 times.
92038 if (sc->has_palette) {
10012 uint8_t *pal;
10013
10014 18 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
10015
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if (!pal) {
10016 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
10017 } else {
10018 18 memcpy(pal, sc->palette, AVPALETTE_SIZE);
10019 18 sc->has_palette = 0;
10020 }
10021 }
10022
4/6
✓ Branch 0 taken 288 times.
✓ Branch 1 taken 91750 times.
✓ Branch 3 taken 288 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 288 times.
✗ Branch 6 not taken.
92038 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !ffstream(st)->need_parsing && pkt->size > 4) {
10023
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 288 times.
288 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
10024 ffstream(st)->need_parsing = AVSTREAM_PARSE_FULL;
10025 }
10026 }
10027
10028 98857 ret = mov_finalize_packet(s, st, sample, current_index, pkt);
10029
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 98857 times.
98857 if (ret < 0)
10030 return ret;
10031
10032
2/2
✓ Branch 0 taken 6819 times.
✓ Branch 1 taken 92038 times.
98857 if (st->discard == AVDISCARD_ALL)
10033 6819 goto retry;
10034
10035
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 92038 times.
92038 if (mov->aax_mode)
10036 aax_filter(pkt->data, pkt->size, mov);
10037
10038 92038 ret = cenc_filter(mov, st, sc, pkt, current_index);
10039
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 92038 times.
92038 if (ret < 0) {
10040 return ret;
10041 }
10042
10043 92038 return 0;
10044 }
10045
10046 361 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
10047 {
10048 361 MOVContext *mov = s->priv_data;
10049 int index;
10050
10051
2/2
✓ Branch 0 taken 335 times.
✓ Branch 1 taken 26 times.
361 if (!mov->frag_index.complete)
10052 335 return 0;
10053
10054 26 index = search_frag_timestamp(s, &mov->frag_index, st, timestamp);
10055
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 22 times.
26 if (index < 0)
10056 4 index = 0;
10057
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (!mov->frag_index.item[index].headers_read)
10058 return mov_switch_root(s, -1, index);
10059
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 if (index + 1 < mov->frag_index.nb_items)
10060 26 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
10061
10062 26 return 0;
10063 }
10064
10065 static int is_open_key_sample(const MOVStreamContext *sc, int sample)
10066 {
10067 // TODO: a bisect search would scale much better
10068 for (int i = 0; i < sc->open_key_samples_count; i++) {
10069 const int oks = sc->open_key_samples[i];
10070 if (oks == sample)
10071 return 1;
10072 if (oks > sample) /* list is monotically increasing so we can stop early */
10073 break;
10074 }
10075 return 0;
10076 }
10077
10078 /*
10079 * Some key sample may be key frames but not IDR frames, so a random access to
10080 * them may not be allowed.
10081 */
10082 229 static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
10083 {
10084 229 MOVStreamContext *sc = st->priv_data;
10085 229 FFStream *const sti = ffstream(st);
10086 int64_t key_sample_dts, key_sample_pts;
10087
10088
1/2
✓ Branch 0 taken 229 times.
✗ Branch 1 not taken.
229 if (st->codecpar->codec_id != AV_CODEC_ID_HEVC)
10089 229 return 1;
10090
10091 if (sample >= sc->sample_offsets_count)
10092 return 1;
10093
10094 key_sample_dts = sti->index_entries[sample].timestamp;
10095 key_sample_pts = key_sample_dts + sc->sample_offsets[sample] + sc->dts_shift;
10096
10097 /*
10098 * If the sample needs to be presented before an open key sample, they may
10099 * not be decodable properly, even though they come after in decoding
10100 * order.
10101 */
10102 if (is_open_key_sample(sc, sample) && key_sample_pts > requested_pts)
10103 return 0;
10104
10105 return 1;
10106 }
10107
10108 361 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
10109 {
10110 361 MOVStreamContext *sc = st->priv_data;
10111 361 FFStream *const sti = ffstream(st);
10112 int sample, time_sample, ret;
10113 unsigned int i;
10114
10115 // Here we consider timestamp to be PTS, hence try to offset it so that we
10116 // can search over the DTS timeline.
10117 361 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
10118
10119 361 ret = mov_seek_fragment(s, st, timestamp);
10120
1/2
✓ Branch 0 taken 361 times.
✗ Branch 1 not taken.
361 if (ret < 0)
10121 return ret;
10122
10123 for (;;) {
10124 361 sample = av_index_search_timestamp(st, timestamp, flags);
10125 361 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
10126
5/6
✓ Branch 0 taken 69 times.
✓ Branch 1 taken 292 times.
✓ Branch 2 taken 69 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 43 times.
✓ Branch 5 taken 26 times.
361 if (sample < 0 && sti->nb_index_entries && timestamp < sti->index_entries[0].timestamp)
10127 43 sample = 0;
10128
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 335 times.
361 if (sample < 0) /* not sure what to do */
10129 26 return AVERROR_INVALIDDATA;
10130
10131
3/4
✓ Branch 0 taken 229 times.
✓ Branch 1 taken 106 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 229 times.
335 if (!sample || can_seek_to_key_sample(st, sample, timestamp))
10132 break;
10133 timestamp -= FFMAX(sc->min_sample_duration, 1);
10134 }
10135
10136 335 mov_current_sample_set(sc, sample);
10137 335 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
10138 /* adjust ctts index */
10139
2/2
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 263 times.
335 if (sc->ctts_data) {
10140 72 time_sample = 0;
10141
1/2
✓ Branch 0 taken 57972 times.
✗ Branch 1 not taken.
57972 for (i = 0; i < sc->ctts_count; i++) {
10142 57972 int next = time_sample + sc->ctts_data[i].count;
10143
2/2
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 57900 times.
57972 if (next > sc->current_sample) {
10144 72 sc->ctts_index = i;
10145 72 sc->ctts_sample = sc->current_sample - time_sample;
10146 72 break;
10147 }
10148 57900 time_sample = next;
10149 }
10150 }
10151
10152 /* adjust stsd index */
10153
2/2
✓ Branch 0 taken 309 times.
✓ Branch 1 taken 26 times.
335 if (sc->chunk_count) {
10154 309 time_sample = 0;
10155
1/2
✓ Branch 0 taken 381 times.
✗ Branch 1 not taken.
381 for (i = 0; i < sc->stsc_count; i++) {
10156 381 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
10157
2/2
✓ Branch 0 taken 309 times.
✓ Branch 1 taken 72 times.
381 if (next > sc->current_sample) {
10158 309 sc->stsc_index = i;
10159 309 sc->stsc_sample = sc->current_sample - time_sample;
10160 309 break;
10161 }
10162
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
72 av_assert0(next == (int)next);
10163 72 time_sample = next;
10164 }
10165 }
10166
10167 335 return sample;
10168 }
10169
10170 335 static int64_t mov_get_skip_samples(AVStream *st, int sample)
10171 {
10172 335 MOVStreamContext *sc = st->priv_data;
10173 335 FFStream *const sti = ffstream(st);
10174 335 int64_t first_ts = sti->index_entries[0].timestamp;
10175 335 int64_t ts = sti->index_entries[sample].timestamp;
10176 int64_t off;
10177
10178
2/2
✓ Branch 0 taken 184 times.
✓ Branch 1 taken 151 times.
335 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO)
10179 184 return 0;
10180
10181 /* compute skip samples according to stream start_pad, seek ts and first ts */
10182 151 off = av_rescale_q(ts - first_ts, st->time_base,
10183 151 (AVRational){1, st->codecpar->sample_rate});
10184 151 return FFMAX(sc->start_pad - off, 0);
10185 }
10186
10187 340 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
10188 {
10189 340 MOVContext *mc = s->priv_data;
10190 AVStream *st;
10191 FFStream *sti;
10192 int sample;
10193 int i;
10194
10195
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 340 times.
340 if (stream_index >= s->nb_streams)
10196 return AVERROR_INVALIDDATA;
10197
10198 340 st = s->streams[stream_index];
10199 340 sti = ffstream(st);
10200 340 sample = mov_seek_stream(s, st, sample_time, flags);
10201
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 314 times.
340 if (sample < 0)
10202 26 return sample;
10203
10204
1/2
✓ Branch 0 taken 314 times.
✗ Branch 1 not taken.
314 if (mc->seek_individually) {
10205 /* adjust seek timestamp to found sample timestamp */
10206 314 int64_t seek_timestamp = sti->index_entries[sample].timestamp;
10207 314 sti->skip_samples = mov_get_skip_samples(st, sample);
10208
10209
2/2
✓ Branch 0 taken 335 times.
✓ Branch 1 taken 314 times.
649 for (i = 0; i < s->nb_streams; i++) {
10210 335 AVStream *const st = s->streams[i];
10211 335 FFStream *const sti = ffstream(st);
10212 int64_t timestamp;
10213
10214
2/2
✓ Branch 0 taken 314 times.
✓ Branch 1 taken 21 times.
335 if (stream_index == i)
10215 314 continue;
10216
10217 21 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
10218 21 sample = mov_seek_stream(s, st, timestamp, flags);
10219
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 if (sample >= 0)
10220 21 sti->skip_samples = mov_get_skip_samples(st, sample);
10221 }
10222 } else {
10223 for (i = 0; i < s->nb_streams; i++) {
10224 MOVStreamContext *sc;
10225 st = s->streams[i];
10226 sc = st->priv_data;
10227 mov_current_sample_set(sc, 0);
10228 }
10229 while (1) {
10230 MOVStreamContext *sc;
10231 AVIndexEntry *entry = mov_find_next_sample(s, &st);
10232 if (!entry)
10233 return AVERROR_INVALIDDATA;
10234 sc = st->priv_data;
10235 if (sc->ffindex == stream_index && sc->current_sample == sample)
10236 break;
10237 mov_current_sample_inc(sc);
10238 }
10239 }
10240 314 return 0;
10241 }
10242
10243 #define OFFSET(x) offsetof(MOVContext, x)
10244 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
10245 static const AVOption mov_options[] = {
10246 {"use_absolute_path",
10247 "allow using absolute path when opening alias, this is a possible security issue",
10248 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
10249 0, 1, FLAGS},
10250 {"seek_streams_individually",
10251 "Seek each stream individually to the closest point",
10252 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
10253 0, 1, FLAGS},
10254 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
10255 0, 1, FLAGS},
10256 {"advanced_editlist",
10257 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
10258 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
10259 0, 1, FLAGS},
10260 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
10261 0, 1, FLAGS},
10262 {"use_mfra_for",
10263 "use mfra for fragment timestamps",
10264 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
10265 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
10266 .unit = "use_mfra_for"},
10267 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
10268 FLAGS, .unit = "use_mfra_for" },
10269 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
10270 FLAGS, .unit = "use_mfra_for" },
10271 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
10272 FLAGS, .unit = "use_mfra_for" },
10273 {"use_tfdt", "use tfdt for fragment timestamps", OFFSET(use_tfdt), AV_OPT_TYPE_BOOL, {.i64 = 1},
10274 0, 1, FLAGS},
10275 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
10276 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
10277 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
10278 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
10279 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
10280 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
10281 { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
10282 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
10283 { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
10284 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
10285 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
10286 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
10287 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
10288 .flags = AV_OPT_FLAG_DECODING_PARAM },
10289 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
10290 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
10291 {.i64 = 0}, 0, 1, FLAGS },
10292 { "max_stts_delta", "treat offsets above this value as invalid", OFFSET(max_stts_delta), AV_OPT_TYPE_INT, {.i64 = UINT_MAX-48000*10 }, 0, UINT_MAX, .flags = AV_OPT_FLAG_DECODING_PARAM },
10293 { "interleaved_read", "Interleave packets from multiple tracks at demuxer level", OFFSET(interleaved_read), AV_OPT_TYPE_BOOL, {.i64 = 1 }, 0, 1, .flags = AV_OPT_FLAG_DECODING_PARAM },
10294
10295 { NULL },
10296 };
10297
10298 static const AVClass mov_class = {
10299 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
10300 .item_name = av_default_item_name,
10301 .option = mov_options,
10302 .version = LIBAVUTIL_VERSION_INT,
10303 };
10304
10305 const FFInputFormat ff_mov_demuxer = {
10306 .p.name = "mov,mp4,m4a,3gp,3g2,mj2",
10307 .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
10308 .p.priv_class = &mov_class,
10309 .p.extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v,avif,heic,heif",
10310 .p.flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS | AVFMT_SHOW_IDS,
10311 .priv_data_size = sizeof(MOVContext),
10312 .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
10313 .read_probe = mov_probe,
10314 .read_header = mov_read_header,
10315 .read_packet = mov_read_packet,
10316 .read_close = mov_read_close,
10317 .read_seek = mov_read_seek,
10318 };
10319