FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/flac.c
Date: 2024-09-07 18:49:03
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 10705 static int64_t get_utf8(GetBitContext *gb)
45 {
46 int64_t val;
47
7/8
✓ Branch 1 taken 10639 times.
✓ Branch 2 taken 66 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10639 times.
✓ Branch 6 taken 55 times.
✓ Branch 7 taken 2270 times.
✓ Branch 8 taken 2325 times.
✓ Branch 9 taken 10584 times.
12975 GET_UTF8(val, get_bits(gb, 8), return -1;)
48 10584 return val;
49 }
50
51 11332 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 10 times.
✓ Branch 2 taken 11322 times.
11332 if ((get_bits(gb, 15) & 0x7FFF) != 0x7FFC) {
58 10 av_log(logctx, AV_LOG_ERROR + log_level_offset, "invalid sync code\n");
59 10 return AVERROR_INVALIDDATA;
60 }
61
62 /* variable block size stream code */
63 11322 fi->is_var_size = get_bits1(gb);
64
65 /* block size and sample rate codes */
66 11322 bs_code = get_bits(gb, 4);
67 11322 sr_code = get_bits(gb, 4);
68
69 /* channels and decorrelation */
70 11322 fi->ch_mode = get_bits(gb, 4);
71
2/2
✓ Branch 0 taken 3940 times.
✓ Branch 1 taken 7382 times.
11322 if (fi->ch_mode < FLAC_MAX_CHANNELS) {
72 3940 fi->channels = fi->ch_mode + 1;
73 3940 fi->ch_mode = FLAC_CHMODE_INDEPENDENT;
74
2/2
✓ Branch 0 taken 7090 times.
✓ Branch 1 taken 292 times.
7382 } else if (fi->ch_mode < FLAC_MAX_CHANNELS + FLAC_CHMODE_MID_SIDE) {
75 7090 fi->channels = 2;
76 7090 fi->ch_mode -= FLAC_MAX_CHANNELS - 1;
77 } else {
78 292 av_log(logctx, AV_LOG_ERROR + log_level_offset,
79 "invalid channel mode: %d\n", fi->ch_mode);
80 292 return AVERROR_INVALIDDATA;
81 }
82
83 /* bits per sample */
84 11030 bps_code = get_bits(gb, 3);
85
2/2
✓ Branch 0 taken 59 times.
✓ Branch 1 taken 10971 times.
11030 if (bps_code == 3) {
86 59 av_log(logctx, AV_LOG_ERROR + log_level_offset,
87 "invalid sample size code (%d)\n",
88 bps_code);
89 59 return AVERROR_INVALIDDATA;
90 }
91 10971 fi->bps = sample_size_table[bps_code];
92
93 /* reserved bit */
94
2/2
✓ Branch 1 taken 266 times.
✓ Branch 2 taken 10705 times.
10971 if (get_bits1(gb)) {
95 266 av_log(logctx, AV_LOG_ERROR + log_level_offset,
96 "broken stream, invalid padding\n");
97 266 return AVERROR_INVALIDDATA;
98 }
99
100 /* sample or frame count */
101 10705 fi->frame_or_sample_num = get_utf8(gb);
102
2/2
✓ Branch 0 taken 121 times.
✓ Branch 1 taken 10584 times.
10705 if (fi->frame_or_sample_num < 0) {
103 121 av_log(logctx, AV_LOG_ERROR + log_level_offset,
104 "sample/frame number invalid; utf8 fscked\n");
105 121 return AVERROR_INVALIDDATA;
106 }
107
108 /* blocksize */
109
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 10554 times.
10584 if (bs_code == 0) {
110 30 av_log(logctx, AV_LOG_ERROR + log_level_offset,
111 "reserved blocksize code: 0\n");
112 30 return AVERROR_INVALIDDATA;
113
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 10549 times.
10554 } else if (bs_code == 6) {
114 5 fi->blocksize = get_bits(gb, 8) + 1;
115
2/2
✓ Branch 0 taken 105 times.
✓ Branch 1 taken 10444 times.
10549 } else if (bs_code == 7) {
116 105 fi->blocksize = get_bits(gb, 16) + 1;
117 } else {
118 10444 fi->blocksize = ff_flac_blocksize_table[bs_code];
119 }
120
121 /* sample rate */
122
2/2
✓ Branch 0 taken 10508 times.
✓ Branch 1 taken 46 times.
10554 if (sr_code < 12) {
123 10508 fi->samplerate = ff_flac_sample_rate_table[sr_code];
124
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 28 times.
46 } else if (sr_code == 12) {
125 18 fi->samplerate = get_bits(gb, 8) * 1000;
126
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 20 times.
28 } else if (sr_code == 13) {
127 8 fi->samplerate = get_bits(gb, 16);
128
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
20 } else if (sr_code == 14) {
129 10 fi->samplerate = get_bits(gb, 16) * 10;
130 } else {
131 10 av_log(logctx, AV_LOG_ERROR + log_level_offset,
132 "illegal sample rate code %d\n",
133 sr_code);
134 10 return AVERROR_INVALIDDATA;
135 }
136
137 /* header CRC-8 check */
138 10544 skip_bits(gb, 8);
139
2/2
✓ Branch 0 taken 123 times.
✓ Branch 1 taken 10421 times.
10544 if (av_crc(av_crc_get_table(AV_CRC_8_ATM), 0, gb->buffer,
140 10544 get_bits_count(gb)/8)) {
141 123 av_log(logctx, AV_LOG_ERROR + log_level_offset,
142 "header crc mismatch\n");
143 123 return AVERROR_INVALIDDATA;
144 }
145
146 10421 return 0;
147 }
148
149 221 int ff_flac_is_extradata_valid(AVCodecContext *avctx,
150 uint8_t **streaminfo_start)
151 {
152
2/4
✓ Branch 0 taken 221 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 221 times.
221 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 221 times.
✗ Branch 1 not taken.
221 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 221 times.
221 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 221 *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 221 return 1;
171 }
172
173 9258 void ff_flac_set_channel_layout(AVCodecContext *avctx, int channels)
174 {
175
2/2
✓ Branch 0 taken 9226 times.
✓ Branch 1 taken 32 times.
9258 if (channels == avctx->ch_layout.nb_channels &&
176
2/2
✓ Branch 0 taken 9225 times.
✓ Branch 1 taken 1 times.
9226 avctx->ch_layout.order != AV_CHANNEL_ORDER_UNSPEC)
177 9225 return;
178
179 33 av_channel_layout_uninit(&avctx->ch_layout);
180
1/2
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
33 if (channels <= FF_ARRAY_ELEMS(flac_channel_layouts))
181 33 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 221 int ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s,
188 const uint8_t *buffer)
189 {
190 GetBitContext gb;
191 221 init_get_bits(&gb, buffer, FLAC_STREAMINFO_SIZE*8);
192
193 221 skip_bits(&gb, 16); /* skip min blocksize */
194 221 s->max_blocksize = get_bits(&gb, 16);
195
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 221 times.
221 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 221 skip_bits(&gb, 24); /* skip min frame size */
203 221 s->max_framesize = get_bits(&gb, 24);
204
205 221 s->samplerate = get_bits(&gb, 20);
206 221 s->channels = get_bits(&gb, 3) + 1;
207 221 s->bps = get_bits(&gb, 5) + 1;
208
209
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 221 times.
221 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 221 avctx->sample_rate = s->samplerate;
216 221 avctx->bits_per_raw_sample = s->bps;
217 221 ff_flac_set_channel_layout(avctx, s->channels);
218
219 221 s->samples = get_bits64(&gb, 36);
220
221 221 skip_bits_long(&gb, 64); /* md5 sum */
222 221 skip_bits_long(&gb, 64); /* md5 sum */
223
224 221 return 0;
225 }
226