This patch flushes the buffer when the sink input is detached
and discards data after attaching a sink input until the pop callback
is called for the first time, thus eliminating latency arising from
slow starting sinks and from streaming to the previous sink.

----

 src/modules/module-loopback.c                             | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

----

diff --git a/src/modules/module-loopback.c b/src/modules/module-loopback.c
index da83894..22eadfc 100644
--- a/src/modules/module-loopback.c
+++ b/src/modules/module-loopback.c
@@ -87,6 +87,7 @@ struct userdata {
     pa_usec_t latency;

     bool in_pop;
+    bool pop_called;
     size_t min_memblockq_length;

     struct {
@@ -464,6 +465,8 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk
     pa_assert_se(u = i->userdata);
     pa_assert(chunk);

+ if (PA_SINK_IS_RUNNING(u->sink_input->sink->thread_info.state) && !u->pop_called)
+        u->pop_called = true;
     u->in_pop = true;
     while (pa_asyncmsgq_process_one(u->asyncmsgq) > 0)
         ;
@@ -515,7 +518,7 @@ static int sink_input_process_msg_cb(pa_msgobject *obj, int code, void *data, in

             pa_sink_input_assert_io_context(u->sink_input);

-            if (PA_SINK_IS_OPENED(u->sink_input->sink->thread_info.state))
+ if (PA_SINK_IS_RUNNING(u->sink_input->sink->thread_info.state) && u->pop_called)
                 pa_memblockq_push_align(u->memblockq, chunk);
             else
                 pa_memblockq_flush_write(u->memblockq, true);
@@ -542,7 +545,7 @@ static int sink_input_process_msg_cb(pa_msgobject *obj, int code, void *data, in

             pa_sink_input_assert_io_context(u->sink_input);

-            if (PA_SINK_IS_OPENED(u->sink_input->sink->thread_info.state))
+ if (PA_SINK_IS_RUNNING(u->sink_input->sink->thread_info.state) && u->pop_called) pa_memblockq_seek(u->memblockq, -offset, PA_SEEK_RELATIVE, true);
             else
                 pa_memblockq_flush_write(u->memblockq, true);
@@ -607,6 +610,7 @@ static void sink_input_attach_cb(pa_sink_input *i) {
pa_memblockq_set_maxrewind(u->memblockq, pa_sink_input_get_max_rewind(i));

     u->min_memblockq_length = (size_t) -1;
+    u->pop_called = false;
 }

 /* Called from output thread context */
@@ -621,6 +625,8 @@ static void sink_input_detach_cb(pa_sink_input *i) {
         pa_rtpoll_item_free(u->rtpoll_item_read);
         u->rtpoll_item_read = NULL;
     }
+    pa_memblockq_flush_write(u->memblockq, true);
+    update_min_memblockq_length(u);
 }

 /* Called from output thread context */
@@ -820,6 +826,7 @@ int pa__init(pa_module *m) {
     u->core = m->core;
     u->module = m;
     u->latency = (pa_usec_t) latency_msec * PA_USEC_PER_MSEC;
+    u->pop_called = false;

     adjust_time_sec = DEFAULT_ADJUST_TIME_USEC / PA_USEC_PER_SEC;
if (pa_modargs_get_value_u32(ma, "adjust_time", &adjust_time_sec) < 0) {

_______________________________________________
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Reply via email to