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