summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlper Nebi Yasak <alpernebiyasak@gmail.com>2022-06-29 15:37:18 +0300
committerPulseAudio Marge Bot <pulseaudio-maintainers@lists.freedesktop.org>2023-03-19 20:51:00 +0000
commitb74269016c1f7babcdd69d33f20cedbe33fe3124 (patch)
tree030b9bb14a880c52bfc5d93172e4dbecec4a110e
parentb382a00f8bf937e6825892ea0c971c99018dc466 (diff)
downloadpulseaudio-b74269016c1f7babcdd69d33f20cedbe33fe3124.tar.gz
alsa-ucm: Disable old modifiers when switching profiles of same verb
While switching profiles of the same UCM verb, existing code first disables devices that are only on the first profile to avoid conflicts. However, it only disables devices, not modifiers. Even worse, modifiers which have PlaybackPCM/CapturePCM are incorrectly treated as devices and result in a segmentation fault. Check what we are disabling, and call the appropriate disable function for both devices and modifiers. Modifiers are disabled before devices, because _dismod calls fail when the modifier's supported devices are disabled. Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com> Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/742>
-rw-r--r--src/modules/alsa/alsa-ucm.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/src/modules/alsa/alsa-ucm.c b/src/modules/alsa/alsa-ucm.c
index ecf296442..785b23453 100644
--- a/src/modules/alsa/alsa-ucm.c
+++ b/src/modules/alsa/alsa-ucm.c
@@ -1498,15 +1498,28 @@ int pa_alsa_ucm_set_profile(pa_alsa_ucm_config *ucm, pa_card *card, pa_alsa_prof
}
} else if (ucm->active_verb) {
+ /* Disable modifiers not in new profile. Has to be done before
+ * devices, because _dismod fails if a modifier's supported
+ * devices are disabled. */
+ PA_IDXSET_FOREACH(map, old_profile->input_mappings, idx)
+ if (new_profile && !pa_idxset_contains(new_profile->input_mappings, map))
+ if (map->ucm_context.ucm_modifier && ucm_modifier_disable(ucm, map->ucm_context.ucm_modifier) < 0)
+ ret = -1;
+
+ PA_IDXSET_FOREACH(map, old_profile->output_mappings, idx)
+ if (new_profile && !pa_idxset_contains(new_profile->output_mappings, map))
+ if (map->ucm_context.ucm_modifier && ucm_modifier_disable(ucm, map->ucm_context.ucm_modifier) < 0)
+ ret = -1;
+
/* Disable devices not in new profile */
PA_IDXSET_FOREACH(map, old_profile->input_mappings, idx)
if (new_profile && !pa_idxset_contains(new_profile->input_mappings, map))
- if (ucm_device_disable(ucm, map->ucm_context.ucm_device) < 0)
+ if (map->ucm_context.ucm_device && ucm_device_disable(ucm, map->ucm_context.ucm_device) < 0)
ret = -1;
PA_IDXSET_FOREACH(map, old_profile->output_mappings, idx)
if (new_profile && !pa_idxset_contains(new_profile->output_mappings, map))
- if (ucm_device_disable(ucm, map->ucm_context.ucm_device) < 0)
+ if (map->ucm_context.ucm_device && ucm_device_disable(ucm, map->ucm_context.ucm_device) < 0)
ret = -1;
}
ucm->active_verb = verb;