diff options
author | Max Kellermann <max@duempel.org> | 2009-02-23 09:29:56 +0100 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2009-02-23 09:29:56 +0100 |
commit | 5a898c15e79ab87d2466e61549fcc20ce115c67e (patch) | |
tree | cb65b88718b0b8f3cf05221816b193833c41fe8a /src/output_thread.c | |
parent | d50a3d513eb0452e762f1e4eeb717318958cd83c (diff) | |
download | mpd-5a898c15e79ab87d2466e61549fcc20ce115c67e.tar.gz mpd-5a898c15e79ab87d2466e61549fcc20ce115c67e.tar.xz mpd-5a898c15e79ab87d2466e61549fcc20ce115c67e.zip |
output_api: play() returns a length
The old API required an output plugin to not return until all data
passed to the play() method is consumed. Some output plugins have to
loop to fulfill that requirement, and may block during that. Simplify
these, by letting them consume only part of the buffer: make play()
return the length of the consumed data.
Diffstat (limited to '')
-rw-r--r-- | src/output_thread.c | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/src/output_thread.c b/src/output_thread.c index 098e1b427..709d8d1a2 100644 --- a/src/output_thread.c +++ b/src/output_thread.c @@ -52,9 +52,9 @@ static void ao_play(struct audio_output *ao) { const char *data = ao->args.play.data; size_t size = ao->args.play.size; - bool ret; assert(size > 0); + assert(size % audio_format_frame_size(&ao->out_audio_format) == 0); if (!audio_format_equals(&ao->in_audio_format, &ao->out_audio_format)) { data = pcm_convert(&ao->convert_state, @@ -69,10 +69,22 @@ static void ao_play(struct audio_output *ao) return; } - ret = ao_plugin_play(ao->plugin, ao->data, data, size); - if (!ret) { - ao_plugin_cancel(ao->plugin, ao->data); - ao_close(ao); + while (size > 0) { + size_t nbytes; + + nbytes = ao_plugin_play(ao->plugin, ao->data, data, size); + if (nbytes == 0) { + /* play()==0 means failure */ + ao_plugin_cancel(ao->plugin, ao->data); + ao_close(ao); + break; + } + + assert(nbytes <= size); + assert(nbytes % audio_format_frame_size(&ao->out_audio_format) == 0); + + data += nbytes; + size -= nbytes; } ao_command_finished(ao); |