[pulseaudio-discuss] [PATCH 5/5] device-port: Make it impossible to have a dual-direction port.
Tanu Kaskinen
tanu.kaskinen at digia.com
Tue Apr 17 01:08:58 PDT 2012
---
src/modules/alsa/alsa-mixer.c | 81 ++++++++++++++++++-------
src/modules/module-switch-on-port-available.c | 27 +++++----
src/pulsecore/device-port.c | 5 +-
src/pulsecore/device-port.h | 5 +-
src/pulsecore/protocol-native.c | 2 +-
5 files changed, 79 insertions(+), 41 deletions(-)
diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c
index 98a0da5..5cb6a17 100644
--- a/src/modules/alsa/alsa-mixer.c
+++ b/src/modules/alsa/alsa-mixer.c
@@ -2804,12 +2804,41 @@ void pa_alsa_path_set_set_callback(pa_alsa_path_set *ps, snd_mixer_t *m, snd_mix
pa_alsa_path_set_callback(p, m, cb, userdata);
}
+static pa_alsa_path *profile_set_get_path(pa_alsa_profile_set *ps, const char *path_name) {
+ pa_alsa_path *path;
+
+ pa_assert(ps);
+ pa_assert(path_name);
+
+ if ((path = pa_hashmap_get(ps->output_paths, path_name)))
+ return path;
+
+ return pa_hashmap_get(ps->input_paths, path_name);
+}
+
+static void profile_set_add_path(pa_alsa_profile_set *ps, pa_alsa_path *path) {
+ pa_assert(ps);
+ pa_assert(path);
+
+ switch (path->direction) {
+ case PA_ALSA_DIRECTION_OUTPUT:
+ pa_assert_se(pa_hashmap_put(ps->output_paths, path->name, path) >= 0);
+ break;
+
+ case PA_ALSA_DIRECTION_INPUT:
+ pa_assert_se(pa_hashmap_put(ps->input_paths, path->name, path) >= 0);
+ break;
+
+ default:
+ pa_assert_not_reached();
+ }
+}
+
pa_alsa_path_set *pa_alsa_path_set_new(pa_alsa_mapping *m, pa_alsa_direction_t direction, const char *paths_dir) {
pa_alsa_path_set *ps;
char **pn = NULL, **en = NULL, **ie;
pa_alsa_decibel_fix *db_fix;
void *state, *state2;
- pa_hashmap *cache;
pa_assert(m);
pa_assert(m->profile_set);
@@ -2823,14 +2852,10 @@ pa_alsa_path_set *pa_alsa_path_set_new(pa_alsa_mapping *m, pa_alsa_direction_t d
ps->direction = direction;
ps->paths = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
- if (direction == PA_ALSA_DIRECTION_OUTPUT) {
+ if (direction == PA_ALSA_DIRECTION_OUTPUT)
pn = m->output_path_names;
- cache = m->profile_set->output_paths;
- }
- else if (direction == PA_ALSA_DIRECTION_INPUT) {
+ else
pn = m->input_path_names;
- cache = m->profile_set->input_paths;
- }
if (pn) {
char **in;
@@ -2849,15 +2874,21 @@ pa_alsa_path_set *pa_alsa_path_set_new(pa_alsa_mapping *m, pa_alsa_direction_t d
if (duplicate)
continue;
- p = pa_hashmap_get(cache, *in);
+ p = profile_set_get_path(m->profile_set, *in);
+
+ if (p && p->direction != direction) {
+ pa_log("Configuration error: Path %s is used both as an input and as an output path.", p->name);
+ goto fail;
+ }
+
if (!p) {
char *fn = pa_sprintf_malloc("%s.conf", *in);
p = pa_alsa_path_new(paths_dir, fn, direction);
pa_xfree(fn);
if (p)
- pa_hashmap_put(cache, *in, p);
+ profile_set_add_path(m->profile_set, p);
}
- pa_assert(pa_hashmap_get(cache, *in) == p);
+
if (p)
pa_hashmap_put(ps->paths, p, p);
@@ -2868,13 +2899,11 @@ pa_alsa_path_set *pa_alsa_path_set_new(pa_alsa_mapping *m, pa_alsa_direction_t d
if (direction == PA_ALSA_DIRECTION_OUTPUT)
en = m->output_element;
- else if (direction == PA_ALSA_DIRECTION_INPUT)
+ else
en = m->input_element;
- if (!en) {
- pa_alsa_path_set_free(ps);
- return NULL;
- }
+ if (!en)
+ goto fail;
for (ie = en; *ie; ie++) {
char **je;
@@ -2926,6 +2955,12 @@ finish:
}
return ps;
+
+fail:
+ if (ps)
+ pa_alsa_path_set_free(ps);
+
+ return NULL;
}
void pa_alsa_path_set_dump(pa_alsa_path_set *ps) {
@@ -4321,13 +4356,13 @@ void pa_alsa_profile_set_dump(pa_alsa_profile_set *ps) {
pa_alsa_decibel_fix_dump(db_fix);
}
-static pa_device_port* device_port_alsa_init(pa_hashmap *ports,
+static pa_device_port* device_port_alsa_init(pa_hashmap *ports, /* card ports */
const char* name,
const char* description,
pa_alsa_path *path,
pa_alsa_setting *setting,
pa_card_profile *cp,
- pa_hashmap *extra,
+ pa_hashmap *extra, /* sink/source ports */
pa_core *core) {
pa_device_port *p;
@@ -4338,8 +4373,11 @@ static pa_device_port* device_port_alsa_init(pa_hashmap *ports,
if (!p) {
pa_alsa_port_data *data;
+ pa_direction_t direction;
- p = pa_device_port_new(core, name, description, sizeof(pa_alsa_port_data));
+ direction = path->direction == PA_ALSA_DIRECTION_OUTPUT ? PA_DIRECTION_OUTPUT : PA_DIRECTION_INPUT;
+
+ p = pa_device_port_new(core, name, description, direction, sizeof(pa_alsa_port_data));
pa_assert(p);
pa_hashmap_put(ports, p->name, p);
pa_proplist_update(p->proplist, PA_UPDATE_REPLACE, path->proplist);
@@ -4350,9 +4388,6 @@ static pa_device_port* device_port_alsa_init(pa_hashmap *ports,
path->port = p;
}
- p->is_input |= path->direction == PA_ALSA_DIRECTION_ANY || path->direction == PA_ALSA_DIRECTION_INPUT;
- p->is_output |= path->direction == PA_ALSA_DIRECTION_ANY || path->direction == PA_ALSA_DIRECTION_OUTPUT;
-
if (cp)
pa_hashmap_put(p->profiles, cp->name, cp);
@@ -4367,8 +4402,8 @@ static pa_device_port* device_port_alsa_init(pa_hashmap *ports,
void pa_alsa_path_set_add_ports(
pa_alsa_path_set *ps,
pa_card_profile *cp,
- pa_hashmap *ports,
- pa_hashmap *extra,
+ pa_hashmap *ports, /* card ports */
+ pa_hashmap *extra, /* sink/source ports */
pa_core *core) {
pa_alsa_path *path;
diff --git a/src/modules/module-switch-on-port-available.c b/src/modules/module-switch-on-port-available.c
index f83b7aa..a1f0ab8 100644
--- a/src/modules/module-switch-on-port-available.c
+++ b/src/modules/module-switch-on-port-available.c
@@ -92,8 +92,6 @@ static pa_bool_t try_to_switch_profile(pa_card *card, pa_device_port *port) {
pa_log_debug("Finding best profile");
PA_HASHMAP_FOREACH(profile, port->profiles, state) {
- pa_direction_t direction = port->is_output ? PA_DIRECTION_OUTPUT : PA_DIRECTION_INPUT;
-
if (best_profile && best_profile->priority >= profile->priority)
continue;
@@ -103,7 +101,7 @@ static pa_bool_t try_to_switch_profile(pa_card *card, pa_device_port *port) {
}
/* We make a best effort to keep other direction unchanged */
- switch (direction) {
+ switch (port->direction) {
case PA_DIRECTION_OUTPUT:
if (!profile_good_for_output(profile))
continue;
@@ -140,15 +138,22 @@ static void find_sink_and_source(pa_card *card, pa_device_port *port, pa_sink **
pa_source *source = NULL;
uint32_t state;
- if (port->is_output)
- PA_IDXSET_FOREACH(sink, card->sinks, state)
- if (sink->ports && port == pa_hashmap_get(sink->ports, port->name))
- break;
+ switch (port->direction) {
+ case PA_DIRECTION_OUTPUT:
+ PA_IDXSET_FOREACH(sink, card->sinks, state)
+ if (sink->ports && port == pa_hashmap_get(sink->ports, port->name))
+ break;
+ break;
- if (port->is_input)
- PA_IDXSET_FOREACH(source, card->sources, state)
- if (source->ports && port == pa_hashmap_get(source->ports, port->name))
- break;
+ case PA_DIRECTION_INPUT:
+ PA_IDXSET_FOREACH(source, card->sources, state)
+ if (source->ports && port == pa_hashmap_get(source->ports, port->name))
+ break;
+ break;
+
+ default:
+ pa_assert_not_reached();
+ }
*si = sink;
*so = source;
diff --git a/src/pulsecore/device-port.c b/src/pulsecore/device-port.c
index c2d8fff..b7a4692 100644
--- a/src/pulsecore/device-port.c
+++ b/src/pulsecore/device-port.c
@@ -81,7 +81,7 @@ static void device_port_free(pa_object *o) {
}
-pa_device_port *pa_device_port_new(pa_core *c, const char *name, const char *description, size_t extra) {
+pa_device_port *pa_device_port_new(pa_core *c, const char *name, const char *description, pa_direction_t direction, size_t extra) {
pa_device_port *p;
pa_assert(name);
@@ -94,10 +94,9 @@ pa_device_port *pa_device_port_new(pa_core *c, const char *name, const char *des
p->core = c;
p->priority = 0;
p->available = PA_PORT_AVAILABLE_UNKNOWN;
- p->is_input = FALSE;
- p->is_output = FALSE;
p->profiles = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
p->proplist = pa_proplist_new();
+ p->direction = direction;
return p;
}
diff --git a/src/pulsecore/device-port.h b/src/pulsecore/device-port.h
index 63d5ccf..c9f222e 100644
--- a/src/pulsecore/device-port.h
+++ b/src/pulsecore/device-port.h
@@ -49,8 +49,7 @@ struct pa_device_port {
pa_proplist *proplist;
pa_hashmap *profiles; /* Does not own the profiles */
- pa_bool_t is_input:1;
- pa_bool_t is_output:1;
+ pa_direction_t direction;
/* .. followed by some implementation specific data */
};
@@ -60,7 +59,7 @@ PA_DECLARE_PUBLIC_CLASS(pa_device_port);
#define PA_DEVICE_PORT_DATA(d) ((void*) ((uint8_t*) d + PA_ALIGN(sizeof(pa_device_port))))
-pa_device_port *pa_device_port_new(pa_core *c, const char *name, const char *description, size_t extra);
+pa_device_port *pa_device_port_new(pa_core *c, const char *name, const char *description, pa_direction_t direction, size_t extra);
void pa_device_port_hashmap_free(pa_hashmap *h);
diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c
index 5b2c433..7ceeb35 100644
--- a/src/pulsecore/protocol-native.c
+++ b/src/pulsecore/protocol-native.c
@@ -3274,7 +3274,7 @@ static void card_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_car
pa_tagstruct_puts(t, port->description);
pa_tagstruct_putu32(t, port->priority);
pa_tagstruct_putu32(t, port->available);
- pa_tagstruct_putu8(t, /* FIXME: port->direction */ (port->is_input ? PA_DIRECTION_INPUT : 0) | (port->is_output ? PA_DIRECTION_OUTPUT : 0));
+ pa_tagstruct_putu8(t, port->direction);
pa_tagstruct_put_proplist(t, port->proplist);
pa_tagstruct_putu32(t, pa_hashmap_size(port->profiles));
--
1.7.10
More information about the pulseaudio-discuss
mailing list