Line | Branch | Exec | Source |
---|---|---|---|
1 | /* | ||
2 | * RIFF demuxing functions and data | ||
3 | * Copyright (c) 2000 Fabrice Bellard | ||
4 | * | ||
5 | * This file is part of FFmpeg. | ||
6 | * | ||
7 | * FFmpeg is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU Lesser General Public | ||
9 | * License as published by the Free Software Foundation; either | ||
10 | * version 2.1 of the License, or (at your option) any later version. | ||
11 | * | ||
12 | * FFmpeg is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * Lesser General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public | ||
18 | * License along with FFmpeg; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
20 | */ | ||
21 | |||
22 | #include "libavutil/avassert.h" | ||
23 | #include "libavutil/dict.h" | ||
24 | #include "libavutil/error.h" | ||
25 | #include "libavutil/intreadwrite.h" | ||
26 | #include "libavutil/log.h" | ||
27 | #include "libavutil/mem.h" | ||
28 | #include "avformat.h" | ||
29 | #include "avio_internal.h" | ||
30 | #include "demux.h" | ||
31 | #include "riff.h" | ||
32 | |||
33 | 2252 | int ff_get_guid(AVIOContext *s, ff_asf_guid *g) | |
34 | { | ||
35 | int ret; | ||
36 | av_assert0(sizeof(*g) == 16); //compiler will optimize this out | ||
37 | 2252 | ret = ffio_read_size(s, *g, sizeof(*g)); | |
38 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 2242 times.
|
2252 | if (ret < 0) { |
39 | 10 | memset(*g, 0, sizeof(*g)); | |
40 | 10 | return ret; | |
41 | } | ||
42 | 2242 | return 0; | |
43 | } | ||
44 | |||
45 | 10 | enum AVCodecID ff_codec_guid_get_id(const AVCodecGuid *guids, ff_asf_guid guid) | |
46 | { | ||
47 | int i; | ||
48 |
1/2✓ Branch 0 taken 34 times.
✗ Branch 1 not taken.
|
34 | for (i = 0; guids[i].id != AV_CODEC_ID_NONE; i++) |
49 |
2/2✓ Branch 1 taken 10 times.
✓ Branch 2 taken 24 times.
|
34 | if (!ff_guidcmp(guids[i].guid, guid)) |
50 | 10 | return guids[i].id; | |
51 | ✗ | return AV_CODEC_ID_NONE; | |
52 | } | ||
53 | |||
54 | /* We could be given one of the three possible structures here: | ||
55 | * WAVEFORMAT, PCMWAVEFORMAT or WAVEFORMATEX. Each structure | ||
56 | * is an expansion of the previous one with the fields added | ||
57 | * at the bottom. PCMWAVEFORMAT adds 'WORD wBitsPerSample' and | ||
58 | * WAVEFORMATEX adds 'WORD cbSize' and basically makes itself | ||
59 | * an openended structure. | ||
60 | */ | ||
61 | |||
62 | 15 | static void parse_waveformatex(void *logctx, AVIOContext *pb, AVCodecParameters *par) | |
63 | { | ||
64 | ff_asf_guid subformat; | ||
65 | int bps; | ||
66 | uint64_t mask; | ||
67 | |||
68 | 15 | bps = avio_rl16(pb); | |
69 |
1/2✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
|
15 | if (bps) |
70 | 15 | par->bits_per_coded_sample = bps; | |
71 | |||
72 | 15 | mask = avio_rl32(pb); /* dwChannelMask */ | |
73 | 15 | av_channel_layout_from_mask(&par->ch_layout, mask); | |
74 | |||
75 | 15 | ff_get_guid(pb, &subformat); | |
76 | 15 | if (!memcmp(subformat + 4, | |
77 |
1/2✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
|
15 | (const uint8_t[]){ FF_AMBISONIC_BASE_GUID }, 12) || |
78 | 15 | !memcmp(subformat + 4, | |
79 |
1/2✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
|
15 | (const uint8_t[]){ FF_BROKEN_BASE_GUID }, 12) || |
80 | 15 | !memcmp(subformat + 4, | |
81 |
1/2✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
|
15 | (const uint8_t[]){ FF_MEDIASUBTYPE_BASE_GUID }, 12)) { |
82 | 15 | par->codec_tag = AV_RL32(subformat); | |
83 | 15 | par->codec_id = ff_wav_codec_get_id(par->codec_tag, | |
84 | par->bits_per_coded_sample); | ||
85 | } else { | ||
86 | ✗ | par->codec_id = ff_codec_guid_get_id(ff_codec_wav_guids, subformat); | |
87 | ✗ | if (!par->codec_id) | |
88 | ✗ | av_log(logctx, AV_LOG_WARNING, | |
89 | "unknown subformat:"FF_PRI_GUID"\n", | ||
90 | ✗ | FF_ARG_GUID(subformat)); | |
91 | } | ||
92 | 15 | } | |
93 | |||
94 | /* "big_endian" values are needed for RIFX file format */ | ||
95 | 631 | int ff_get_wav_header(void *logctx, AVIOContext *pb, | |
96 | AVCodecParameters *par, int size, int big_endian) | ||
97 | { | ||
98 | 631 | int id, channels = 0, ret; | |
99 | 631 | uint64_t bitrate = 0; | |
100 | |||
101 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 631 times.
|
631 | if (size < 14) { |
102 | ✗ | avpriv_request_sample(logctx, "wav header size < 14"); | |
103 | ✗ | return AVERROR_INVALIDDATA; | |
104 | } | ||
105 | |||
106 | 631 | av_channel_layout_uninit(&par->ch_layout); | |
107 | |||
108 | 631 | par->codec_type = AVMEDIA_TYPE_AUDIO; | |
109 |
1/2✓ Branch 0 taken 631 times.
✗ Branch 1 not taken.
|
631 | if (!big_endian) { |
110 | 631 | id = avio_rl16(pb); | |
111 |
1/2✓ Branch 0 taken 631 times.
✗ Branch 1 not taken.
|
631 | if (id != 0x0165) { |
112 | 631 | channels = avio_rl16(pb); | |
113 | 631 | par->sample_rate = avio_rl32(pb); | |
114 | 631 | bitrate = avio_rl32(pb) * 8LL; | |
115 | 631 | par->block_align = avio_rl16(pb); | |
116 | } | ||
117 | } else { | ||
118 | ✗ | id = avio_rb16(pb); | |
119 | ✗ | channels = avio_rb16(pb); | |
120 | ✗ | par->sample_rate = avio_rb32(pb); | |
121 | ✗ | bitrate = avio_rb32(pb) * 8LL; | |
122 | ✗ | par->block_align = avio_rb16(pb); | |
123 | } | ||
124 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 631 times.
|
631 | if (size == 14) { /* We're dealing with plain vanilla WAVEFORMAT */ |
125 | ✗ | par->bits_per_coded_sample = 8; | |
126 | } else { | ||
127 |
1/2✓ Branch 0 taken 631 times.
✗ Branch 1 not taken.
|
631 | if (!big_endian) { |
128 | 631 | par->bits_per_coded_sample = avio_rl16(pb); | |
129 | } else { | ||
130 | ✗ | par->bits_per_coded_sample = avio_rb16(pb); | |
131 | } | ||
132 | } | ||
133 |
2/2✓ Branch 0 taken 15 times.
✓ Branch 1 taken 616 times.
|
631 | if (id == 0xFFFE) { |
134 | 15 | par->codec_tag = 0; | |
135 | } else { | ||
136 | 616 | par->codec_tag = id; | |
137 | 616 | par->codec_id = ff_wav_codec_get_id(id, | |
138 | par->bits_per_coded_sample); | ||
139 | } | ||
140 |
3/4✓ Branch 0 taken 596 times.
✓ Branch 1 taken 35 times.
✓ Branch 2 taken 596 times.
✗ Branch 3 not taken.
|
1227 | if (size >= 18 && id != 0x0165) { /* We're obviously dealing with WAVEFORMATEX */ |
141 | 596 | int cbSize = avio_rl16(pb); /* cbSize */ | |
142 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 596 times.
|
596 | if (big_endian) { |
143 | ✗ | avpriv_report_missing_feature(logctx, "WAVEFORMATEX support for RIFX files"); | |
144 | ✗ | return AVERROR_PATCHWELCOME; | |
145 | } | ||
146 | 596 | size -= 18; | |
147 | 596 | cbSize = FFMIN(size, cbSize); | |
148 |
4/4✓ Branch 0 taken 42 times.
✓ Branch 1 taken 554 times.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 27 times.
|
596 | if (cbSize >= 22 && id == 0xfffe) { /* WAVEFORMATEXTENSIBLE */ |
149 | 15 | parse_waveformatex(logctx, pb, par); | |
150 | 15 | cbSize -= 22; | |
151 | 15 | size -= 22; | |
152 | } | ||
153 |
2/2✓ Branch 0 taken 67 times.
✓ Branch 1 taken 529 times.
|
596 | if (cbSize > 0) { |
154 | 67 | ret = ff_get_extradata(logctx, par, pb, cbSize); | |
155 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 67 times.
|
67 | if (ret < 0) |
156 | ✗ | return ret; | |
157 | 67 | size -= cbSize; | |
158 | } | ||
159 | |||
160 | /* It is possible for the chunk to contain garbage at the end */ | ||
161 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 591 times.
|
596 | if (size > 0) |
162 | 5 | avio_skip(pb, size); | |
163 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 35 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
35 | } else if (id == 0x0165 && size >= 32) { |
164 | int nb_streams, i; | ||
165 | |||
166 | ✗ | size -= 4; | |
167 | ✗ | ret = ff_get_extradata(logctx, par, pb, size); | |
168 | ✗ | if (ret < 0) | |
169 | ✗ | return ret; | |
170 | ✗ | nb_streams = AV_RL16(par->extradata + 4); | |
171 | ✗ | par->sample_rate = AV_RL32(par->extradata + 12); | |
172 | ✗ | channels = 0; | |
173 | ✗ | bitrate = 0; | |
174 | ✗ | if (size < 8 + nb_streams * 20) | |
175 | ✗ | return AVERROR_INVALIDDATA; | |
176 | ✗ | for (i = 0; i < nb_streams; i++) | |
177 | ✗ | channels += par->extradata[8 + i * 20 + 17]; | |
178 | } | ||
179 | |||
180 | 631 | par->bit_rate = bitrate; | |
181 | |||
182 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 631 times.
|
631 | if (par->sample_rate <= 0) { |
183 | ✗ | av_log(logctx, AV_LOG_ERROR, | |
184 | "Invalid sample rate: %d\n", par->sample_rate); | ||
185 | ✗ | return AVERROR_INVALIDDATA; | |
186 | } | ||
187 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 631 times.
|
631 | if (par->codec_id == AV_CODEC_ID_AAC_LATM) { |
188 | /* Channels and sample_rate values are those prior to applying SBR | ||
189 | * and/or PS. */ | ||
190 | ✗ | channels = 0; | |
191 | ✗ | par->sample_rate = 0; | |
192 | } | ||
193 | /* override bits_per_coded_sample for G.726 */ | ||
194 |
3/4✓ Branch 0 taken 4 times.
✓ Branch 1 taken 627 times.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
|
631 | if (par->codec_id == AV_CODEC_ID_ADPCM_G726 && par->sample_rate) |
195 | 4 | par->bits_per_coded_sample = par->bit_rate / par->sample_rate; | |
196 | |||
197 | /* ignore WAVEFORMATEXTENSIBLE layout if different from channel count */ | ||
198 |
2/2✓ Branch 0 taken 624 times.
✓ Branch 1 taken 7 times.
|
631 | if (channels != par->ch_layout.nb_channels) { |
199 | 624 | av_channel_layout_uninit(&par->ch_layout); | |
200 | 624 | par->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC; | |
201 | 624 | par->ch_layout.nb_channels = channels; | |
202 | } | ||
203 | |||
204 | 631 | return 0; | |
205 | } | ||
206 | |||
207 | 633 | enum AVCodecID ff_wav_codec_get_id(unsigned int tag, int bps) | |
208 | { | ||
209 | enum AVCodecID id; | ||
210 | 633 | id = ff_codec_get_id(ff_codec_wav_tags, tag); | |
211 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 632 times.
|
633 | if (id <= 0) |
212 | 1 | return id; | |
213 | |||
214 |
2/2✓ Branch 0 taken 542 times.
✓ Branch 1 taken 90 times.
|
632 | if (id == AV_CODEC_ID_PCM_S16LE) |
215 | 542 | id = ff_get_pcm_codec_id(bps, 0, 0, ~1); | |
216 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 86 times.
|
90 | else if (id == AV_CODEC_ID_PCM_F32LE) |
217 | 4 | id = ff_get_pcm_codec_id(bps, 1, 0, 0); | |
218 | |||
219 |
3/4✓ Branch 0 taken 6 times.
✓ Branch 1 taken 626 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
|
632 | if (id == AV_CODEC_ID_ADPCM_IMA_WAV && bps == 8) |
220 | ✗ | id = AV_CODEC_ID_ADPCM_ZORK; | |
221 | 632 | return id; | |
222 | } | ||
223 | |||
224 | 467 | int ff_get_bmp_header(AVIOContext *pb, AVStream *st, uint32_t *size) | |
225 | { | ||
226 | int tag1; | ||
227 | 467 | uint32_t size_ = avio_rl32(pb); | |
228 |
2/2✓ Branch 0 taken 463 times.
✓ Branch 1 taken 4 times.
|
467 | if (size) |
229 | 463 | *size = size_; | |
230 | 467 | st->codecpar->width = avio_rl32(pb); | |
231 | 467 | st->codecpar->height = (int32_t)avio_rl32(pb); | |
232 | 467 | avio_rl16(pb); /* planes */ | |
233 | 467 | st->codecpar->bits_per_coded_sample = avio_rl16(pb); /* depth */ | |
234 | 467 | tag1 = avio_rl32(pb); | |
235 | 467 | avio_rl32(pb); /* ImageSize */ | |
236 | 467 | avio_rl32(pb); /* XPelsPerMeter */ | |
237 | 467 | avio_rl32(pb); /* YPelsPerMeter */ | |
238 | 467 | avio_rl32(pb); /* ClrUsed */ | |
239 | 467 | avio_rl32(pb); /* ClrImportant */ | |
240 | 467 | return tag1; | |
241 | } | ||
242 | |||
243 | 80 | int ff_read_riff_info(AVFormatContext *s, int64_t size) | |
244 | { | ||
245 | int64_t start, end, cur; | ||
246 | 80 | AVIOContext *pb = s->pb; | |
247 | |||
248 | 80 | start = avio_tell(pb); | |
249 | 80 | end = start + size; | |
250 | |||
251 |
1/2✓ Branch 1 taken 174 times.
✗ Branch 2 not taken.
|
174 | while ((cur = avio_tell(pb)) >= 0 && |
252 |
2/2✓ Branch 0 taken 94 times.
✓ Branch 1 taken 80 times.
|
174 | cur <= end - 8 /* = tag + size */) { |
253 | uint32_t chunk_code; | ||
254 | int64_t chunk_size; | ||
255 | 94 | char key[5] = { 0 }; | |
256 | char *value; | ||
257 | |||
258 | 94 | chunk_code = avio_rl32(pb); | |
259 | 94 | chunk_size = avio_rl32(pb); | |
260 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 94 times.
|
94 | if (avio_feof(pb)) { |
261 | ✗ | if (chunk_code || chunk_size) { | |
262 | ✗ | av_log(s, AV_LOG_WARNING, "INFO subchunk truncated\n"); | |
263 | ✗ | return AVERROR_INVALIDDATA; | |
264 | } | ||
265 | ✗ | return AVERROR_EOF; | |
266 | } | ||
267 |
1/2✓ Branch 0 taken 94 times.
✗ Branch 1 not taken.
|
94 | if (chunk_size > end || |
268 |
2/4✓ Branch 0 taken 94 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 94 times.
|
94 | end - chunk_size < cur || |
269 | chunk_size == UINT_MAX) { | ||
270 | ✗ | avio_seek(pb, -9, SEEK_CUR); | |
271 | ✗ | chunk_code = avio_rl32(pb); | |
272 | ✗ | chunk_size = avio_rl32(pb); | |
273 | ✗ | if (chunk_size > end || end - chunk_size < cur || chunk_size == UINT_MAX) { | |
274 | ✗ | av_log(s, AV_LOG_WARNING, "too big INFO subchunk\n"); | |
275 | ✗ | return AVERROR_INVALIDDATA; | |
276 | } | ||
277 | } | ||
278 | |||
279 | 94 | chunk_size += (chunk_size & 1); | |
280 | |||
281 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 92 times.
|
94 | if (!chunk_code) { |
282 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | if (chunk_size) |
283 | 2 | avio_skip(pb, chunk_size); | |
284 | ✗ | else if (pb->eof_reached) { | |
285 | ✗ | av_log(s, AV_LOG_WARNING, "truncated file\n"); | |
286 | ✗ | return AVERROR_EOF; | |
287 | } | ||
288 | 2 | continue; | |
289 | } | ||
290 | |||
291 | 92 | value = av_mallocz(chunk_size + 1); | |
292 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 92 times.
|
92 | if (!value) { |
293 | ✗ | av_log(s, AV_LOG_ERROR, | |
294 | "out of memory, unable to read INFO tag\n"); | ||
295 | ✗ | return AVERROR(ENOMEM); | |
296 | } | ||
297 | |||
298 | 92 | AV_WL32(key, chunk_code); | |
299 | // Work around VC++ 2015 Update 1 code-gen bug: | ||
300 | // https://connect.microsoft.com/VisualStudio/feedback/details/2291638 | ||
301 | 92 | key[4] = 0; | |
302 | |||
303 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 92 times.
|
92 | if (avio_read(pb, value, chunk_size) != chunk_size) { |
304 | ✗ | av_log(s, AV_LOG_WARNING, | |
305 | "premature end of file while reading INFO tag\n"); | ||
306 | } | ||
307 | |||
308 | 92 | av_dict_set(&s->metadata, key, value, AV_DICT_DONT_STRDUP_VAL); | |
309 | } | ||
310 | |||
311 | 80 | return 0; | |
312 | } | ||
313 |