From faf2eeaa99f8fda3afffc13720cee3d65e845264 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 5 Jul 2016 19:27:40 +0200 Subject: [PATCH] decoder/flac: evaluate all possible FLAC__stream_decoder_get_state() values Stop after all fatal errors. This fixes assertion failures in libFLAC. --- NEWS | 2 ++ src/decoder/plugins/FlacDecoderPlugin.cxx | 28 +++++++++++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 3260b0142..8ae416442 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,6 @@ ver 0.19.17 (not yet released) +* decoder + - flac: fix assertion failure while seeking * fix spurious seek error "Failed to allocate silence buffer" * replay gain: fix "replay_gain_handler mixer" setting * DSD: use 0x69 as silence pattern diff --git a/src/decoder/plugins/FlacDecoderPlugin.cxx b/src/decoder/plugins/FlacDecoderPlugin.cxx index eea813401..003e98975 100644 --- a/src/decoder/plugins/FlacDecoderPlugin.cxx +++ b/src/decoder/plugins/FlacDecoderPlugin.cxx @@ -194,10 +194,34 @@ flac_decoder_loop(struct flac_data *data, FLAC__StreamDecoder *flac_dec, decoder_command_finished(decoder); } else decoder_seek_error(decoder); - } else if (cmd == DecoderCommand::STOP || - FLAC__stream_decoder_get_state(flac_dec) == FLAC__STREAM_DECODER_END_OF_STREAM) + } else if (cmd == DecoderCommand::STOP) break; + switch (FLAC__stream_decoder_get_state(flac_dec)) { + case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA: + case FLAC__STREAM_DECODER_READ_METADATA: + case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC: + case FLAC__STREAM_DECODER_READ_FRAME: + /* continue decoding */ + break; + + case FLAC__STREAM_DECODER_END_OF_STREAM: + /* regular end of stream */ + return; + + case FLAC__STREAM_DECODER_OGG_ERROR: + case FLAC__STREAM_DECODER_SEEK_ERROR: + case FLAC__STREAM_DECODER_ABORTED: + case FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR: + /* an error, fatal enough for us to abort the + decoder */ + return; + + case FLAC__STREAM_DECODER_UNINITIALIZED: + /* we shouldn't see this, ever - bail out */ + return; + } + if (t_end != 0 && data->next_frame >= t_end) /* end of this sub track */ break;