OutputControl: reduce the number of OutputThread wakeups

Wake up the OutputThread only if it hasn't already been woken up and
if it isn't already in the playback loop.
This commit is contained in:
Max Kellermann 2013-11-06 23:47:30 +01:00
parent 77c63511d8
commit f8f95e2dbd
4 changed files with 30 additions and 2 deletions

View File

@ -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)

View File

@ -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 */

View File

@ -127,6 +127,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

View File

@ -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);
}
}
}