diff options
author | Max Kellermann <max@duempel.org> | 2009-03-09 19:25:26 +0100 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2009-03-09 19:25:26 +0100 |
commit | 3291666b570b1d20f59db42936eaa37dbeb9ca65 (patch) | |
tree | c3905d60131c9f440d8ca7d7d1ec45cecce02d85 /src/output_control.c | |
parent | ab3d7c29dae44f39df28c85e26b108c44fdbc4bf (diff) | |
download | mpd-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.c | 36 |
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); } |