aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/OutputControl.cxx5
-rw-r--r--src/OutputInit.cxx2
-rw-r--r--src/OutputInternal.hxx15
-rw-r--r--src/OutputThread.cxx10
4 files changed, 30 insertions, 2 deletions
diff --git a/src/OutputControl.cxx b/src/OutputControl.cxx
index 648705908..553507a2a 100644
--- a/src/OutputControl.cxx
+++ b/src/OutputControl.cxx
@@ -248,8 +248,11 @@ audio_output_play(struct audio_output *ao)
assert(ao->allow_play);
- if (audio_output_is_open(ao))
+ if (audio_output_is_open(ao) && !ao->in_playback_loop &&
+ !ao->woken_for_play) {
+ ao->woken_for_play = true;
ao->cond.signal();
+ }
}
void audio_output_pause(struct audio_output *ao)
diff --git a/src/OutputInit.cxx b/src/OutputInit.cxx
index 49b5d68b9..28eba1ab2 100644
--- a/src/OutputInit.cxx
+++ b/src/OutputInit.cxx
@@ -171,6 +171,8 @@ ao_base_init(struct audio_output *ao,
ao->open = false;
ao->pause = false;
ao->allow_play = true;
+ ao->in_playback_loop = false;
+ ao->woken_for_play = false;
ao->fail_timer = nullptr;
/* set up the filter chain */
diff --git a/src/OutputInternal.hxx b/src/OutputInternal.hxx
index 2b3136f94..c07cdf856 100644
--- a/src/OutputInternal.hxx
+++ b/src/OutputInternal.hxx
@@ -128,6 +128,21 @@ struct audio_output {
bool allow_play;
/**
+ * True while the OutputThread is inside ao_play(). This
+ * means the PlayerThread does not need to wake up the
+ * OutputThread when new chunks are added to the MusicPipe,
+ * because the OutputThread is already watching that.
+ */
+ bool in_playback_loop;
+
+ /**
+ * Has the OutputThread been woken up to play more chunks?
+ * This is set by audio_output_play() and reset by ao_play()
+ * to reduce the number of duplicate wakeups.
+ */
+ bool woken_for_play;
+
+ /**
* If not nullptr, the device has failed, and this timer is used
* to estimate how long it should stay disabled (unless
* explicitly reopened with "play").
diff --git a/src/OutputThread.cxx b/src/OutputThread.cxx
index c6f2e4d30..30d3ba30f 100644
--- a/src/OutputThread.cxx
+++ b/src/OutputThread.cxx
@@ -510,6 +510,9 @@ ao_play(struct audio_output *ao)
ao->chunk_finished = false;
+ assert(!ao->in_playback_loop);
+ ao->in_playback_loop = true;
+
while (chunk != nullptr && ao->command == AO_COMMAND_NONE) {
assert(!ao->chunk_finished);
@@ -525,6 +528,9 @@ ao_play(struct audio_output *ao)
chunk = chunk->next;
}
+ assert(ao->in_playback_loop);
+ ao->in_playback_loop = false;
+
ao->chunk_finished = true;
ao->mutex.unlock();
@@ -656,8 +662,10 @@ audio_output_task(void *arg)
chunks in the pipe */
continue;
- if (ao->command == AO_COMMAND_NONE)
+ if (ao->command == AO_COMMAND_NONE) {
+ ao->woken_for_play = false;
ao->cond.wait(ao->mutex);
+ }
}
}