From: Josh Coalson Date: Tue, 23 Mar 2004 04:27:47 +0000 (+0000) Subject: fix seeking bug where I/O seek to "unparseable" frame header caused a seek error... X-Git-Tag: 1.2.0~907 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d666ed70f7d2b4db4fe29c7f6ee296cfcb6d218b;p=platform%2Fupstream%2Fflac.git fix seeking bug where I/O seek to "unparseable" frame header caused a seek error: SF bug #851155 --- diff --git a/src/libFLAC/seekable_stream_decoder.c b/src/libFLAC/seekable_stream_decoder.c index 92eef70..94b6f58 100644 --- a/src/libFLAC/seekable_stream_decoder.c +++ b/src/libFLAC/seekable_stream_decoder.c @@ -970,9 +970,32 @@ FLAC__bool seek_to_absolute_sample_(FLAC__SeekableStreamDecoder *decoder, FLAC__ return false; } } - if(!FLAC__stream_decoder_process_single(decoder->private_->stream_decoder)) { - decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR; - return false; + /* Now we need to get a frame. It is possible for our seek + * to land in the middle of audio data that looks exactly like + * a frame header from a future version of an encoder. When + * that happens, FLAC__stream_decoder_process_single() will + * return false and the state will be + * FLAC__STREAM_DECODER_UNPARSEABLE_STREAM. But there is a + * remote possibility that it is properly synced at such a + * "future-codec frame", so to make sure, we wait to see + * several "unparseable" errors in a row before bailing out. + */ + { + unsigned unparseable_count; + FLAC__bool got_a_frame = false; + for (unparseable_count = 0; !got_a_frame && unparseable_count < 10; unparseable_count++) { + if(FLAC__stream_decoder_process_single(decoder->private_->stream_decoder)) + got_a_frame = true; + else if(decoder->private_->stream_decoder->protected_->state == FLAC__STREAM_DECODER_UNPARSEABLE_STREAM) + /* try again. we don't want to flush the decoder since that clears the bitbuffer */ + decoder->private_->stream_decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + else /* it's a real error */ + break; + } + if (!got_a_frame) { + decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR; + return false; + } } /* our write callback will change the state when it gets to the target frame */ if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_SEEKING) {