diff options
author | Lennart Poettering <lennart@poettering.net> | 2010-02-18 01:54:51 +0100 |
---|---|---|
committer | Wim Taymans <wtaymans@redhat.com> | 2014-04-02 14:37:27 +0200 |
commit | 1d60f019050e543a8aefb6a0cdfc7736157922cd (patch) | |
tree | 4a8fccbb63df94cfbfbdf37ce0b296ba2ebeaef9 | |
parent | 4c6faa438e919cc0d556b3e16d83ad8a9792c880 (diff) |
pacat: always fully fulfill write requests
Make sure we always fulfill write requests from the server. If we don't
the server won't ask us again and playback will stay stuck.
https://tango.0pointer.de/pipermail/pulseaudio-discuss/2010-February/006611.html
-rw-r--r-- | src/utils/pacat.c | 47 |
1 files changed, 30 insertions, 17 deletions
diff --git a/src/utils/pacat.c b/src/utils/pacat.c index a5d2e9a68..d136f6b30 100644 --- a/src/utils/pacat.c +++ b/src/utils/pacat.c @@ -195,28 +195,41 @@ static void stream_write_callback(pa_stream *s, size_t length, void *userdata) { pa_assert(sndfile); - if (pa_stream_begin_write(s, &data, &length) < 0) { - pa_log(_("pa_stream_begin_write() failed: %s"), pa_strerror(pa_context_errno(context))); - quit(1); - return; - } + for (;;) { + size_t data_length = length; - if (readf_function) { - size_t k = pa_frame_size(&sample_spec); + if (pa_stream_begin_write(s, &data, &data_length) < 0) { + pa_log(_("pa_stream_begin_write() failed: %s"), pa_strerror(pa_context_errno(context))); + quit(1); + return; + } - if ((bytes = readf_function(sndfile, data, (sf_count_t) (length/k))) > 0) - bytes *= (sf_count_t) k; + if (readf_function) { + size_t k = pa_frame_size(&sample_spec); - } else - bytes = sf_read_raw(sndfile, data, (sf_count_t) length); + if ((bytes = readf_function(sndfile, data, (sf_count_t) (data_length/k))) > 0) + bytes *= (sf_count_t) k; - if (bytes > 0) - pa_stream_write(s, data, (size_t) bytes, NULL, 0, PA_SEEK_RELATIVE); - else - pa_stream_cancel_write(s); + } else + bytes = sf_read_raw(sndfile, data, (sf_count_t) data_length); - if (bytes < (sf_count_t) length) - start_drain(); + if (bytes > 0) + pa_stream_write(s, data, (size_t) bytes, NULL, 0, PA_SEEK_RELATIVE); + else + pa_stream_cancel_write(s); + + /* EOF? */ + if (bytes < (sf_count_t) data_length) { + start_drain(); + break; + } + + /* Request fulfilled */ + if ((size_t) bytes >= length) + break; + + length -= bytes; + } } } |