[pulseaudio-commits] 7 commits - src/modules src/pulse src/pulsecore
Arun Raghavan
arun at kemper.freedesktop.org
Fri Jun 12 00:14:32 PDT 2015
src/modules/echo-cancel/adrian-aec.c | 4 ++++
src/modules/echo-cancel/module-echo-cancel.c | 26 ++++++++++++++++++++++----
src/modules/module-always-sink.c | 13 ++++++++++---
src/modules/module-equalizer-sink.c | 9 ++++++---
src/modules/module-filter-apply.c | 4 ++--
src/pulse/stream.c | 18 ++++++++++++++----
src/pulsecore/sink.c | 9 ++++++++-
src/pulsecore/sink.h | 2 ++
src/pulsecore/source.c | 9 ++++++++-
src/pulsecore/source.h | 2 ++
10 files changed, 78 insertions(+), 18 deletions(-)
New commits:
commit aafb56d9024eb09135da1a58b8a0948095b7f998
Author: Arun Raghavan <git at arunraghavan.net>
Date: Tue Jun 9 12:31:12 2015 +0530
equalizer: Handle underlying sink going away better when autoloaded
Detailed description in fix for module-echo-cancel.
Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=90416
diff --git a/src/modules/module-equalizer-sink.c b/src/modules/module-equalizer-sink.c
index 96a19b6..9c25f3f 100644
--- a/src/modules/module-equalizer-sink.c
+++ b/src/modules/module-equalizer-sink.c
@@ -1055,9 +1055,6 @@ static bool sink_input_may_move_to_cb(pa_sink_input *i, pa_sink *dest) {
pa_sink_input_assert_ref(i);
pa_assert_se(u = i->userdata);
- if (u->autoloaded)
- return false;
-
return u->sink != dest;
}
@@ -1068,6 +1065,12 @@ static void sink_input_moving_cb(pa_sink_input *i, pa_sink *dest) {
pa_sink_input_assert_ref(i);
pa_assert_se(u = i->userdata);
+ if (u->autoloaded) {
+ /* We were autoloaded, and don't support moving. Let's unload ourselves. */
+ pa_log_debug("Can't move autoloaded stream, unloading");
+ pa_module_unload_request(u->module, true);
+ }
+
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);
commit bf7bc1a55fa383b6aa487bedee90065afdbef9e6
Author: Arun Raghavan <git at arunraghavan.net>
Date: Tue Jun 9 12:10:01 2015 +0530
echo-cancel: Handle underlying sink going away better when autoloaded
When we the underlying sink/source goes away, there is an intermediate
state where the asyncmsgqs that we were using for the sink-input and
source-output go away. This is usually okay if the sink-input and
source-output are moved to another device, but can be problematic if we
don't support moving (which is the case when the filter is autoloaded).
This becomes a problem because of the following chain of events:
* The underlying sink goes away
* Moving the filter sink-input fails (because it is autloaded)
* At this point the sink-input has no underlying sink, and thus
no underlying asyncmsgq
* This also applies to all sink-inputs connected to the echo-cancel
module
* The sink-input is killed, triggering a module unload
* On unlink, module-rescue-streams tries to move sink-inputs to
another sink, starting with a START_MOVE message
* There is no asyncmsgq for the message, so we crash
* We can't just perform a NULL check for the asyncmsgq, since there
are state changes we need to effect during the move
To fix this, we pretend to allow the move to the new sink, and then
unlink ourselves *after* the move is complete. This ensures that we
never find ourselves in a position where we need the underlying
sink/asyncmsgq to be present when it is not.
Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=90416
diff --git a/src/modules/echo-cancel/module-echo-cancel.c b/src/modules/echo-cancel/module-echo-cancel.c
index 639cd41..b0b98db 100644
--- a/src/modules/echo-cancel/module-echo-cancel.c
+++ b/src/modules/echo-cancel/module-echo-cancel.c
@@ -1412,7 +1412,7 @@ static bool source_output_may_move_to_cb(pa_source_output *o, pa_source *dest) {
pa_assert_ctl_context();
pa_assert_se(u = o->userdata);
- if (u->dead || u->autoloaded)
+ if (u->dead)
return false;
return (u->source != dest) && (u->sink != dest->monitor_of);
@@ -1425,7 +1425,7 @@ static bool sink_input_may_move_to_cb(pa_sink_input *i, pa_sink *dest) {
pa_sink_input_assert_ref(i);
pa_assert_se(u = i->userdata);
- if (u->dead || u->autoloaded)
+ if (u->dead)
return false;
return u->sink != dest;
@@ -1439,6 +1439,12 @@ static void source_output_moving_cb(pa_source_output *o, pa_source *dest) {
pa_assert_ctl_context();
pa_assert_se(u = o->userdata);
+ if (u->autoloaded) {
+ /* We were autoloaded, and don't support moving. Let's unload ourselves. */
+ pa_log_debug("Can't move autoloaded streams, unloading");
+ pa_module_unload_request(u->module, true);
+ }
+
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);
@@ -1450,7 +1456,10 @@ static void source_output_moving_cb(pa_source_output *o, pa_source *dest) {
pa_proplist *pl;
pl = pa_proplist_new();
- y = pa_proplist_gets(u->sink_input->sink->proplist, PA_PROP_DEVICE_DESCRIPTION);
+ if (u->sink_input->sink)
+ y = pa_proplist_gets(u->sink_input->sink->proplist, PA_PROP_DEVICE_DESCRIPTION);
+ else
+ y = "<unknown>"; /* Probably in the middle of a move */
z = pa_proplist_gets(dest->proplist, PA_PROP_DEVICE_DESCRIPTION);
pa_proplist_setf(pl, PA_PROP_DEVICE_DESCRIPTION, "%s (echo cancelled with %s)", z ? z : dest->name,
y ? y : u->sink_input->sink->name);
@@ -1467,6 +1476,12 @@ static void sink_input_moving_cb(pa_sink_input *i, pa_sink *dest) {
pa_sink_input_assert_ref(i);
pa_assert_se(u = i->userdata);
+ if (u->autoloaded) {
+ /* We were autoloaded, and don't support moving. Let's unload ourselves. */
+ pa_log_debug("Can't move autoloaded streams, unloading");
+ pa_module_unload_request(u->module, true);
+ }
+
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);
@@ -1478,7 +1493,10 @@ static void sink_input_moving_cb(pa_sink_input *i, pa_sink *dest) {
pa_proplist *pl;
pl = pa_proplist_new();
- y = pa_proplist_gets(u->source_output->source->proplist, PA_PROP_DEVICE_DESCRIPTION);
+ if (u->source_output->source)
+ y = pa_proplist_gets(u->source_output->source->proplist, PA_PROP_DEVICE_DESCRIPTION);
+ else
+ y = "<unknown>"; /* Probably in the middle of a move */
z = pa_proplist_gets(dest->proplist, PA_PROP_DEVICE_DESCRIPTION);
pa_proplist_setf(pl, PA_PROP_DEVICE_DESCRIPTION, "%s (echo cancelled with %s)", z ? z : dest->name,
y ? y : u->source_output->source->name);
commit ceae6b1e61e97c45c726a09ffc74b0ee72a66303
Author: Arun Raghavan <git at arunraghavan.net>
Date: Tue Jun 9 12:07:44 2015 +0530
always-sink: Ignore filter sinks
We don't want to count filter sinks towards the list of actual sinks,
since those also need a real underlying sink to exist.
diff --git a/src/modules/module-always-sink.c b/src/modules/module-always-sink.c
index d2edf12..b5721bf 100644
--- a/src/modules/module-always-sink.c
+++ b/src/modules/module-always-sink.c
@@ -61,12 +61,15 @@ static void load_null_sink_if_needed(pa_core *c, pa_sink *sink, struct userdata*
pa_assert(c);
pa_assert(u);
- pa_assert(u->null_module == PA_INVALID_INDEX);
+
+ if (u->null_module != PA_INVALID_INDEX)
+ return; /* We've already got a null-sink loaded */
/* Loop through all sinks and check to see if we have *any*
- * sinks. Ignore the sink passed in (if it's not null) */
+ * sinks. Ignore the sink passed in (if it's not null), and
+ * don't count filter sinks. */
PA_IDXSET_FOREACH(target, c->sinks, idx)
- if (!sink || target != sink)
+ if (!sink || ((target != sink) && !pa_sink_is_filter(target)))
break;
if (target)
@@ -111,6 +114,10 @@ static pa_hook_result_t put_hook_callback(pa_core *c, pa_sink *sink, void* userd
if (sink->module && sink->module->index == u->null_module)
return PA_HOOK_OK;
+ /* We don't count filter sinks since they need a real sink */
+ if (pa_sink_is_filter(sink))
+ return PA_HOOK_OK;
+
pa_log_info("A new sink has been discovered. Unloading null-sink.");
pa_module_unload_request_by_index(c, u->null_module, true);
commit 81f7589a3fcba771e94d2aec67fb9e04a44e7086
Author: Arun Raghavan <git at arunraghavan.net>
Date: Tue Jun 9 12:06:48 2015 +0530
sink,source: Add a helper function to check whether this is a filter
diff --git a/src/modules/module-filter-apply.c b/src/modules/module-filter-apply.c
index 5a927a3..c3f83ce 100644
--- a/src/modules/module-filter-apply.c
+++ b/src/modules/module-filter-apply.c
@@ -356,7 +356,7 @@ static void find_filters_for_module(struct userdata *u, pa_module *m, const char
PA_IDXSET_FOREACH(sink, u->core->sinks, idx) {
if (sink->module == m) {
- pa_assert(sink->input_to_master != NULL);
+ pa_assert(pa_sink_is_filter(sink));
fltr = filter_new(name, sink->input_to_master->sink, NULL);
fltr->module_index = m->index;
@@ -368,7 +368,7 @@ static void find_filters_for_module(struct userdata *u, pa_module *m, const char
PA_IDXSET_FOREACH(source, u->core->sources, idx) {
if (source->module == m && !source->monitor_of) {
- pa_assert(source->output_from_master != NULL);
+ pa_assert(pa_source_is_filter(source));
if (!fltr) {
fltr = filter_new(name, NULL, source->output_from_master->source);
diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
index a22c199..c2bf0e4 100644
--- a/src/pulsecore/sink.c
+++ b/src/pulsecore/sink.c
@@ -580,7 +580,7 @@ void pa_sink_put(pa_sink* s) {
pa_assert_ctl_context();
pa_assert(s->state == PA_SINK_INIT);
- pa_assert(!(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER) || s->input_to_master);
+ pa_assert(!(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER) || pa_sink_is_filter(s));
/* The following fields must be initialized properly when calling _put() */
pa_assert(s->asyncmsgq);
@@ -1558,6 +1558,13 @@ pa_sink *pa_sink_get_master(pa_sink *s) {
}
/* Called from main context */
+bool pa_sink_is_filter(pa_sink *s) {
+ pa_sink_assert_ref(s);
+
+ return (s->input_to_master != NULL);
+}
+
+/* Called from main context */
bool pa_sink_is_passthrough(pa_sink *s) {
pa_sink_input *alt_i;
uint32_t idx;
diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h
index ed0f9ee..3ae8240 100644
--- a/src/pulsecore/sink.h
+++ b/src/pulsecore/sink.h
@@ -440,6 +440,8 @@ bool pa_sink_flat_volume_enabled(pa_sink *s);
/* Get the master sink when sharing volumes */
pa_sink *pa_sink_get_master(pa_sink *s);
+bool pa_sink_is_filter(pa_sink *s);
+
/* Is the sink in passthrough mode? (that is, is there a passthrough sink input
* connected to this sink? */
bool pa_sink_is_passthrough(pa_sink *s);
diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c
index 4be7306..2dd7a28 100644
--- a/src/pulsecore/source.c
+++ b/src/pulsecore/source.c
@@ -531,7 +531,7 @@ void pa_source_put(pa_source *s) {
pa_assert_ctl_context();
pa_assert(s->state == PA_SOURCE_INIT);
- pa_assert(!(s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER) || s->output_from_master);
+ pa_assert(!(s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER) || pa_source_is_filter(s));
/* The following fields must be initialized properly when calling _put() */
pa_assert(s->asyncmsgq);
@@ -1173,6 +1173,13 @@ pa_source *pa_source_get_master(pa_source *s) {
}
/* Called from main context */
+bool pa_source_is_filter(pa_source *s) {
+ pa_source_assert_ref(s);
+
+ return (s->output_from_master != NULL);
+}
+
+/* Called from main context */
bool pa_source_is_passthrough(pa_source *s) {
pa_source_assert_ref(s);
diff --git a/src/pulsecore/source.h b/src/pulsecore/source.h
index e7fc3e2..9ee0783 100644
--- a/src/pulsecore/source.h
+++ b/src/pulsecore/source.h
@@ -371,6 +371,8 @@ bool pa_source_flat_volume_enabled(pa_source *s);
/* Get the master source when sharing volumes */
pa_source *pa_source_get_master(pa_source *s);
+bool pa_source_is_filter(pa_source *s);
+
/* Is the source in passthrough mode? (that is, is this a monitor source for a sink
* that has a passthrough sink input connected to it. */
bool pa_source_is_passthrough(pa_source *s);
commit 5adb126259958ab106584034f6a3c94a8ec4af60
Author: Arun Raghavan <git at arunraghavan.net>
Date: Thu Jun 11 11:01:30 2015 +0530
stream: Support extended API with PULSE_LATENCY_MSEC if possible
This only works in the single-format case (i.e. we know the format
up-front and we're not negotiating).
diff --git a/src/pulse/stream.c b/src/pulse/stream.c
index c301b8e..6fea996 100644
--- a/src/pulse/stream.c
+++ b/src/pulse/stream.c
@@ -987,6 +987,14 @@ static void patch_buffer_attr(pa_stream *s, pa_buffer_attr *attr, pa_stream_flag
if ((e = getenv("PULSE_LATENCY_MSEC"))) {
uint32_t ms;
+ pa_sample_spec ss;
+
+ pa_sample_spec_init(&ss);
+
+ if (pa_sample_spec_valid(&s->sample_spec))
+ ss = s->sample_spec;
+ else if (s->n_formats == 1)
+ pa_format_info_to_sample_spec(s->req_formats[0], &ss, NULL);
if (pa_atou(e, &ms) < 0 || ms <= 0)
pa_log_debug("Failed to parse $PULSE_LATENCY_MSEC: %s", e);
@@ -994,7 +1002,7 @@ static void patch_buffer_attr(pa_stream *s, pa_buffer_attr *attr, pa_stream_flag
pa_log_debug("Ignoring $PULSE_LATENCY_MSEC: %s (invalid sample spec)", e);
else {
attr->maxlength = (uint32_t) -1;
- attr->tlength = pa_usec_to_bytes(ms * PA_USEC_PER_MSEC, &s->sample_spec);
+ attr->tlength = pa_usec_to_bytes(ms * PA_USEC_PER_MSEC, &ss);
attr->minreq = (uint32_t) -1;
attr->prebuf = (uint32_t) -1;
attr->fragsize = attr->tlength;
commit a1c4a6916f74306fb1ddc9c1d5a77a57e4e30a6f
Author: David Henningsson <david.henningsson at canonical.com>
Date: Wed Jun 10 17:29:54 2015 +0200
stream: Check sample spec validity before abiding PULSE_LATENCY_MSEC
In case the sample spec is not known, as can be the case when
pa_stream_new_extended is used, we cannot satisfy the PULSE_LATENCY_MSEC
request.
As a workaround disable being able to use PULSE_LATENCY_MSEC in this case.
Reported-by: Fritsch <fritsch at xbmc.org>
Signed-off-by: David Henningsson <david.henningsson at canonical.com>
diff --git a/src/pulse/stream.c b/src/pulse/stream.c
index d4ad505..c301b8e 100644
--- a/src/pulse/stream.c
+++ b/src/pulse/stream.c
@@ -990,16 +990,18 @@ static void patch_buffer_attr(pa_stream *s, pa_buffer_attr *attr, pa_stream_flag
if (pa_atou(e, &ms) < 0 || ms <= 0)
pa_log_debug("Failed to parse $PULSE_LATENCY_MSEC: %s", e);
+ else if (!pa_sample_spec_valid(&s->sample_spec))
+ pa_log_debug("Ignoring $PULSE_LATENCY_MSEC: %s (invalid sample spec)", e);
else {
attr->maxlength = (uint32_t) -1;
attr->tlength = pa_usec_to_bytes(ms * PA_USEC_PER_MSEC, &s->sample_spec);
attr->minreq = (uint32_t) -1;
attr->prebuf = (uint32_t) -1;
attr->fragsize = attr->tlength;
- }
- if (flags)
- *flags |= PA_STREAM_ADJUST_LATENCY;
+ if (flags)
+ *flags |= PA_STREAM_ADJUST_LATENCY;
+ }
}
if (s->context->version >= 13)
commit cbc0d5ffcbc32a193205bdfc14fc0a476d30c3d1
Author: David Henningsson <david.henningsson at canonical.com>
Date: Fri Jun 12 08:51:21 2015 +0200
echo-cancel: Add config.h in adrian-aec.c
This fixes a compiler warning on some platform.
BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=90881
Signed-off-by: David Henningsson <david.henningsson at canonical.com>
diff --git a/src/modules/echo-cancel/adrian-aec.c b/src/modules/echo-cancel/adrian-aec.c
index 67a2794..71461e4 100644
--- a/src/modules/echo-cancel/adrian-aec.c
+++ b/src/modules/echo-cancel/adrian-aec.c
@@ -14,6 +14,10 @@
#define _GNU_SOURCE
#endif
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
#include <math.h>
#include <string.h>
#include <stdint.h>
More information about the pulseaudio-commits
mailing list