FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/flac.c
Date: 2026-11-01 18:52:00
Exec Total Coverage
Lines: 86 101 85.1%
Functions: 5 5 100.0%
Branches: 46 56 82.1%

Line Branch Exec Source
1 /*
2 * FLAC common code
3 * Copyright (c) 2009 Justin Ruggles
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/channel_layout.h"
23 #include "libavutil/crc.h"
24 #include "libavutil/log.h"
25 #include "bytestream.h"
26 #include "get_bits.h"
27 #include "flac.h"
28 #include "flacdata.h"
29 #include "flac_parse.h"
30
31 static const int8_t sample_size_table[] = { 0, 8, 12, 0, 16, 20, 24, 32 };
32
33 static const AVChannelLayout flac_channel_layouts[8] = {
34 AV_CHANNEL_LAYOUT_MONO,
35 AV_CHANNEL_LAYOUT_STEREO,
36 AV_CHANNEL_LAYOUT_SURROUND,
37 AV_CHANNEL_LAYOUT_QUAD,
38 AV_CHANNEL_LAYOUT_5POINT0,
39 AV_CHANNEL_LAYOUT_5POINT1,
40 AV_CHANNEL_LAYOUT_6POINT1,
41 AV_CHANNEL_LAYOUT_7POINT1
42 };
43
44 10156 static int64_t get_utf8(GetBitContext *gb)
45 {
46 int64_t val;
47
7/8
✓ Branch 1 taken 10096 times.
✓ Branch 2 taken 60 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10096 times.
✓ Branch 6 taken 35 times.
✓ Branch 7 taken 1819 times.
✓ Branch 8 taken 1854 times.
✓ Branch 9 taken 10061 times.
11975 GET_UTF8(val, get_bits(gb, 8), return -1;)
48 10061 return val;
49 }
50
51 10843 int ff_flac_decode_frame_header(void *logctx, GetBitContext *gb,
52 FLACFrameInfo *fi, int log_level_offset)
53 {
54 int bs_code, sr_code, bps_code;
55
56 /* frame sync code */
57
2/2
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 10830 times.
10843 if ((get_bits(gb, 15) & 0x7FFF) != 0x7FFC) {
58 13 av_log(logctx, AV_LOG_ERROR + log_level_offset, "invalid sync code\n");
59 13 return AVERROR_INVALIDDATA;
60 }
61
62 /* variable block size stream code */
63 10830 fi->is_var_size = get_bits1(gb);
64
65 /* block size and sample rate codes */
66 10830 bs_code = get_bits(gb, 4);
67 10830 sr_code = get_bits(gb, 4);
68
69 /* channels and decorrelation */
70 10830 fi->ch_mode = get_bits(gb, 4);
71
2/2
✓ Branch 0 taken 4117 times.
✓ Branch 1 taken 6713 times.
10830 if (fi->ch_mode < FLAC_MAX_CHANNELS) {
72 4117 fi->channels = fi->ch_mode + 1;
73 4117 fi->ch_mode = FLAC_CHMODE_INDEPENDENT;
74
2/2
✓ Branch 0 taken 6417 times.
✓ Branch 1 taken 296 times.
6713 } else if (fi->ch_mode < FLAC_MAX_CHANNELS + FLAC_CHMODE_MID_SIDE) {
75 6417 fi->channels = 2;
76 6417 fi->ch_mode -= FLAC_MAX_CHANNELS - 1;
77 } else {
78 296 av_log(logctx, AV_LOG_ERROR + log_level_offset,
79 "invalid channel mode: %d\n", fi->ch_mode);
80 296 return AVERROR_INVALIDDATA;
81 }
82
83 /* bits per sample */
84 10534 bps_code = get_bits(gb, 3);
85
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 10478 times.
10534 if (bps_code == 3) {
86 56 av_log(logctx, AV_LOG_ERROR + log_level_offset,
87 "invalid sample size code (%d)\n",
88 bps_code);
89 56 return AVERROR_INVALIDDATA;
90 }
91 10478 fi->bps = sample_size_table[bps_code];
92
93 /* reserved bit */
94
2/2
✓ Branch 1 taken 322 times.
✓ Branch 2 taken 10156 times.
10478 if (get_bits1(gb)) {
95 322 av_log(logctx, AV_LOG_ERROR + log_level_offset,
96 "broken stream, invalid padding\n");
97 322 return AVERROR_INVALIDDATA;
98 }
99
100 /* sample or frame count */
101 10156 fi->frame_or_sample_num = get_utf8(gb);
102
2/2
✓ Branch 0 taken 95 times.
✓ Branch 1 taken 10061 times.
10156 if (fi->frame_or_sample_num < 0) {
103 95 av_log(logctx, AV_LOG_ERROR + log_level_offset,
104 "sample/frame number invalid; utf8 fscked\n");
105 95 return AVERROR_INVALIDDATA;
106 }
107
108 /* blocksize */
109
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 10039 times.
10061 if (bs_code == 0) {
110 22 av_log(logctx, AV_LOG_ERROR + log_level_offset,
111 "reserved blocksize code: 0\n");
112 22 return AVERROR_INVALIDDATA;
113
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 10033 times.
10039 } else if (bs_code == 6) {
114 6 fi->blocksize = get_bits(gb, 8) + 1;
115
2/2
✓ Branch 0 taken 135 times.
✓ Branch 1 taken 9898 times.
10033 } else if (bs_code == 7) {
116 135 fi->blocksize = get_bits(gb, 16) + 1;
117 } else {
118 9898 fi->blocksize = ff_flac_blocksize_table[bs_code];
119 }
120
121 /* sample rate */
122
2/2
✓ Branch 0 taken 9951 times.
✓ Branch 1 taken 88 times.
10039 if (sr_code < 12) {
123 9951 fi->samplerate = ff_flac_sample_rate_table[sr_code];
124
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 71 times.
88 } else if (sr_code == 12) {
125 17 fi->samplerate = get_bits(gb, 8) * 1000;
126
2/2
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 22 times.
71 } else if (sr_code == 13) {
127 49 fi->samplerate = get_bits(gb, 16);
128
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 12 times.
22 } else if (sr_code == 14) {
129 10 fi->samplerate = get_bits(gb, 16) * 10;
130 } else {
131 12 av_log(logctx, AV_LOG_ERROR + log_level_offset,
132 "illegal sample rate code %d\n",
133 sr_code);
134 12 return AVERROR_INVALIDDATA;
135 }
136
137 /* header CRC-8 check */
138 10027 skip_bits(gb, 8);
139
2/2
✓ Branch 0 taken 190 times.
✓ Branch 1 taken 9837 times.
10027 if (av_crc(av_crc_get_table(AV_CRC_8_ATM), 0, gb->buffer,
140 10027 get_bits_count(gb)/8)) {
141 190 av_log(logctx, AV_LOG_ERROR + log_level_offset,
142 "header crc mismatch\n");
143 190 return AVERROR_INVALIDDATA;
144 }
145
146 9837 return 0;
147 }
148
149 303 int ff_flac_is_extradata_valid(AVCodecContext *avctx,
150 uint8_t **streaminfo_start)
151 {
152
2/4
✓ Branch 0 taken 303 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 303 times.
303 if (!avctx->extradata || avctx->extradata_size < FLAC_STREAMINFO_SIZE) {
153 ✗ av_log(avctx, AV_LOG_ERROR, "extradata NULL or too small.\n");
154 ✗ return 0;
155 }
156
1/2
✓ Branch 0 taken 303 times.
✗ Branch 1 not taken.
303 if (AV_RL32(avctx->extradata) != MKTAG('f','L','a','C')) {
157 /* extradata contains STREAMINFO only */
158
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 303 times.
303 if (avctx->extradata_size != FLAC_STREAMINFO_SIZE) {
159 ✗ av_log(avctx, AV_LOG_WARNING, "extradata contains %d bytes too many.\n",
160 ✗ FLAC_STREAMINFO_SIZE-avctx->extradata_size);
161 }
162 303 *streaminfo_start = avctx->extradata;
163 } else {
164 ✗ if (avctx->extradata_size < 8+FLAC_STREAMINFO_SIZE) {
165 ✗ av_log(avctx, AV_LOG_ERROR, "extradata too small.\n");
166 ✗ return 0;
167 }
168 ✗ *streaminfo_start = &avctx->extradata[8];
169 }
170 303 return 1;
171 }
172
173 8879 void ff_flac_set_channel_layout(AVCodecContext *avctx, int channels)
174 {
175
2/2
✓ Branch 0 taken 8840 times.
✓ Branch 1 taken 39 times.
8879 if (channels == avctx->ch_layout.nb_channels &&
176
2/2
✓ Branch 0 taken 8835 times.
✓ Branch 1 taken 5 times.
8840 avctx->ch_layout.order != AV_CHANNEL_ORDER_UNSPEC)
177 8835 return;
178
179 44 av_channel_layout_uninit(&avctx->ch_layout);
180
1/2
✓ Branch 0 taken 44 times.
✗ Branch 1 not taken.
44 if (channels <= FF_ARRAY_ELEMS(flac_channel_layouts))
181 44 avctx->ch_layout = flac_channel_layouts[channels - 1];
182 else
183 ✗ avctx->ch_layout = (AVChannelLayout){ .order = AV_CHANNEL_ORDER_UNSPEC,
184 .nb_channels = channels };
185 }
186
187 303 int ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s,
188 const uint8_t *buffer)
189 {
190 GetBitContext gb;
191 303 init_get_bits(&gb, buffer, FLAC_STREAMINFO_SIZE*8);
192
193 303 skip_bits(&gb, 16); /* skip min blocksize */
194 303 s->max_blocksize = get_bits(&gb, 16);
195
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 303 times.
303 if (s->max_blocksize < FLAC_MIN_BLOCKSIZE) {
196 ✗ av_log(avctx, AV_LOG_WARNING, "invalid max blocksize: %d\n",
197 s->max_blocksize);
198 ✗ s->max_blocksize = 16;
199 ✗ return AVERROR_INVALIDDATA;
200 }
201
202 303 skip_bits(&gb, 24); /* skip min frame size */
203 303 s->max_framesize = get_bits(&gb, 24);
204
205 303 s->samplerate = get_bits(&gb, 20);
206 303 s->channels = get_bits(&gb, 3) + 1;
207 303 s->bps = get_bits(&gb, 5) + 1;
208
209
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 303 times.
303 if (s->bps < 4) {
210 ✗ av_log(avctx, AV_LOG_ERROR, "invalid bps: %d\n", s->bps);
211 ✗ s->bps = 16;
212 ✗ return AVERROR_INVALIDDATA;
213 }
214
215 303 avctx->sample_rate = s->samplerate;
216 303 avctx->bits_per_raw_sample = s->bps;
217 303 ff_flac_set_channel_layout(avctx, s->channels);
218
219 303 s->samples = get_bits64(&gb, 36);
220
221 303 skip_bits_long(&gb, 64); /* md5 sum */
222 303 skip_bits_long(&gb, 64); /* md5 sum */
223
224 303 return 0;
225 }
226