[pulseaudio-discuss] [PATCH 1/3] sink, source: Propagate flag changes to filters

Tanu Kaskinen tanuk at iki.fi
Thu Mar 28 08:30:14 PDT 2013


An example: let's say that there's an alsa sink and two filter sinks
on top of each other:

        alsa-sink <- filter1 <- filter2

With the old code, if filter1 gets moved to another sink, and the
new sink doesn't have the LATENCY and DYNAMIC_LATENCY flags set
(unlike alsa-sink), filter1's flags are updated fine in the moving()
callback, but filter2 is not notified at all about the flag changes.
With this patch, the flag changes are propagated to filter2 too.
---
 src/pulsecore/sink.c   |   34 ++++++++++++++++++++++++++--------
 src/pulsecore/source.c |   23 ++++++++++++++++++++---
 2 files changed, 46 insertions(+), 11 deletions(-)

diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
index d2d6c97..2320359 100644
--- a/src/pulsecore/sink.c
+++ b/src/pulsecore/sink.c
@@ -761,22 +761,40 @@ void pa_sink_set_asyncmsgq(pa_sink *s, pa_asyncmsgq *q) {
 
 /* Called from main context, and not while the IO thread is active, please */
 void pa_sink_update_flags(pa_sink *s, pa_sink_flags_t mask, pa_sink_flags_t value) {
+    pa_sink_flags_t old_flags;
+    pa_sink_input *input;
+    uint32_t idx;
+
     pa_sink_assert_ref(s);
     pa_assert_ctl_context();
 
-    if (mask == 0)
-        return;
-
     /* For now, allow only a minimal set of flags to be changed. */
     pa_assert((mask & ~(PA_SINK_DYNAMIC_LATENCY|PA_SINK_LATENCY)) == 0);
 
+    old_flags = s->flags;
     s->flags = (s->flags & ~mask) | (value & mask);
 
-    pa_source_update_flags(s->monitor_source,
-                           ((mask & PA_SINK_LATENCY) ? PA_SOURCE_LATENCY : 0) |
-                           ((mask & PA_SINK_DYNAMIC_LATENCY) ? PA_SOURCE_DYNAMIC_LATENCY : 0),
-                           ((value & PA_SINK_LATENCY) ? PA_SOURCE_LATENCY : 0) |
-                           ((value & PA_SINK_DYNAMIC_LATENCY) ? PA_SOURCE_DYNAMIC_LATENCY : 0));
+    if (s->flags == old_flags)
+        return;
+
+    if ((s->flags & PA_SINK_LATENCY) != (old_flags & PA_SINK_LATENCY))
+        pa_log_debug("Sink %s: LATENCY flag %s.", s->name, (s->flags & PA_SINK_LATENCY) ? "enabled" : "disabled");
+
+    if ((s->flags & PA_SINK_DYNAMIC_LATENCY) != (old_flags & PA_SINK_DYNAMIC_LATENCY))
+        pa_log_debug("Sink %s: DYNAMIC_LATENCY flag %s.",
+                     s->name, (s->flags & PA_SINK_DYNAMIC_LATENCY) ? "enabled" : "disabled");
+
+    if (s->monitor_source)
+        pa_source_update_flags(s->monitor_source,
+                               ((mask & PA_SINK_LATENCY) ? PA_SOURCE_LATENCY : 0) |
+                               ((mask & PA_SINK_DYNAMIC_LATENCY) ? PA_SOURCE_DYNAMIC_LATENCY : 0),
+                               ((value & PA_SINK_LATENCY) ? PA_SOURCE_LATENCY : 0) |
+                               ((value & PA_SINK_DYNAMIC_LATENCY) ? PA_SOURCE_DYNAMIC_LATENCY : 0));
+
+    PA_IDXSET_FOREACH(input, s->inputs, idx) {
+        if (input->origin_sink)
+            pa_sink_update_flags(input->origin_sink, mask, value);
+    }
 }
 
 /* Called from IO context, or before _put() from main context */
diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c
index 4e4cd67..fb2e14b 100644
--- a/src/pulsecore/source.c
+++ b/src/pulsecore/source.c
@@ -687,16 +687,33 @@ void pa_source_set_asyncmsgq(pa_source *s, pa_asyncmsgq *q) {
 
 /* Called from main context, and not while the IO thread is active, please */
 void pa_source_update_flags(pa_source *s, pa_source_flags_t mask, pa_source_flags_t value) {
+    pa_source_flags_t old_flags;
+    pa_source_output *output;
+    uint32_t idx;
+
     pa_source_assert_ref(s);
     pa_assert_ctl_context();
 
-    if (mask == 0)
-        return;
-
     /* For now, allow only a minimal set of flags to be changed. */
     pa_assert((mask & ~(PA_SOURCE_DYNAMIC_LATENCY|PA_SOURCE_LATENCY)) == 0);
 
+    old_flags = s->flags;
     s->flags = (s->flags & ~mask) | (value & mask);
+
+    if (s->flags == old_flags)
+        return;
+
+    if ((s->flags & PA_SOURCE_LATENCY) != (old_flags & PA_SOURCE_LATENCY))
+        pa_log_debug("Source %s: LATENCY flag %s.", s->name, (s->flags & PA_SOURCE_LATENCY) ? "enabled" : "disabled");
+
+    if ((s->flags & PA_SOURCE_DYNAMIC_LATENCY) != (old_flags & PA_SOURCE_DYNAMIC_LATENCY))
+        pa_log_debug("Source %s: DYNAMIC_LATENCY flag %s.",
+                     s->name, (s->flags & PA_SOURCE_DYNAMIC_LATENCY) ? "enabled" : "disabled");
+
+    PA_IDXSET_FOREACH(output, s->outputs, idx) {
+        if (output->destination_source)
+            pa_source_update_flags(output->destination_source, mask, value);
+    }
 }
 
 /* Called from IO context, or before _put() from main context */
-- 
1.7.10.4



More information about the pulseaudio-discuss mailing list