From b8361cc5680f66afe9b5d46106f3e3c795ff9fda Mon Sep 17 00:00:00 2001 From: Alper Nebi Yasak Date: Mon, 27 Nov 2023 23:49:27 +0300 Subject: [PATCH] alsa-ucm: Make ports store only one device After previous patches, we should be generating no combination ports, so we don't need to store multiple devices per port. Simplify the code based on this. Link: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/commit/bf1708213b0f28093ea4de6c033f0d5a29dabcbb Signed-off-by: Alper Nebi Yasak --- spa/plugins/alsa/acp/acp.c | 6 +- spa/plugins/alsa/acp/alsa-ucm.c | 120 ++++++-------------------------- spa/plugins/alsa/acp/alsa-ucm.h | 6 +- 3 files changed, 24 insertions(+), 108 deletions(-) diff --git a/spa/plugins/alsa/acp/acp.c b/spa/plugins/alsa/acp/acp.c index cc13530ea..7992b4508 100644 --- a/spa/plugins/alsa/acp/acp.c +++ b/spa/plugins/alsa/acp/acp.c @@ -1330,8 +1330,7 @@ static int setup_mixer(pa_card *impl, pa_alsa_device *dev, bool ignore_dB) * will be NULL, but the UCM device enable sequence will still need to be * executed. */ if (dev->active_port && dev->ucm_context) { - if ((res = pa_alsa_ucm_set_port(dev->ucm_context, dev->active_port, - dev->direction == PA_ALSA_DIRECTION_OUTPUT)) < 0) + if ((res = pa_alsa_ucm_set_port(dev->ucm_context, dev->active_port)) < 0) return res; } @@ -1927,8 +1926,7 @@ int acp_device_set_port(struct acp_device *dev, uint32_t port_index, uint32_t fl mixer_volume_init(impl, d); sync_mixer(d, p); - res = pa_alsa_ucm_set_port(d->ucm_context, p, - dev->direction == ACP_DIRECTION_PLAYBACK); + res = pa_alsa_ucm_set_port(d->ucm_context, p); } else { pa_alsa_port_data *data; diff --git a/spa/plugins/alsa/acp/alsa-ucm.c b/spa/plugins/alsa/acp/alsa-ucm.c index d111a1c6b..4d1bde570 100644 --- a/spa/plugins/alsa/acp/alsa-ucm.c +++ b/spa/plugins/alsa/acp/alsa-ucm.c @@ -72,9 +72,8 @@ static pa_alsa_ucm_device *verb_find_device(pa_alsa_ucm_verb *verb, const char * static void ucm_port_data_init(pa_alsa_ucm_port_data *port, pa_alsa_ucm_config *ucm, pa_device_port *core_port, - pa_alsa_ucm_device **devices, unsigned n_devices); + pa_alsa_ucm_device *device); static void ucm_port_data_free(pa_device_port *port); -static void ucm_port_update_available(pa_alsa_ucm_port_data *port); static struct ucm_type types[] = { {"None", PA_DEVICE_PORT_TYPE_UNKNOWN}, @@ -945,30 +944,15 @@ static void set_eld_devices(pa_hashmap *hash) pa_device_port *port; pa_alsa_ucm_port_data *data; pa_alsa_ucm_device *dev; - const char *eld_mixer_device_name; void *state; - int idx, eld_device; PA_HASHMAP_FOREACH(port, hash, state) { data = PA_DEVICE_PORT_DATA(port); - eld_mixer_device_name = NULL; - eld_device = -1; - PA_DYNARRAY_FOREACH(dev, data->devices, idx) { - if (dev->eld_device >= 0 && dev->eld_mixer_device_name) { - if (eld_device >= 0 && eld_device != dev->eld_device) { - pa_log_error("The ELD device is already set!"); - } else if (eld_mixer_device_name && pa_streq(dev->eld_mixer_device_name, eld_mixer_device_name)) { - pa_log_error("The ELD mixer device is already set (%s, %s)!", dev->eld_mixer_device_name, dev->eld_mixer_device_name); - } else { - eld_mixer_device_name = dev->eld_mixer_device_name; - eld_device = dev->eld_device; - } - } - } - data->eld_device = eld_device; + dev = data->device; + data->eld_device = dev->eld_device; if (data->eld_mixer_device_name) pa_xfree(data->eld_mixer_device_name); - data->eld_mixer_device_name = pa_xstrdup(eld_mixer_device_name); + data->eld_mixer_device_name = pa_xstrdup(dev->eld_mixer_device_name); } } @@ -991,24 +975,14 @@ static void probe_volumes(pa_hashmap *hash, bool is_sink, snd_pcm_t *pcm_handle, pa_alsa_ucm_port_data *data; pa_alsa_ucm_device *dev; snd_mixer_t *mixer_handle; - const char *profile, *mdev, *mdev2; + const char *profile, *mdev; void *state, *state2; - int idx; PA_HASHMAP_FOREACH(port, hash, state) { data = PA_DEVICE_PORT_DATA(port); - mdev = NULL; - PA_DYNARRAY_FOREACH(dev, data->devices, idx) { - mdev2 = get_mixer_device(dev, is_sink); - if (mdev && mdev2 && !pa_streq(mdev, mdev2)) { - pa_log_error("Two mixer device names found ('%s', '%s'), using s/w volume", mdev, mdev2); - goto fail; - } - if (mdev2) - mdev = mdev2; - } - + dev = data->device; + mdev = get_mixer_device(dev, is_sink); if (mdev == NULL || !(mixer_handle = pa_alsa_open_mixer_by_name(mixers, mdev, true))) { pa_log_error("Failed to find a working mixer device (%s).", mdev); goto fail; @@ -1226,7 +1200,7 @@ void pa_alsa_ucm_add_port( pa_device_port_new_data_done(&port_data); data = PA_DEVICE_PORT_DATA(port); - ucm_port_data_init(data, context->ucm, port, &dev, 1); + ucm_port_data_init(data, context->ucm, port, dev); port->impl_free = ucm_port_data_free; pa_hashmap_put(ports, port->name, port); @@ -1278,27 +1252,6 @@ void pa_alsa_ucm_add_port( set_eld_devices(ports); } -static int ucm_port_contains(const char *port_name, const char *dev_name, bool is_sink) { - int ret = 0; - const char *r; - const char *state = NULL; - size_t len; - - if (!port_name || !dev_name) - return false; - - port_name += is_sink ? strlen(PA_UCM_PRE_TAG_OUTPUT) : strlen(PA_UCM_PRE_TAG_INPUT); - - while ((r = pa_split_in_place(port_name, "+", &len, &state))) { - if (strlen(dev_name) == len && !strncmp(r, dev_name, len)) { - ret = 1; - break; - } - } - - return ret; -} - static bool devset_supports_device(pa_idxset *devices, pa_alsa_ucm_device *dev) { pa_alsa_ucm_device *d; uint32_t idx; @@ -1495,7 +1448,7 @@ int pa_alsa_ucm_set_profile(pa_alsa_ucm_config *ucm, pa_card *card, pa_alsa_prof return ret; } -int pa_alsa_ucm_set_port(pa_alsa_ucm_mapping_context *context, pa_device_port *port, bool is_sink) { +int pa_alsa_ucm_set_port(pa_alsa_ucm_mapping_context *context, pa_device_port *port) { int i; int ret = 0; pa_alsa_ucm_config *ucm; @@ -1503,19 +1456,20 @@ int pa_alsa_ucm_set_port(pa_alsa_ucm_mapping_context *context, pa_device_port *p int enable_num = 0; uint32_t idx; pa_alsa_ucm_device *dev; + pa_alsa_ucm_port_data *data; pa_assert(context && context->ucm); ucm = context->ucm; pa_assert(ucm->ucm_mgr); + data = PA_DEVICE_PORT_DATA(port); + enable_devs = pa_xnew(pa_alsa_ucm_device *, pa_idxset_size(context->ucm_devices)); /* first disable then enable */ PA_IDXSET_FOREACH(dev, context->ucm_devices, idx) { - const char *dev_name = pa_proplist_gets(dev->proplist, PA_ALSA_PROP_UCM_NAME); - - if (ucm_port_contains(port->name, dev_name, is_sink)) + if (dev == data->device) enable_devs[enable_num++] = dev; else ret = ucm_device_disable(ucm, dev); @@ -2357,13 +2311,6 @@ void pa_alsa_ucm_roled_stream_end(pa_alsa_ucm_config *ucm, const char *role, pa_ } } -static void device_add_ucm_port(pa_alsa_ucm_device *device, pa_alsa_ucm_port_data *port) { - pa_assert(device); - pa_assert(port); - - pa_dynarray_append(device->ucm_ports, port); -} - static void device_set_jack(pa_alsa_ucm_device *device, pa_alsa_jack *jack) { pa_assert(device); pa_assert(jack); @@ -2396,7 +2343,7 @@ static void device_set_available(pa_alsa_ucm_device *device, pa_available_t avai device->available = available; PA_DYNARRAY_FOREACH(port, device->ucm_ports, idx) - ucm_port_update_available(port); + pa_device_port_set_available(port->core_port, port->device->available); } void pa_alsa_ucm_device_update_available(pa_alsa_ucm_device *device) { @@ -2420,26 +2367,21 @@ void pa_alsa_ucm_device_update_available(pa_alsa_ucm_device *device) { } static void ucm_port_data_init(pa_alsa_ucm_port_data *port, pa_alsa_ucm_config *ucm, pa_device_port *core_port, - pa_alsa_ucm_device **devices, unsigned n_devices) { - unsigned i; - + pa_alsa_ucm_device *device) { pa_assert(ucm); pa_assert(core_port); - pa_assert(devices); + pa_assert(device); port->ucm = ucm; port->core_port = core_port; - port->devices = pa_dynarray_new(NULL); port->eld_device = -1; - for (i = 0; i < n_devices; i++) { - pa_dynarray_append(port->devices, devices[i]); - device_add_ucm_port(devices[i], port); - } + port->device = device; + pa_dynarray_append(device->ucm_ports, port); port->paths = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, pa_xfree, NULL); - ucm_port_update_available(port); + pa_device_port_set_available(port->core_port, port->device->available); } static void ucm_port_data_free(pa_device_port *port) { @@ -2449,34 +2391,12 @@ static void ucm_port_data_free(pa_device_port *port) { ucm_port = PA_DEVICE_PORT_DATA(port); - if (ucm_port->devices) - pa_dynarray_free(ucm_port->devices); - if (ucm_port->paths) pa_hashmap_free(ucm_port->paths); pa_xfree(ucm_port->eld_mixer_device_name); } -static void ucm_port_update_available(pa_alsa_ucm_port_data *port) { - pa_alsa_ucm_device *device; - unsigned idx; - pa_available_t available = PA_AVAILABLE_YES; - - pa_assert(port); - - PA_DYNARRAY_FOREACH(device, port->devices, idx) { - if (device->available == PA_AVAILABLE_UNKNOWN) - available = PA_AVAILABLE_UNKNOWN; - else if (device->available == PA_AVAILABLE_NO) { - available = PA_AVAILABLE_NO; - break; - } - } - - pa_device_port_set_available(port->core_port, available); -} - #else /* HAVE_ALSA_UCM */ /* Dummy functions for systems without UCM support */ @@ -2517,7 +2437,7 @@ void pa_alsa_ucm_add_port( pa_core *core) { } -int pa_alsa_ucm_set_port(pa_alsa_ucm_mapping_context *context, pa_device_port *port, bool is_sink) { +int pa_alsa_ucm_set_port(pa_alsa_ucm_mapping_context *context, pa_device_port *port) { return -1; } diff --git a/spa/plugins/alsa/acp/alsa-ucm.h b/spa/plugins/alsa/acp/alsa-ucm.h index 848c8625d..2d8f8ab45 100644 --- a/spa/plugins/alsa/acp/alsa-ucm.h +++ b/spa/plugins/alsa/acp/alsa-ucm.h @@ -167,7 +167,7 @@ void pa_alsa_ucm_add_port( pa_hashmap *ports, pa_card_profile *cp, pa_core *core); -int pa_alsa_ucm_set_port(pa_alsa_ucm_mapping_context *context, pa_device_port *port, bool is_sink); +int pa_alsa_ucm_set_port(pa_alsa_ucm_mapping_context *context, pa_device_port *port); void pa_alsa_ucm_free(pa_alsa_ucm_config *ucm); void pa_alsa_ucm_mapping_context_free(pa_alsa_ucm_mapping_context *context); @@ -280,9 +280,7 @@ struct pa_alsa_ucm_port_data { pa_alsa_ucm_config *ucm; pa_device_port *core_port; - /* A single port will be associated with multiple devices if it represents - * a combination of devices. */ - pa_dynarray *devices; /* pa_alsa_ucm_device */ + pa_alsa_ucm_device *device; /* profile name -> pa_alsa_path for volume control */ pa_hashmap *paths;