summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMax Kellermann <max@musicpd.org>2021-02-15 16:15:27 +0100
committerMax Kellermann <max@musicpd.org>2021-02-15 16:39:13 +0100
commitefde78db777c2d0f8f956196d8022777838ce9e1 (patch)
treed266e7b4878f3db19fb647943627d4488f1d71ce /src
parentf1b8bcd6b26ff40fc49dab1b46f4a85e58eafeab (diff)
output/Thread: skip drain calls if there is no data to be played
Keep track of whether there is data being played, and don't call AudioOutput::Drain() after Cancel() has been called already.
Diffstat (limited to 'src')
-rw-r--r--src/output/Control.hxx8
-rw-r--r--src/output/Thread.cxx14
2 files changed, 21 insertions, 1 deletions
diff --git a/src/output/Control.hxx b/src/output/Control.hxx
index ba61ced6e..734b29e67 100644
--- a/src/output/Control.hxx
+++ b/src/output/Control.hxx
@@ -182,6 +182,14 @@ class AudioOutputControl {
bool open = false;
/**
+ * Is the device currently playing, i.e. is its buffer
+ * (likely) non-empty? If not, then it will never be drained.
+ *
+ * This field is only valid while the output is open.
+ */
+ bool playing;
+
+ /**
* Is the device paused? i.e. the output thread is in the
* ao_pause() loop.
*/
diff --git a/src/output/Thread.cxx b/src/output/Thread.cxx
index 3da07c6b2..c0aed30b0 100644
--- a/src/output/Thread.cxx
+++ b/src/output/Thread.cxx
@@ -53,7 +53,7 @@ AudioOutputControl::InternalOpen2(const AudioFormat in_audio_format)
if (open && cf != output->filter_audio_format)
/* if the filter's output format changes, the output
must be reopened as well */
- InternalCloseOutput(true);
+ InternalCloseOutput(playing);
output->filter_audio_format = cf;
@@ -64,6 +64,7 @@ AudioOutputControl::InternalOpen2(const AudioFormat in_audio_format)
}
open = true;
+ playing = false;
} else if (in_audio_format != output->out_audio_format) {
/* reconfigure the final ConvertFilter for its new
input AudioFormat */
@@ -285,6 +286,9 @@ AudioOutputControl::PlayChunk(std::unique_lock<Mutex> &lock) noexcept
assert(nbytes % output->out_audio_format.GetFrameSize() == 0);
source.ConsumeData(nbytes);
+
+ /* there's data to be drained from now on */
+ playing = true;
}
return true;
@@ -371,6 +375,9 @@ AudioOutputControl::InternalPause(std::unique_lock<Mutex> &lock) noexcept
}
skip_delay = true;
+
+ /* ignore drain commands until we got something new to play */
+ playing = false;
}
static void
@@ -390,6 +397,10 @@ PlayFull(FilteredAudioOutput &output, ConstBuffer<void> _buffer)
inline void
AudioOutputControl::InternalDrain() noexcept
{
+ /* after this method finishes, there's nothing left to be
+ drained */
+ playing = false;
+
try {
/* flush the filter and play its remaining output */
@@ -518,6 +529,7 @@ AudioOutputControl::Task() noexcept
source.Cancel();
if (open) {
+ playing = false;
const ScopeUnlock unlock(mutex);
output->Cancel();
}