aboutsummaryrefslogtreecommitdiffstats
path: root/src/output_control.c
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2009-03-09 19:25:26 +0100
committerMax Kellermann <max@duempel.org>2009-03-09 19:25:26 +0100
commit3291666b570b1d20f59db42936eaa37dbeb9ca65 (patch)
treec3905d60131c9f440d8ca7d7d1ec45cecce02d85 /src/output_control.c
parentab3d7c29dae44f39df28c85e26b108c44fdbc4bf (diff)
downloadmpd-3291666b570b1d20f59db42936eaa37dbeb9ca65.tar.gz
mpd-3291666b570b1d20f59db42936eaa37dbeb9ca65.tar.xz
mpd-3291666b570b1d20f59db42936eaa37dbeb9ca65.zip
output: play from a music_pipe object
Instead of passing individual buffers to audio_output_all_play(), pass music_chunk objects. Append all those chunks asynchronously to a music_pipe instance. All output threads may then read chunks from this pipe. This reduces MPD's internal latency by an order of magnitude.
Diffstat (limited to '')
-rw-r--r--src/output_control.c36
1 files changed, 17 insertions, 19 deletions
diff --git a/src/output_control.c b/src/output_control.c
index 47bb844d5..85bbea329 100644
--- a/src/output_control.c
+++ b/src/output_control.c
@@ -57,8 +57,11 @@ static void ao_command_async(struct audio_output *ao,
static bool
audio_output_open(struct audio_output *ao,
- const struct audio_format *audio_format)
+ const struct audio_format *audio_format,
+ const struct music_pipe *mp)
{
+ assert(mp != NULL);
+
if (ao->fail_timer != NULL) {
g_timer_destroy(ao->fail_timer);
ao->fail_timer = NULL;
@@ -66,10 +69,13 @@ audio_output_open(struct audio_output *ao,
if (ao->open &&
audio_format_equals(audio_format, &ao->in_audio_format)) {
+ assert(ao->pipe == mp);
+
return true;
}
ao->in_audio_format = *audio_format;
+ ao->chunk = NULL;
if (audio_format_defined(&ao->config_audio_format)) {
/* copy config_audio_format to out_audio_format only if the
@@ -85,6 +91,8 @@ audio_output_open(struct audio_output *ao,
audio_output_close(ao);
}
+ ao->pipe = mp;
+
if (ao->thread == NULL)
audio_output_thread_start(ao);
@@ -96,12 +104,15 @@ audio_output_open(struct audio_output *ao,
bool
audio_output_update(struct audio_output *ao,
- const struct audio_format *audio_format)
+ const struct audio_format *audio_format,
+ const struct music_pipe *mp)
{
+ assert(mp != NULL);
+
if (ao->enabled) {
if (ao->fail_timer == NULL ||
g_timer_elapsed(ao->fail_timer, NULL) > REOPEN_AFTER)
- return audio_output_open(ao, audio_format);
+ return audio_output_open(ao, audio_format, mp);
} else if (audio_output_is_open(ao))
audio_output_close(ao);
@@ -115,16 +126,12 @@ audio_output_signal(struct audio_output *ao)
}
void
-audio_output_play(struct audio_output *ao, const void *chunk, size_t size)
+audio_output_play(struct audio_output *ao)
{
- assert(size > 0);
-
if (!ao->open)
return;
- ao->args.play.data = chunk;
- ao->args.play.size = size;
- ao_command_async(ao, AO_COMMAND_PLAY);
+ notify_signal(&ao->notify);
}
void audio_output_pause(struct audio_output *ao)
@@ -163,14 +170,5 @@ void audio_output_finish(struct audio_output *ao)
ao_plugin_finish(ao->plugin, ao->data);
notify_deinit(&ao->notify);
-}
-
-void
-audio_output_send_tag(struct audio_output *ao, const struct tag *tag)
-{
- if (ao->plugin->send_tag == NULL)
- return;
-
- ao->args.tag = tag;
- ao_command_async(ao, AO_COMMAND_SEND_TAG);
+ g_mutex_free(ao->mutex);
}