[pulseaudio-commits] 3 commits - src/modules
Arun Raghavan
arun at kemper.freedesktop.org
Wed Nov 23 23:06:56 PST 2011
src/modules/echo-cancel/module-echo-cancel.c | 32 ++++----
src/modules/module-equalizer-sink.c | 3
src/modules/module-filter-apply.c | 105 ++++++++++++++-------------
3 files changed, 79 insertions(+), 61 deletions(-)
New commits:
commit c30a68ebbda56aa1da0d0855f01d195f7d25d448
Author: Arun Raghavan <arun.raghavan at collabora.co.uk>
Date: Fri Nov 11 15:08:24 2011 +0530
filters: Allow a filter to have both sink and source
This sets the base for better representing module-echo-cancel. This
patch itself should change no behaviour -- it only makes way for other
changes.
diff --git a/src/modules/module-filter-apply.c b/src/modules/module-filter-apply.c
index dd9a137..d1fb5df 100644
--- a/src/modules/module-filter-apply.c
+++ b/src/modules/module-filter-apply.c
@@ -57,9 +57,10 @@ static const char* const valid_modargs[] = {
struct filter {
char *name;
uint32_t module_index;
- pa_bool_t is_sink;
- pa_object *parent_obj; /* source or sink that the filter is connected to */
- pa_object *obj; /* source or sink of the filter */
+ pa_sink *sink;
+ pa_sink *sink_master;
+ pa_source *source;
+ pa_source *source_master;
};
struct userdata {
@@ -83,17 +84,19 @@ struct userdata {
static unsigned filter_hash(const void *p) {
const struct filter *f = p;
- if (f->is_sink)
- return (unsigned) (PA_SINK(f->parent_obj)->index + pa_idxset_string_hash_func(f->name));
+ if (f->sink_master && !f->source_master)
+ return (unsigned) (f->sink_master->index + pa_idxset_string_hash_func(f->name));
+ else if (!f->sink_master && f->source_master)
+ return (unsigned) ((f->source_master->index << 16) + pa_idxset_string_hash_func(f->name));
else
- return (unsigned) ((PA_SOURCE(f->parent_obj)->index << 16) + pa_idxset_string_hash_func(f->name));
+ pa_assert_not_reached();
}
static int filter_compare(const void *a, const void *b) {
const struct filter *fa = a, *fb = b;
int r;
- if (fa->parent_obj != fb->parent_obj)
+ if (fa->sink_master != fb->sink_master || fa->source_master != fb->source_master)
return 1;
if ((r = strcmp(fa->name, fb->name)))
return r;
@@ -101,15 +104,19 @@ static int filter_compare(const void *a, const void *b) {
return 0;
}
-static struct filter *filter_new(const char *name, pa_object* parent_obj, pa_bool_t is_sink) {
+static struct filter *filter_new(const char *name, pa_sink *sink, pa_source *source) {
struct filter *f;
+ pa_assert(sink || source);
+
f = pa_xnew(struct filter, 1);
f->name = pa_xstrdup(name);
- pa_assert_se(f->parent_obj = parent_obj);
- f->is_sink = is_sink;
+ f->sink_master = sink;
+ f->source_master = source;
f->module_index = PA_INVALID_INDEX;
- f->obj = NULL;
+ f->sink = NULL;
+ f->source = NULL;
+
return f;
}
@@ -140,12 +147,15 @@ static const char* should_filter(pa_object *o, pa_bool_t is_sink_input) {
return NULL;
}
-static pa_bool_t nothing_attached(pa_object *obj, pa_bool_t is_sink)
-{
- if (is_sink)
- return pa_idxset_isempty(PA_SINK(obj)->inputs);
- else
- return pa_idxset_isempty(PA_SOURCE(obj)->outputs);
+static pa_bool_t nothing_attached(struct filter *f) {
+ pa_bool_t no_si = TRUE, no_so = TRUE;
+
+ if (f->sink)
+ no_si = pa_idxset_isempty(f->sink->inputs);
+ else if (f->source)
+ no_so = pa_idxset_isempty(f->source->outputs);
+
+ return no_si && no_so;
}
static void housekeeping_time_callback(pa_mainloop_api*a, pa_time_event* e, const struct timeval *t, void *userdata) {
@@ -162,7 +172,7 @@ static void housekeeping_time_callback(pa_mainloop_api*a, pa_time_event* e, cons
u->housekeeping_time_event = NULL;
PA_HASHMAP_FOREACH(filter, u->filters, state) {
- if (filter->obj && nothing_attached(filter->obj, filter->is_sink)) {
+ if (nothing_attached(filter)) {
uint32_t idx;
pa_log_debug("Detected filter %s as no longer used. Unloading.", filter->name);
@@ -203,13 +213,13 @@ static void move_object_for_filter(pa_object *o, struct filter* filter, pa_bool_
pa_assert(o);
pa_assert(filter);
- pa_assert_se(parent = (restore ? filter->parent_obj : filter->obj));
-
if (is_sink_input) {
pl = PA_SINK_INPUT(o)->proplist;
+ pa_assert_se(parent = PA_OBJECT(restore ? filter->sink_master : filter->sink));
name = PA_SINK(parent)->name;
} else {
pl = PA_SOURCE_OUTPUT(o)->proplist;
+ pa_assert_se(parent = PA_OBJECT(restore ? filter->source_master : filter->source));
name = PA_SOURCE(parent)->name;
}
@@ -235,9 +245,9 @@ static void find_filters_for_module(struct userdata *u, pa_module *m, const char
if (sink->module == m) {
pa_assert(sink->input_to_master != NULL);
- fltr = filter_new(name, PA_OBJECT(sink->input_to_master->sink), TRUE);
+ fltr = filter_new(name, sink->input_to_master->sink, NULL);
fltr->module_index = m->index;
- fltr->obj = PA_OBJECT(sink);
+ fltr->sink = sink;
pa_hashmap_put(u->filters, fltr, fltr);
}
@@ -247,9 +257,9 @@ static void find_filters_for_module(struct userdata *u, pa_module *m, const char
if (source->module == m && !source->monitor_of) {
pa_assert(source->output_from_master != NULL);
- fltr = filter_new(name, PA_OBJECT(source->output_from_master->source), FALSE);
+ fltr = filter_new(name, NULL, source->output_from_master->source);
fltr->module_index = m->index;
- fltr->obj = PA_OBJECT(source);
+ fltr->source = source;
pa_hashmap_put(u->filters, fltr, fltr);
}
@@ -262,7 +272,7 @@ static pa_bool_t can_unload_module(struct userdata *u, uint32_t idx) {
/* Check if any other struct filters point to the same module */
PA_HASHMAP_FOREACH(filter, u->filters, state) {
- if (filter->module_index == idx && !nothing_attached(filter->obj, pa_sink_isinstance(filter->obj)))
+ if (filter->module_index == idx && !nothing_attached(filter))
return FALSE;
}
@@ -272,23 +282,23 @@ static pa_bool_t can_unload_module(struct userdata *u, uint32_t idx) {
static pa_hook_result_t process(struct userdata *u, pa_object *o, pa_bool_t is_sink_input) {
const char *want;
pa_bool_t done_something = FALSE;
-
- pa_object *parent; /* source/sink of the given source-output/sink-input */
- const char *parent_name;
+ pa_sink *sink = NULL;
+ pa_source *source = NULL;
+ const char *sink_name = NULL, *source_name = NULL;
pa_module *module;
if (is_sink_input) {
- parent = PA_OBJECT(PA_SINK_INPUT(o)->sink);
- parent_name = PA_SINK_INPUT(o)->sink->name;
- module = PA_SINK_INPUT(o)->sink->module;
+ sink = PA_SINK_INPUT(o)->sink;
+ sink_name = sink->name;
+ module = sink->module;
} else {
- parent = PA_OBJECT(PA_SOURCE_OUTPUT(o)->source);
- parent_name = PA_SOURCE_OUTPUT(o)->source->name;
- module = PA_SOURCE_OUTPUT(o)->source->module;
+ source = PA_SOURCE_OUTPUT(o)->source;
+ source_name = source->name;
+ module = source->module;
}
- /* If there is no sink yet, we can't do much */
- if (!parent)
+ /* If there is no sink/source yet, we can't do much */
+ if ((is_sink_input && !sink) || (!is_sink_input && !source))
return PA_HOOK_OK;
/* If the stream doesn't what any filter, then let it be. */
@@ -309,13 +319,14 @@ static pa_hook_result_t process(struct userdata *u, pa_object *o, pa_bool_t is_s
return PA_HOOK_OK;
}
- fltr = filter_new(want, parent, is_sink_input);
+ fltr = filter_new(want, sink, source);
if (!(filter = pa_hashmap_get(u->filters, fltr))) {
char *args;
pa_module *m;
- args = pa_sprintf_malloc("autoloaded=1 %s_master=%s", is_sink_input ? "sink" : "source", parent_name);
+ args = pa_sprintf_malloc("autoloaded=1 %s_master=%s", is_sink_input ? "sink" : "source",
+ is_sink_input ? sink_name : source_name);
pa_log_debug("Loading %s with arguments '%s'", module_name, args);
if ((m = pa_module_load(u->core, module_name, args))) {
@@ -329,15 +340,15 @@ static pa_hook_result_t process(struct userdata *u, pa_object *o, pa_bool_t is_s
pa_xfree(fltr);
if (!filter) {
- pa_log("Unable to load %s for <%s>", module_name, parent_name);
+ pa_log("Unable to load %s for <%s>", module_name, is_sink_input ? sink_name : source_name);
pa_xfree(module_name);
return PA_HOOK_OK;
}
pa_xfree(module_name);
- if (filter->obj) {
- /* We can move the sink_input now as the know the destination.
- * If this isn't true, we will do it later when the sink appears. */
+ /* We can move the stream now as we know the destination. If this
+ * isn't true, we will do it later when the sink appears. */
+ if ((is_sink_input && filter->sink) || (!is_sink_input && filter->source)) {
move_object_for_filter(o, filter, FALSE, is_sink_input);
done_something = TRUE;
}
@@ -348,7 +359,7 @@ static pa_hook_result_t process(struct userdata *u, pa_object *o, pa_bool_t is_s
/* We do not want to filter... but are we already filtered?
* This can happen if an input's proplist changes */
PA_HASHMAP_FOREACH(filter, u->filters, state) {
- if (parent == filter->obj) {
+ if ((is_sink_input && sink == filter->sink) || (!is_sink_input && source == filter->source)) {
move_object_for_filter(o, filter, TRUE, is_sink_input);
done_something = TRUE;
break;
@@ -409,13 +420,13 @@ static pa_hook_result_t sink_unlink_cb(pa_core *core, pa_sink *sink, struct user
/* If either the parent or the sink we've loaded disappears,
* we should remove it from our hashmap */
PA_HASHMAP_FOREACH(filter, u->filters, state) {
- if (filter->parent_obj == PA_OBJECT(sink) || filter->obj == PA_OBJECT(sink)) {
+ if (filter->sink_master == sink || filter->sink == sink) {
uint32_t idx;
/* Attempt to rescue any streams to the parent sink as this is likely
* the best course of action (as opposed to a generic rescue via
* module-rescue-streams */
- if (filter->obj == PA_OBJECT(sink)) {
+ if (filter->sink == sink) {
pa_sink_input *i;
PA_IDXSET_FOREACH(i, sink->inputs, idx)
@@ -481,13 +492,13 @@ static pa_hook_result_t source_unlink_cb(pa_core *core, pa_source *source, struc
/* If either the parent or the source we've loaded disappears,
* we should remove it from our hashmap */
PA_HASHMAP_FOREACH(filter, u->filters, state) {
- if (filter->parent_obj == PA_OBJECT(source) || filter->obj == PA_OBJECT(source)) {
+ if (filter->source_master == source || filter->source == source) {
uint32_t idx;
/* Attempt to rescue any streams to the parent source as this is likely
* the best course of action (as opposed to a generic rescue via
* module-rescue-streams */
- if (filter->obj == PA_OBJECT(source)) {
+ if (filter->source == source) {
pa_source_output *o;
PA_IDXSET_FOREACH(o, source->outputs, idx)
commit aaf0f5bd6e29c86dd5b96f2185bedc520d745ad4
Author: Arun Raghavan <arun.raghavan at collabora.co.uk>
Date: Wed Nov 23 16:46:12 2011 +0530
filters: Fix the master source/sink when autoloaded
When autoloaded, it is expected that module-filter-apply (or whatever is
loading us) will take care of applying the filter on the correct
sink/source master. Instead of adding complexity by tracking what is
currently being filtered, we just disallow filtering anything except the
original master sink/source and let module-filter-apply or whatever is
loading us deal with dynamic sink/source changes.
diff --git a/src/modules/echo-cancel/module-echo-cancel.c b/src/modules/echo-cancel/module-echo-cancel.c
index b810a4e..64e17bf 100644
--- a/src/modules/echo-cancel/module-echo-cancel.c
+++ b/src/modules/echo-cancel/module-echo-cancel.c
@@ -1399,7 +1399,7 @@ static pa_bool_t source_output_may_move_to_cb(pa_source_output *o, pa_source *de
pa_assert_ctl_context();
pa_assert_se(u = o->userdata);
- if (u->dead)
+ if (u->dead || u->autoloaded)
return FALSE;
return (u->source != dest) && (u->sink != dest->monitor_of);
@@ -1412,7 +1412,7 @@ static pa_bool_t 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)
+ if (u->dead || u->autoloaded)
return FALSE;
return u->sink != dest;
diff --git a/src/modules/module-equalizer-sink.c b/src/modules/module-equalizer-sink.c
index e83a41d..006b3d1 100644
--- a/src/modules/module-equalizer-sink.c
+++ b/src/modules/module-equalizer-sink.c
@@ -1055,6 +1055,9 @@ static pa_bool_t 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;
}
commit ac3d66f978f4276317e11ba9f1f156926a90b30c
Author: Arun Raghavan <arun.raghavan at collabora.co.uk>
Date: Tue Nov 22 13:24:22 2011 +0530
echo-cancel: Use more human-friendly descriptions
This makes what devices are being cancelled clearer in the UI (at the
cost of being somewhat less clear when multiple devices of the same name
are plugged, but at least that's a much smaller set than everyone).
diff --git a/src/modules/echo-cancel/module-echo-cancel.c b/src/modules/echo-cancel/module-echo-cancel.c
index c063734..b810a4e 100644
--- a/src/modules/echo-cancel/module-echo-cancel.c
+++ b/src/modules/echo-cancel/module-echo-cancel.c
@@ -1433,13 +1433,14 @@ static void source_output_moving_cb(pa_source_output *o, pa_source *dest) {
pa_source_set_asyncmsgq(u->source, NULL);
if (u->source_auto_desc && dest) {
- const char *z;
+ const char *y, *z;
pa_proplist *pl;
pl = pa_proplist_new();
+ y = pa_proplist_gets(u->sink_input->sink->proplist, PA_PROP_DEVICE_DESCRIPTION);
z = pa_proplist_gets(dest->proplist, PA_PROP_DEVICE_DESCRIPTION);
- pa_proplist_setf(pl, PA_PROP_DEVICE_DESCRIPTION, "Echo-Cancel Source %s on %s",
- pa_proplist_gets(u->source->proplist, "device.echo-cancel.name"), z ? z : dest->name);
+ pa_proplist_setf(pl, PA_PROP_DEVICE_DESCRIPTION, "%s (echo cancelled with %s)", z ? z : dest->name,
+ y ? y : u->sink_input->sink->name);
pa_source_update_proplist(u->source, PA_UPDATE_REPLACE, pl);
pa_proplist_free(pl);
@@ -1460,13 +1461,14 @@ static void sink_input_moving_cb(pa_sink_input *i, pa_sink *dest) {
pa_sink_set_asyncmsgq(u->sink, NULL);
if (u->sink_auto_desc && dest) {
- const char *z;
+ const char *y, *z;
pa_proplist *pl;
pl = pa_proplist_new();
+ y = pa_proplist_gets(u->source_output->source->proplist, PA_PROP_DEVICE_DESCRIPTION);
z = pa_proplist_gets(dest->proplist, PA_PROP_DEVICE_DESCRIPTION);
- pa_proplist_setf(pl, PA_PROP_DEVICE_DESCRIPTION, "Echo-Cancel Sink %s on %s",
- pa_proplist_gets(u->sink->proplist, "device.echo-cancel.name"), z ? z : dest->name);
+ pa_proplist_setf(pl, PA_PROP_DEVICE_DESCRIPTION, "%s (echo cancelled with %s)", z ? z : dest->name,
+ y ? y : u->source_output->source->name);
pa_sink_update_proplist(u->sink, PA_UPDATE_REPLACE, pl);
pa_proplist_free(pl);
@@ -1709,7 +1711,6 @@ int pa__init(pa_module*m) {
pa_proplist_sets(source_data.proplist, PA_PROP_DEVICE_CLASS, "filter");
if (!u->autoloaded)
pa_proplist_sets(source_data.proplist, PA_PROP_DEVICE_INTENDED_ROLES, "phone");
- pa_proplist_sets(source_data.proplist, "device.echo-cancel.name", source_data.name);
if (pa_modargs_get_proplist(ma, "source_properties", source_data.proplist, PA_UPDATE_REPLACE) < 0) {
pa_log("Invalid properties");
@@ -1718,10 +1719,12 @@ int pa__init(pa_module*m) {
}
if ((u->source_auto_desc = !pa_proplist_contains(source_data.proplist, PA_PROP_DEVICE_DESCRIPTION))) {
- const char *z;
+ const char *y, *z;
+ y = pa_proplist_gets(sink_master->proplist, PA_PROP_DEVICE_DESCRIPTION);
z = pa_proplist_gets(source_master->proplist, PA_PROP_DEVICE_DESCRIPTION);
- pa_proplist_setf(source_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Echo-Cancel Source %s on %s", source_data.name, z ? z : source_master->name);
+ pa_proplist_setf(source_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "%s (echo cancelled with %s)",
+ z ? z : source_master->name, y ? y : sink_master->name);
}
u->source = pa_source_new(m->core, &source_data, (source_master->flags & (PA_SOURCE_LATENCY | PA_SOURCE_DYNAMIC_LATENCY))
@@ -1759,7 +1762,6 @@ int pa__init(pa_module*m) {
pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_CLASS, "filter");
if (!u->autoloaded)
pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_INTENDED_ROLES, "phone");
- pa_proplist_sets(sink_data.proplist, "device.echo-cancel.name", sink_data.name);
if (pa_modargs_get_proplist(ma, "sink_properties", sink_data.proplist, PA_UPDATE_REPLACE) < 0) {
pa_log("Invalid properties");
@@ -1768,10 +1770,12 @@ int pa__init(pa_module*m) {
}
if ((u->sink_auto_desc = !pa_proplist_contains(sink_data.proplist, PA_PROP_DEVICE_DESCRIPTION))) {
- const char *z;
+ const char *y, *z;
+ y = pa_proplist_gets(source_master->proplist, PA_PROP_DEVICE_DESCRIPTION);
z = pa_proplist_gets(sink_master->proplist, PA_PROP_DEVICE_DESCRIPTION);
- pa_proplist_setf(sink_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Echo-Cancel Sink %s on %s", sink_data.name, z ? z : sink_master->name);
+ pa_proplist_setf(sink_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "%s (echo cancelled with %s)",
+ z ? z : sink_master->name, y ? y : source_master->name);
}
u->sink = pa_sink_new(m->core, &sink_data, (sink_master->flags & (PA_SINK_LATENCY | PA_SINK_DYNAMIC_LATENCY))
More information about the pulseaudio-commits
mailing list