<div dir="ltr">Thank, you !!<div><br></div><div>I will try it as soon as possible (v3.99, then I will update it.)</div><div><br></div><div>Thank you again.</div><div><br></div><div>HY</div></div><div class="gmail_extra"><br><div class="gmail_quote">2014-10-02 15:58 GMT+02:00 David Henningsson <span dir="ltr"><<a href="mailto:david.henningsson@canonical.com" target="_blank">david.henningsson@canonical.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">The drain speed increase done a while ago, only worked when directly connected<br>
to ALSA sinks. Playing through an module-virtual-sink would cause slower drains.<br>
<br>
This fix has two parts:<br>
 1) We now refuse to process handed out silence. This has the effect<br>
    that it tells ALSAs sink input that we're draining, and that we want to<br>
    be woken up exactly at this sample based point in time.<br>
 2) When we're being called to process input underruns, we know this has<br>
    happened, so we can just forward the call up the sink chain to get<br>
    to protocol-native, which can acknowledge that the drain has completed.<br>
<br>
This fix is incomplete, because if more than one sink input is playing back<br>
into the sink, only the last one will be drained in time. But it's better<br>
than nothing.<br>
<br>
Signed-off-by: David Henningsson <<a href="mailto:david.henningsson@canonical.com">david.henningsson@canonical.com</a>><br>
---<br>
<br>
Happy for testing of this patch - Ubuntu runs HDA-intel with 64K buffers instead of the 2M that<br>
some distros use, so I'm not seeing that much difference that you do anyway.<br>
<br>
Also, when I was testing, I also noticed a bigger startup latency when playing<br>
back through a virtual sink. This is nothing I have looked deeper at.<br>
<br>
 src/modules/module-virtual-sink.c | 22 ++++++++++++++++++++++<br>
 1 file changed, 22 insertions(+)<br>
<br>
diff --git a/src/modules/module-virtual-sink.c b/src/modules/module-virtual-sink.c<br>
index 66fd8a9..c1e5969 100644<br>
--- a/src/modules/module-virtual-sink.c<br>
+++ b/src/modules/module-virtual-sink.c<br>
@@ -216,6 +216,10 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk<br>
         pa_memchunk nchunk;<br>
<br>
         pa_sink_render(u->sink, nbytes, &nchunk);<br>
+        if (nchunk.memblock == u->sink->silence.memblock) {<br>
+            pa_memblock_unref(nchunk.memblock);<br>
+            return -1;<br>
+        }<br>
         pa_memblockq_push(u->memblockq, &nchunk);<br>
         pa_memblock_unref(nchunk.memblock);<br>
     }<br>
@@ -265,6 +269,23 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk<br>
     return 0;<br>
 }<br>
<br>
+/* Called from thread context */<br>
+<br>
+static bool sink_input_process_underrun_cb(pa_sink_input *i) {<br>
+    struct userdata *u;<br>
+<br>
+    pa_sink_input_assert_ref(i);<br>
+    pa_assert_se(u = i->userdata);<br>
+<br>
+    if (!PA_SINK_IS_LINKED(u->sink->thread_info.state) ||<br>
+        !PA_SINK_INPUT_IS_LINKED(u->sink_input->thread_info.state))<br>
+        return false;<br>
+<br>
+    pa_log_debug("sink_input_process_underrun_cb for virtual sink");<br>
+    return pa_sink_process_input_underruns(u->sink, 0);<br>
+}<br>
+<br>
+<br>
 /* Called from I/O thread context */<br>
 static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes) {<br>
     struct userdata *u;<br>
@@ -586,6 +607,7 @@ int pa__init(pa_module*m) {<br>
         goto fail;<br>
<br>
     u->sink_input->pop = sink_input_pop_cb;<br>
+    u->sink_input->process_underrun = sink_input_process_underrun_cb;<br>
     u->sink_input->process_rewind = sink_input_process_rewind_cb;<br>
     u->sink_input->update_max_rewind = sink_input_update_max_rewind_cb;<br>
     u->sink_input->update_max_request = sink_input_update_max_request_cb;<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.9.1<br>
<br>
</font></span></blockquote></div><br></div>