/src/vlc/modules/packetizer/flac.h
Line | Count | Source |
1 | | /***************************************************************************** |
2 | | * flac.h: fLAC audio headers |
3 | | ***************************************************************************** |
4 | | * Copyright (C) 2001-2018 VLC authors, VideoLabs and VideoLAN |
5 | | * |
6 | | * This program is free software; you can redistribute it and/or modify it |
7 | | * under the terms of the GNU Lesser General Public License as published by |
8 | | * the Free Software Foundation; either version 2.1 of the License, or |
9 | | * (at your option) any later version. |
10 | | * |
11 | | * This program is distributed in the hope that it will be useful, |
12 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | * GNU Lesser General Public License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU Lesser General Public License |
17 | | * along with this program; if not, write to the Free Software Foundation, |
18 | | * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. |
19 | | *****************************************************************************/ |
20 | | #include <vlc_common.h> |
21 | | |
22 | 271k | #define FLAC_HEADER_SIZE_MIN 9 |
23 | 128M | #define FLAC_HEADER_SIZE_MAX 16 |
24 | 11.9k | #define FLAC_STREAMINFO_SIZE 34 |
25 | 29.0M | #define FLAC_FRAME_SIZE_MIN ((48+(8 + 4 + 1*4)+FLAC_HEADER_SIZE_MAX)/8) |
26 | | |
27 | | struct flac_stream_info |
28 | | { |
29 | | unsigned min_blocksize, max_blocksize; |
30 | | unsigned min_framesize, max_framesize; |
31 | | unsigned sample_rate; |
32 | | unsigned channels; |
33 | | unsigned bits_per_sample; |
34 | | uint64_t total_samples; |
35 | | }; |
36 | | |
37 | | struct flac_header_info |
38 | | { |
39 | | vlc_tick_t i_pts; |
40 | | unsigned i_rate; |
41 | | unsigned i_channels; |
42 | | unsigned i_bits_per_sample; |
43 | | unsigned i_frame_length; |
44 | | }; |
45 | | |
46 | | static inline void FLAC_ParseStreamInfo( const uint8_t *p_buf, |
47 | | struct flac_stream_info *stream_info ) |
48 | 2.52k | { |
49 | 2.52k | stream_info->min_blocksize = GetWBE( &p_buf[0] ); |
50 | 2.52k | stream_info->min_blocksize = VLC_CLIP( stream_info->min_blocksize, 16, 65535 ); |
51 | | |
52 | 2.52k | stream_info->max_blocksize = GetWBE( &p_buf[2] ); |
53 | 2.52k | stream_info->max_blocksize = VLC_CLIP( stream_info->max_blocksize, 16, 65535 ); |
54 | | |
55 | 2.52k | stream_info->min_framesize = GetDWBE( &p_buf[3] ) & 0x00FFFFFF; |
56 | 2.52k | stream_info->min_framesize = __MAX( stream_info->min_framesize, FLAC_FRAME_SIZE_MIN ); |
57 | | |
58 | 2.52k | stream_info->max_framesize = GetDWBE( &p_buf[6] ) & 0x00FFFFFF; |
59 | | |
60 | 2.52k | stream_info->sample_rate = GetDWBE( &p_buf[10] ) >> 12; |
61 | 2.52k | stream_info->channels = (p_buf[12] & 0x0F >> 1) + 1; |
62 | 2.52k | stream_info->bits_per_sample = (((p_buf[12] & 0x01) << 4) | p_buf[13] >> 4) + 1; |
63 | | |
64 | 2.52k | stream_info->total_samples = GetQWBE(&p_buf[4+6]) & ((INT64_C(1)<<36)-1); |
65 | 2.52k | } |
66 | | |
67 | | /* Will return UINT64_MAX for an invalid utf-8 sequence */ |
68 | | static inline uint64_t read_utf8(const uint8_t *p_buf, unsigned i_buf, int *pi_read) |
69 | 23.8M | { |
70 | | /* Max coding bits is 56 - 8 */ |
71 | | /* Value max precision is 36 bits */ |
72 | 23.8M | uint64_t i_result = 0; |
73 | 23.8M | unsigned i; |
74 | | |
75 | 23.8M | if(i_buf < 1) |
76 | 0 | return UINT64_MAX; |
77 | | |
78 | 23.8M | if (!(p_buf[0] & 0x80)) { /* 0xxxxxxx */ |
79 | 21.5M | i_result = p_buf[0]; |
80 | 21.5M | i = 0; |
81 | 21.5M | } else if (p_buf[0] & 0xC0 && !(p_buf[0] & 0x20)) { /* 110xxxxx */ |
82 | 88.1k | i_result = p_buf[0] & 0x1F; |
83 | 88.1k | i = 1; |
84 | 2.21M | } else if (p_buf[0] & 0xE0 && !(p_buf[0] & 0x10)) { /* 1110xxxx */ |
85 | 210k | i_result = p_buf[0] & 0x0F; |
86 | 210k | i = 2; |
87 | 2.00M | } else if (p_buf[0] & 0xF0 && !(p_buf[0] & 0x08)) { /* 11110xxx */ |
88 | 205k | i_result = p_buf[0] & 0x07; |
89 | 205k | i = 3; |
90 | 1.79M | } else if (p_buf[0] & 0xF8 && !(p_buf[0] & 0x04)) { /* 111110xx */ |
91 | 294k | i_result = p_buf[0] & 0x03; |
92 | 294k | i = 4; |
93 | 1.50M | } else if (p_buf[0] & 0xFC && !(p_buf[0] & 0x02)) { /* 1111110x */ |
94 | 737k | i_result = p_buf[0] & 0x01; |
95 | 737k | i = 5; |
96 | 763k | } else if (p_buf[0] & 0xFE && !(p_buf[0] & 0x01)) { /* 11111110 */ |
97 | 78.8k | i_result = 0; |
98 | 78.8k | i = 6; |
99 | 684k | } else { |
100 | 684k | return UINT64_MAX; |
101 | 684k | } |
102 | | |
103 | 23.1M | if(i_buf < i + 1) |
104 | 0 | return UINT64_MAX; |
105 | | |
106 | 28.5M | for (unsigned j = 1; j <= i; j++) { |
107 | 5.85M | if (!(p_buf[j] & 0x80) || (p_buf[j] & 0x40)) { /* 10xxxxxx */ |
108 | 510k | return UINT64_MAX; |
109 | 510k | } |
110 | 5.34M | i_result <<= 6; |
111 | 5.34M | i_result |= (p_buf[j] & 0x3F); |
112 | 5.34M | } |
113 | | |
114 | 22.6M | *pi_read = i; |
115 | 22.6M | return i_result; |
116 | 23.1M | } |
117 | | |
118 | | static inline int FLAC_CheckFrameInfo(const struct flac_stream_info *stream_info, |
119 | | const struct flac_header_info *h) |
120 | 22.3M | { |
121 | | /* Sanity check using stream info header when possible */ |
122 | 22.3M | if (stream_info) |
123 | 22.3M | { |
124 | 22.3M | if ((stream_info->min_blocksize != stream_info->max_blocksize && |
125 | 5.25M | h->i_frame_length < stream_info->min_blocksize) || |
126 | 21.9M | h->i_frame_length > stream_info->max_blocksize) |
127 | 6.08M | return 0; |
128 | 16.2M | if(stream_info->max_framesize && |
129 | 16.1M | stream_info->min_framesize > stream_info->max_framesize) |
130 | 32.1k | return 0; |
131 | 16.1M | if (h->i_bits_per_sample != stream_info->bits_per_sample) |
132 | 290k | return 0; |
133 | 15.8M | if (h->i_rate != stream_info->sample_rate) |
134 | 512k | return 0; |
135 | 15.8M | } |
136 | 15.3M | return 1; |
137 | 22.3M | } |
138 | | |
139 | | /***************************************************************************** |
140 | | * FLAC_ParseSyncInfo: parse FLAC sync info |
141 | | * - stream_info can be NULL |
142 | | * - pf_crc8 can be NULL to skip crc check |
143 | | * Returns: 1 on success, 0 on failure, and -1 if could be incorrect |
144 | | *****************************************************************************/ |
145 | | static inline int FLAC_ParseSyncInfo(const uint8_t *p_buf, unsigned i_buf, |
146 | | const struct flac_stream_info *stream_info, |
147 | | uint8_t(*pf_crc8)(const uint8_t *, size_t), |
148 | | struct flac_header_info *h) |
149 | 56.7M | { |
150 | 56.7M | bool b_guessing = false; |
151 | | |
152 | 56.7M | if(unlikely(i_buf < FLAC_HEADER_SIZE_MIN)) |
153 | 0 | return 0; |
154 | | |
155 | | /* Check syncword */ |
156 | 56.7M | if (p_buf[0] != 0xFF || (p_buf[1] & 0xFE) != 0xF8) |
157 | 0 | return 0; |
158 | | |
159 | | /* Check there is no emulated sync code in the rest of the header */ |
160 | 56.7M | if (p_buf[2] == 0xff || p_buf[3] == 0xFF) |
161 | 13.0M | return 0; |
162 | | |
163 | | /* Find blocksize (framelength) */ |
164 | 43.7M | int blocksize_hint = 0; |
165 | 43.7M | unsigned blocksize = p_buf[2] >> 4; |
166 | 43.7M | if (blocksize >= 8) { |
167 | 4.18M | blocksize = 256 << (blocksize - 8); |
168 | 39.5M | } else if (blocksize == 0) { /* value 0 is reserved */ |
169 | 15.0M | b_guessing = true; |
170 | 15.0M | if (stream_info && |
171 | 15.0M | stream_info->min_blocksize == stream_info->max_blocksize) |
172 | 14.3M | blocksize = stream_info->min_blocksize; |
173 | 654k | else |
174 | 654k | return 0; /* We can't do anything with this */ |
175 | 24.4M | } else if (blocksize == 1) { |
176 | 324k | blocksize = 192; |
177 | 24.1M | } else if (blocksize == 6 || blocksize == 7) { |
178 | 10.8M | blocksize_hint = blocksize; |
179 | 10.8M | blocksize = 0; |
180 | 13.3M | } else /* 2, 3, 4, 5 */ { |
181 | 13.3M | blocksize = 576 << (blocksize - 2); |
182 | 13.3M | } |
183 | | |
184 | 43.0M | if (stream_info && !blocksize_hint) |
185 | 32.1M | if (blocksize < stream_info->min_blocksize || |
186 | 24.9M | blocksize > stream_info->max_blocksize) |
187 | 16.0M | return 0; |
188 | | |
189 | | /* Find samplerate */ |
190 | 26.9M | int samplerate_hint = p_buf[2] & 0xf; |
191 | 26.9M | unsigned int samplerate; |
192 | 26.9M | if (samplerate_hint == 0) { |
193 | 25.0M | if (stream_info) |
194 | 25.0M | samplerate = stream_info->sample_rate; |
195 | 9.34k | else |
196 | 9.34k | return 0; /* We can't do anything with this */ |
197 | 25.0M | } else if (samplerate_hint == 15) { |
198 | 28.8k | return 0; /* invalid */ |
199 | 1.91M | } else if (samplerate_hint < 12) { |
200 | 1.38M | static const int16_t flac_samplerate[12] = { |
201 | 1.38M | 0, 8820, 17640, 19200, |
202 | 1.38M | 800, 1600, 2205, 2400, |
203 | 1.38M | 3200, 4410, 4800, 9600, |
204 | 1.38M | }; |
205 | 1.38M | samplerate = flac_samplerate[samplerate_hint] * 10; |
206 | 1.38M | } else { |
207 | 528k | samplerate = 0; /* at end of header */ |
208 | 528k | } |
209 | | |
210 | | /* Find channels */ |
211 | 26.9M | unsigned channels = p_buf[3] >> 4; |
212 | 26.9M | if (channels >= 8) { |
213 | 605k | if (channels >= 11) /* reserved */ |
214 | 232k | return 0; |
215 | 372k | channels = 2; |
216 | 372k | } else |
217 | 26.3M | channels++; |
218 | | |
219 | | |
220 | | /* Find bits per sample */ |
221 | 26.7M | static const int8_t flac_bits_per_sample[8] = { |
222 | 26.7M | 0, 8, 12, -1, 16, 20, 24, -1 |
223 | 26.7M | }; |
224 | 26.7M | int bits_per_sample = flac_bits_per_sample[(p_buf[3] & 0x0e) >> 1]; |
225 | 26.7M | if (bits_per_sample == 0) { |
226 | 14.5M | if (stream_info) |
227 | 14.5M | bits_per_sample = stream_info->bits_per_sample; |
228 | 10.5k | else |
229 | 10.5k | return 0; |
230 | 14.5M | } else if (bits_per_sample < 0) |
231 | 132k | return 0; |
232 | | |
233 | | |
234 | | /* reserved for future use */ |
235 | 26.5M | if (p_buf[3] & 0x01) |
236 | 2.70M | return 0; |
237 | | |
238 | | /* End of fixed size header */ |
239 | 23.8M | unsigned i_header = 4; |
240 | | |
241 | | /* > FLAC_HEADER_SIZE_MIN checks start here */ |
242 | | |
243 | | /* Check Sample/Frame number */ |
244 | 23.8M | int i_read; |
245 | 23.8M | uint64_t i_fsnumber = read_utf8(&p_buf[i_header++], i_buf - 4, &i_read); |
246 | | |
247 | | /* Invalid UTF-8 */ |
248 | 23.8M | if (i_fsnumber == UINT64_MAX) |
249 | 1.19M | return 0; |
250 | | |
251 | | /* Invalid Sample/Frame number */ |
252 | 22.6M | if (stream_info && stream_info->total_samples != 0 && i_fsnumber > stream_info->total_samples) |
253 | 62.3k | return 0; |
254 | | |
255 | 22.6M | i_header += i_read; |
256 | | |
257 | | /* Read blocksize */ |
258 | 22.6M | if (blocksize_hint) { |
259 | 9.95M | if(i_header == i_buf) |
260 | 0 | return 0; |
261 | 9.95M | blocksize = p_buf[i_header++]; |
262 | 9.95M | if (blocksize_hint == 7) { |
263 | 9.00M | blocksize <<= 8; |
264 | 9.00M | blocksize |= p_buf[i_header++]; |
265 | 9.00M | } |
266 | 9.95M | blocksize++; |
267 | 9.95M | } |
268 | | |
269 | | /* Read sample rate */ |
270 | 22.6M | if (samplerate == 0) { |
271 | 261k | if(i_header == i_buf) |
272 | 0 | return 0; |
273 | 261k | samplerate = p_buf[i_header++]; |
274 | 261k | if (samplerate_hint != 12) { /* 16 bits */ |
275 | 217k | if(i_header == i_buf) |
276 | 0 | return 0; |
277 | 217k | samplerate <<= 8; |
278 | 217k | samplerate |= p_buf[i_header++]; |
279 | 217k | } |
280 | | |
281 | 261k | if (samplerate_hint == 12) |
282 | 44.0k | samplerate *= 1000; |
283 | 217k | else if (samplerate_hint == 14) |
284 | 161k | samplerate *= 10; |
285 | 261k | } |
286 | | |
287 | 22.6M | if ( !samplerate ) |
288 | 4.97k | return 0; |
289 | | |
290 | 22.5M | if(i_header == i_buf) /* no crc space */ |
291 | 0 | return 0; |
292 | | |
293 | | /* Check the CRC-8 byte */ |
294 | 22.5M | if (pf_crc8 && |
295 | 619k | pf_crc8(p_buf, i_header) != p_buf[i_header]) |
296 | 158k | return 0; |
297 | | |
298 | | /* Compute from frame absolute time */ |
299 | 22.4M | if ( (p_buf[1] & 0x01) == 0 ) /* Fixed blocksize stream / Frames */ |
300 | 12.7M | { |
301 | 12.7M | const unsigned fixedblocksize = stream_info ? stream_info->min_blocksize : blocksize; |
302 | 12.7M | h->i_pts = VLC_TICK_0 + vlc_tick_from_samples(fixedblocksize * i_fsnumber, samplerate); |
303 | 12.7M | } |
304 | 9.67M | else /* Variable blocksize stream / Samples */ |
305 | 9.67M | h->i_pts = VLC_TICK_0 + vlc_tick_from_samples(i_fsnumber, samplerate); |
306 | | |
307 | 22.4M | h->i_bits_per_sample = bits_per_sample; |
308 | 22.4M | h->i_rate = samplerate; |
309 | 22.4M | h->i_channels = channels; |
310 | 22.4M | h->i_frame_length = blocksize; |
311 | | |
312 | 22.4M | return b_guessing ? -1 : 1; |
313 | 22.5M | } |