diff --git a/src/output/OutputThread.cxx b/src/output/OutputThread.cxx index 7a343229a..c117ce0b6 100644 --- a/src/output/OutputThread.cxx +++ b/src/output/OutputThread.cxx @@ -264,7 +264,7 @@ AudioOutput::WaitForDelay() bool AudioOutput::FillSourceOrClose() try { - return source.Fill(); + return source.Fill(mutex); } catch (const std::runtime_error &e) { FormatError(e, "Failed to filter for output \"%s\" [%s]", name, plugin.name); diff --git a/src/output/Source.cxx b/src/output/Source.cxx index 9649c9858..a8b9037e1 100644 --- a/src/output/Source.cxx +++ b/src/output/Source.cxx @@ -23,6 +23,7 @@ #include "filter/FilterInternal.hxx" #include "filter/plugins/ReplayGainFilterPlugin.hxx" #include "pcm/PcmMix.hxx" +#include "thread/Mutex.hxx" #include "util/ConstBuffer.hxx" #include "util/RuntimeError.hxx" @@ -187,7 +188,7 @@ AudioOutputSource::FilterChunk(const MusicChunk &chunk) } bool -AudioOutputSource::Fill() +AudioOutputSource::Fill(Mutex &mutex) { if (current_chunk != nullptr && pending_tag == nullptr && pending_data.IsEmpty()) @@ -203,6 +204,10 @@ AudioOutputSource::Fill() pending_tag = current_chunk->tag; try { + /* release the mutex while the filter runs, because + that may take a while */ + const ScopeUnlock unlock(mutex); + pending_data = pending_data.FromVoid(FilterChunk(*current_chunk)); } catch (...) { current_chunk = nullptr; diff --git a/src/output/Source.hxx b/src/output/Source.hxx index 63504a37d..9209d8837 100644 --- a/src/output/Source.hxx +++ b/src/output/Source.hxx @@ -36,6 +36,7 @@ struct MusicChunk; struct Tag; +class Mutex; class Filter; class PreparedFilter; @@ -147,10 +148,13 @@ public: * * Throws std::runtime_error on error * + * @param mutex the #Mutex which protects the + * #SharedPipeConsumer; it is locked by the caller, and may be + * unlocked temporarily by this method * @return true if any input is available, false if the source * has (temporarily?) run empty */ - bool Fill(); + bool Fill(Mutex &mutex); /** * Reads the #Tag to be processed. Be sure to call Fill()