[pulseaudio-discuss] [PATCH 1/3] Propagate the PA_{SINK, SOURCE}_LATENCY flag changes through a chain of filter sinks/sources.

Tanu Kaskinen tanu.kaskinen at jollamobile.com
Thu Sep 20 08:27:40 PDT 2012


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 flag set (unlike alsa-sink), the
LATENCY flag of filter1 is updated fine in the moving() callback, but
filter2 is not notified at all about the flag change. With this patch,
filter2 can unset its LATENCY flag as it should.
---
 src/modules/echo-cancel/module-echo-cancel.c |    8 ++++--
 src/modules/module-equalizer-sink.c          |    4 ++-
 src/modules/module-ladspa-sink.c             |    4 ++-
 src/modules/module-remap-sink.c              |    4 ++-
 src/modules/module-virtual-sink.c            |    4 ++-
 src/modules/module-virtual-source.c          |    4 ++-
 src/modules/module-virtual-surround-sink.c   |    4 ++-
 src/pulsecore/sink-input.c                   |   10 +++++++
 src/pulsecore/sink-input.h                   |   12 ++++++++
 src/pulsecore/sink.c                         |   40 ++++++++++++++++++++++----
 src/pulsecore/sink.h                         |    1 +
 src/pulsecore/source-output.c                |   10 +++++++
 src/pulsecore/source-output.h                |   14 ++++++++-
 src/pulsecore/source.c                       |   28 +++++++++++++++++-
 src/pulsecore/source.h                       |    1 +
 15 files changed, 132 insertions(+), 16 deletions(-)

diff --git a/src/modules/echo-cancel/module-echo-cancel.c b/src/modules/echo-cancel/module-echo-cancel.c
index 8a9823b..fbeac69 100644
--- a/src/modules/echo-cancel/module-echo-cancel.c
+++ b/src/modules/echo-cancel/module-echo-cancel.c
@@ -1452,7 +1452,8 @@ static void source_output_moving_cb(pa_source_output *o, pa_source *dest) {
 
     if (dest) {
         pa_source_set_asyncmsgq(u->source, dest->asyncmsgq);
-        pa_source_update_flags(u->source, PA_SOURCE_LATENCY|PA_SOURCE_DYNAMIC_LATENCY, dest->flags);
+        pa_source_set_latency_flag(u->source, dest->flags & PA_SOURCE_LATENCY);
+        pa_source_update_flags(u->source, PA_SOURCE_DYNAMIC_LATENCY, dest->flags);
     } else
         pa_source_set_asyncmsgq(u->source, NULL);
 
@@ -1480,7 +1481,8 @@ static void sink_input_moving_cb(pa_sink_input *i, pa_sink *dest) {
 
     if (dest) {
         pa_sink_set_asyncmsgq(u->sink, dest->asyncmsgq);
-        pa_sink_update_flags(u->sink, PA_SINK_LATENCY|PA_SINK_DYNAMIC_LATENCY, dest->flags);
+        pa_sink_set_latency_flag(u->sink, dest->flags & PA_SINK_LATENCY);
+        pa_sink_update_flags(u->sink, PA_SINK_DYNAMIC_LATENCY, dest->flags);
     } else
         pa_sink_set_asyncmsgq(u->sink, NULL);
 
@@ -1863,6 +1865,7 @@ int pa__init(pa_module*m) {
     u->source_output->update_source_requested_latency = source_output_update_source_requested_latency_cb;
     u->source_output->update_source_latency_range = source_output_update_source_latency_range_cb;
     u->source_output->update_source_fixed_latency = source_output_update_source_fixed_latency_cb;
+    u->source_output->update_source_latency_flag = pa_source_output_update_source_latency_flag_cb;
     u->source_output->kill = source_output_kill_cb;
     u->source_output->attach = source_output_attach_cb;
     u->source_output->detach = source_output_detach_cb;
@@ -1899,6 +1902,7 @@ int pa__init(pa_module*m) {
     u->sink_input->update_sink_requested_latency = sink_input_update_sink_requested_latency_cb;
     u->sink_input->update_sink_latency_range = sink_input_update_sink_latency_range_cb;
     u->sink_input->update_sink_fixed_latency = sink_input_update_sink_fixed_latency_cb;
+    u->sink_input->update_sink_latency_flag = pa_sink_input_update_sink_latency_flag_cb;
     u->sink_input->kill = sink_input_kill_cb;
     u->sink_input->attach = sink_input_attach_cb;
     u->sink_input->detach = sink_input_detach_cb;
diff --git a/src/modules/module-equalizer-sink.c b/src/modules/module-equalizer-sink.c
index 8b9075c..42334b3 100644
--- a/src/modules/module-equalizer-sink.c
+++ b/src/modules/module-equalizer-sink.c
@@ -1075,7 +1075,8 @@ static void sink_input_moving_cb(pa_sink_input *i, pa_sink *dest) {
 
     if (dest) {
         pa_sink_set_asyncmsgq(u->sink, dest->asyncmsgq);
-        pa_sink_update_flags(u->sink, PA_SINK_LATENCY|PA_SINK_DYNAMIC_LATENCY, dest->flags);
+        pa_sink_set_latency_flag(u->sink, dest->flags & PA_SINK_LATENCY);
+        pa_sink_update_flags(u->sink, PA_SINK_DYNAMIC_LATENCY, dest->flags);
     } else
         pa_sink_set_asyncmsgq(u->sink, NULL);
 }
@@ -1247,6 +1248,7 @@ int pa__init(pa_module*m) {
     u->sink_input->update_max_request = sink_input_update_max_request_cb;
     u->sink_input->update_sink_latency_range = sink_input_update_sink_latency_range_cb;
     u->sink_input->update_sink_fixed_latency = sink_input_update_sink_fixed_latency_cb;
+    u->sink_input->update_sink_latency_flag = pa_sink_input_update_sink_latency_flag_cb;
     u->sink_input->kill = sink_input_kill_cb;
     u->sink_input->attach = sink_input_attach_cb;
     u->sink_input->detach = sink_input_detach_cb;
diff --git a/src/modules/module-ladspa-sink.c b/src/modules/module-ladspa-sink.c
index 05fb215..441b2fa 100644
--- a/src/modules/module-ladspa-sink.c
+++ b/src/modules/module-ladspa-sink.c
@@ -674,7 +674,8 @@ static void sink_input_moving_cb(pa_sink_input *i, pa_sink *dest) {
 
     if (dest) {
         pa_sink_set_asyncmsgq(u->sink, dest->asyncmsgq);
-        pa_sink_update_flags(u->sink, PA_SINK_LATENCY|PA_SINK_DYNAMIC_LATENCY, dest->flags);
+        pa_sink_set_latency_flag(u->sink, dest->flags & PA_SINK_LATENCY);
+        pa_sink_update_flags(u->sink, PA_SINK_DYNAMIC_LATENCY, dest->flags);
     } else
         pa_sink_set_asyncmsgq(u->sink, NULL);
 
@@ -1313,6 +1314,7 @@ int pa__init(pa_module*m) {
     u->sink_input->update_max_request = sink_input_update_max_request_cb;
     u->sink_input->update_sink_latency_range = sink_input_update_sink_latency_range_cb;
     u->sink_input->update_sink_fixed_latency = sink_input_update_sink_fixed_latency_cb;
+    u->sink_input->update_sink_latency_flag = pa_sink_input_update_sink_latency_flag_cb;
     u->sink_input->kill = sink_input_kill_cb;
     u->sink_input->attach = sink_input_attach_cb;
     u->sink_input->detach = sink_input_detach_cb;
diff --git a/src/modules/module-remap-sink.c b/src/modules/module-remap-sink.c
index 41a07fc..179743b 100644
--- a/src/modules/module-remap-sink.c
+++ b/src/modules/module-remap-sink.c
@@ -308,7 +308,8 @@ static void sink_input_moving_cb(pa_sink_input *i, pa_sink *dest) {
 
     if (dest) {
         pa_sink_set_asyncmsgq(u->sink, dest->asyncmsgq);
-        pa_sink_update_flags(u->sink, PA_SINK_LATENCY|PA_SINK_DYNAMIC_LATENCY, dest->flags);
+        pa_sink_set_latency_flag(u->sink, dest->flags & PA_SINK_LATENCY);
+        pa_sink_update_flags(u->sink, PA_SINK_DYNAMIC_LATENCY, dest->flags);
     } else
         pa_sink_set_asyncmsgq(u->sink, NULL);
 
@@ -441,6 +442,7 @@ int pa__init(pa_module*m) {
     u->sink_input->update_max_request = sink_input_update_max_request_cb;
     u->sink_input->update_sink_latency_range = sink_input_update_sink_latency_range_cb;
     u->sink_input->update_sink_fixed_latency = sink_input_update_sink_fixed_latency_cb;
+    u->sink_input->update_sink_latency_flag = pa_sink_input_update_sink_latency_flag_cb;
     u->sink_input->attach = sink_input_attach_cb;
     u->sink_input->detach = sink_input_detach_cb;
     u->sink_input->kill = sink_input_kill_cb;
diff --git a/src/modules/module-virtual-sink.c b/src/modules/module-virtual-sink.c
index eabd321..1883d00 100644
--- a/src/modules/module-virtual-sink.c
+++ b/src/modules/module-virtual-sink.c
@@ -438,7 +438,8 @@ static void sink_input_moving_cb(pa_sink_input *i, pa_sink *dest) {
 
     if (dest) {
         pa_sink_set_asyncmsgq(u->sink, dest->asyncmsgq);
-        pa_sink_update_flags(u->sink, PA_SINK_LATENCY|PA_SINK_DYNAMIC_LATENCY, dest->flags);
+        pa_sink_set_latency_flag(u->sink, dest->flags & PA_SINK_LATENCY);
+        pa_sink_update_flags(u->sink, PA_SINK_DYNAMIC_LATENCY, dest->flags);
     } else
         pa_sink_set_asyncmsgq(u->sink, NULL);
 
@@ -603,6 +604,7 @@ int pa__init(pa_module*m) {
     u->sink_input->update_max_request = sink_input_update_max_request_cb;
     u->sink_input->update_sink_latency_range = sink_input_update_sink_latency_range_cb;
     u->sink_input->update_sink_fixed_latency = sink_input_update_sink_fixed_latency_cb;
+    u->sink_input->update_sink_latency_flag = pa_sink_input_update_sink_latency_flag_cb;
     u->sink_input->kill = sink_input_kill_cb;
     u->sink_input->attach = sink_input_attach_cb;
     u->sink_input->detach = sink_input_detach_cb;
diff --git a/src/modules/module-virtual-source.c b/src/modules/module-virtual-source.c
index b2a8359..212bbc6 100644
--- a/src/modules/module-virtual-source.c
+++ b/src/modules/module-virtual-source.c
@@ -469,7 +469,8 @@ static void source_output_moving_cb(pa_source_output *o, pa_source *dest) {
 
     if (dest) {
         pa_source_set_asyncmsgq(u->source, dest->asyncmsgq);
-        pa_source_update_flags(u->source, PA_SOURCE_LATENCY|PA_SOURCE_DYNAMIC_LATENCY, dest->flags);
+        pa_source_set_latency_flag(u->source, dest->flags & PA_SOURCE_LATENCY);
+        pa_source_update_flags(u->source, PA_SOURCE_DYNAMIC_LATENCY, dest->flags);
     } else
         pa_source_set_asyncmsgq(u->source, NULL);
 
@@ -627,6 +628,7 @@ int pa__init(pa_module*m) {
     u->source_output->parent.process_msg = source_output_process_msg_cb;
     u->source_output->push = source_output_push_cb;
     u->source_output->process_rewind = source_output_process_rewind_cb;
+    u->source_output->update_source_latency_flag = pa_source_output_update_source_latency_flag_cb;
     u->source_output->kill = source_output_kill_cb;
     u->source_output->attach = source_output_attach_cb;
     u->source_output->detach = source_output_detach_cb;
diff --git a/src/modules/module-virtual-surround-sink.c b/src/modules/module-virtual-surround-sink.c
index d64e577..4bef912 100644
--- a/src/modules/module-virtual-surround-sink.c
+++ b/src/modules/module-virtual-surround-sink.c
@@ -448,7 +448,8 @@ static void sink_input_moving_cb(pa_sink_input *i, pa_sink *dest) {
 
     if (dest) {
         pa_sink_set_asyncmsgq(u->sink, dest->asyncmsgq);
-        pa_sink_update_flags(u->sink, PA_SINK_LATENCY|PA_SINK_DYNAMIC_LATENCY, dest->flags);
+        pa_sink_set_latency_flag(u->sink, dest->flags & PA_SINK_LATENCY);
+        pa_sink_update_flags(u->sink, PA_SINK_DYNAMIC_LATENCY, dest->flags);
     } else
         pa_sink_set_asyncmsgq(u->sink, NULL);
 
@@ -700,6 +701,7 @@ int pa__init(pa_module*m) {
     u->sink_input->update_max_request = sink_input_update_max_request_cb;
     u->sink_input->update_sink_latency_range = sink_input_update_sink_latency_range_cb;
     u->sink_input->update_sink_fixed_latency = sink_input_update_sink_fixed_latency_cb;
+    u->sink_input->update_sink_latency_flag = pa_sink_input_update_sink_latency_flag_cb;
     u->sink_input->kill = sink_input_kill_cb;
     u->sink_input->attach = sink_input_attach_cb;
     u->sink_input->detach = sink_input_detach_cb;
diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
index 7a7575a..fa5e979 100644
--- a/src/pulsecore/sink-input.c
+++ b/src/pulsecore/sink-input.c
@@ -218,6 +218,7 @@ static void reset_callbacks(pa_sink_input *i) {
     i->update_sink_requested_latency = NULL;
     i->update_sink_latency_range = NULL;
     i->update_sink_fixed_latency = NULL;
+    i->update_sink_latency_flag = NULL;
     i->attach = NULL;
     i->detach = NULL;
     i->suspend = NULL;
@@ -2096,3 +2097,12 @@ int pa_sink_input_update_rate(pa_sink_input *i) {
 
     return 0;
 }
+
+/* Called from the main thread while the IO thread is inactive. */
+void pa_sink_input_update_sink_latency_flag_cb(pa_sink_input *i) {
+    pa_sink_input_assert_ref(i);
+    pa_assert_ctl_context();
+
+    if (i->origin_sink)
+        pa_sink_set_latency_flag(i->origin_sink, i->sink->flags & PA_SINK_LATENCY);
+}
diff --git a/src/pulsecore/sink-input.h b/src/pulsecore/sink-input.h
index af2177a..28a8eb4 100644
--- a/src/pulsecore/sink-input.h
+++ b/src/pulsecore/sink-input.h
@@ -152,6 +152,10 @@ struct pa_sink_input {
      * is one. Called from IO context. */
     void (*update_sink_fixed_latency) (pa_sink_input *i); /* may be NULL */
 
+    /* Called whenever the PA_SINK_LATENCY flag of the sink changes state.
+     * Called from the main context while the IO thread is inactive. */
+    void (*update_sink_latency_flag) (pa_sink_input *i); /* may be NULL */
+
     /* If non-NULL this function is called when the input is first
      * connected to a sink or when the rtpoll/asyncmsgq fields
      * change. You usually don't need to implement this function
@@ -398,6 +402,14 @@ pa_bool_t pa_sink_input_safe_to_remove(pa_sink_input *i);
 
 pa_memchunk* pa_sink_input_get_silence(pa_sink_input *i, pa_memchunk *ret);
 
+/* "Standard" callback implementations to be used by sink input implementations
+ * if they don't need anything more specialized. */
+
+/* update_sink_latency_flag() implementation that propagates the
+ * PA_SINK_LATENCY flag to the origin sink. If the input doesn't have an origin
+ * sink, this does nothing. */
+void pa_sink_input_update_sink_latency_flag_cb(pa_sink_input *i);
+
 #define pa_sink_input_assert_io_context(s) \
     pa_assert(pa_thread_mq_get() || !PA_SINK_INPUT_IS_LINKED((s)->state))
 
diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
index a41d2e7..722db15 100644
--- a/src/pulsecore/sink.c
+++ b/src/pulsecore/sink.c
@@ -760,6 +760,35 @@ void pa_sink_set_asyncmsgq(pa_sink *s, pa_asyncmsgq *q) {
         pa_source_set_asyncmsgq(s->monitor_source, q);
 }
 
+/* Called from main context, and not while the IO thread is active, please. */
+void pa_sink_set_latency_flag(pa_sink *s, bool enabled) {
+    pa_sink_input *i;
+    uint32_t idx;
+
+    pa_sink_assert_ref(s);
+    pa_assert_ctl_context();
+
+    if (enabled == !!(s->flags & PA_SINK_LATENCY))
+        return;
+
+    if (enabled)
+        s->flags |= PA_SINK_LATENCY;
+    else
+        s->flags &= ~PA_SINK_LATENCY;
+
+    pa_log_debug("Sink %s LATENCY flag %s.", s->name, enabled ? "enabled" : "disabled");
+
+    pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
+
+    PA_IDXSET_FOREACH(i, s->inputs, idx) {
+        if (i->update_sink_latency_flag)
+            i->update_sink_latency_flag(i);
+    }
+
+    if (s->monitor_source)
+        pa_source_set_latency_flag(s->monitor_source, enabled);
+}
+
 /* 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_assert_ref(s);
@@ -769,15 +798,14 @@ void pa_sink_update_flags(pa_sink *s, pa_sink_flags_t mask, pa_sink_flags_t valu
         return;
 
     /* For now, allow only a minimal set of flags to be changed. */
-    pa_assert((mask & ~(PA_SINK_DYNAMIC_LATENCY|PA_SINK_LATENCY)) == 0);
+    pa_assert((mask & ~PA_SINK_DYNAMIC_LATENCY) == 0);
 
     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_SINK_DYNAMIC_LATENCY : 0));
+    if (s->monitor_source)
+        pa_source_update_flags(s->monitor_source,
+                               (mask & PA_SINK_DYNAMIC_LATENCY) ? PA_SOURCE_DYNAMIC_LATENCY : 0,
+                               (value & PA_SINK_DYNAMIC_LATENCY) ? PA_SOURCE_DYNAMIC_LATENCY : 0);
 }
 
 /* Called from IO context, or before _put() from main context */
diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h
index 2c52348..c0ef8ce 100644
--- a/src/pulsecore/sink.h
+++ b/src/pulsecore/sink.h
@@ -400,6 +400,7 @@ void pa_sink_set_soft_volume(pa_sink *s, const pa_cvolume *volume);
 void pa_sink_volume_changed(pa_sink *s, const pa_cvolume *new_volume);
 void pa_sink_mute_changed(pa_sink *s, pa_bool_t new_muted);
 
+void pa_sink_set_latency_flag(pa_sink *s, bool enabled);
 void pa_sink_update_flags(pa_sink *s, pa_sink_flags_t mask, pa_sink_flags_t value);
 
 pa_bool_t pa_device_init_description(pa_proplist *p);
diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c
index 1297ec7..d19d903 100644
--- a/src/pulsecore/source-output.c
+++ b/src/pulsecore/source-output.c
@@ -198,6 +198,7 @@ static void reset_callbacks(pa_source_output *o) {
     o->update_source_requested_latency = NULL;
     o->update_source_latency_range = NULL;
     o->update_source_fixed_latency = NULL;
+    o->update_source_latency_flag = NULL;
     o->attach = NULL;
     o->detach = NULL;
     o->suspend = NULL;
@@ -1683,3 +1684,12 @@ int pa_source_output_update_rate(pa_source_output *o) {
 
     return 0;
 }
+
+/* Called from the main thread while the IO thread is inactive. */
+void pa_source_output_update_source_latency_flag_cb(pa_source_output *o) {
+    pa_source_output_assert_ref(o);
+    pa_assert_ctl_context();
+
+    if (o->destination_source)
+        pa_source_set_latency_flag(o->destination_source, o->source->flags & PA_SOURCE_LATENCY);
+}
diff --git a/src/pulsecore/source-output.h b/src/pulsecore/source-output.h
index e60430f..50a0aba 100644
--- a/src/pulsecore/source-output.h
+++ b/src/pulsecore/source-output.h
@@ -130,7 +130,11 @@ struct pa_source_output {
 
     /* Called whenever the fixed latency of the source changes, if there
      * is one. Called from IO context. */
-    void (*update_source_fixed_latency) (pa_source_output *i); /* may be NULL */
+    void (*update_source_fixed_latency) (pa_source_output *o); /* may be NULL */
+
+    /* Called whenever the PA_SOURCE_LATENCY flag of the source changes state.
+     * Called from the main context while the IO thread is inactive. */
+    void (*update_source_latency_flag) (pa_source_output *o); /* may be NULL */
 
     /* If non-NULL this function is called when the output is first
      * connected to a source or when the rtpoll/asyncmsgq fields
@@ -353,6 +357,14 @@ int pa_source_output_process_msg(pa_msgobject *mo, int code, void *userdata, int
 
 pa_usec_t pa_source_output_set_requested_latency_within_thread(pa_source_output *o, pa_usec_t usec);
 
+/* "Standard" callback implementations to be used by source output
+ * implementations if they don't need anything more specialized. */
+
+/* update_source_latency_flag() implementation that propagates the
+ * PA_SOURCE_LATENCY flag to the destination source. If the output doesn't have
+ * a destination source, this does nothing. */
+void pa_source_output_update_source_latency_flag_cb(pa_source_output *o);
+
 #define pa_source_output_assert_io_context(s) \
     pa_assert(pa_thread_mq_get() || !PA_SOURCE_OUTPUT_IS_LINKED((s)->state))
 
diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c
index cefddae..947a773 100644
--- a/src/pulsecore/source.c
+++ b/src/pulsecore/source.c
@@ -687,6 +687,32 @@ void pa_source_set_asyncmsgq(pa_source *s, pa_asyncmsgq *q) {
     s->asyncmsgq = q;
 }
 
+/* Called from main context, and not while the IO thread is active, please. */
+void pa_source_set_latency_flag(pa_source *s, bool enabled) {
+    pa_source_output *o;
+    uint32_t idx;
+
+    pa_source_assert_ref(s);
+    pa_assert_ctl_context();
+
+    if (enabled == !!(s->flags & PA_SOURCE_LATENCY))
+        return;
+
+    if (enabled)
+        s->flags |= PA_SOURCE_LATENCY;
+    else
+        s->flags &= ~PA_SOURCE_LATENCY;
+
+    pa_log_debug("Source %s LATENCY flag %s.", s->name, enabled ? "enabled" : "disabled");
+
+    pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
+
+    PA_IDXSET_FOREACH(o, s->outputs, idx) {
+        if (o->update_source_latency_flag)
+            o->update_source_latency_flag(o);
+    }
+}
+
 /* 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_assert_ref(s);
@@ -696,7 +722,7 @@ void pa_source_update_flags(pa_source *s, pa_source_flags_t mask, pa_source_flag
         return;
 
     /* For now, allow only a minimal set of flags to be changed. */
-    pa_assert((mask & ~(PA_SOURCE_DYNAMIC_LATENCY|PA_SOURCE_LATENCY)) == 0);
+    pa_assert((mask & ~PA_SOURCE_DYNAMIC_LATENCY) == 0);
 
     s->flags = (s->flags & ~mask) | (value & mask);
 }
diff --git a/src/pulsecore/source.h b/src/pulsecore/source.h
index dd1e09b..ca83ad0 100644
--- a/src/pulsecore/source.h
+++ b/src/pulsecore/source.h
@@ -338,6 +338,7 @@ void pa_source_mute_changed(pa_source *s, pa_bool_t new_muted);
 
 int pa_source_sync_suspend(pa_source *s);
 
+void pa_source_set_latency_flag(pa_source *s, bool enabled);
 void pa_source_update_flags(pa_source *s, pa_source_flags_t mask, pa_source_flags_t value);
 
 /*** May be called by everyone, from main context */
-- 
1.7.10.4



More information about the pulseaudio-discuss mailing list