output/Source: release the mutex while the filter runs
The filter can take some time to finish, even more so on a weak machine with a saturated CPU. By not holding the mutex during that time, we can reduce PlayerThread latency a lot, because that thread needs to synchronize a lot with all outputs.
This commit is contained in:
parent
86d3b25aec
commit
b6004b6837
@ -264,7 +264,7 @@ AudioOutput::WaitForDelay()
|
|||||||
bool
|
bool
|
||||||
AudioOutput::FillSourceOrClose()
|
AudioOutput::FillSourceOrClose()
|
||||||
try {
|
try {
|
||||||
return source.Fill();
|
return source.Fill(mutex);
|
||||||
} catch (const std::runtime_error &e) {
|
} catch (const std::runtime_error &e) {
|
||||||
FormatError(e, "Failed to filter for output \"%s\" [%s]",
|
FormatError(e, "Failed to filter for output \"%s\" [%s]",
|
||||||
name, plugin.name);
|
name, plugin.name);
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "filter/FilterInternal.hxx"
|
#include "filter/FilterInternal.hxx"
|
||||||
#include "filter/plugins/ReplayGainFilterPlugin.hxx"
|
#include "filter/plugins/ReplayGainFilterPlugin.hxx"
|
||||||
#include "pcm/PcmMix.hxx"
|
#include "pcm/PcmMix.hxx"
|
||||||
|
#include "thread/Mutex.hxx"
|
||||||
#include "util/ConstBuffer.hxx"
|
#include "util/ConstBuffer.hxx"
|
||||||
#include "util/RuntimeError.hxx"
|
#include "util/RuntimeError.hxx"
|
||||||
|
|
||||||
@ -187,7 +188,7 @@ AudioOutputSource::FilterChunk(const MusicChunk &chunk)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
AudioOutputSource::Fill()
|
AudioOutputSource::Fill(Mutex &mutex)
|
||||||
{
|
{
|
||||||
if (current_chunk != nullptr && pending_tag == nullptr &&
|
if (current_chunk != nullptr && pending_tag == nullptr &&
|
||||||
pending_data.IsEmpty())
|
pending_data.IsEmpty())
|
||||||
@ -203,6 +204,10 @@ AudioOutputSource::Fill()
|
|||||||
pending_tag = current_chunk->tag;
|
pending_tag = current_chunk->tag;
|
||||||
|
|
||||||
try {
|
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));
|
pending_data = pending_data.FromVoid(FilterChunk(*current_chunk));
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
current_chunk = nullptr;
|
current_chunk = nullptr;
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
|
|
||||||
struct MusicChunk;
|
struct MusicChunk;
|
||||||
struct Tag;
|
struct Tag;
|
||||||
|
class Mutex;
|
||||||
class Filter;
|
class Filter;
|
||||||
class PreparedFilter;
|
class PreparedFilter;
|
||||||
|
|
||||||
@ -147,10 +148,13 @@ public:
|
|||||||
*
|
*
|
||||||
* Throws std::runtime_error on error
|
* 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
|
* @return true if any input is available, false if the source
|
||||||
* has (temporarily?) run empty
|
* has (temporarily?) run empty
|
||||||
*/
|
*/
|
||||||
bool Fill();
|
bool Fill(Mutex &mutex);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads the #Tag to be processed. Be sure to call Fill()
|
* Reads the #Tag to be processed. Be sure to call Fill()
|
||||||
|
Loading…
Reference in New Issue
Block a user