[pulseaudio-discuss] [PATCH 2/3] Propagate the PA_{SINK, SOURCE}_DYNAMIC_LATENCY flag changes through a chain of filter sinks/sources.
Tanu Kaskinen
tanu.kaskinen at jollamobile.com
Thu Sep 20 08:27:41 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 DYNAMIC_LATENCY flag set (unlike alsa-sink),
the DYNAMIC_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 DYNAMIC_LATENCY flag as it
should.
---
src/modules/echo-cancel/module-echo-cancel.c | 6 ++++--
src/modules/module-equalizer-sink.c | 3 ++-
src/modules/module-ladspa-sink.c | 3 ++-
src/modules/module-remap-sink.c | 3 ++-
src/modules/module-virtual-sink.c | 3 ++-
src/modules/module-virtual-source.c | 3 ++-
src/modules/module-virtual-surround-sink.c | 3 ++-
src/pulsecore/sink-input.c | 10 +++++++++
src/pulsecore/sink-input.h | 9 +++++++++
src/pulsecore/sink.c | 28 +++++++++++++++++---------
src/pulsecore/sink.h | 2 +-
src/pulsecore/source-output.c | 10 +++++++++
src/pulsecore/source-output.h | 9 +++++++++
src/pulsecore/source.c | 24 ++++++++++++++++------
src/pulsecore/source.h | 2 +-
15 files changed, 93 insertions(+), 25 deletions(-)
diff --git a/src/modules/echo-cancel/module-echo-cancel.c b/src/modules/echo-cancel/module-echo-cancel.c
index fbeac69..db166e5 100644
--- a/src/modules/echo-cancel/module-echo-cancel.c
+++ b/src/modules/echo-cancel/module-echo-cancel.c
@@ -1453,7 +1453,7 @@ 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_set_latency_flag(u->source, dest->flags & PA_SOURCE_LATENCY);
- pa_source_update_flags(u->source, PA_SOURCE_DYNAMIC_LATENCY, dest->flags);
+ pa_source_set_dynamic_latency_flag(u->source, dest->flags & PA_SOURCE_DYNAMIC_LATENCY);
} else
pa_source_set_asyncmsgq(u->source, NULL);
@@ -1482,7 +1482,7 @@ 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_set_latency_flag(u->sink, dest->flags & PA_SINK_LATENCY);
- pa_sink_update_flags(u->sink, PA_SINK_DYNAMIC_LATENCY, dest->flags);
+ pa_sink_set_dynamic_latency_flag(u->sink, dest->flags & PA_SINK_DYNAMIC_LATENCY);
} else
pa_sink_set_asyncmsgq(u->sink, NULL);
@@ -1866,6 +1866,7 @@ int pa__init(pa_module*m) {
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->update_source_dynamic_latency_flag = pa_source_output_update_source_dynamic_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;
@@ -1903,6 +1904,7 @@ int pa__init(pa_module*m) {
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->update_sink_dynamic_latency_flag = pa_sink_input_update_sink_dynamic_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 42334b3..0ebf605 100644
--- a/src/modules/module-equalizer-sink.c
+++ b/src/modules/module-equalizer-sink.c
@@ -1076,7 +1076,7 @@ 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_set_latency_flag(u->sink, dest->flags & PA_SINK_LATENCY);
- pa_sink_update_flags(u->sink, PA_SINK_DYNAMIC_LATENCY, dest->flags);
+ pa_sink_set_dynamic_latency_flag(u->sink, dest->flags & PA_SINK_DYNAMIC_LATENCY);
} else
pa_sink_set_asyncmsgq(u->sink, NULL);
}
@@ -1249,6 +1249,7 @@ int pa__init(pa_module*m) {
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->update_sink_dynamic_latency_flag = pa_sink_input_update_sink_dynamic_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 441b2fa..1234813 100644
--- a/src/modules/module-ladspa-sink.c
+++ b/src/modules/module-ladspa-sink.c
@@ -675,7 +675,7 @@ 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_set_latency_flag(u->sink, dest->flags & PA_SINK_LATENCY);
- pa_sink_update_flags(u->sink, PA_SINK_DYNAMIC_LATENCY, dest->flags);
+ pa_sink_set_dynamic_latency_flag(u->sink, dest->flags & PA_SINK_DYNAMIC_LATENCY);
} else
pa_sink_set_asyncmsgq(u->sink, NULL);
@@ -1315,6 +1315,7 @@ int pa__init(pa_module*m) {
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->update_sink_dynamic_latency_flag = pa_sink_input_update_sink_dynamic_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 179743b..0e52c83 100644
--- a/src/modules/module-remap-sink.c
+++ b/src/modules/module-remap-sink.c
@@ -309,7 +309,7 @@ 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_set_latency_flag(u->sink, dest->flags & PA_SINK_LATENCY);
- pa_sink_update_flags(u->sink, PA_SINK_DYNAMIC_LATENCY, dest->flags);
+ pa_sink_set_dynamic_latency_flag(u->sink, dest->flags & PA_SINK_DYNAMIC_LATENCY);
} else
pa_sink_set_asyncmsgq(u->sink, NULL);
@@ -443,6 +443,7 @@ int pa__init(pa_module*m) {
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->update_sink_dynamic_latency_flag = pa_sink_input_update_sink_dynamic_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 1883d00..97ab64e 100644
--- a/src/modules/module-virtual-sink.c
+++ b/src/modules/module-virtual-sink.c
@@ -439,7 +439,7 @@ 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_set_latency_flag(u->sink, dest->flags & PA_SINK_LATENCY);
- pa_sink_update_flags(u->sink, PA_SINK_DYNAMIC_LATENCY, dest->flags);
+ pa_sink_set_dynamic_latency_flag(u->sink, dest->flags & PA_SINK_DYNAMIC_LATENCY);
} else
pa_sink_set_asyncmsgq(u->sink, NULL);
@@ -605,6 +605,7 @@ int pa__init(pa_module*m) {
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->update_sink_dynamic_latency_flag = pa_sink_input_update_sink_dynamic_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 212bbc6..6909edc 100644
--- a/src/modules/module-virtual-source.c
+++ b/src/modules/module-virtual-source.c
@@ -470,7 +470,7 @@ 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_set_latency_flag(u->source, dest->flags & PA_SOURCE_LATENCY);
- pa_source_update_flags(u->source, PA_SOURCE_DYNAMIC_LATENCY, dest->flags);
+ pa_source_set_dynamic_latency_flag(u->source, dest->flags & PA_SOURCE_DYNAMIC_LATENCY);
} else
pa_source_set_asyncmsgq(u->source, NULL);
@@ -629,6 +629,7 @@ int pa__init(pa_module*m) {
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->update_source_dynamic_latency_flag = pa_source_output_update_source_dynamic_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 4bef912..7216345 100644
--- a/src/modules/module-virtual-surround-sink.c
+++ b/src/modules/module-virtual-surround-sink.c
@@ -449,7 +449,7 @@ 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_set_latency_flag(u->sink, dest->flags & PA_SINK_LATENCY);
- pa_sink_update_flags(u->sink, PA_SINK_DYNAMIC_LATENCY, dest->flags);
+ pa_sink_set_dynamic_latency_flag(u->sink, dest->flags & PA_SINK_DYNAMIC_LATENCY);
} else
pa_sink_set_asyncmsgq(u->sink, NULL);
@@ -702,6 +702,7 @@ int pa__init(pa_module*m) {
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->update_sink_dynamic_latency_flag = pa_sink_input_update_sink_dynamic_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 fa5e979..4562560 100644
--- a/src/pulsecore/sink-input.c
+++ b/src/pulsecore/sink-input.c
@@ -219,6 +219,7 @@ static void reset_callbacks(pa_sink_input *i) {
i->update_sink_latency_range = NULL;
i->update_sink_fixed_latency = NULL;
i->update_sink_latency_flag = NULL;
+ i->update_sink_dynamic_latency_flag = NULL;
i->attach = NULL;
i->detach = NULL;
i->suspend = NULL;
@@ -2106,3 +2107,12 @@ void pa_sink_input_update_sink_latency_flag_cb(pa_sink_input *i) {
if (i->origin_sink)
pa_sink_set_latency_flag(i->origin_sink, i->sink->flags & PA_SINK_LATENCY);
}
+
+/* Called from the main thread while the IO thread is inactive. */
+void pa_sink_input_update_sink_dynamic_latency_flag_cb(pa_sink_input *i) {
+ pa_sink_input_assert_ref(i);
+ pa_assert_ctl_context();
+
+ if (i->origin_sink)
+ pa_sink_set_dynamic_latency_flag(i->origin_sink, i->sink->flags & PA_SINK_DYNAMIC_LATENCY);
+}
diff --git a/src/pulsecore/sink-input.h b/src/pulsecore/sink-input.h
index 28a8eb4..0e7cf4a 100644
--- a/src/pulsecore/sink-input.h
+++ b/src/pulsecore/sink-input.h
@@ -156,6 +156,10 @@ struct pa_sink_input {
* Called from the main context while the IO thread is inactive. */
void (*update_sink_latency_flag) (pa_sink_input *i); /* may be NULL */
+ /* Called whenever the PA_SINK_DYNAMIC_LATENCY flag of the sink changes
+ * state. Called from the main context while the IO thread is inactive. */
+ void (*update_sink_dynamic_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
@@ -410,6 +414,11 @@ pa_memchunk* pa_sink_input_get_silence(pa_sink_input *i, pa_memchunk *ret);
* sink, this does nothing. */
void pa_sink_input_update_sink_latency_flag_cb(pa_sink_input *i);
+/* update_sink_dynamic_latency_flag() implementation that propagates the
+ * PA_SINK_DYNAMIC_LATENCY flag to the origin sink. If the input doesn't have
+ * an origin sink, this does nothing. */
+void pa_sink_input_update_sink_dynamic_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 722db15..89273c8 100644
--- a/src/pulsecore/sink.c
+++ b/src/pulsecore/sink.c
@@ -789,23 +789,33 @@ void pa_sink_set_latency_flag(pa_sink *s, bool enabled) {
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) {
+/* Called from main context, and not while the IO thread is active, please. */
+void pa_sink_set_dynamic_latency_flag(pa_sink *s, bool enabled) {
+ pa_sink_input *i;
+ uint32_t idx;
+
pa_sink_assert_ref(s);
pa_assert_ctl_context();
- if (mask == 0)
+ if (enabled == !!(s->flags & PA_SINK_DYNAMIC_LATENCY))
return;
- /* For now, allow only a minimal set of flags to be changed. */
- pa_assert((mask & ~PA_SINK_DYNAMIC_LATENCY) == 0);
+ if (enabled)
+ s->flags |= PA_SINK_DYNAMIC_LATENCY;
+ else
+ s->flags &= ~PA_SINK_DYNAMIC_LATENCY;
+
+ pa_log_debug("Sink %s DYNAMIC_LATENCY flag %s.", s->name, enabled ? "enabled" : "disabled");
+
+ pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
- s->flags = (s->flags & ~mask) | (value & mask);
+ PA_IDXSET_FOREACH(i, s->inputs, idx) {
+ if (i->update_sink_dynamic_latency_flag)
+ i->update_sink_dynamic_latency_flag(i);
+ }
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);
+ pa_source_set_dynamic_latency_flag(s->monitor_source, enabled);
}
/* Called from IO context, or before _put() from main context */
diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h
index c0ef8ce..eb616d6 100644
--- a/src/pulsecore/sink.h
+++ b/src/pulsecore/sink.h
@@ -401,7 +401,7 @@ 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);
+void pa_sink_set_dynamic_latency_flag(pa_sink *s, bool enabled);
pa_bool_t pa_device_init_description(pa_proplist *p);
pa_bool_t pa_device_init_icon(pa_proplist *p, pa_bool_t is_sink);
diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c
index d19d903..8a89780 100644
--- a/src/pulsecore/source-output.c
+++ b/src/pulsecore/source-output.c
@@ -199,6 +199,7 @@ static void reset_callbacks(pa_source_output *o) {
o->update_source_latency_range = NULL;
o->update_source_fixed_latency = NULL;
o->update_source_latency_flag = NULL;
+ o->update_source_dynamic_latency_flag = NULL;
o->attach = NULL;
o->detach = NULL;
o->suspend = NULL;
@@ -1693,3 +1694,12 @@ void pa_source_output_update_source_latency_flag_cb(pa_source_output *o) {
if (o->destination_source)
pa_source_set_latency_flag(o->destination_source, o->source->flags & PA_SOURCE_LATENCY);
}
+
+/* Called from the main thread while the IO thread is inactive. */
+void pa_source_output_update_source_dynamic_latency_flag_cb(pa_source_output *o) {
+ pa_source_output_assert_ref(o);
+ pa_assert_ctl_context();
+
+ if (o->destination_source)
+ pa_source_set_dynamic_latency_flag(o->destination_source, o->source->flags & PA_SOURCE_DYNAMIC_LATENCY);
+}
diff --git a/src/pulsecore/source-output.h b/src/pulsecore/source-output.h
index 50a0aba..749d7fd 100644
--- a/src/pulsecore/source-output.h
+++ b/src/pulsecore/source-output.h
@@ -136,6 +136,10 @@ struct pa_source_output {
* Called from the main context while the IO thread is inactive. */
void (*update_source_latency_flag) (pa_source_output *o); /* may be NULL */
+ /* Called whenever the PA_SOURCE_DYNAMIC_LATENCY flag of the source changes
+ * state. Called from the main context while the IO thread is inactive. */
+ void (*update_source_dynamic_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
* change. You usually don't need to implement this function
@@ -365,6 +369,11 @@ pa_usec_t pa_source_output_set_requested_latency_within_thread(pa_source_output
* a destination source, this does nothing. */
void pa_source_output_update_source_latency_flag_cb(pa_source_output *o);
+/* update_source_dynamic_latency_flag() implementation that propagates the
+ * PA_SOURCE_DYNAMIC_LATENCY flag to the destination source. If the output
+ * doesn't have a destination source, this does nothing. */
+void pa_source_output_update_source_dynamic_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 947a773..45923b2 100644
--- a/src/pulsecore/source.c
+++ b/src/pulsecore/source.c
@@ -713,18 +713,30 @@ void pa_source_set_latency_flag(pa_source *s, bool enabled) {
}
}
-/* 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) {
+/* Called from main context, and not while the IO thread is active, please. */
+void pa_source_set_dynamic_latency_flag(pa_source *s, bool enabled) {
+ pa_source_output *o;
+ uint32_t idx;
+
pa_source_assert_ref(s);
pa_assert_ctl_context();
- if (mask == 0)
+ if (enabled == !!(s->flags & PA_SOURCE_DYNAMIC_LATENCY))
return;
- /* For now, allow only a minimal set of flags to be changed. */
- pa_assert((mask & ~PA_SOURCE_DYNAMIC_LATENCY) == 0);
+ if (enabled)
+ s->flags |= PA_SOURCE_DYNAMIC_LATENCY;
+ else
+ s->flags &= ~PA_SOURCE_DYNAMIC_LATENCY;
+
+ pa_log_debug("Source %s DYNAMIC_LATENCY flag %s.", s->name, enabled ? "enabled" : "disabled");
+
+ pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
- s->flags = (s->flags & ~mask) | (value & mask);
+ PA_IDXSET_FOREACH(o, s->outputs, idx) {
+ if (o->update_source_dynamic_latency_flag)
+ o->update_source_dynamic_latency_flag(o);
+ }
}
/* Called from IO context, or before _put() from main context */
diff --git a/src/pulsecore/source.h b/src/pulsecore/source.h
index ca83ad0..7d7a9a9 100644
--- a/src/pulsecore/source.h
+++ b/src/pulsecore/source.h
@@ -339,7 +339,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);
+void pa_source_set_dynamic_latency_flag(pa_source *s, bool enabled);
/*** May be called by everyone, from main context */
--
1.7.10.4
More information about the pulseaudio-discuss
mailing list