[pulseaudio-discuss] [PATCH] sink: Make early drain reporting propagate down to filters

arun at accosted.net arun at accosted.net
Mon Nov 16 23:13:16 PST 2015


From: Arun Raghavan <git at arunraghavan.net>

The drain reporting improvements that were added to alsa-sink were only
being applied to directly connected sink inputs. This patch makes the
same logic also recurse down the filter hierarchy, so drains are
acknowledged more accurately (and not late) even if there is a filter
sink in between.

Also does some minor reorganisation of the code and sprinkles in some
comments as documentation.
---
 src/pulsecore/sink.c | 38 +++++++++++++++++++++++++++++++-------
 1 file changed, 31 insertions(+), 7 deletions(-)

diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
index 9ddb527..0b44fc7 100644
--- a/src/pulsecore/sink.c
+++ b/src/pulsecore/sink.c
@@ -950,18 +950,42 @@ size_t pa_sink_process_input_underruns(pa_sink *s, size_t left_to_play) {
 
     PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state) {
         size_t uf = i->thread_info.underrun_for_sink;
-        if (uf == 0)
-            continue;
-        if (uf >= left_to_play) {
-            if (pa_sink_input_process_underrun(i))
-                continue;
+
+        /* Propagate down the filter tree */
+        if (i->origin_sink) {
+            size_t filter_result, left_to_play_origin;
+
+            /* The recursive call works in the origin sink domain ... */
+            left_to_play_origin = pa_convert_size(left_to_play, &i->sink->sample_spec, &i->origin_sink->sample_spec);
+
+            /* .. and returns the time to sleep before waking up. We need the
+             * underrun duration for comparisons, so we undo the subtraction on
+             * the return value... */
+            filter_result = left_to_play_origin - pa_sink_process_input_underruns(i->origin_sink, left_to_play_origin);
+
+            /* ... and convert it back to the master sink domain */
+            filter_result = pa_convert_size(filter_result, &i->origin_sink->sample_spec, &i->sink->sample_spec);
+
+            /* Remember the longest underrun so far */
+            if (filter_result > result)
+                result = filter_result;
         }
-        else if (uf > result)
+
+        if (uf == 0) {
+            /* No underrun here, move on */
+            continue;
+        } else if (uf >= left_to_play) {
+            /* The sink has possibly consumed all the data the sink input provided */
+            pa_sink_input_process_underrun(i);
+        } else if (uf > result) {
+            /* Remember the longest underrun so far */
             result = uf;
+        }
     }
 
     if (result > 0)
-        pa_log_debug("Found underrun %ld bytes ago (%ld bytes ahead in playback buffer)", (long) result, (long) left_to_play - result);
+        pa_log_debug("%s: Found underrun %ld bytes ago (%ld bytes ahead in playback buffer)", s->name,
+                (long) result, (long) left_to_play - result);
     return left_to_play - result;
 }
 
-- 
2.5.0



More information about the pulseaudio-discuss mailing list