summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2010-02-18 01:54:51 +0100
committerWim Taymans <wtaymans@redhat.com>2014-04-02 14:37:27 +0200
commit1d60f019050e543a8aefb6a0cdfc7736157922cd (patch)
tree4a8fccbb63df94cfbfbdf37ce0b296ba2ebeaef9
parent4c6faa438e919cc0d556b3e16d83ad8a9792c880 (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.c47
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;
+ }
}
}