If the amount of data in the implementor buffer is very tiny,
i e even less than what we will likely be asked for, don't ask
for a rewind as that would lead to another underrun.

--
David Henningsson, Canonical Ltd.
http://launchpad.net/~diwic
>From 3c0bf348c3395b3cff0d77fd52a2e1e725c6e4cd Mon Sep 17 00:00:00 2001
From: David Henningsson <[email protected]>
Date: Thu, 9 Dec 2010 14:25:58 +0100
Subject: [PATCH 3/3] Fighting rewinds: Make sure there is some headroom after an underrun

If the amount of data in the implementor buffer is very tiny,
i e even less than what we will likely be asked for, don't ask
for a rewind as that would lead to another underrun.

Signed-off-by: David Henningsson <[email protected]>
---
 src/pulsecore/protocol-native.c |   15 +++++++++++++--
 1 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c
index 5dab80e..378a401 100644
--- a/src/pulsecore/protocol-native.c
+++ b/src/pulsecore/protocol-native.c
@@ -1321,9 +1321,18 @@ static void handle_seek(playback_stream *s, int64_t indexw) {
 /*         pa_log("%lu vs. %lu", (unsigned long) pa_memblockq_get_length(s->memblockq), (unsigned long) pa_memblockq_get_prebuf(s->memblockq)); */
 
         if (pa_memblockq_is_readable(s->memblockq)) {
+            if (s->sink_input->sink) {
+                pa_usec_t usec = pa_sink_get_latency_within_thread(s->sink_input->sink);
+                int latency = pa_usec_to_bytes(usec, &s->sink_input->sample_spec);
+                if (latency > pa_memblockq_get_length(s->memblockq)) {
+                    pa_log_debug("Skipping rewind, need at least %d bytes.", latency);
+                    playback_stream_request_bytes(s);
+                    return;
+                }
+            }
 
-            /* We just ended an underrun, let's ask the sink
-             * for a complete rewind rewrite */
+            /* We ended an underrun and got some head start,
+             * let's ask the sink for a complete rewind rewrite */
 
             pa_log_debug("Requesting rewind due to end of underrun.");
             pa_sink_input_request_rewind(s->sink_input,
@@ -1524,6 +1533,8 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk
         s->is_underrun = TRUE;
 
         playback_stream_request_bytes(s);
+        /* Don't return a block here - it confuses the underrun handling in sink-input later */
+        return -1;
     }
 
     /* This call will not fail with prebuf=0, hence we check for
-- 
1.7.1

_______________________________________________
pulseaudio-discuss mailing list
[email protected]
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss

Reply via email to