From: Josh Coalson Date: Wed, 8 Nov 2006 17:07:58 +0000 (+0000) Subject: fixes for new seeking algorithm X-Git-Tag: 1.2.0~318 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8295fd03b671ea9326cc5d95c246c2e62d5413f4;p=platform%2Fupstream%2Fflac.git fixes for new seeking algorithm --- diff --git a/src/libFLAC/stream_decoder.c b/src/libFLAC/stream_decoder.c index 9aca775..baa0fae 100644 --- a/src/libFLAC/stream_decoder.c +++ b/src/libFLAC/stream_decoder.c @@ -2928,17 +2928,23 @@ FLAC__bool seek_to_absolute_sample_(FLAC__StreamDecoder *decoder, FLAC__uint64 s FLAC__int64 pos = -1; int i; unsigned approx_bytes_per_frame; - FLAC__bool needs_seek = true, first_seek = true; + FLAC__bool first_seek = true; const FLAC__uint64 total_samples = FLAC__stream_decoder_get_total_samples(decoder); const unsigned min_blocksize = decoder->private_->stream_info.data.stream_info.min_blocksize; const unsigned max_blocksize = decoder->private_->stream_info.data.stream_info.max_blocksize; const unsigned max_framesize = decoder->private_->stream_info.data.stream_info.max_framesize; const unsigned min_framesize = decoder->private_->stream_info.data.stream_info.min_framesize; /* take these from the current frame in case they've changed mid-stream */ - const unsigned channels = FLAC__stream_decoder_get_channels(decoder); - const unsigned bps = FLAC__stream_decoder_get_bits_per_sample(decoder); + unsigned channels = FLAC__stream_decoder_get_channels(decoder); + unsigned bps = FLAC__stream_decoder_get_bits_per_sample(decoder); const FLAC__StreamMetadata_SeekTable *seek_table = decoder->private_->has_seek_table? &decoder->private_->seek_table.data.seek_table : 0; + /* use values from stream info if we didn't decode a frame */ + if(channels == 0) + channels = decoder->private_->stream_info.data.stream_info.channels; + if(bps == 0) + bps = decoder->private_->stream_info.data.stream_info.bits_per_sample; + /* we are just guessing here */ if(max_framesize > 0) approx_bytes_per_frame = (max_framesize + min_framesize) / 2 + 1; @@ -2966,6 +2972,8 @@ FLAC__bool seek_to_absolute_sample_(FLAC__StreamDecoder *decoder, FLAC__uint64 s lower_bound_sample = 0; upper_bound = stream_length; upper_bound_sample = total_samples > 0 ? total_samples : target_sample; + if(upper_bound_sample == 0) + upper_bound_sample = 1; /* * Now we refine the bounds if we have a seektable with @@ -3001,33 +3009,31 @@ FLAC__bool seek_to_absolute_sample_(FLAC__StreamDecoder *decoder, FLAC__uint64 s decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; return false; } - if(needs_seek) { #ifndef FLAC__INTEGER_ONLY_LIBRARY #if defined _MSC_VER || defined __MINGW32__ - /* with VC++ you have to spoon feed it the casting */ - pos = (FLAC__int64)lower_bound + (FLAC__int64)((FLAC__double)(FLAC__int64)(target_sample - lower_bound_sample) / (FLAC__double)(FLAC__int64)(upper_bound_sample - lower_bound_sample) * (FLAC__double)(FLAC__int64)(upper_bound - lower_bound)) - approx_bytes_per_frame; + /* with VC++ you have to spoon feed it the casting */ + pos = (FLAC__int64)lower_bound + (FLAC__int64)((FLAC__double)(FLAC__int64)(target_sample - lower_bound_sample) / (FLAC__double)(FLAC__int64)(upper_bound_sample - lower_bound_sample) * (FLAC__double)(FLAC__int64)(upper_bound - lower_bound)) - approx_bytes_per_frame; #else - pos = (FLAC__int64)lower_bound + (FLAC__int64)((FLAC__double)(target_sample - lower_bound_sample) / (FLAC__double)(upper_bound_sample - lower_bound_sample) * (FLAC__double)(upper_bound - lower_bound)) - approx_bytes_per_frame; + pos = (FLAC__int64)lower_bound + (FLAC__int64)((FLAC__double)(target_sample - lower_bound_sample) / (FLAC__double)(upper_bound_sample - lower_bound_sample) * (FLAC__double)(upper_bound - lower_bound)) - approx_bytes_per_frame; #endif #else - /* a little less accurate: */ - if (upper_bound - lower_bound < 0xffffffff) - pos = (FLAC__int64)lower_bound + (FLAC__int64)(((target_sample - lower_bound_sample) * (upper_bound - lower_bound)) / (upper_bound_sample - lower_bound_sample)) - approx_bytes_per_frame; - else /* @@@ WATCHOUT, ~2TB limit */ - pos = (FLAC__int64)lower_bound + (FLAC__int64)((((target_sample - lower_bound_sample)>>8) * ((upper_bound - lower_bound)>>8)) / ((upper_bound_sample - lower_bound_sample)>>16)) - approx_bytes_per_frame; + /* a little less accurate: */ + if(upper_bound - lower_bound < 0xffffffff) + pos = (FLAC__int64)lower_bound + (FLAC__int64)(((target_sample - lower_bound_sample) * (upper_bound - lower_bound)) / (upper_bound_sample - lower_bound_sample)) - approx_bytes_per_frame; + else /* @@@ WATCHOUT, ~2TB limit */ + pos = (FLAC__int64)lower_bound + (FLAC__int64)((((target_sample - lower_bound_sample)>>8) * ((upper_bound - lower_bound)>>8)) / ((upper_bound_sample - lower_bound_sample)>>16)) - approx_bytes_per_frame; #endif - if(pos >= (FLAC__int64)upper_bound) - pos = (FLAC__int64)upper_bound - 1; - if(pos < (FLAC__int64)lower_bound) - pos = (FLAC__int64)lower_bound; - if(decoder->private_->seek_callback(decoder, (FLAC__uint64)pos, decoder->private_->client_data) != FLAC__STREAM_DECODER_SEEK_STATUS_OK) { - decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; - return false; - } - if(!FLAC__stream_decoder_flush(decoder)) { - /* above call sets the state for us */ - return false; - } + if(pos >= (FLAC__int64)upper_bound) + pos = (FLAC__int64)upper_bound - 1; + if(pos < (FLAC__int64)lower_bound) + pos = (FLAC__int64)lower_bound; + if(decoder->private_->seek_callback(decoder, (FLAC__uint64)pos, decoder->private_->client_data) != FLAC__STREAM_DECODER_SEEK_STATUS_OK) { + decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; + return false; + } + if(!FLAC__stream_decoder_flush(decoder)) { + /* above call sets the state for us */ + return false; } /* Now we need to get a frame. First we need to reset our * unparseable_frame_count; if we get too many unparseable @@ -3053,7 +3059,7 @@ FLAC__bool seek_to_absolute_sample_(FLAC__StreamDecoder *decoder, FLAC__uint64 s this_frame_sample = decoder->private_->last_frame.header.number.sample_number; if (!decoder->private_->samples_decoded || (this_frame_sample + decoder->private_->last_frame.header.blocksize >= upper_bound_sample && !first_seek)) { - if (pos == (FLAC__int64)lower_bound || !needs_seek) { + if (pos == (FLAC__int64)lower_bound) { decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; return false; } @@ -3072,8 +3078,6 @@ FLAC__bool seek_to_absolute_sample_(FLAC__StreamDecoder *decoder, FLAC__uint64 s FLAC__ASSERT(decoder->private_->last_frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER); - approx_bytes_per_frame = decoder->private_->last_frame.header.blocksize * channels * bps/8 + 64; - /* we need to narrow the search */ if(target_sample < this_frame_sample) { upper_bound_sample = this_frame_sample + decoder->private_->last_frame.header.blocksize; @@ -3081,19 +3085,17 @@ FLAC__bool seek_to_absolute_sample_(FLAC__StreamDecoder *decoder, FLAC__uint64 s decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; return false; } + approx_bytes_per_frame = 2 * (upper_bound - pos) / 3 + 16; } else { /* target_sample >= this_frame_sample + this frame's blocksize */ - /* we are close, continue in decoding next frames */ - if(target_sample < this_frame_sample + 4 * decoder->private_->last_frame.header.blocksize) - needs_seek = false; - lower_bound_sample = this_frame_sample + decoder->private_->last_frame.header.blocksize; if(!FLAC__stream_decoder_get_decode_position(decoder, &lower_bound)) { decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; return false; } + approx_bytes_per_frame = 2 * (lower_bound - pos) / 3 + 16; } }