[pulseaudio-commits] 2 commits - src/pulse src/utils

Tanu Kaskinen tanuk at kemper.freedesktop.org
Thu Nov 24 18:42:27 UTC 2016


 src/pulse/stream.c |    7 ++++++-
 src/utils/pacat.c  |    9 +++++----
 2 files changed, 11 insertions(+), 5 deletions(-)

New commits:
commit 058f223a99acc1e7f74ff190f43ef6ad4f4a8134
Author: Ahmed S. Darwish <darwish.07 at gmail.com>
Date:   Tue Nov 22 22:18:56 2016 +0200

    stream: Frame-align divided audio segments
    
    Executing below command will not produce any audio:
    
      pacat  --channels=3 /dev/urandom
    
    Turns out that pa_stream_write() breaks large audio buffers into
    segments of the maximum memblock size available -- a value which
    is not necessarily frame aligned.
    
    Meanwhile the server discards any non-aligned client audio, as a
    security measure, due to some earlier reported daemon crashes.
    Thus divide sent audio to the expected aligned form.
    
    CommitReference-1: 22827a5e1e62
    CommitReference-2: 150ace90f380
    BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=98475
    BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=77595
    Signed-off-by: Ahmed S. Darwish <darwish.07 at gmail.com>

diff --git a/src/pulse/stream.c b/src/pulse/stream.c
index e10ab12..ee95757 100644
--- a/src/pulse/stream.c
+++ b/src/pulse/stream.c
@@ -33,6 +33,7 @@
 #include <pulse/fork-detect.h>
 
 #include <pulsecore/pstream-util.h>
+#include <pulsecore/sample-util.h>
 #include <pulsecore/log.h>
 #include <pulsecore/hashmap.h>
 #include <pulsecore/macro.h>
@@ -1532,8 +1533,12 @@ int pa_stream_write_ext_free(
                 chunk.length = t_length;
             } else {
                 void *d;
+                size_t blk_size_max;
 
-                chunk.length = PA_MIN(t_length, pa_mempool_block_size_max(s->context->mempool));
+                /* Break large audio streams into _aligned_ blocks or the
+                 * other endpoint will happily discard them upon arrival. */
+                blk_size_max = pa_frame_align(pa_mempool_block_size_max(s->context->mempool), &s->sample_spec);
+                chunk.length = PA_MIN(t_length, blk_size_max);
                 chunk.memblock = pa_memblock_new(s->context->mempool, chunk.length);
 
                 d = pa_memblock_acquire(chunk.memblock);

commit f5315113a5932a44b219c872fec589ded9d3e991
Author: Ahmed S. Darwish <darwish.07 at gmail.com>
Date:   Tue Nov 22 22:16:10 2016 +0200

    pacat: Synchronize STDIN and "write stream ready" events
    
    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>

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) {



More information about the pulseaudio-commits mailing list