[Flac-dev] libFLAC header checking
LRN
lrn1986 at gmail.com
Wed Dec 10 08:23:11 PST 2008
On 06.11.2008 22:16, LRN wrote:
> In stream_decoder.c function find_metadata_() checks whether a file is
> valid or not. There are 4 cases it recognizes:
> 1) file begins with 'fLaC'
> 2) file begins with ID3 (skipped), followed by 'fLaC'
> 3) file may begin with 11111111 111110?? sync code (or 11111111111110,
> depends on endianess i suppose). That is - a raw file with FLAC
> frames, without header (right?).
> 4) file begins with ID3 (again - skipped), followed by the same sync
> code as in case 3
>
> find_metadata_() accepts all 4 types of files.
>
> I don't know what was the intention behind accepting case 3, but case
> 4 ALSO matches mp3 files - they have ID3 at the beginning and
> FLAC-like two-byte sync code 11111111 11111011 afterwards. Sequence is
> slightly different, but when it is read as two separate bytes and the
> second byte is SHR'ed twice to form 00111110, it matches.
> Because of this FLAC decoder initially accepts an mp3 file as a valid
> FLAC file. Of course, once decoding starts, decoder throws an error
> and discards the file (at least i think it does, i never reached that
> far myself).
> Unfortunately, some applications using libFLAC may assume that lack of
> errors after FLAC__stream_decoder_process_until_end_of_metadata()
> indicates that header is read and stream information (channel number,
> for example) is available.
>
> Would you kindly check the find_metadata_() function to make sure it
> only accepts real FLAC sync codes, not the MP3 ones? Or at least
> mention in the documentation that FLAC__STREAM_DECODER_READ_FRAME
> status doesn't means that stream info is available.
Further information:
FLAC header:
11111111 111110AB and so on
A =
0 - mandatory
1 - reserved
B =
0 - fixed-blocksize
1 - variable-blocksize
CCCC =
0000 - reserved
0001 - 192 samples
0010-0101 - 576 * (2^(n-2)) samples
0110 - get 8 bit (blocksize-1) from end of header
0111 - get 16 bit (blocksize-1) from end of header
1000-1111 - 256 * (2^(n-8)) samples
MP3:
11111111 111BBCCD and so on
BB =
00 - MPEG 2.5
01 - reserved
10 - MPEG 2
11 - MPEG 1
CC =
00 - reserved
01 - layer 3
10 - layer 2
11 - layer 1
D =
0 - with CRC
1 - without CRC
The best way to distinguish FLAC header from MP3 header is to look at
"0A" (FLAC) or "CC" (MP3) bit pair.
In FLAC it must be 00 (first 0 is from magic number second 0 is from
reserved bit that should always be 0)
In MP3 it must not be 00 (00 is reserved).
Suggested code change is
from:
else if(x >> 2 == 0x3e) { /* MAGIC NUMBER for the last 6
sync bits */
decoder->private_->header_warmup[1] = (FLAC__byte)x;
decoder->protected_->state =
FLAC__STREAM_DECODER_READ_FRAME;
return true;
}
to
else if(x >> 1 == 0x7c) { /* MAGIC NUMBER for the last 6
sync bits and reserved 7th bit*/
decoder->private_->header_warmup[1] = (FLAC__byte)x;
decoder->protected_->state =
FLAC__STREAM_DECODER_READ_FRAME;
return true;
}
More information about the Flac-dev
mailing list