diff --git a/src/decoder/Bridge.hxx b/src/decoder/Bridge.hxx index b9760a41d..0efbb3f55 100644 --- a/src/decoder/Bridge.hxx +++ b/src/decoder/Bridge.hxx @@ -40,6 +40,7 @@ class DecoderBridge final : public DecoderClient { public: DecoderControl &dc; +private: /** * For converting input data to the configured audio format. * nullptr means no conversion necessary. @@ -83,12 +84,14 @@ public: */ std::unique_ptr song_tag; +public: /** the last tag received from the stream */ std::unique_ptr stream_tag; /** the last tag received from the decoder plugin */ std::unique_ptr decoder_tag; +private: /** the chunk currently being written to */ MusicChunkPtr current_chunk; @@ -106,11 +109,16 @@ public: */ std::exception_ptr error; +public: DecoderBridge(DecoderControl &_dc, bool _initial_seek_pending, std::unique_ptr _tag) noexcept; ~DecoderBridge() noexcept; + void Reset() noexcept { + error = {}; + } + /** * Should be read operation be cancelled? That is the case when the * player thread has sent a command such as "STOP". @@ -135,6 +143,16 @@ public: */ void FlushChunk() noexcept; + void CheckFlushChunk() { + if (current_chunk != nullptr) + FlushChunk(); + } + + void CheckRethrowError() { + if (error) + std::rethrow_exception(error); + } + /* virtual methods from DecoderClient */ void Ready(AudioFormat audio_format, bool seekable, SignedSongTime duration) override; diff --git a/src/decoder/Thread.cxx b/src/decoder/Thread.cxx index 9021af57a..f34d0f429 100644 --- a/src/decoder/Thread.cxx +++ b/src/decoder/Thread.cxx @@ -210,7 +210,7 @@ decoder_run_stream_plugin(DecoderBridge &bridge, InputStream &is, if (!decoder_check_plugin(plugin, is, suffix)) return false; - bridge.error = std::exception_ptr(); + bridge.Reset(); tried_r = true; return decoder_stream_decode(plugin, bridge, is); @@ -316,7 +316,7 @@ TryDecoderFile(DecoderBridge &bridge, Path path_fs, const char *suffix, if (!plugin.SupportsSuffix(suffix)) return false; - bridge.error = std::exception_ptr(); + bridge.Reset(); DecoderControl &dc = bridge.dc; @@ -344,7 +344,7 @@ TryContainerDecoder(DecoderBridge &bridge, Path path_fs, const char *suffix, !plugin.SupportsSuffix(suffix)) return false; - bridge.error = nullptr; + bridge.Reset(); DecoderControl &dc = bridge.dc; const std::lock_guard protect(dc.mutex); @@ -472,19 +472,16 @@ decoder_run_song(DecoderControl &dc, AtScopeExit(&bridge) { /* flush the last chunk */ - if (bridge.current_chunk != nullptr) - bridge.FlushChunk(); + bridge.CheckFlushChunk(); }; success = DecoderUnlockedRunUri(bridge, uri, path_fs); } - if (bridge.error) { - /* copy the Error from struct Decoder to - DecoderControl */ - std::rethrow_exception(bridge.error); - } else if (success) + bridge.CheckRethrowError(); + + if (success) dc.state = DecoderState::STOP; else { const char *error_uri = song.GetURI();