[pulseaudio-discuss] sink-input's membockq's read-index rewound to a huge negative causing silence delay, almost 2~3 seconds

xing wang wangxingchao2011 at gmail.com
Thu Jun 9 07:19:33 PDT 2011


Hi all,

I wrote a patch to drop the silence data in such situation. There're
two cases need consider: 1) when read_index/write_index both negative
and the gap is quite huge, this take some time to consume the silence
before real audio data comes. the patch reduces the silence length to
make it near the 0. this is my current case. while droping the
silence, keep write_index updated, otherwise there's underrun.
2) if write_index is positive and read-index is negative, only update
the read_index is enough.
i am afraid this case may also be reproduced. After the first
rewinding of latency change, the read_index is a huge negative value
while the write_index is 0, in such situation, the new request data
will cause long time silence.

I'm not quite familiar with pulseaudio and please help share your
better ideas. Any comments are appreciated! :-)

thanks
--xingchao

diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c
index e0a195e..53bd615 100644
--- a/src/pulsecore/protocol-native.c
+++ b/src/pulsecore/protocol-native.c
@@ -1506,6 +1506,7 @@ static int sink_input_process_msg(pa_msgobject
*o, int code, void *userdata, int
 /* Called from thread context */
 static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes,
pa_memchunk *chunk) {
     playback_stream *s;
+    size_t r_offset, w_offset;

     pa_sink_input_assert_ref(i);
     s = PLAYBACK_STREAM(i->userdata);
@@ -1514,9 +1515,24 @@ static int sink_input_pop_cb(pa_sink_input *i,
size_t nbytes, pa_memchunk *chunk

 /*     pa_log("%s, pop(): %lu", pa_proplist_gets(i->proplist,
PA_PROP_MEDIA_NAME), (unsigned long)
pa_memblockq_get_length(s->memblockq)); */

-    if (pa_memblockq_is_readable(s->memblockq))
+    if (pa_memblockq_is_readable(s->memblockq)) {
         s->is_underrun = FALSE;
-    else {
+
+        /* If read_index is huge negative, there's piece of silence
as bad feeling.
+	 * Check if read_index/write_index is negative, first drop the data
to make sure
+          read_index move forward, also seek ahead to keep the
memblockq's length.*/
+	if (s->memblockq->read_index < 0) {
+	    if (s->memblockq->write_index < 0) {
+		    r_offset = w_offset = -(s->memblockq->write_index)
+	    } else {
+		    r_offset = -(s->memblockq->read_index);
+		    w_offset = 0;
+	    }
+	    pa_memblockq_drop(s->memblockq, r_offset);
+	    if (!w_offset)
+		    pa_memblockq_seek(s->memblockq, w_offset, PA_SEEK_RELATIVE, TRUE);
+	}
+    } else {
         if (!s->is_underrun)
             pa_log_debug("Underrun on '%s', %lu bytes in queue.",
pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_MEDIA_NAME)),
(unsigned long) pa_memblockq_get_length(s->memblockq));


2011/6/9 xing wang <wangxingchao2011 at gmail.com>:
> hi all,
>
> i've a finding about silence delay, the background is looking like
> this post : "[pulseaudio-discuss] [PATCH] core: Drop empty gaps in the
> memblockq when playing data from it."
> (http://www.mail-archive.com/pulseaudio-discuss@mail.0pointer.de/msg09579.html)
>
> with tsched=1 and using default 2s buffer size,,while alsa-driver
> provides a even bigger buffer(5s),after the first rewind of "latency
> change" before starting playback, the buffer had been shrinked to a
> smaller value according to app's request, this trigger sink-input's
> rewinding , read-index become a negative value,,nearly -buffer_size.
>
> in pa_sink_input_cb() , pa_memblockq_peek() will return silence before
> the readindex reach 0 from the negative value. that caused obvious
> delay.
>
> i had one idea to disable alsa-sink's first rewind request of "latency
> change" , to avoid  sink-input's read-index moved back, but seems
> still delay...so a bit confused.
>
> Thanks
> --xingchao
>


More information about the pulseaudio-discuss mailing list