Commit ba056083 authored by Josh Coalson's avatar Josh Coalson
Browse files

again fix logic around deciphering frame/sample number from frame header

parent 663c599b
......@@ -121,6 +121,7 @@ typedef struct FLAC__StreamDecoderPrivate {
FLAC__EntropyCodingMethod_PartitionedRiceContents partitioned_rice_contents[FLAC__MAX_CHANNELS];
unsigned output_capacity, output_channels;
FLAC__uint32 last_frame_number;
FLAC__uint32 last_block_size;
FLAC__uint64 samples_decoded;
FLAC__bool has_stream_info, has_seek_table;
FLAC__StreamMetadata stream_info;
......@@ -284,6 +285,7 @@ FLAC_API FLAC__StreamDecoderState FLAC__stream_decoder_init(FLAC__StreamDecoder
return decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
decoder->private_->last_frame_number = 0;
decoder->private_->last_block_size = 0;
decoder->private_->samples_decoded = 0;
decoder->private_->has_stream_info = false;
decoder->private_->cached = false;
......@@ -590,6 +592,8 @@ FLAC_API FLAC__bool FLAC__stream_decoder_flush(FLAC__StreamDecoder *decoder)
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false;
}
decoder->private_->last_frame_number = 0;
decoder->private_->last_block_size = 0;
decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
return true;
......@@ -1702,18 +1706,34 @@ FLAC__bool read_frame_header_(FLAC__StreamDecoder *decoder)
return true;
}
if(blocksize_hint && is_known_variable_blocksize_stream) {
if(!FLAC__bitbuffer_read_utf8_uint64(decoder->private_->input, &xx, read_callback_, decoder, raw_header, &raw_header_len))
return false; /* the read_callback_ sets the state for us */
if(xx == FLAC__U64L(0xffffffffffffffff)) { /* i.e. non-UTF8 code... */
decoder->private_->lookahead = raw_header[raw_header_len-1]; /* back up as much as we can */
decoder->private_->cached = true;
decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER, decoder->private_->client_data);
decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
return true;
/*
* Now we get to the regrettable consequences of not knowing for sure
* whether we got a frame number or a sample number. There are no
* encoders that do variable-blocksize encoding so unless we know from
* the STREAMINFO that it is variable-blocksize we will assume it is
* fixed-blocksize. The trouble comes when we have no STREAMINFO; again
* we will guess that is fixed-blocksize. Where this can go wrong: 1) a
* variable-blocksize stream with no STREAMINFO; 2) a fixed-blocksize
* stream that was edited such that one or more frames before or
* including this one do not have the same number of samples as the
* STREAMINFO's min and max blocksize.
*/
if(is_known_variable_blocksize_stream) {
if(blocksize_hint) {
if(!FLAC__bitbuffer_read_utf8_uint64(decoder->private_->input, &xx, read_callback_, decoder, raw_header, &raw_header_len))
return false; /* the read_callback_ sets the state for us */
if(xx == FLAC__U64L(0xffffffffffffffff)) { /* i.e. non-UTF8 code... */
decoder->private_->lookahead = raw_header[raw_header_len-1]; /* back up as much as we can */
decoder->private_->cached = true;
decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER, decoder->private_->client_data);
decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
return true;
}
decoder->private_->frame.header.number_type = FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER;
decoder->private_->frame.header.number.sample_number = xx;
}
decoder->private_->frame.header.number_type = FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER;
decoder->private_->frame.header.number.sample_number = xx;
else
is_unparseable = true;
}
else {
if(!FLAC__bitbuffer_read_utf8_uint32(decoder->private_->input, &x, read_callback_, decoder, raw_header, &raw_header_len))
......@@ -1727,14 +1747,21 @@ FLAC__bool read_frame_header_(FLAC__StreamDecoder *decoder)
}
decoder->private_->last_frame_number = x;
decoder->private_->frame.header.number_type = FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER;
if(blocksize_hint) {
if(decoder->private_->has_stream_info)
decoder->private_->frame.header.number.sample_number = (FLAC__int64)decoder->private_->stream_info.data.stream_info.min_blocksize * (FLAC__int64)x;
if(decoder->private_->has_stream_info) {
FLAC__ASSERT(decoder->private_->stream_info.data.stream_info.min_blocksize == decoder->private_->stream_info.data.stream_info.max_blocksize);
decoder->private_->frame.header.number.sample_number = (FLAC__uint64)decoder->private_->stream_info.data.stream_info.min_blocksize * (FLAC__uint64)x;
decoder->private_->last_block_size = (FLAC__uint64)decoder->private_->frame.header.blocksize;
}
else if(blocksize_hint) {
if(decoder->private_->last_block_size)
decoder->private_->frame.header.number.sample_number = (FLAC__uint64)decoder->private_->last_block_size * (FLAC__uint64)x;
else
is_unparseable = true;
}
else
decoder->private_->frame.header.number.sample_number = (FLAC__int64)decoder->private_->frame.header.blocksize * (FLAC__int64)x;
else {
decoder->private_->frame.header.number.sample_number = (FLAC__uint64)decoder->private_->frame.header.blocksize * (FLAC__uint64)x;
decoder->private_->last_block_size = (FLAC__uint64)decoder->private_->frame.header.blocksize;
}
}
if(blocksize_hint) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment