From: Tanu Kaskinen <tanu.kaskinen@xxxxxxxxx> --- src/modules/alsa/alsa-mixer.c | 81 ++++++++++++++++------- src/modules/bluetooth/module-bluetooth-device.c | 24 ++----- src/modules/module-switch-on-port-available.c | 27 +++++--- src/pulsecore/device-port.c | 45 ++++++++----- src/pulsecore/device-port.h | 5 +- src/pulsecore/protocol-native.c | 2 +- 6 files changed, 111 insertions(+), 73 deletions(-) diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c index b573e8d..90b55f5 100644 --- a/src/modules/alsa/alsa-mixer.c +++ b/src/modules/alsa/alsa-mixer.c @@ -2812,12 +2812,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); @@ -2831,14 +2860,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; @@ -2857,15 +2882,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); @@ -2876,13 +2907,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; @@ -2934,6 +2963,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) { @@ -4376,13 +4411,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; @@ -4393,8 +4428,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); @@ -4405,9 +4443,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); @@ -4422,8 +4457,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/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index 06b4033..3b841ff 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -2759,51 +2759,39 @@ static void create_ports_for_profile(struct userdata *u, pa_card_new_data *card_ switch (*d) { case PROFILE_A2DP: - pa_assert_se(port = pa_device_port_new(u->core, "a2dp-output", _("Bluetooth High Quality (A2DP)"), 0)); + pa_assert_se(port = pa_device_port_new(u->core, "a2dp-output", _("Bluetooth High Quality (A2DP)"), PA_DIRECTION_OUTPUT, 0)); pa_assert_se(pa_hashmap_put(card_new_data->ports, port->name, port) >= 0); - port->is_output = 1; - port->is_input = 0; port->priority = profile->priority * 100; pa_hashmap_put(port->profiles, profile->name, profile); break; case PROFILE_A2DP_SOURCE: - pa_assert_se(port = pa_device_port_new(u->core, "a2dp-input", _("Bluetooth High Quality (A2DP)"), 0)); + pa_assert_se(port = pa_device_port_new(u->core, "a2dp-input", _("Bluetooth High Quality (A2DP)"), PA_DIRECTION_INPUT, 0)); pa_assert_se(pa_hashmap_put(card_new_data->ports, port->name, port) >= 0); - port->is_output = 0; - port->is_input = 1; port->priority = profile->priority * 100; pa_hashmap_put(port->profiles, profile->name, profile); break; case PROFILE_HSP: - pa_assert_se(port = pa_device_port_new(u->core, "hsp-output", _("Bluetooth Telephony (HSP/HFP)"), 0)); + pa_assert_se(port = pa_device_port_new(u->core, "hsp-output", _("Bluetooth Telephony (HSP/HFP)"), PA_DIRECTION_OUTPUT, 0)); pa_assert_se(pa_hashmap_put(card_new_data->ports, port->name, port) >= 0); - port->is_output = 1; - port->is_input = 0; port->priority = profile->priority * 100; pa_hashmap_put(port->profiles, profile->name, profile); - pa_assert_se(port = pa_device_port_new(u->core, "hsp-input", _("Bluetooth Telephony (HSP/HFP)"), 0)); + pa_assert_se(port = pa_device_port_new(u->core, "hsp-input", _("Bluetooth Telephony (HSP/HFP)"), PA_DIRECTION_INPUT, 0)); pa_assert_se(pa_hashmap_put(card_new_data->ports, port->name, port) >= 0); - port->is_output = 0; - port->is_input = 1; port->priority = profile->priority * 100; pa_hashmap_put(port->profiles, profile->name, profile); break; case PROFILE_HFGW: - pa_assert_se(port = pa_device_port_new(u->core, "hfgw-output", _("Bluetooth Handsfree Gateway"), 0)); + pa_assert_se(port = pa_device_port_new(u->core, "hfgw-output", _("Bluetooth Handsfree Gateway"), PA_DIRECTION_OUTPUT, 0)); pa_assert_se(pa_hashmap_put(card_new_data->ports, port->name, port) >= 0); - port->is_output = 1; - port->is_input = 0; port->priority = profile->priority * 100; pa_hashmap_put(port->profiles, profile->name, profile); - pa_assert_se(port = pa_device_port_new(u->core, "hfgw-input", _("Bluetooth Handsfree Gateway"), 0)); + pa_assert_se(port = pa_device_port_new(u->core, "hfgw-input", _("Bluetooth Handsfree Gateway"), PA_DIRECTION_INPUT, 0)); pa_assert_se(pa_hashmap_put(card_new_data->ports, port->name, port) >= 0); - port->is_output = 0; - port->is_input = 1; port->priority = profile->priority * 100; pa_hashmap_put(port->profiles, profile->name, profile); break; diff --git a/src/modules/module-switch-on-port-available.c b/src/modules/module-switch-on-port-available.c index 05bf5fe..07586de 100644 --- a/src/modules/module-switch-on-port-available.c +++ b/src/modules/module-switch-on-port-available.c @@ -92,13 +92,11 @@ 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; /* 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; @@ -135,15 +133,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 (port == pa_hashmap_get(sink->ports, port->name)) - break; + switch (port->direction) { + case PA_DIRECTION_OUTPUT: + PA_IDXSET_FOREACH(sink, card->sinks, state) + if (port == pa_hashmap_get(sink->ports, port->name)) + break; + break; - if (port->is_input) - PA_IDXSET_FOREACH(source, card->sources, state) - if (port == pa_hashmap_get(source->ports, port->name)) - break; + case PA_DIRECTION_INPUT: + PA_IDXSET_FOREACH(source, card->sources, state) + if (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 28879f7..ef178ab 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); @@ -89,16 +89,15 @@ pa_device_port *pa_device_port_new(pa_core *c, const char *name, const char *des p = PA_DEVICE_PORT(pa_object_new_internal(PA_ALIGN(sizeof(pa_device_port)) + extra, pa_device_port_type_id, pa_device_port_check_type)); p->parent.free = device_port_free; + p->core = c; p->name = pa_xstrdup(name); p->description = pa_xstrdup(description); - p->core = c; p->priority = 0; p->available = PA_PORT_AVAILABLE_UNKNOWN; + p->proplist = pa_proplist_new(); p->profiles = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); - p->is_input = FALSE; - p->is_output = FALSE; + p->direction = direction; p->latency_offset = 0; - p->proplist = pa_proplist_new(); return p; } @@ -121,22 +120,34 @@ void pa_device_port_set_latency_offset(pa_device_port *p, int64_t offset) { p->latency_offset = offset; - if (p->is_output) { - pa_sink *sink; + switch (p->direction) { + case PA_DIRECTION_OUTPUT: { + pa_sink *sink; - PA_IDXSET_FOREACH(sink, p->core->sinks, state) - if (sink->active_port == p) { - pa_sink_set_latency_offset(sink, p->latency_offset); - break; + PA_IDXSET_FOREACH(sink, p->core->sinks, state) { + if (sink->active_port == p) { + pa_sink_set_latency_offset(sink, p->latency_offset); + break; + } } - } else { - pa_source *source; + break; + } - PA_IDXSET_FOREACH(source, p->core->sources, state) - if (source->active_port == p) { - pa_source_set_latency_offset(source, p->latency_offset); - break; + case PA_DIRECTION_INPUT: { + pa_source *source; + + PA_IDXSET_FOREACH(source, p->core->sources, state) { + if (source->active_port == p) { + pa_source_set_latency_offset(source, p->latency_offset); + break; + } } + + break; + } + + default: + pa_assert_not_reached(); } } diff --git a/src/pulsecore/device-port.h b/src/pulsecore/device-port.h index a5c6420..45f5553 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; int64_t latency_offset; /* .. followed by some implementation specific data */ @@ -61,7 +60,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 3e9c911..f34264f 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -3265,7 +3265,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