[pulseaudio-discuss] [PATCH 1/2] pacat: Synchronize STDIN and "write stream ready" events
Ahmed S. Darwish
darwish.07 at gmail.com
Tue Nov 22 20:16:10 UTC 2016
Users reported pacat crashes when playing certain multi-channel
audio. For example:
pacat --channels=2 /dev/zero works
pacat --channels=3 /dev/zero pa_stream_write() failed: EINVAL
pacat --channels=4 /dev/zero works
pacat --channels=5 /dev/zero pa_stream_write() failed: EINVAL
pacat audio playback is pipe-like, from STDIN to PA write stream.
Meanwhile STDIN "ready to read" events got regularly triggered
before the write stream was even created, or at moments where the
stream could not accept any more audio.
In these out-of-sync cases, the write stream could not report the
appropriate buffer lengths it accepts, thus a default of 4K bytes
was chosen -- compatible by luck with some channel counts and
incompatible with others.
Instead of choosing a faulty default in these scenarios, mute the
the STDIN events until the write stream is available & queriable.
BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=98475
Reported-by: Tanu Kaskinen <tanuk at iki.fi>
Signed-off-by: Ahmed S. Darwish <darwish.07 at gmail.com>
---
src/utils/pacat.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/src/utils/pacat.c b/src/utils/pacat.c
index 2ded613..68362ec 100644
--- a/src/utils/pacat.c
+++ b/src/utils/pacat.c
@@ -542,19 +542,20 @@ fail:
static void stdin_callback(pa_mainloop_api*a, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata) {
size_t l, w = 0;
ssize_t r;
+ bool stream_not_ready;
pa_assert(a == mainloop_api);
pa_assert(e);
pa_assert(stdio_event == e);
- if (buffer) {
+ stream_not_ready = !stream || pa_stream_get_state(stream) != PA_STREAM_READY ||
+ !(l = w = pa_stream_writable_size(stream));
+
+ if (buffer || stream_not_ready) {
mainloop_api->io_enable(stdio_event, PA_IO_EVENT_NULL);
return;
}
- if (!stream || pa_stream_get_state(stream) != PA_STREAM_READY || !(l = w = pa_stream_writable_size(stream)))
- l = 4096;
-
buffer = pa_xmalloc(l);
if ((r = pa_read(fd, buffer, l, userdata)) <= 0) {
--
Darwish
http://darwish.chasingpointers.com
More information about the pulseaudio-discuss
mailing list