FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/mov.c
Date: 2022-12-05 03:11:11
Exec Total Coverage
Lines: 3230 5418 59.6%
Functions: 136 179 76.0%
Branches: 1880 3699 50.8%

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/opt.h"
44 #include "libavutil/aes.h"
45 #include "libavutil/aes_ctr.h"
46 #include "libavutil/pixdesc.h"
47 #include "libavutil/sha.h"
48 #include "libavutil/spherical.h"
49 #include "libavutil/stereo3d.h"
50 #include "libavutil/timecode.h"
51 #include "libavutil/uuid.h"
52 #include "libavcodec/ac3tab.h"
53 #include "libavcodec/flac.h"
54 #include "libavcodec/hevc.h"
55 #include "libavcodec/mpegaudiodecheader.h"
56 #include "libavcodec/mlp_parse.h"
57 #include "avformat.h"
58 #include "internal.h"
59 #include "avio_internal.h"
60 #include "demux.h"
61 #include "dovi_isom.h"
62 #include "riff.h"
63 #include "isom.h"
64 #include "libavcodec/get_bits.h"
65 #include "id3v1.h"
66 #include "mov_chan.h"
67 #include "replaygain.h"
68
69 #if CONFIG_ZLIB
70 #include <zlib.h>
71 #endif
72
73 #include "qtpalette.h"
74
75 /* those functions parse an atom */
76 /* links atom IDs to parse functions */
77 typedef struct MOVParseTableEntry {
78 uint32_t type;
79 int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
80 } MOVParseTableEntry;
81
82 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
83 static int mov_read_mfra(MOVContext *c, AVIOContext *f);
84 static int64_t add_ctts_entry(MOVCtts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
85 int count, int duration);
86
87 22 static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb,
88 unsigned len, const char *key)
89 {
90 char buf[16];
91
92 22 short current, total = 0;
93 22 avio_rb16(pb); // unknown
94 22 current = avio_rb16(pb);
95
1/2
✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
22 if (len >= 6)
96 22 total = avio_rb16(pb);
97
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 18 times.
22 if (!total)
98 4 snprintf(buf, sizeof(buf), "%d", current);
99 else
100 18 snprintf(buf, sizeof(buf), "%d/%d", current, total);
101 22 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
102 22 av_dict_set(&c->fc->metadata, key, buf, 0);
103
104 22 return 0;
105 }
106
107 static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb,
108 unsigned len, const char *key)
109 {
110 /* bypass padding bytes */
111 avio_r8(pb);
112 avio_r8(pb);
113 avio_r8(pb);
114
115 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
116 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
117
118 return 0;
119 }
120
121 24 static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb,
122 unsigned len, const char *key)
123 {
124 24 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
125 24 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
126
127 24 return 0;
128 }
129
130 9 static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb,
131 unsigned len, const char *key)
132 {
133 short genre;
134
135 9 avio_r8(pb); // unknown
136
137 9 genre = avio_r8(pb);
138
2/4
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
9 if (genre < 1 || genre > ID3v1_GENRE_MAX)
139 return 0;
140 9 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
141 9 av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
142
143 9 return 0;
144 }
145
146 static const uint32_t mac_to_unicode[128] = {
147 0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
148 0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
149 0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
150 0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
151 0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
152 0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
153 0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
154 0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
155 0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
156 0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
157 0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
158 0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
159 0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
160 0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
161 0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
162 0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
163 };
164
165 285 static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len,
166 char *dst, int dstlen)
167 {
168 285 char *p = dst;
169 285 char *end = dst+dstlen-1;
170 int i;
171
172
2/2
✓ Branch 0 taken 2550 times.
✓ Branch 1 taken 285 times.
2835 for (i = 0; i < len; i++) {
173 2550 uint8_t t, c = avio_r8(pb);
174
175
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2550 times.
2550 if (p >= end)
176 continue;
177
178
2/2
✓ Branch 0 taken 2547 times.
✓ Branch 1 taken 3 times.
2550 if (c < 0x80)
179 2547 *p++ = c;
180
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 else if (p < end)
181
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;);
182 }
183 285 *p = 0;
184 285 return p - dst;
185 }
186
187 13 static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
188 {
189 AVStream *st;
190 MOVStreamContext *sc;
191 enum AVCodecID id;
192 int ret;
193
194
2/4
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
13 switch (type) {
195 7 case 0xd: id = AV_CODEC_ID_MJPEG; break;
196 6 case 0xe: id = AV_CODEC_ID_PNG; break;
197 case 0x1b: id = AV_CODEC_ID_BMP; break;
198 default:
199 av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
200 avio_skip(pb, len);
201 return 0;
202 }
203
204 13 sc = av_mallocz(sizeof(*sc));
205
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if (!sc)
206 return AVERROR(ENOMEM);
207 13 ret = ff_add_attached_pic(c->fc, NULL, pb, NULL, len);
208
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if (ret < 0) {
209 av_free(sc);
210 return ret;
211 }
212 13 st = c->fc->streams[c->fc->nb_streams - 1];
213 13 st->priv_data = sc;
214
215
2/4
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
13 if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) {
216
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 7 times.
13 if (AV_RB64(st->attached_pic.data) == 0x89504e470d0a1a0a) {
217 6 id = AV_CODEC_ID_PNG;
218 } else {
219 7 id = AV_CODEC_ID_MJPEG;
220 }
221 }
222 13 st->codecpar->codec_id = id;
223
224 13 return 0;
225 }
226
227 // 3GPP TS 26.244
228 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
229 {
230 char language[4] = { 0 };
231 char buf[200], place[100];
232 uint16_t langcode = 0;
233 double longitude, latitude, altitude;
234 const char *key = "location";
235
236 if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
237 av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
238 return AVERROR_INVALIDDATA;
239 }
240
241 avio_skip(pb, 4); // version+flags
242 langcode = avio_rb16(pb);
243 ff_mov_lang_to_iso639(langcode, language);
244 len -= 6;
245
246 len -= avio_get_str(pb, len, place, sizeof(place));
247 if (len < 1) {
248 av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
249 return AVERROR_INVALIDDATA;
250 }
251 avio_skip(pb, 1); // role
252 len -= 1;
253
254 if (len < 12) {
255 av_log(c->fc, AV_LOG_ERROR,
256 "loci too short (%u bytes left, need at least %d)\n", len, 12);
257 return AVERROR_INVALIDDATA;
258 }
259 longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
260 latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
261 altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
262
263 // Try to output in the same format as the ?xyz field
264 snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
265 if (altitude)
266 av_strlcatf(buf, sizeof(buf), "%+f", altitude);
267 av_strlcatf(buf, sizeof(buf), "/%s", place);
268
269 if (*language && strcmp(language, "und")) {
270 char key2[16];
271 snprintf(key2, sizeof(key2), "%s-%s", key, language);
272 av_dict_set(&c->fc->metadata, key2, buf, 0);
273 }
274 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
275 return av_dict_set(&c->fc->metadata, key, buf, 0);
276 }
277
278 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
279 {
280 int i, n_hmmt;
281
282 if (len < 2)
283 return 0;
284 if (c->ignore_chapters)
285 return 0;
286
287 n_hmmt = avio_rb32(pb);
288 if (n_hmmt > len / 4)
289 return AVERROR_INVALIDDATA;
290 for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
291 int moment_time = avio_rb32(pb);
292 avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
293 }
294 if (avio_feof(pb))
295 return AVERROR_INVALIDDATA;
296 return 0;
297 }
298
299 426 static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
300 {
301 426 char tmp_key[AV_FOURCC_MAX_STRING_SIZE] = {0};
302 426 char key2[32], language[4] = {0};
303 426 char *str = NULL;
304 426 const char *key = NULL;
305 426 uint16_t langcode = 0;
306 426 uint32_t data_type = 0, str_size, str_size_alloc;
307 426 int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
308 426 int raw = 0;
309 426 int num = 0;
310
311
24/74
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 138 times.
✓ Branch 4 taken 11 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 12 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 11 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✓ Branch 14 taken 9 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 12 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 11 times.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✓ Branch 39 taken 15 times.
✗ Branch 40 not taken.
✓ Branch 41 taken 15 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 34 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 54 times.
✓ Branch 68 taken 47 times.
✗ Branch 69 not taken.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
✗ Branch 72 not taken.
✓ Branch 73 taken 5 times.
426 switch (atom.type) {
312 3 case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
313 3 case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
314 2 case MKTAG( 'X','M','P','_'):
315
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (c->export_xmp) { key = "xmp"; raw = 1; } break;
316 11 case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
317 case MKTAG( 'a','k','I','D'): key = "account_type";
318 parse = mov_metadata_int8_no_padding; break;
319 case MKTAG( 'a','p','I','D'): key = "account_id"; break;
320 case MKTAG( 'c','a','t','g'): key = "category"; break;
321 12 case MKTAG( 'c','p','i','l'): key = "compilation";
322 12 parse = mov_metadata_int8_no_padding; break;
323 case MKTAG( 'c','p','r','t'): key = "copyright"; break;
324 case MKTAG( 'd','e','s','c'): key = "description"; break;
325 11 case MKTAG( 'd','i','s','k'): key = "disc";
326 11 parse = mov_metadata_track_or_disc_number; break;
327 case MKTAG( 'e','g','i','d'): key = "episode_uid";
328 parse = mov_metadata_int8_no_padding; break;
329 case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
330 9 case MKTAG( 'g','n','r','e'): key = "genre";
331 9 parse = mov_metadata_gnre; break;
332 case MKTAG( 'h','d','v','d'): key = "hd_video";
333 parse = mov_metadata_int8_no_padding; break;
334 case MKTAG( 'H','M','M','T'):
335 return mov_metadata_hmmt(c, pb, atom.size);
336 case MKTAG( 'k','e','y','w'): key = "keywords"; break;
337 case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
338 case MKTAG( 'l','o','c','i'):
339 return mov_metadata_loci(c, pb, atom.size);
340 case MKTAG( 'm','a','n','u'): key = "make"; break;
341 case MKTAG( 'm','o','d','l'): key = "model"; break;
342 case MKTAG( 'p','c','s','t'): key = "podcast";
343 parse = mov_metadata_int8_no_padding; break;
344 12 case MKTAG( 'p','g','a','p'): key = "gapless_playback";
345 12 parse = mov_metadata_int8_no_padding; break;
346 case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
347 case MKTAG( 'r','t','n','g'): key = "rating";
348 parse = mov_metadata_int8_no_padding; break;
349 case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
350 case MKTAG( 's','o','a','l'): key = "sort_album"; break;
351 case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
352 case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
353 case MKTAG( 's','o','n','m'): key = "sort_name"; break;
354 case MKTAG( 's','o','s','n'): key = "sort_show"; break;
355 case MKTAG( 's','t','i','k'): key = "media_type";
356 parse = mov_metadata_int8_no_padding; break;
357 11 case MKTAG( 't','r','k','n'): key = "track";
358 11 parse = mov_metadata_track_or_disc_number; break;
359 case MKTAG( 't','v','e','n'): key = "episode_id"; break;
360 case MKTAG( 't','v','e','s'): key = "episode_sort";
361 parse = mov_metadata_int8_bypass_padding; break;
362 case MKTAG( 't','v','n','n'): key = "network"; break;
363 case MKTAG( 't','v','s','h'): key = "show"; break;
364 case MKTAG( 't','v','s','n'): key = "season_number";
365 parse = mov_metadata_int8_bypass_padding; break;
366 15 case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
367 case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
368 15 case MKTAG(0xa9,'a','l','b'): key = "album"; break;
369 3 case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
370 case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
371 7 case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
372 case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
373 4 case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
374 16 case MKTAG(0xa9,'d','a','y'): key = "date"; break;
375 case MKTAG(0xa9,'d','i','r'): key = "director"; break;
376 case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
377 case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
378 2 case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
379 case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
380 2 case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
381 case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
382 case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
383 case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
384 case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
385 5 case MKTAG(0xa9,'m','a','k'): key = "make"; break;
386 5 case MKTAG(0xa9,'m','o','d'): key = "model"; break;
387 34 case MKTAG(0xa9,'n','a','m'): key = "title"; break;
388 case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
389 case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
390 case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
391 case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
392 case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
393 case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
394 54 case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
395 47 case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
396 case MKTAG(0xa9,'t','r','k'): key = "track"; break;
397 case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
398 case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
399 case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
400 5 case MKTAG(0xa9,'x','y','z'): key = "location"; break;
401 }
402 2 retry:
403
3/4
✓ Branch 0 taken 260 times.
✓ Branch 1 taken 168 times.
✓ Branch 2 taken 260 times.
✗ Branch 3 not taken.
675 if (c->itunes_metadata && atom.size > 8) {
404 260 int data_size = avio_rb32(pb);
405 260 int tag = avio_rl32(pb);
406
3/6
✓ Branch 0 taken 260 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 260 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 260 times.
✗ Branch 5 not taken.
260 if (tag == MKTAG('d','a','t','a') && data_size <= atom.size && data_size >= 16) {
407 260 data_type = avio_rb32(pb); // type
408 260 avio_rb32(pb); // unknown
409 260 str_size = data_size - 16;
410 260 atom.size -= 16;
411
412
5/6
✓ Branch 0 taken 73 times.
✓ Branch 1 taken 187 times.
✓ Branch 2 taken 41 times.
✓ Branch 3 taken 32 times.
✓ Branch 4 taken 41 times.
✗ Branch 5 not taken.
260 if (!key && c->found_hdlr_mdta && c->meta_keys) {
413 41 uint32_t index = av_bswap32(atom.type); // BE number has been read as LE
414
2/4
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 41 times.
✗ Branch 3 not taken.
41 if (index < c->meta_keys_count && index > 0) {
415 41 key = c->meta_keys[index];
416 } else if (atom.type != MKTAG('c', 'o', 'v', 'r')) {
417 av_log(c->fc, AV_LOG_WARNING,
418 "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
419 index, c->meta_keys_count);
420 }
421 }
422
4/4
✓ Branch 0 taken 247 times.
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 228 times.
✓ Branch 3 taken 19 times.
260 if (atom.type == MKTAG('c', 'o', 'v', 'r') ||
423
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 228 times.
228 (key && !strcmp(key, "com.apple.quicktime.artwork"))) {
424 13 int ret = mov_read_covr(c, pb, data_type, str_size);
425
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if (ret < 0) {
426 av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
427 return ret;
428 }
429 13 atom.size -= str_size;
430
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 11 times.
13 if (atom.size > 8)
431 2 goto retry;
432 11 return ret;
433 }
434 } else return 0;
435
7/8
✓ Branch 0 taken 150 times.
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 99 times.
✓ Branch 3 taken 51 times.
✓ Branch 4 taken 99 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 93 times.
✓ Branch 7 taken 6 times.
168 } else if (atom.size > 4 && key && !c->itunes_metadata && !raw) {
436 93 str_size = avio_rb16(pb); // string length
437
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 93 times.
93 if (str_size > atom.size) {
438 raw = 1;
439 avio_seek(pb, -2, SEEK_CUR);
440 av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
441 goto retry;
442 }
443 93 langcode = avio_rb16(pb);
444 93 ff_mov_lang_to_iso639(langcode, language);
445 93 atom.size -= 4;
446 } else
447 75 str_size = atom.size;
448
449
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 415 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
415 if (c->export_all && !key) {
450 key = av_fourcc_make_string(tmp_key, atom.type);
451 }
452
453
2/2
✓ Branch 0 taken 88 times.
✓ Branch 1 taken 327 times.
415 if (!key)
454 88 return 0;
455
2/4
✓ Branch 0 taken 327 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 327 times.
327 if (atom.size < 0 || str_size >= INT_MAX/2)
456 return AVERROR_INVALIDDATA;
457
458 // Allocates enough space if data_type is a int32 or float32 number, otherwise
459 // worst-case requirement for output string in case of utf8 coded input
460
3/4
✓ Branch 0 taken 37 times.
✓ Branch 1 taken 290 times.
✓ Branch 2 taken 37 times.
✗ Branch 3 not taken.
327 num = (data_type >= 21 && data_type <= 23);
461
4/4
✓ Branch 0 taken 290 times.
✓ Branch 1 taken 37 times.
✓ Branch 2 taken 284 times.
✓ Branch 3 taken 6 times.
327 str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
462 327 str = av_mallocz(str_size_alloc);
463
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 327 times.
327 if (!str)
464 return AVERROR(ENOMEM);
465
466
2/2
✓ Branch 0 taken 55 times.
✓ Branch 1 taken 272 times.
327 if (parse)
467 55 parse(c, pb, str_size, key);
468 else {
469
8/10
✓ Branch 0 taken 266 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 266 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 94 times.
✓ Branch 5 taken 172 times.
✓ Branch 6 taken 80 times.
✓ Branch 7 taken 14 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 80 times.
272 if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
470 14 mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
471
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 258 times.
258 } else if (data_type == 21) { // BE signed integer, variable size
472 int val = 0;
473 if (str_size == 1)
474 val = (int8_t)avio_r8(pb);
475 else if (str_size == 2)
476 val = (int16_t)avio_rb16(pb);
477 else if (str_size == 3)
478 val = ((int32_t)(avio_rb24(pb)<<8))>>8;
479 else if (str_size == 4)
480 val = (int32_t)avio_rb32(pb);
481 if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
482 av_log(c->fc, AV_LOG_ERROR,
483 "Failed to store the number (%d) in string.\n", val);
484 av_free(str);
485 return AVERROR_INVALIDDATA;
486 }
487
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 258 times.
258 } else if (data_type == 22) { // BE unsigned integer, variable size
488 unsigned int val = 0;
489 if (str_size == 1)
490 val = avio_r8(pb);
491 else if (str_size == 2)
492 val = avio_rb16(pb);
493 else if (str_size == 3)
494 val = avio_rb24(pb);
495 else if (str_size == 4)
496 val = avio_rb32(pb);
497 if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
498 av_log(c->fc, AV_LOG_ERROR,
499 "Failed to store the number (%u) in string.\n", val);
500 av_free(str);
501 return AVERROR_INVALIDDATA;
502 }
503
3/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 245 times.
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
271 } else if (data_type == 23 && str_size >= 4) { // BE float32
504 13 float val = av_int2float(avio_rb32(pb));
505
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
506 av_log(c->fc, AV_LOG_ERROR,
507 "Failed to store the float32 number (%f) in string.\n", val);
508 av_free(str);
509 return AVERROR_INVALIDDATA;
510 }
511
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 245 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
245 } else if (data_type > 1 && data_type != 4) {
512 // data_type can be 0 if not set at all above. data_type 1 means
513 // UTF8 and 4 means "UTF8 sort". For any other type (UTF16 or e.g.
514 // a picture), don't return it blindly in a string that is supposed
515 // to be UTF8 text.
516 av_log(c->fc, AV_LOG_WARNING, "Skipping unhandled metadata %s of type %d\n", key, data_type);
517 av_free(str);
518 return 0;
519 } else {
520 245 int ret = ffio_read_size(pb, str, str_size);
521
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 245 times.
245 if (ret < 0) {
522 av_free(str);
523 return ret;
524 }
525 245 str[str_size] = 0;
526 }
527 272 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
528 272 av_dict_set(&c->fc->metadata, key, str, 0);
529
4/4
✓ Branch 0 taken 93 times.
✓ Branch 1 taken 179 times.
✓ Branch 2 taken 37 times.
✓ Branch 3 taken 56 times.
272 if (*language && strcmp(language, "und")) {
530 37 snprintf(key2, sizeof(key2), "%s-%s", key, language);
531 37 av_dict_set(&c->fc->metadata, key2, str, 0);
532 }
533
2/2
✓ Branch 0 taken 103 times.
✓ Branch 1 taken 169 times.
272 if (!strcmp(key, "encoder")) {
534 int major, minor, micro;
535
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 103 times.
103 if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, &micro) == 3) {
536 c->handbrake_version = 1000000*major + 1000*minor + micro;
537 }
538 }
539 }
540
541 327 av_freep(&str);
542 327 return 0;
543 }
544
545 12 static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
546 {
547 int64_t start;
548 int i, nb_chapters, str_len, version;
549 char str[256+1];
550 int ret;
551
552
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (c->ignore_chapters)
553 return 0;
554
555
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if ((atom.size -= 5) < 0)
556 return 0;
557
558 12 version = avio_r8(pb);
559 12 avio_rb24(pb);
560
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if (version)
561 12 avio_rb32(pb); // ???
562 12 nb_chapters = avio_r8(pb);
563
564
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 12 times.
30 for (i = 0; i < nb_chapters; i++) {
565
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if (atom.size < 9)
566 return 0;
567
568 18 start = avio_rb64(pb);
569 18 str_len = avio_r8(pb);
570
571
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if ((atom.size -= 9+str_len) < 0)
572 return 0;
573
574 18 ret = ffio_read_size(pb, str, str_len);
575
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if (ret < 0)
576 return ret;
577 18 str[str_len] = 0;
578 18 avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
579 }
580 12 return 0;
581 }
582
583 #define MIN_DATA_ENTRY_BOX_SIZE 12
584 529 static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
585 {
586 AVStream *st;
587 MOVStreamContext *sc;
588 int entries, i, j;
589
590
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 529 times.
529 if (c->fc->nb_streams < 1)
591 return 0;
592 529 st = c->fc->streams[c->fc->nb_streams-1];
593 529 sc = st->priv_data;
594
595 529 avio_rb32(pb); // version + flags
596 529 entries = avio_rb32(pb);
597
1/2
✓ Branch 0 taken 529 times.
✗ Branch 1 not taken.
529 if (!entries ||
598
1/2
✓ Branch 0 taken 529 times.
✗ Branch 1 not taken.
529 entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
599
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 529 times.
529 entries >= UINT_MAX / sizeof(*sc->drefs))
600 return AVERROR_INVALIDDATA;
601
602
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 529 times.
529 for (i = 0; i < sc->drefs_count; i++) {
603 MOVDref *dref = &sc->drefs[i];
604 av_freep(&dref->path);
605 av_freep(&dref->dir);
606 }
607 529 av_free(sc->drefs);
608 529 sc->drefs_count = 0;
609 529 sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
610
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 529 times.
529 if (!sc->drefs)
611 return AVERROR(ENOMEM);
612 529 sc->drefs_count = entries;
613
614
2/2
✓ Branch 0 taken 529 times.
✓ Branch 1 taken 529 times.
1058 for (i = 0; i < entries; i++) {
615 529 MOVDref *dref = &sc->drefs[i];
616 529 uint32_t size = avio_rb32(pb);
617 529 int64_t next = avio_tell(pb);
618
619
3/6
✓ Branch 0 taken 529 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 529 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 529 times.
529 if (size < 12 || next < 0 || next > INT64_MAX - size)
620 return AVERROR_INVALIDDATA;
621
622 529 next += size - 4;
623
624 529 dref->type = avio_rl32(pb);
625 529 avio_rb32(pb); // version + flags
626
627
3/4
✓ Branch 0 taken 109 times.
✓ Branch 1 taken 420 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 109 times.
529 if (dref->type == MKTAG('a','l','i','s') && size > 150) {
628 /* macintosh alias record */
629 uint16_t volume_len, len;
630 int16_t type;
631 int ret;
632
633 avio_skip(pb, 10);
634
635 volume_len = avio_r8(pb);
636 volume_len = FFMIN(volume_len, 27);
637 ret = ffio_read_size(pb, dref->volume, 27);
638 if (ret < 0)
639 return ret;
640 dref->volume[volume_len] = 0;
641 av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
642
643 avio_skip(pb, 12);
644
645 len = avio_r8(pb);
646 len = FFMIN(len, 63);
647 ret = ffio_read_size(pb, dref->filename, 63);
648 if (ret < 0)
649 return ret;
650 dref->filename[len] = 0;
651 av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
652
653 avio_skip(pb, 16);
654
655 /* read next level up_from_alias/down_to_target */
656 dref->nlvl_from = avio_rb16(pb);
657 dref->nlvl_to = avio_rb16(pb);
658 av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
659 dref->nlvl_from, dref->nlvl_to);
660
661 avio_skip(pb, 16);
662
663 for (type = 0; type != -1 && avio_tell(pb) < next; ) {
664 if (avio_feof(pb))
665 return AVERROR_EOF;
666 type = avio_rb16(pb);
667 len = avio_rb16(pb);
668 av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
669 if (len&1)
670 len += 1;
671 if (type == 2) { // absolute path
672 av_free(dref->path);
673 dref->path = av_mallocz(len+1);
674 if (!dref->path)
675 return AVERROR(ENOMEM);
676
677 ret = ffio_read_size(pb, dref->path, len);
678 if (ret < 0) {
679 av_freep(&dref->path);
680 return ret;
681 }
682 if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
683 len -= volume_len;
684 memmove(dref->path, dref->path+volume_len, len);
685 dref->path[len] = 0;
686 }
687 // trim string of any ending zeros
688 for (j = len - 1; j >= 0; j--) {
689 if (dref->path[j] == 0)
690 len--;
691 else
692 break;
693 }
694 for (j = 0; j < len; j++)
695 if (dref->path[j] == ':' || dref->path[j] == 0)
696 dref->path[j] = '/';
697 av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
698 } else if (type == 0) { // directory name
699 av_free(dref->dir);
700 dref->dir = av_malloc(len+1);
701 if (!dref->dir)
702 return AVERROR(ENOMEM);
703
704 ret = ffio_read_size(pb, dref->dir, len);
705 if (ret < 0) {
706 av_freep(&dref->dir);
707 return ret;
708 }
709 dref->dir[len] = 0;
710 for (j = 0; j < len; j++)
711 if (dref->dir[j] == ':')
712 dref->dir[j] = '/';
713 av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
714 } else
715 avio_skip(pb, len);
716 }
717 } else {
718 529 av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
719 dref->type, size);
720 529 entries--;
721 529 i--;
722 }
723 529 avio_seek(pb, next, SEEK_SET);
724 }
725 529 return 0;
726 }
727
728 958 static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
729 {
730 AVStream *st;
731 uint32_t type;
732 uint32_t ctype;
733 int64_t title_size;
734 char *title_str;
735 int ret;
736
737 958 avio_r8(pb); /* version */
738 958 avio_rb24(pb); /* flags */
739
740 /* component type */
741 958 ctype = avio_rl32(pb);
742 958 type = avio_rl32(pb); /* component subtype */
743
744 958 av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
745 958 av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
746
747
2/2
✓ Branch 0 taken 101 times.
✓ Branch 1 taken 857 times.
958 if (c->trak_index < 0) { // meta not inside a trak
748
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 93 times.
101 if (type == MKTAG('m','d','t','a')) {
749 8 c->found_hdlr_mdta = 1;
750 }
751 101 return 0;
752 }
753
754 857 st = c->fc->streams[c->fc->nb_streams-1];
755
756
2/2
✓ Branch 0 taken 263 times.
✓ Branch 1 taken 594 times.
857 if (type == MKTAG('v','i','d','e'))
757 263 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
758
2/2
✓ Branch 0 taken 220 times.
✓ Branch 1 taken 374 times.
594 else if (type == MKTAG('s','o','u','n'))
759 220 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
760
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 374 times.
374 else if (type == MKTAG('m','1','a',' '))
761 st->codecpar->codec_id = AV_CODEC_ID_MP2;
762
2/4
✓ Branch 0 taken 374 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 374 times.
374 else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
763 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
764
765 857 avio_rb32(pb); /* component manufacture */
766 857 avio_rb32(pb); /* component flags */
767 857 avio_rb32(pb); /* component flags mask */
768
769 857 title_size = atom.size - 24;
770
2/2
✓ Branch 0 taken 854 times.
✓ Branch 1 taken 3 times.
857 if (title_size > 0) {
771
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 854 times.
854 if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
772 return AVERROR_INVALIDDATA;
773 854 title_str = av_malloc(title_size + 1); /* Add null terminator */
774
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 854 times.
854 if (!title_str)
775 return AVERROR(ENOMEM);
776
777 854 ret = ffio_read_size(pb, title_str, title_size);
778
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 854 times.
854 if (ret < 0) {
779 av_freep(&title_str);
780 return ret;
781 }
782 854 title_str[title_size] = 0;
783
2/2
✓ Branch 0 taken 804 times.
✓ Branch 1 taken 50 times.
854 if (title_str[0]) {
784
4/4
✓ Branch 0 taken 632 times.
✓ Branch 1 taken 172 times.
✓ Branch 2 taken 630 times.
✓ Branch 3 taken 2 times.
804 int off = (!c->isom && title_str[0] == title_size - 1);
785 // flag added so as to not set stream handler name if already set from mdia->hdlr
786 804 av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
787 }
788 854 av_freep(&title_str);
789 }
790
791 857 return 0;
792 }
793
794 142 static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
795 {
796 142 return ff_mov_read_esds(c->fc, pb);
797 }
798
799 7 static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
800 {
801 AVStream *st;
802 enum AVAudioServiceType *ast;
803 int ac3info, acmod, lfeon, bsmod;
804 uint64_t mask;
805
806
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (c->fc->nb_streams < 1)
807 return 0;
808 7 st = c->fc->streams[c->fc->nb_streams-1];
809
810 7 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
811 sizeof(*ast));
812
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (!ast)
813 return AVERROR(ENOMEM);
814
815 7 ac3info = avio_rb24(pb);
816 7 bsmod = (ac3info >> 14) & 0x7;
817 7 acmod = (ac3info >> 11) & 0x7;
818 7 lfeon = (ac3info >> 10) & 0x1;
819
820 7 mask = ff_ac3_channel_layout_tab[acmod];
821
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
7 if (lfeon)
822 1 mask |= AV_CH_LOW_FREQUENCY;
823 7 av_channel_layout_uninit(&st->codecpar->ch_layout);
824 7 av_channel_layout_from_mask(&st->codecpar->ch_layout, mask);
825
826 7 *ast = bsmod;
827
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)
828 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
829
830 7 return 0;
831 }
832
833 1 static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
834 {
835 AVStream *st;
836 enum AVAudioServiceType *ast;
837 int eac3info, acmod, lfeon, bsmod;
838 uint64_t mask;
839
840
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (c->fc->nb_streams < 1)
841 return 0;
842 1 st = c->fc->streams[c->fc->nb_streams-1];
843
844 1 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
845 sizeof(*ast));
846
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!ast)
847 return AVERROR(ENOMEM);
848
849 /* No need to parse fields for additional independent substreams and its
850 * associated dependent substreams since libavcodec's E-AC-3 decoder
851 * does not support them yet. */
852 1 avio_rb16(pb); /* data_rate and num_ind_sub */
853 1 eac3info = avio_rb24(pb);
854 1 bsmod = (eac3info >> 12) & 0x1f;
855 1 acmod = (eac3info >> 9) & 0x7;
856 1 lfeon = (eac3info >> 8) & 0x1;
857
858 1 mask = ff_ac3_channel_layout_tab[acmod];
859
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (lfeon)
860 mask |= AV_CH_LOW_FREQUENCY;
861 1 av_channel_layout_uninit(&st->codecpar->ch_layout);
862 1 av_channel_layout_from_mask(&st->codecpar->ch_layout, mask);
863
864 1 *ast = bsmod;
865
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)
866 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
867
868 1 return 0;
869 }
870
871 static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
872 {
873 #define DDTS_SIZE 20
874 uint8_t buf[DDTS_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
875 AVStream *st = NULL;
876 uint32_t frame_duration_code = 0;
877 uint32_t channel_layout_code = 0;
878 GetBitContext gb;
879 int ret;
880
881 if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
882 return ret;
883
884 init_get_bits(&gb, buf, 8 * DDTS_SIZE);
885
886 if (c->fc->nb_streams < 1) {
887 return 0;
888 }
889 st = c->fc->streams[c->fc->nb_streams-1];
890
891 st->codecpar->sample_rate = get_bits_long(&gb, 32);
892 if (st->codecpar->sample_rate <= 0) {
893 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
894 return AVERROR_INVALIDDATA;
895 }
896 skip_bits_long(&gb, 32); /* max bitrate */
897 st->codecpar->bit_rate = get_bits_long(&gb, 32);
898 st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
899 frame_duration_code = get_bits(&gb, 2);
900 skip_bits(&gb, 30); /* various fields */
901 channel_layout_code = get_bits(&gb, 16);
902
903 st->codecpar->frame_size =
904 (frame_duration_code == 0) ? 512 :
905 (frame_duration_code == 1) ? 1024 :
906 (frame_duration_code == 2) ? 2048 :
907 (frame_duration_code == 3) ? 4096 : 0;
908
909 if (channel_layout_code > 0xff) {
910 av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout\n");
911 }
912 av_channel_layout_uninit(&st->codecpar->ch_layout);
913 av_channel_layout_from_mask(&st->codecpar->ch_layout,
914 ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
915 ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
916 ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
917 ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
918 ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
919 ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0));
920
921 return 0;
922 }
923
924 50 static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
925 {
926 AVStream *st;
927
928
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 50 times.
50 if (c->fc->nb_streams < 1)
929 return 0;
930 50 st = c->fc->streams[c->fc->nb_streams-1];
931
932
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 50 times.
50 if (atom.size < 16)
933 return 0;
934
935 /* skip version and flags */
936 50 avio_skip(pb, 4);
937
938 50 ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
939
940 50 return 0;
941 }
942
943 2 static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
944 {
945 AVStream *st;
946 int ret;
947
948
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (c->fc->nb_streams < 1)
949 return 0;
950 2 st = c->fc->streams[c->fc->nb_streams-1];
951
952
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)
953 av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
954
955 2 return ret;
956 }
957
958 /* This atom overrides any previously set aspect ratio */
959 57 static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
960 {
961 57 const int num = avio_rb32(pb);
962 57 const int den = avio_rb32(pb);
963 AVStream *st;
964
965
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if (c->fc->nb_streams < 1)
966 return 0;
967 57 st = c->fc->streams[c->fc->nb_streams-1];
968
969
2/2
✓ Branch 0 taken 55 times.
✓ Branch 1 taken 2 times.
57 if (den != 0) {
970 55 av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den,
971 num, den, 32767);
972 }
973 57 return 0;
974 }
975
976 /* this atom contains actual media data */
977 811 static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
978 {
979
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 811 times.
811 if (atom.size == 0) /* wrong one (MP4) */
980 return 0;
981 811 c->found_mdat=1;
982 811 return 0; /* now go for moov */
983 }
984
985 #define DRM_BLOB_SIZE 56
986
987 static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
988 {
989 uint8_t intermediate_key[20];
990 uint8_t intermediate_iv[20];
991 uint8_t input[64];
992 uint8_t output[64];
993 uint8_t file_checksum[20];
994 uint8_t calculated_checksum[20];
995 char checksum_string[2 * sizeof(file_checksum) + 1];
996 struct AVSHA *sha;
997 int i;
998 int ret = 0;
999 uint8_t *activation_bytes = c->activation_bytes;
1000 uint8_t *fixed_key = c->audible_fixed_key;
1001
1002 c->aax_mode = 1;
1003
1004 sha = av_sha_alloc();
1005 if (!sha)
1006 return AVERROR(ENOMEM);
1007 av_free(c->aes_decrypt);
1008 c->aes_decrypt = av_aes_alloc();
1009 if (!c->aes_decrypt) {
1010 ret = AVERROR(ENOMEM);
1011 goto fail;
1012 }
1013
1014 /* drm blob processing */
1015 avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1016 avio_read(pb, input, DRM_BLOB_SIZE);
1017 avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1018 avio_read(pb, file_checksum, 20);
1019
1020 // required by external tools
1021 ff_data_to_hex(checksum_string, file_checksum, sizeof(file_checksum), 1);
1022 av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == %s\n", checksum_string);
1023
1024 /* verify activation data */
1025 if (!activation_bytes) {
1026 av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1027 ret = 0; /* allow ffprobe to continue working on .aax files */
1028 goto fail;
1029 }
1030 if (c->activation_bytes_size != 4) {
1031 av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1032 ret = AVERROR(EINVAL);
1033 goto fail;
1034 }
1035
1036 /* verify fixed key */
1037 if (c->audible_fixed_key_size != 16) {
1038 av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1039 ret = AVERROR(EINVAL);
1040 goto fail;
1041 }
1042
1043 /* AAX (and AAX+) key derivation */
1044 av_sha_init(sha, 160);
1045 av_sha_update(sha, fixed_key, 16);
1046 av_sha_update(sha, activation_bytes, 4);
1047 av_sha_final(sha, intermediate_key);
1048 av_sha_init(sha, 160);
1049 av_sha_update(sha, fixed_key, 16);
1050 av_sha_update(sha, intermediate_key, 20);
1051 av_sha_update(sha, activation_bytes, 4);
1052 av_sha_final(sha, intermediate_iv);
1053 av_sha_init(sha, 160);
1054 av_sha_update(sha, intermediate_key, 16);
1055 av_sha_update(sha, intermediate_iv, 16);
1056 av_sha_final(sha, calculated_checksum);
1057 if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1058 av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1059 ret = AVERROR_INVALIDDATA;
1060 goto fail;
1061 }
1062 av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1063 av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1064 for (i = 0; i < 4; i++) {
1065 // file data (in output) is stored in big-endian mode
1066 if (activation_bytes[i] != output[3 - i]) { // critical error
1067 av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1068 ret = AVERROR_INVALIDDATA;
1069 goto fail;
1070 }
1071 }
1072 memcpy(c->file_key, output + 8, 16);
1073 memcpy(input, output + 26, 16);
1074 av_sha_init(sha, 160);
1075 av_sha_update(sha, input, 16);
1076 av_sha_update(sha, c->file_key, 16);
1077 av_sha_update(sha, fixed_key, 16);
1078 av_sha_final(sha, c->file_iv);
1079
1080 fail:
1081 av_free(sha);
1082
1083 return ret;
1084 }
1085
1086 static int mov_aaxc_crypto(MOVContext *c)
1087 {
1088 if (c->audible_key_size != 16) {
1089 av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
1090 return AVERROR(EINVAL);
1091 }
1092
1093 if (c->audible_iv_size != 16) {
1094 av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
1095 return AVERROR(EINVAL);
1096 }
1097
1098 c->aes_decrypt = av_aes_alloc();
1099 if (!c->aes_decrypt) {
1100 return AVERROR(ENOMEM);
1101 }
1102
1103 memcpy(c->file_key, c->audible_key, 16);
1104 memcpy(c->file_iv, c->audible_iv, 16);
1105 c->aax_mode = 1;
1106
1107 return 0;
1108 }
1109
1110 // Audible AAX (and AAX+) bytestream decryption
1111 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1112 {
1113 int blocks = 0;
1114 unsigned char iv[16];
1115
1116 memcpy(iv, c->file_iv, 16); // iv is overwritten
1117 blocks = size >> 4; // trailing bytes are not encrypted!
1118 av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1119 av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1120
1121 return 0;
1122 }
1123
1124 /* read major brand, minor version and compatible brands and store them as metadata */
1125 390 static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1126 {
1127 uint32_t minor_ver;
1128 int comp_brand_size;
1129 char* comp_brands_str;
1130 390 uint8_t type[5] = {0};
1131 390 int ret = ffio_read_size(pb, type, 4);
1132
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 390 times.
390 if (ret < 0)
1133 return ret;
1134
1135
2/2
✓ Branch 0 taken 180 times.
✓ Branch 1 taken 210 times.
390 if (strcmp(type, "qt "))
1136 180 c->isom = 1;
1137 390 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1138 390 av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1139 390 c->is_still_picture_avif = !strncmp(type, "avif", 4);
1140 390 minor_ver = avio_rb32(pb); /* minor version */
1141 390 av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1142
1143 390 comp_brand_size = atom.size - 8;
1144
2/4
✓ Branch 0 taken 390 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 390 times.
390 if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1145 return AVERROR_INVALIDDATA;
1146 390 comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1147
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 390 times.
390 if (!comp_brands_str)
1148 return AVERROR(ENOMEM);
1149
1150 390 ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1151
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 390 times.
390 if (ret < 0) {
1152 av_freep(&comp_brands_str);
1153 return ret;
1154 }
1155 390 comp_brands_str[comp_brand_size] = 0;
1156 390 av_dict_set(&c->fc->metadata, "compatible_brands",
1157 comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1158
1159 // Logic for handling Audible's .aaxc files
1160
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 390 times.
390 if (!strcmp(type, "aaxc")) {
1161 mov_aaxc_crypto(c);
1162 }
1163
1164 390 return 0;
1165 }
1166
1167 /* this atom should contain all header atoms */
1168 434 static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1169 {
1170 int ret;
1171
1172
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 434 times.
434 if (c->found_moov) {
1173 av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1174 avio_skip(pb, atom.size);
1175 return 0;
1176 }
1177
1178
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 434 times.
434 if ((ret = mov_read_default(c, pb, atom)) < 0)
1179 return ret;
1180 /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1181 /* so we don't parse the whole file if over a network */
1182 434 c->found_moov=1;
1183 434 return 0; /* now go for mdat */
1184 }
1185
1186 2869 static MOVFragmentStreamInfo * get_frag_stream_info(
1187 MOVFragmentIndex *frag_index,
1188 int index,
1189 int id)
1190 {
1191 int i;
1192 MOVFragmentIndexItem * item;
1193
1194
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)
1195 return NULL;
1196 2869 item = &frag_index->item[index];
1197
1/2
✓ Branch 0 taken 2993 times.
✗ Branch 1 not taken.
2993 for (i = 0; i < item->nb_stream_info; i++)
1198
2/2
✓ Branch 0 taken 2869 times.
✓ Branch 1 taken 124 times.
2993 if (item->stream_info[i].id == id)
1199 2869 return &item->stream_info[i];
1200
1201 // This shouldn't happen
1202 return NULL;
1203 }
1204
1205 388 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1206 {
1207 int i;
1208 MOVFragmentIndexItem * item;
1209
1210
1/2
✓ Branch 0 taken 388 times.
✗ Branch 1 not taken.
388 if (frag_index->current < 0 ||
1211
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 388 times.
388 frag_index->current >= frag_index->nb_items)
1212 return;
1213
1214 388 item = &frag_index->item[frag_index->current];
1215
1/2
✓ Branch 0 taken 394 times.
✗ Branch 1 not taken.
394 for (i = 0; i < item->nb_stream_info; i++)
1216
2/2
✓ Branch 0 taken 388 times.
✓ Branch 1 taken 6 times.
394 if (item->stream_info[i].id == id) {
1217 388 item->current = i;
1218 388 return;
1219 }
1220
1221 // id not found. This shouldn't happen.
1222 item->current = -1;
1223 }
1224
1225 1149 static MOVFragmentStreamInfo * get_current_frag_stream_info(
1226 MOVFragmentIndex *frag_index)
1227 {
1228 MOVFragmentIndexItem *item;
1229
1/2
✓ Branch 0 taken 1149 times.
✗ Branch 1 not taken.
1149 if (frag_index->current < 0 ||
1230
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1146 times.
1149 frag_index->current >= frag_index->nb_items)
1231 3 return NULL;
1232
1233 1146 item = &frag_index->item[frag_index->current];
1234
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)
1235 1146 return &item->stream_info[item->current];
1236
1237 // This shouldn't happen
1238 return NULL;
1239 }
1240
1241 798 static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
1242 {
1243 int a, b, m;
1244 int64_t moof_offset;
1245
1246 // Optimize for appending new entries
1247
2/2
✓ Branch 0 taken 788 times.
✓ Branch 1 taken 10 times.
798 if (!frag_index->nb_items ||
1248
2/2
✓ Branch 0 taken 383 times.
✓ Branch 1 taken 405 times.
788 frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1249 393 return frag_index->nb_items;
1250
1251 405 a = -1;
1252 405 b = frag_index->nb_items;
1253
1254
2/2
✓ Branch 0 taken 2655 times.
✓ Branch 1 taken 405 times.
3060 while (b - a > 1) {
1255 2655 m = (a + b) >> 1;
1256 2655 moof_offset = frag_index->item[m].moof_offset;
1257
2/2
✓ Branch 0 taken 732 times.
✓ Branch 1 taken 1923 times.
2655 if (moof_offset >= offset)
1258 732 b = m;
1259
2/2
✓ Branch 0 taken 2328 times.
✓ Branch 1 taken 327 times.
2655 if (moof_offset <= offset)
1260 2328 a = m;
1261 }
1262 405 return b;
1263 }
1264
1265 static int64_t get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
1266 {
1267 av_assert0(frag_stream_info);
1268 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1269 return frag_stream_info->sidx_pts;
1270 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1271 return frag_stream_info->first_tfra_pts;
1272 return frag_stream_info->tfdt_dts;
1273 }
1274
1275 219 static int64_t get_frag_time(AVFormatContext *s, AVStream *dst_st,
1276 MOVFragmentIndex *frag_index, int index)
1277 {
1278 MOVFragmentStreamInfo * frag_stream_info;
1279 219 MOVStreamContext *sc = dst_st->priv_data;
1280 int64_t timestamp;
1281 int i, j;
1282
1283 // If the stream is referenced by any sidx, limit the search
1284 // to fragments that referenced this stream in the sidx
1285
1/2
✓ Branch 0 taken 219 times.
✗ Branch 1 not taken.
219 if (sc->has_sidx) {
1286 219 frag_stream_info = get_frag_stream_info(frag_index, index, dst_st->id);
1287
1/2
✓ Branch 0 taken 219 times.
✗ Branch 1 not taken.
219 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1288 219 return frag_stream_info->sidx_pts;
1289 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1290 return frag_stream_info->first_tfra_pts;
1291 return frag_stream_info->sidx_pts;
1292 }
1293
1294 for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1295 AVStream *frag_stream = NULL;
1296 frag_stream_info = &frag_index->item[index].stream_info[i];
1297 for (j = 0; j < s->nb_streams; j++)
1298 if (s->streams[j]->id == frag_stream_info->id)
1299 frag_stream = s->streams[j];
1300 if (!frag_stream) {
1301 av_log(s, AV_LOG_WARNING, "No stream matching sidx ID found.\n");
1302 continue;
1303 }
1304 timestamp = get_stream_info_time(frag_stream_info);
1305 if (timestamp != AV_NOPTS_VALUE)
1306 return av_rescale_q(timestamp, frag_stream->time_base, dst_st->time_base);
1307 }
1308 return AV_NOPTS_VALUE;
1309 }
1310
1311 26 static int search_frag_timestamp(AVFormatContext *s, MOVFragmentIndex *frag_index,
1312 AVStream *st, int64_t timestamp)
1313 {
1314 int a, b, m, m0;
1315 int64_t frag_time;
1316
1317 26 a = -1;
1318 26 b = frag_index->nb_items;
1319
1320
2/2
✓ Branch 0 taken 219 times.
✓ Branch 1 taken 26 times.
245 while (b - a > 1) {
1321 219 m0 = m = (a + b) >> 1;
1322
1323
2/4
✓ Branch 0 taken 219 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 219 times.
438 while (m < b &&
1324 219 (frag_time = get_frag_time(s, st, frag_index, m)) == AV_NOPTS_VALUE)
1325 m++;
1326
1327
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)
1328 93 a = m;
1329 else
1330 126 b = m0;
1331 }
1332
1333 26 return a;
1334 }
1335
1336 756 static int update_frag_index(MOVContext *c, int64_t offset)
1337 {
1338 int index, i;
1339 MOVFragmentIndexItem * item;
1340 MOVFragmentStreamInfo * frag_stream_info;
1341
1342 // If moof_offset already exists in frag_index, return index to it
1343 756 index = search_frag_moof_offset(&c->frag_index, offset);
1344
2/2
✓ Branch 0 taken 367 times.
✓ Branch 1 taken 389 times.
756 if (index < c->frag_index.nb_items &&
1345
1/2
✓ Branch 0 taken 367 times.
✗ Branch 1 not taken.
367 c->frag_index.item[index].moof_offset == offset)
1346 367 return index;
1347
1348 // offset is not yet in frag index.
1349 // Insert new item at index (sorted by moof offset)
1350 389 item = av_fast_realloc(c->frag_index.item,
1351 389 &c->frag_index.allocated_size,
1352 389 (c->frag_index.nb_items + 1) *
1353 sizeof(*c->frag_index.item));
1354
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 389 times.
389 if (!item)
1355 return -1;
1356 389 c->frag_index.item = item;
1357
1358 389 frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1359 sizeof(*item->stream_info));
1360
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 389 times.
389 if (!frag_stream_info)
1361 return -1;
1362
1363
2/2
✓ Branch 0 taken 407 times.
✓ Branch 1 taken 389 times.
796 for (i = 0; i < c->fc->nb_streams; i++) {
1364 // Avoid building frag index if streams lack track id.
1365
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 407 times.
407 if (c->fc->streams[i]->id < 0) {
1366 av_free(frag_stream_info);
1367 return AVERROR_INVALIDDATA;
1368 }
1369
1370 407 frag_stream_info[i].id = c->fc->streams[i]->id;
1371 407 frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1372 407 frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1373 407 frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1374 407 frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1375 407 frag_stream_info[i].index_base = -1;
1376 407 frag_stream_info[i].index_entry = -1;
1377 407 frag_stream_info[i].encryption_index = NULL;
1378 }
1379
1380
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 389 times.
389 if (index < c->frag_index.nb_items)
1381 memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1382 (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1383
1384 389 item = &c->frag_index.item[index];
1385 389 item->headers_read = 0;
1386 389 item->current = 0;
1387 389 item->nb_stream_info = c->fc->nb_streams;
1388 389 item->moof_offset = offset;
1389 389 item->stream_info = frag_stream_info;
1390 389 c->frag_index.nb_items++;
1391
1392 389 return index;
1393 }
1394
1395 388 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1396 int id, int entries)
1397 {
1398 int i;
1399 MOVFragmentStreamInfo * frag_stream_info;
1400
1401
1/2
✓ Branch 0 taken 388 times.
✗ Branch 1 not taken.
388 if (index < 0)
1402 388 return;
1403 for (i = index; i < frag_index->nb_items; i++) {
1404 frag_stream_info = get_frag_stream_info(frag_index, i, id);
1405 if (frag_stream_info && frag_stream_info->index_entry >= 0)
1406 frag_stream_info->index_entry += entries;
1407 }
1408 }
1409
1410 388 static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1411 {
1412 // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1413 388 c->fragment.found_tfhd = 0;
1414
1415
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) {
1416 c->has_looked_for_mfra = 1;
1417 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1418 int ret;
1419 av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1420 "for a mfra\n");
1421 if ((ret = mov_read_mfra(c, pb)) < 0) {
1422 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1423 "read the mfra (may be a live ismv)\n");
1424 }
1425 } else {
1426 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1427 "seekable, can not look for mfra\n");
1428 }
1429 }
1430 388 c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1431 388 av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1432 388 c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1433 388 return mov_read_default(c, pb, atom);
1434 }
1435
1436 960 static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time, void *logctx)
1437 {
1438
2/2
✓ Branch 0 taken 495 times.
✓ Branch 1 taken 465 times.
960 if (time) {
1439
2/2
✓ Branch 0 taken 447 times.
✓ Branch 1 taken 48 times.
495 if (time >= 2082844800)
1440 447 time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1441
1442
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 495 times.
495 if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1443 av_log(logctx, AV_LOG_DEBUG, "creation_time is not representable\n");
1444 return;
1445 }
1446
1447 495 avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1448 }
1449 }
1450
1451 529 static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1452 {
1453 AVStream *st;
1454 MOVStreamContext *sc;
1455 int version;
1456 529 char language[4] = {0};
1457 unsigned lang;
1458 int64_t creation_time;
1459
1460
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 529 times.
529 if (c->fc->nb_streams < 1)
1461 return 0;
1462 529 st = c->fc->streams[c->fc->nb_streams-1];
1463 529 sc = st->priv_data;
1464
1465
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 529 times.
529 if (sc->time_scale) {
1466 av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1467 return AVERROR_INVALIDDATA;
1468 }
1469
1470 529 version = avio_r8(pb);
1471
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 529 times.
529 if (version > 1) {
1472 avpriv_request_sample(c->fc, "Version %d", version);
1473 return AVERROR_PATCHWELCOME;
1474 }
1475 529 avio_rb24(pb); /* flags */
1476
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 520 times.
529 if (version == 1) {
1477 9 creation_time = avio_rb64(pb);
1478 9 avio_rb64(pb);
1479 } else {
1480 520 creation_time = avio_rb32(pb);
1481 520 avio_rb32(pb); /* modification time */
1482 }
1483 529 mov_metadata_creation_time(&st->metadata, creation_time, c->fc);
1484
1485 529 sc->time_scale = avio_rb32(pb);
1486
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 529 times.
529 if (sc->time_scale <= 0) {
1487 av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1488 sc->time_scale = 1;
1489 }
1490
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 520 times.
529 st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1491
1492
6/6
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 520 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 520 times.
✓ Branch 5 taken 4 times.
529 if ((version == 1 && st->duration == UINT64_MAX) ||
1493
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 520 times.
520 (version != 1 && st->duration == UINT32_MAX)) {
1494 5 st->duration = 0;
1495 }
1496
1497 529 lang = avio_rb16(pb); /* language */
1498
2/2
✓ Branch 1 taken 377 times.
✓ Branch 2 taken 152 times.
529 if (ff_mov_lang_to_iso639(lang, language))
1499 377 av_dict_set(&st->metadata, "language", language, 0);
1500 529 avio_rb16(pb); /* quality */
1501
1502 529 return 0;
1503 }
1504
1505 431 static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1506 {
1507 int i;
1508 int64_t creation_time;
1509 431 int version = avio_r8(pb); /* version */
1510 431 avio_rb24(pb); /* flags */
1511
1512
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 429 times.
431 if (version == 1) {
1513 2 creation_time = avio_rb64(pb);
1514 2 avio_rb64(pb);
1515 } else {
1516 429 creation_time = avio_rb32(pb);
1517 429 avio_rb32(pb); /* modification time */
1518 }
1519 431 mov_metadata_creation_time(&c->fc->metadata, creation_time, c->fc);
1520 431 c->time_scale = avio_rb32(pb); /* time scale */
1521
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 431 times.
431 if (c->time_scale <= 0) {
1522 av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1523 c->time_scale = 1;
1524 }
1525 431 av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1526
1527
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 429 times.
431 c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1528 431 avio_rb32(pb); /* preferred scale */
1529
1530 431 avio_rb16(pb); /* preferred volume */
1531
1532 431 avio_skip(pb, 10); /* reserved */
1533
1534 /* movie display matrix, store it in main context and use it later on */
1535
2/2
✓ Branch 0 taken 1293 times.
✓ Branch 1 taken 431 times.
1724 for (i = 0; i < 3; i++) {
1536 1293 c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1537 1293 c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1538 1293 c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1539 }
1540
1541 431 avio_rb32(pb); /* preview time */
1542 431 avio_rb32(pb); /* preview duration */
1543 431 avio_rb32(pb); /* poster time */
1544 431 avio_rb32(pb); /* selection time */
1545 431 avio_rb32(pb); /* selection duration */
1546 431 avio_rb32(pb); /* current time */
1547 431 avio_rb32(pb); /* next track ID */
1548
1549 431 return 0;
1550 }
1551
1552 1 static void set_last_stream_little_endian(AVFormatContext *fc)
1553 {
1554 AVStream *st;
1555
1556
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (fc->nb_streams < 1)
1557 return;
1558 1 st = fc->streams[fc->nb_streams-1];
1559
1560
1/6
✗ 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.
1 switch (st->codecpar->codec_id) {
1561 case AV_CODEC_ID_PCM_S16BE:
1562 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
1563 break;
1564 1 case AV_CODEC_ID_PCM_S24BE:
1565 1 st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE;
1566 1 break;
1567 case AV_CODEC_ID_PCM_S32BE:
1568 st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE;
1569 break;
1570 case AV_CODEC_ID_PCM_F32BE:
1571 st->codecpar->codec_id = AV_CODEC_ID_PCM_F32LE;
1572 break;
1573 case AV_CODEC_ID_PCM_F64BE:
1574 st->codecpar->codec_id = AV_CODEC_ID_PCM_F64LE;
1575 break;
1576 default:
1577 break;
1578 }
1579 }
1580
1581 5 static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1582 {
1583 5 int little_endian = avio_rb16(pb) & 0xFF;
1584 5 av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1585
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
5 if (little_endian == 1)
1586 1 set_last_stream_little_endian(c->fc);
1587 5 return 0;
1588 }
1589
1590 static int mov_read_pcmc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1591 {
1592 int format_flags;
1593
1594 if (atom.size < 6) {
1595 av_log(c->fc, AV_LOG_ERROR, "Empty pcmC box\n");
1596 return AVERROR_INVALIDDATA;
1597 }
1598
1599 avio_r8(pb); // version
1600 avio_rb24(pb); // flags
1601 format_flags = avio_r8(pb);
1602 if (format_flags == 1) // indicates little-endian format. If not present, big-endian format is used
1603 set_last_stream_little_endian(c->fc);
1604
1605 return 0;
1606 }
1607
1608 32 static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1609 {
1610 AVStream *st;
1611 uint8_t *icc_profile;
1612 32 char color_parameter_type[5] = { 0 };
1613 uint16_t color_primaries, color_trc, color_matrix;
1614 int ret;
1615
1616
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
32 if (c->fc->nb_streams < 1)
1617 return 0;
1618 32 st = c->fc->streams[c->fc->nb_streams - 1];
1619
1620 32 ret = ffio_read_size(pb, color_parameter_type, 4);
1621
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
32 if (ret < 0)
1622 return ret;
1623
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 6 times.
32 if (strncmp(color_parameter_type, "nclx", 4) &&
1624
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 strncmp(color_parameter_type, "nclc", 4) &&
1625 strncmp(color_parameter_type, "prof", 4)) {
1626 av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
1627 color_parameter_type);
1628 return 0;
1629 }
1630
1631
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
32 if (!strncmp(color_parameter_type, "prof", 4)) {
1632 icc_profile = av_stream_new_side_data(st, AV_PKT_DATA_ICC_PROFILE, atom.size - 4);
1633 if (!icc_profile)
1634 return AVERROR(ENOMEM);
1635 ret = ffio_read_size(pb, icc_profile, atom.size - 4);
1636 if (ret < 0)
1637 return ret;
1638 } else {
1639 32 color_primaries = avio_rb16(pb);
1640 32 color_trc = avio_rb16(pb);
1641 32 color_matrix = avio_rb16(pb);
1642
1643 32 av_log(c->fc, AV_LOG_TRACE,
1644 "%s: pri %d trc %d matrix %d",
1645 color_parameter_type, color_primaries, color_trc, color_matrix);
1646
1647
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 26 times.
32 if (!strncmp(color_parameter_type, "nclx", 4)) {
1648 6 uint8_t color_range = avio_r8(pb) >> 7;
1649 6 av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
1650
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (color_range)
1651 st->codecpar->color_range = AVCOL_RANGE_JPEG;
1652 else
1653 6 st->codecpar->color_range = AVCOL_RANGE_MPEG;
1654 }
1655
1656
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
32 if (!av_color_primaries_name(color_primaries))
1657 color_primaries = AVCOL_PRI_UNSPECIFIED;
1658
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
32 if (!av_color_transfer_name(color_trc))
1659 color_trc = AVCOL_TRC_UNSPECIFIED;
1660
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
32 if (!av_color_space_name(color_matrix))
1661 color_matrix = AVCOL_SPC_UNSPECIFIED;
1662
1663 32 st->codecpar->color_primaries = color_primaries;
1664 32 st->codecpar->color_trc = color_trc;
1665 32 st->codecpar->color_space = color_matrix;
1666 32 av_log(c->fc, AV_LOG_TRACE, "\n");
1667 }
1668 32 return 0;
1669 }
1670
1671 99 static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1672 {
1673 AVStream *st;
1674 unsigned mov_field_order;
1675 99 enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
1676
1677
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 99 times.
99 if (c->fc->nb_streams < 1) // will happen with jp2 files
1678 return 0;
1679 99 st = c->fc->streams[c->fc->nb_streams-1];
1680
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 99 times.
99 if (atom.size < 2)
1681 return AVERROR_INVALIDDATA;
1682 99 mov_field_order = avio_rb16(pb);
1683
2/2
✓ Branch 0 taken 87 times.
✓ Branch 1 taken 12 times.
99 if ((mov_field_order & 0xFF00) == 0x0100)
1684 87 decoded_field_order = AV_FIELD_PROGRESSIVE;
1685
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 else if ((mov_field_order & 0xFF00) == 0x0200) {
1686
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) {
1687 1 case 0x01: decoded_field_order = AV_FIELD_TT;
1688 1 break;
1689 case 0x06: decoded_field_order = AV_FIELD_BB;
1690 break;
1691 1 case 0x09: decoded_field_order = AV_FIELD_TB;
1692 1 break;
1693 10 case 0x0E: decoded_field_order = AV_FIELD_BT;
1694 10 break;
1695 }
1696 }
1697
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 99 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
99 if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
1698 av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
1699 }
1700 99 st->codecpar->field_order = decoded_field_order;
1701
1702 99 return 0;
1703 }
1704
1705 64 static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
1706 {
1707 64 int err = 0;
1708 64 uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
1709
2/4
✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 64 times.
64 if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
1710 return AVERROR_INVALIDDATA;
1711
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 64 times.
64 if ((err = av_reallocp(&par->extradata, size)) < 0) {
1712 par->extradata_size = 0;
1713 return err;
1714 }
1715 64 par->extradata_size = size - AV_INPUT_BUFFER_PADDING_SIZE;
1716 64 return 0;
1717 }
1718
1719 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
1720 64 static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1721 AVCodecParameters *par, uint8_t *buf)
1722 {
1723 64 int64_t result = atom.size;
1724 int err;
1725
1726 64 AV_WB32(buf , atom.size + 8);
1727 64 AV_WL32(buf + 4, atom.type);
1728 64 err = ffio_read_size(pb, buf + 8, atom.size);
1729
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 64 times.
64 if (err < 0) {
1730 par->extradata_size -= atom.size;
1731 return err;
1732
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 64 times.
64 } else if (err < atom.size) {
1733 av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
1734 par->extradata_size -= atom.size - err;
1735 result = err;
1736 }
1737 64 memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1738 64 return result;
1739 }
1740
1741 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
1742 57 static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1743 enum AVCodecID codec_id)
1744 {
1745 AVStream *st;
1746 uint64_t original_size;
1747 int err;
1748
1749
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if (c->fc->nb_streams < 1) // will happen with jp2 files
1750 return 0;
1751 57 st = c->fc->streams[c->fc->nb_streams-1];
1752
1753
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 38 times.
57 if (st->codecpar->codec_id != codec_id)
1754 19 return 0; /* unexpected codec_id - don't mess with extradata */
1755
1756 38 original_size = st->codecpar->extradata_size;
1757 38 err = mov_realloc_extradata(st->codecpar, atom);
1758
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 if (err)
1759 return err;
1760
1761 38 err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
1762
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 if (err < 0)
1763 return err;
1764 38 return 0; // Note: this is the original behavior to ignore truncation.
1765 }
1766
1767 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
1768 15 static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1769 {
1770 15 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
1771 }
1772
1773 static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1774 {
1775 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS);
1776 }
1777
1778 static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1779 {
1780 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
1781 }
1782
1783 static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1784 {
1785 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
1786 }
1787
1788 19 static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1789 {
1790 19 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
1791
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 if (!ret)
1792 19 ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
1793 19 return ret;
1794 }
1795
1796 static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1797 {
1798 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
1799
1800 if (!ret && c->fc->nb_streams >= 1) {
1801 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1802 if (par->extradata_size >= 40) {
1803 par->height = AV_RB16(&par->extradata[36]);
1804 par->width = AV_RB16(&par->extradata[38]);
1805 }
1806 }
1807 return ret;
1808 }
1809
1810 16 static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1811 {
1812
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 if (c->fc->nb_streams >= 1) {
1813 16 AVStream *const st = c->fc->streams[c->fc->nb_streams - 1];
1814 16 FFStream *const sti = ffstream(st);
1815 16 AVCodecParameters *par = st->codecpar;
1816
1817
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
1818 par->codec_id == AV_CODEC_ID_H264 &&
1819 atom.size > 11) {
1820 int cid;
1821 avio_skip(pb, 10);
1822 cid = avio_rb16(pb);
1823 /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
1824 if (cid == 0xd4d || cid == 0xd4e)
1825 par->width = 1440;
1826 return 0;
1827
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
1828
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
1829
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 3 times.
16 par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
1830
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 atom.size >= 24) {
1831 int num, den;
1832 13 avio_skip(pb, 12);
1833 13 num = avio_rb32(pb);
1834 13 den = avio_rb32(pb);
1835
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)
1836 return 0;
1837
2/3
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
13 switch (avio_rb32(pb)) {
1838 12 case 2:
1839
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (den >= INT_MAX / 2)
1840 return 0;
1841 12 den *= 2;
1842 13 case 1:
1843 13 sti->display_aspect_ratio = (AVRational){ num, den };
1844 13 default:
1845 13 return 0;
1846 }
1847 }
1848 }
1849
1850 3 return mov_read_avid(c, pb, atom);
1851 }
1852
1853 26 static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1854 {
1855 26 int ret = 0;
1856 26 int length = 0;
1857 uint64_t original_size;
1858
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 if (c->fc->nb_streams >= 1) {
1859 26 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1860
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (par->codec_id == AV_CODEC_ID_H264)
1861 return 0;
1862
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 if (atom.size == 16) {
1863 26 original_size = par->extradata_size;
1864 26 ret = mov_realloc_extradata(par, atom);
1865
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 if (!ret) {
1866 26 length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
1867
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 if (length == atom.size) {
1868 26 const uint8_t range_value = par->extradata[original_size + 19];
1869
1/3
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
26 switch (range_value) {
1870 26 case 1:
1871 26 par->color_range = AVCOL_RANGE_MPEG;
1872 26 break;
1873 case 2:
1874 par->color_range = AVCOL_RANGE_JPEG;
1875 break;
1876 default:
1877 av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
1878 break;
1879 }
1880 ff_dlog(c->fc, "color_range: %d\n", par->color_range);
1881 } else {
1882 /* For some reason the whole atom was not added to the extradata */
1883 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
1884 }
1885 } else {
1886 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
1887 }
1888 } else {
1889 av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
1890 }
1891 }
1892
1893 26 return ret;
1894 }
1895
1896 4 static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1897 {
1898 4 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
1899 }
1900
1901 33 static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1902 {
1903 AVStream *st;
1904 int ret;
1905
1906
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 33 times.
33 if (c->fc->nb_streams < 1)
1907 return 0;
1908 33 st = c->fc->streams[c->fc->nb_streams-1];
1909
1910
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 33 times.
33 if ((uint64_t)atom.size > (1<<30