diff options
author | Max Kellermann <max@duempel.org> | 2009-11-09 22:16:26 +0100 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2009-11-09 22:16:26 +0100 |
commit | 3359f8785ef9b595b3ad943fdd2227f98ce56990 (patch) | |
tree | 248b51245d424b4700fffffb2eb8efd89f1ed6a0 | |
parent | 96b974bc452e6b33ada281c5ccb4df7b9492e1da (diff) | |
download | mpd-3359f8785ef9b595b3ad943fdd2227f98ce56990.tar.gz mpd-3359f8785ef9b595b3ad943fdd2227f98ce56990.tar.xz mpd-3359f8785ef9b595b3ad943fdd2227f98ce56990.zip |
output_thread: added command DRAIN
This command manually drains the hardware buffer. This is useful when
the player thread want to make sure that everything has been played.
-rw-r--r-- | src/output_all.c | 9 | ||||
-rw-r--r-- | src/output_all.h | 6 | ||||
-rw-r--r-- | src/output_control.c | 9 | ||||
-rw-r--r-- | src/output_control.h | 3 | ||||
-rw-r--r-- | src/output_internal.h | 7 | ||||
-rw-r--r-- | src/output_thread.c | 13 |
6 files changed, 47 insertions, 0 deletions
diff --git a/src/output_all.c b/src/output_all.c index 5b7cc4908..29590abf0 100644 --- a/src/output_all.c +++ b/src/output_all.c @@ -496,6 +496,15 @@ audio_output_all_pause(void) } void +audio_output_all_drain(void) +{ + for (unsigned i = 0; i < num_audio_outputs; ++i) + audio_output_drain_async(&audio_outputs[i]); + + audio_output_wait_all(); +} + +void audio_output_all_cancel(void) { unsigned int i; diff --git a/src/output_all.h b/src/output_all.h index 91b6f3f5d..6ff45fb79 100644 --- a/src/output_all.h +++ b/src/output_all.h @@ -130,6 +130,12 @@ void audio_output_all_pause(void); /** + * Drain all audio outputs. + */ +void +audio_output_all_drain(void); + +/** * Try to cancel data which may still be in the device's buffers. */ void diff --git a/src/output_control.c b/src/output_control.c index 842b89030..795d04a8c 100644 --- a/src/output_control.c +++ b/src/output_control.c @@ -229,6 +229,15 @@ void audio_output_pause(struct audio_output *ao) g_mutex_unlock(ao->mutex); } +void +audio_output_drain_async(struct audio_output *ao) +{ + g_mutex_lock(ao->mutex); + if (audio_output_is_open(ao)) + ao_command_async(ao, AO_COMMAND_DRAIN); + g_mutex_unlock(ao->mutex); +} + void audio_output_cancel(struct audio_output *ao) { g_mutex_lock(ao->mutex); diff --git a/src/output_control.h b/src/output_control.h index b2e48fa8d..692c11676 100644 --- a/src/output_control.h +++ b/src/output_control.h @@ -67,6 +67,9 @@ audio_output_play(struct audio_output *ao); void audio_output_pause(struct audio_output *ao); +void +audio_output_drain_async(struct audio_output *ao); + void audio_output_cancel(struct audio_output *ao); void audio_output_close(struct audio_output *ao); void audio_output_finish(struct audio_output *ao); diff --git a/src/output_internal.h b/src/output_internal.h index 6b81bbc78..de1b15c29 100644 --- a/src/output_internal.h +++ b/src/output_internal.h @@ -40,6 +40,13 @@ enum audio_output_command { AO_COMMAND_CLOSE, AO_COMMAND_PAUSE, + + /** + * Drains the internal (hardware) buffers of the device. This + * operation may take a while to complete. + */ + AO_COMMAND_DRAIN, + AO_COMMAND_CANCEL, AO_COMMAND_KILL }; diff --git a/src/output_thread.c b/src/output_thread.c index 40906d82f..fb1701591 100644 --- a/src/output_thread.c +++ b/src/output_thread.c @@ -450,6 +450,19 @@ static gpointer audio_output_task(gpointer arg) the new command first */ continue; + case AO_COMMAND_DRAIN: + if (ao->open) { + assert(ao->chunk == NULL); + assert(music_pipe_peek(ao->pipe) == NULL); + + g_mutex_unlock(ao->mutex); + ao_plugin_drain(ao->plugin, ao->data); + g_mutex_lock(ao->mutex); + } + + ao_command_finished(ao); + continue; + case AO_COMMAND_CANCEL: ao->chunk = NULL; if (ao->open) |