1 /*****************************************************************************
2 * flac.h: fLAC audio headers
3 *****************************************************************************
4 * Copyright (C) 2001-2018 VLC authors, VideoLabs and VideoLAN
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.
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.
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>
22 #define FLAC_HEADER_SIZE_MAX 16
23 #define FLAC_STREAMINFO_SIZE 34
24 #define FLAC_FRAME_SIZE_MIN ((48+(8 + 4 + 1*4)+FLAC_HEADER_SIZE_MAX)/8)
26 struct flac_stream_info
28 unsigned min_blocksize
, max_blocksize
;
29 unsigned min_framesize
, max_framesize
;
32 unsigned bits_per_sample
;
33 uint64_t total_samples
;
36 struct flac_header_info
41 unsigned i_bits_per_sample
;
42 unsigned i_frame_length
;
45 static inline void FLAC_ParseStreamInfo( const uint8_t *p_buf
,
46 struct flac_stream_info
*stream_info
)
48 stream_info
->min_blocksize
= GetWBE( &p_buf
[0] );
49 stream_info
->min_blocksize
= VLC_CLIP( stream_info
->min_blocksize
, 16, 65535 );
51 stream_info
->max_blocksize
= GetWBE( &p_buf
[2] );
52 stream_info
->max_blocksize
= VLC_CLIP( stream_info
->max_blocksize
, 16, 65535 );
54 stream_info
->min_framesize
= GetDWBE( &p_buf
[3] ) & 0x00FFFFFF;
55 stream_info
->min_framesize
= __MAX( stream_info
->min_framesize
, FLAC_FRAME_SIZE_MIN
);
57 stream_info
->max_framesize
= GetDWBE( &p_buf
[6] ) & 0x00FFFFFF;
59 stream_info
->sample_rate
= GetDWBE( &p_buf
[10] ) >> 12;
60 stream_info
->channels
= (p_buf
[12] & 0x0F >> 1) + 1;
61 stream_info
->bits_per_sample
= (((p_buf
[12] & 0x01) << 4) | p_buf
[13] >> 4) + 1;
63 stream_info
->total_samples
= GetQWBE(&p_buf
[4+6]) & ((INT64_C(1)<<36)-1);
66 /* Will return INT64_MAX for an invalid utf-8 sequence */
67 static inline int64_t read_utf8(const uint8_t *p_buf
, int *pi_read
)
69 /* Max coding bits is 56 - 8 */
70 /* Value max precision is 36 bits */
74 if (!(p_buf
[0] & 0x80)) { /* 0xxxxxxx */
77 } else if (p_buf
[0] & 0xC0 && !(p_buf
[0] & 0x20)) { /* 110xxxxx */
78 i_result
= p_buf
[0] & 0x1F;
80 } else if (p_buf
[0] & 0xE0 && !(p_buf
[0] & 0x10)) { /* 1110xxxx */
81 i_result
= p_buf
[0] & 0x0F;
83 } else if (p_buf
[0] & 0xF0 && !(p_buf
[0] & 0x08)) { /* 11110xxx */
84 i_result
= p_buf
[0] & 0x07;
86 } else if (p_buf
[0] & 0xF8 && !(p_buf
[0] & 0x04)) { /* 111110xx */
87 i_result
= p_buf
[0] & 0x03;
89 } else if (p_buf
[0] & 0xFC && !(p_buf
[0] & 0x02)) { /* 1111110x */
90 i_result
= p_buf
[0] & 0x01;
92 } else if (p_buf
[0] & 0xFE && !(p_buf
[0] & 0x01)) { /* 11111110 */
99 for (unsigned j
= 1; j
<= i
; j
++) {
100 if (!(p_buf
[j
] & 0x80) || (p_buf
[j
] & 0x40)) { /* 10xxxxxx */
104 i_result
|= (p_buf
[j
] & 0x3F);
111 /*****************************************************************************
112 * FLAC_ParseSyncInfo: parse FLAC sync info
113 * - stream_info can be NULL
114 * - pf_crc8 can be NULL to skip crc check
115 * Returns: 1 on success, 0 on failure, and -1 if could be incorrect
116 *****************************************************************************/
117 static inline int FLAC_ParseSyncInfo(const uint8_t *p_buf
,
118 const struct flac_stream_info
*stream_info
,
119 uint8_t(*pf_crc8
)(const uint8_t *, size_t),
120 struct flac_header_info
*h
)
122 bool b_guessing
= false;
125 if (p_buf
[0] != 0xFF || (p_buf
[1] & 0xFE) != 0xF8)
128 /* Check there is no emulated sync code in the rest of the header */
129 if (p_buf
[2] == 0xff || p_buf
[3] == 0xFF)
132 /* Find blocksize (framelength) */
133 int blocksize_hint
= 0;
134 unsigned blocksize
= p_buf
[2] >> 4;
135 if (blocksize
>= 8) {
136 blocksize
= 256 << (blocksize
- 8);
137 } else if (blocksize
== 0) { /* value 0 is reserved */
140 stream_info
->min_blocksize
== stream_info
->max_blocksize
)
141 blocksize
= stream_info
->min_blocksize
;
143 return 0; /* We can't do anything with this */
144 } else if (blocksize
== 1) {
146 } else if (blocksize
== 6 || blocksize
== 7) {
147 blocksize_hint
= blocksize
;
149 } else /* 2, 3, 4, 5 */ {
150 blocksize
= 576 << (blocksize
- 2);
153 if (stream_info
&& !blocksize_hint
)
154 if (blocksize
< stream_info
->min_blocksize
||
155 blocksize
> stream_info
->max_blocksize
)
158 /* Find samplerate */
159 int samplerate_hint
= p_buf
[2] & 0xf;
160 unsigned int samplerate
;
161 if (samplerate_hint
== 0) {
163 samplerate
= stream_info
->sample_rate
;
165 return 0; /* We can't do anything with this */
166 } else if (samplerate_hint
== 15) {
167 return 0; /* invalid */
168 } else if (samplerate_hint
< 12) {
169 static const int16_t flac_samplerate
[12] = {
170 0, 8820, 17640, 19200,
171 800, 1600, 2205, 2400,
172 3200, 4410, 4800, 9600,
174 samplerate
= flac_samplerate
[samplerate_hint
] * 10;
176 samplerate
= 0; /* at end of header */
180 unsigned channels
= p_buf
[3] >> 4;
182 if (channels
>= 11) /* reserved */
189 /* Find bits per sample */
190 static const int8_t flac_bits_per_sample
[8] = {
191 0, 8, 12, -1, 16, 20, 24, -1
193 int bits_per_sample
= flac_bits_per_sample
[(p_buf
[3] & 0x0e) >> 1];
194 if (bits_per_sample
== 0) {
196 bits_per_sample
= stream_info
->bits_per_sample
;
199 } else if (bits_per_sample
< 0)
203 /* reserved for future use */
207 /* End of fixed size header */
210 /* Check Sample/Frame number */
212 int64_t i_fsnumber
= read_utf8(&p_buf
[i_header
++], &i_read
);
213 if ( i_fsnumber
== INT64_MAX
)
219 if (blocksize_hint
) {
220 blocksize
= p_buf
[i_header
++];
221 if (blocksize_hint
== 7) {
223 blocksize
|= p_buf
[i_header
++];
228 /* Read sample rate */
229 if (samplerate
== 0) {
230 samplerate
= p_buf
[i_header
++];
231 if (samplerate_hint
!= 12) { /* 16 bits */
233 samplerate
|= p_buf
[i_header
++];
236 if (samplerate_hint
== 12)
238 else if (samplerate_hint
== 14)
245 /* Check the CRC-8 byte */
247 pf_crc8(p_buf
, i_header
) != p_buf
[i_header
])
250 /* Sanity check using stream info header when possible */
252 if (blocksize
< stream_info
->min_blocksize
||
253 blocksize
> stream_info
->max_blocksize
)
255 if ((unsigned)bits_per_sample
!= stream_info
->bits_per_sample
)
257 if (samplerate
!= stream_info
->sample_rate
)
261 /* Compute from frame absolute time */
262 if ( (p_buf
[1] & 0x01) == 0 ) /* Fixed blocksize stream / Frames */
263 h
->i_pts
= VLC_TICK_0
+ vlc_tick_from_samples(blocksize
* i_fsnumber
, samplerate
);
264 else /* Variable blocksize stream / Samples */
265 h
->i_pts
= VLC_TICK_0
+ vlc_tick_from_samples(i_fsnumber
, samplerate
);
267 h
->i_bits_per_sample
= bits_per_sample
;
268 h
->i_rate
= samplerate
;
269 h
->i_channels
= channels
;
270 h
->i_frame_length
= blocksize
;
272 return b_guessing
? -1 : 1;