FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/riffdec.c
Date: 2026-07-21 08:37:06
Exec Total Coverage
Lines: 145 208 69.7%
Functions: 8 8 100.0%
Branches: 77 133 57.9%

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 2316 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 2316 ret = ffio_read_size(s, *g, sizeof(*g));
38
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 2305 times.
2316 if (ret < 0) {
39 11 memset(*g, 0, sizeof(*g));
40 11 return ret;
41 }
42 2305 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 18 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 18 bps = avio_rl16(pb);
69
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 if (bps)
70 18 par->bits_per_coded_sample = bps;
71
72 18 mask = avio_rl32(pb); /* dwChannelMask */
73 18 av_channel_layout_from_mask(&par->ch_layout, mask);
74
75 18 ff_get_guid(pb, &subformat);
76 18 if (!memcmp(subformat + 4,
77
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 (const uint8_t[]){ FF_AMBISONIC_BASE_GUID }, 12) ||
78 18 !memcmp(subformat + 4,
79
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 (const uint8_t[]){ FF_BROKEN_BASE_GUID }, 12) ||
80 18 !memcmp(subformat + 4,
81
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 (const uint8_t[]){ FF_MEDIASUBTYPE_BASE_GUID }, 12)) {
82 18 par->codec_tag = AV_RL32(subformat);
83 18 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 18 }
93
94 /*
95 * Compute the expected bit_rate for codecs with a deterministic block
96 * structure. Returns 0 when the codec is not handled or the parameters
97 * are not sufficient to derive a reliable value.
98 */
99 698 static int64_t compute_bitrate(const AVCodecParameters *par)
100 {
101
3/4
✓ Branch 0 taken 698 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 696 times.
✓ Branch 3 taken 2 times.
698 if (par->sample_rate <= 0 || par->block_align <= 0 ||
102
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 696 times.
696 par->ch_layout.nb_channels <= 0)
103 2 return 0;
104
105
3/3
✓ Branch 0 taken 609 times.
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 74 times.
696 switch (par->codec_id) {
106 609 case AV_CODEC_ID_PCM_S8:
107 case AV_CODEC_ID_PCM_U8:
108 case AV_CODEC_ID_PCM_S16LE:
109 case AV_CODEC_ID_PCM_S16BE:
110 case AV_CODEC_ID_PCM_U16LE:
111 case AV_CODEC_ID_PCM_U16BE:
112 case AV_CODEC_ID_PCM_S24LE:
113 case AV_CODEC_ID_PCM_S24BE:
114 case AV_CODEC_ID_PCM_S32LE:
115 case AV_CODEC_ID_PCM_S32BE:
116 case AV_CODEC_ID_PCM_S64LE:
117 case AV_CODEC_ID_PCM_F32LE:
118 case AV_CODEC_ID_PCM_F64LE:
119 case AV_CODEC_ID_PCM_ALAW:
120 case AV_CODEC_ID_PCM_MULAW: {
121 609 int block_align = ((par->bits_per_coded_sample + 7) / 8) *
122 609 par->ch_layout.nb_channels;
123
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 603 times.
609 if (par->block_align != block_align)
124 6 return 0;
125 603 return (int64_t)par->sample_rate * block_align * 8;
126 }
127 13 case AV_CODEC_ID_ADPCM_MS:
128 case AV_CODEC_ID_ADPCM_IMA_WAV: {
129 13 int frame_size = av_get_audio_frame_duration2((AVCodecParameters *)par,
130 13 par->block_align);
131
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if (frame_size <= 0)
132 return 0;
133 13 return 8LL * par->sample_rate * par->block_align / frame_size;
134 }
135 74 default:
136 74 return 0;
137 }
138 }
139
140 /* "big_endian" values are needed for RIFX file format */
141 698 int ff_get_wav_header(AVFormatContext *s, AVIOContext *pb,
142 AVCodecParameters *par, int size, int big_endian)
143 {
144 698 int id, channels = 0, ret;
145 698 uint64_t bitrate = 0;
146
147
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 698 times.
698 if (size < 14) {
148 avpriv_request_sample(s, "wav header size < 14");
149 return AVERROR_INVALIDDATA;
150 }
151
152 698 av_channel_layout_uninit(&par->ch_layout);
153
154 698 par->codec_type = AVMEDIA_TYPE_AUDIO;
155
1/2
✓ Branch 0 taken 698 times.
✗ Branch 1 not taken.
698 if (!big_endian) {
156 698 id = avio_rl16(pb);
157
1/2
✓ Branch 0 taken 698 times.
✗ Branch 1 not taken.
698 if (id != 0x0165) {
158 698 channels = avio_rl16(pb);
159 698 par->sample_rate = avio_rl32(pb);
160 698 bitrate = avio_rl32(pb) * 8LL;
161 698 par->block_align = avio_rl16(pb);
162 }
163 } else {
164 id = avio_rb16(pb);
165 channels = avio_rb16(pb);
166 par->sample_rate = avio_rb32(pb);
167 bitrate = avio_rb32(pb) * 8LL;
168 par->block_align = avio_rb16(pb);
169 }
170
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 698 times.
698 if (size == 14) { /* We're dealing with plain vanilla WAVEFORMAT */
171 par->bits_per_coded_sample = 8;
172 } else {
173
1/2
✓ Branch 0 taken 698 times.
✗ Branch 1 not taken.
698 if (!big_endian) {
174 698 par->bits_per_coded_sample = avio_rl16(pb);
175 } else {
176 par->bits_per_coded_sample = avio_rb16(pb);
177 }
178 }
179
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 680 times.
698 if (id == 0xFFFE) {
180 18 par->codec_tag = 0;
181 } else {
182 680 par->codec_tag = id;
183 680 par->codec_id = ff_wav_codec_get_id(id,
184 par->bits_per_coded_sample);
185 }
186
3/4
✓ Branch 0 taken 652 times.
✓ Branch 1 taken 46 times.
✓ Branch 2 taken 652 times.
✗ Branch 3 not taken.
1350 if (size >= 18 && id != 0x0165) { /* We're obviously dealing with WAVEFORMATEX */
187 652 int cbSize = avio_rl16(pb); /* cbSize */
188
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 652 times.
652 if (big_endian) {
189 avpriv_report_missing_feature(s, "WAVEFORMATEX support for RIFX files");
190 return AVERROR_PATCHWELCOME;
191 }
192 652 size -= 18;
193 652 cbSize = FFMIN(size, cbSize);
194
4/4
✓ Branch 0 taken 47 times.
✓ Branch 1 taken 605 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 29 times.
652 if (cbSize >= 22 && id == 0xfffe) { /* WAVEFORMATEXTENSIBLE */
195 18 parse_waveformatex(s, pb, par);
196 18 cbSize -= 22;
197 18 size -= 22;
198
3/4
✓ Branch 0 taken 47 times.
✓ Branch 1 taken 587 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 47 times.
634 } else if (cbSize >= 12 && id == 0x1610) { /* HEAACWAVEFORMAT */
199 int wPayloadType = avio_rl16(pb);
200 if (wPayloadType == 3)
201 par->codec_id = AV_CODEC_ID_AAC_LATM;
202 avio_skip(pb, 2); // wAudioProfileLevelIndication
203 int wStructType = avio_rl16(pb);
204 if (wStructType) {
205 avpriv_report_missing_feature(s, "HEAACWAVEINFO wStructType \"%d\"", wStructType);
206 return AVERROR_PATCHWELCOME;
207 }
208 avio_skip(pb, 2); // wReserved1
209 avio_skip(pb, 4); // dwReserved2
210 cbSize -= 12;
211 size -= 12;
212 }
213
2/2
✓ Branch 0 taken 77 times.
✓ Branch 1 taken 575 times.
652 if (cbSize > 0) {
214 77 ret = ff_get_extradata(s, par, pb, cbSize);
215
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 77 times.
77 if (ret < 0)
216 return ret;
217 77 size -= cbSize;
218 }
219
220 /* It is possible for the chunk to contain garbage at the end */
221
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 647 times.
652 if (size > 0)
222 5 avio_skip(pb, size);
223
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
46 } else if (id == 0x0165 && size >= 32) {
224 int nb_streams, i;
225
226 size -= 4;
227 ret = ff_get_extradata(s, par, pb, size);
228 if (ret < 0)
229 return ret;
230 nb_streams = AV_RL16(par->extradata + 4);
231 par->sample_rate = AV_RL32(par->extradata + 12);
232 channels = 0;
233 bitrate = 0;
234 if (size < 8 + nb_streams * 20)
235 return AVERROR_INVALIDDATA;
236 for (i = 0; i < nb_streams; i++)
237 channels += par->extradata[8 + i * 20 + 17];
238 }
239
240 698 par->bit_rate = bitrate;
241
242
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 698 times.
698 if (par->sample_rate <= 0) {
243 av_log(s, AV_LOG_ERROR,
244 "Invalid sample rate: %d\n", par->sample_rate);
245 return AVERROR_INVALIDDATA;
246 }
247
248
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 698 times.
698 if (par->codec_id == AV_CODEC_ID_AAC_LATM) {
249 /* Channels and sample_rate values are those prior to applying SBR
250 * and/or PS. */
251 channels = 0;
252 par->sample_rate = 0;
253 }
254 /* override bits_per_coded_sample for G.726 */
255
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 694 times.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
698 if (par->codec_id == AV_CODEC_ID_ADPCM_G726 && par->sample_rate)
256 4 par->bits_per_coded_sample = par->bit_rate / par->sample_rate;
257
258 /* ignore WAVEFORMATEXTENSIBLE layout if different from channel count */
259
2/2
✓ Branch 0 taken 689 times.
✓ Branch 1 taken 9 times.
698 if (channels != par->ch_layout.nb_channels) {
260 689 av_channel_layout_uninit(&par->ch_layout);
261 689 par->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
262 689 par->ch_layout.nb_channels = channels;
263 }
264
265 698 int64_t expected_bitrate = compute_bitrate(par);
266
4/4
✓ Branch 0 taken 616 times.
✓ Branch 1 taken 82 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 609 times.
698 if (expected_bitrate && par->bit_rate / 8 != expected_bitrate / 8) {
267 7 av_log(s, AV_LOG_WARNING,
268 "nAvgBytesPerSec %"PRId64" inconsistent with other fields"
269 " (expected %"PRId64"), overriding.\n",
270 7 par->bit_rate / 8, expected_bitrate / 8);
271 7 par->bit_rate = expected_bitrate;
272 }
273
274 698 return 0;
275 }
276
277 700 enum AVCodecID ff_wav_codec_get_id(unsigned int tag, int bps)
278 {
279 enum AVCodecID id;
280 700 id = ff_codec_get_id(ff_codec_wav_tags, tag);
281
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 699 times.
700 if (id <= 0)
282 1 return id;
283
284
2/2
✓ Branch 0 taken 596 times.
✓ Branch 1 taken 103 times.
699 if (id == AV_CODEC_ID_PCM_S16LE)
285 596 id = ff_get_pcm_codec_id(bps, 0, 0, ~1);
286
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 99 times.
103 else if (id == AV_CODEC_ID_PCM_F32LE)
287 4 id = ff_get_pcm_codec_id(bps, 1, 0, 0);
288
289
3/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 693 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
699 if (id == AV_CODEC_ID_ADPCM_IMA_WAV && bps == 8)
290 id = AV_CODEC_ID_ADPCM_ZORK;
291 699 return id;
292 }
293
294 475 int ff_get_bmp_header(AVIOContext *pb, AVStream *st, uint32_t *size)
295 {
296 int tag1;
297 475 uint32_t size_ = avio_rl32(pb);
298
2/2
✓ Branch 0 taken 471 times.
✓ Branch 1 taken 4 times.
475 if (size)
299 471 *size = size_;
300 475 st->codecpar->width = avio_rl32(pb);
301 475 st->codecpar->height = (int32_t)avio_rl32(pb);
302 475 avio_rl16(pb); /* planes */
303 475 st->codecpar->bits_per_coded_sample = avio_rl16(pb); /* depth */
304 475 tag1 = avio_rl32(pb);
305 475 avio_rl32(pb); /* ImageSize */
306 475 avio_rl32(pb); /* XPelsPerMeter */
307 475 avio_rl32(pb); /* YPelsPerMeter */
308 475 avio_rl32(pb); /* ClrUsed */
309 475 avio_rl32(pb); /* ClrImportant */
310 475 return tag1;
311 }
312
313 94 int ff_read_riff_info(AVFormatContext *s, int64_t size)
314 {
315 int64_t start, end, cur;
316 94 AVIOContext *pb = s->pb;
317
318 94 start = avio_tell(pb);
319 94 end = start + size;
320
321
1/2
✓ Branch 1 taken 219 times.
✗ Branch 2 not taken.
219 while ((cur = avio_tell(pb)) >= 0 &&
322
2/2
✓ Branch 0 taken 125 times.
✓ Branch 1 taken 94 times.
219 cur <= end - 8 /* = tag + size */) {
323 uint32_t chunk_code;
324 int64_t chunk_size;
325 125 char key[5] = { 0 };
326 char *value;
327
328 125 chunk_code = avio_rl32(pb);
329 125 chunk_size = avio_rl32(pb);
330
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 125 times.
125 if (avio_feof(pb)) {
331 if (chunk_code || chunk_size) {
332 av_log(s, AV_LOG_WARNING, "INFO subchunk truncated\n");
333 return AVERROR_INVALIDDATA;
334 }
335 return AVERROR_EOF;
336 }
337
1/2
✓ Branch 0 taken 125 times.
✗ Branch 1 not taken.
125 if (chunk_size > end ||
338
2/4
✓ Branch 0 taken 125 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 125 times.
125 end - chunk_size < cur ||
339 chunk_size == UINT_MAX) {
340 avio_seek(pb, -9, SEEK_CUR);
341 chunk_code = avio_rl32(pb);
342 chunk_size = avio_rl32(pb);
343 if (chunk_size > end || end - chunk_size < cur || chunk_size == UINT_MAX) {
344 av_log(s, AV_LOG_WARNING, "too big INFO subchunk\n");
345 return AVERROR_INVALIDDATA;
346 }
347 }
348
349 125 chunk_size += (chunk_size & 1);
350
351
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 123 times.
125 if (!chunk_code) {
352
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (chunk_size)
353 2 avio_skip(pb, chunk_size);
354 else if (pb->eof_reached) {
355 av_log(s, AV_LOG_WARNING, "truncated file\n");
356 return AVERROR_EOF;
357 }
358 2 continue;
359 }
360
361 123 value = av_mallocz(chunk_size + 1);
362
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 123 times.
123 if (!value) {
363 av_log(s, AV_LOG_ERROR,
364 "out of memory, unable to read INFO tag\n");
365 return AVERROR(ENOMEM);
366 }
367
368 123 AV_WL32(key, chunk_code);
369 // Work around VC++ 2015 Update 1 code-gen bug:
370 // https://connect.microsoft.com/VisualStudio/feedback/details/2291638
371 123 key[4] = 0;
372
373
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 123 times.
123 if (avio_read(pb, value, chunk_size) != chunk_size) {
374 av_log(s, AV_LOG_WARNING,
375 "premature end of file while reading INFO tag\n");
376 }
377
378 123 av_dict_set(&s->metadata, key, value, AV_DICT_DONT_STRDUP_VAL);
379 }
380
381 94 return 0;
382 }
383