diff options
author | jcoalson <jcoalson> | 2005-01-24 00:20:49 +0000 |
---|---|---|
committer | jcoalson <jcoalson> | 2005-01-24 00:20:49 +0000 |
commit | b7016f20c88d3463299b812d8f69d46e98ba7494 (patch) | |
tree | d7e987f46e2af9a57b06e020ba34f9e8b8af19f5 /src/libFLAC/stream_decoder.c | |
parent | 233f5a34615526231e781eeb74236fc0538aaf20 (diff) | |
download | flac-arm-1.1.3-b7016f20c88d3463299b812d8f69d46e98ba7494.tar.gz |
again fix logic around deciphering frame/sample number from frame header
Diffstat (limited to 'src/libFLAC/stream_decoder.c')
-rw-r--r-- | src/libFLAC/stream_decoder.c | 59 |
1 files changed, 43 insertions, 16 deletions
diff --git a/src/libFLAC/stream_decoder.c b/src/libFLAC/stream_decoder.c index 5995afeb..ce571dba 100644 --- a/src/libFLAC/stream_decoder.c +++ b/src/libFLAC/stream_decoder.c @@ -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) { |