This ensures that streams are moved away from unavailable outputs or inputs. For example, sometimes HDMI is on a dedicated alsa card, and if all HDMI outputs become unavailable, then the card profile will be set to "off", and the streams will be moved somewhere else. --- Changes in v2: - Don't call deactivate_direction() unconditionally. src/modules/module-switch-on-port-available.c | 40 ++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/src/modules/module-switch-on-port-available.c b/src/modules/module-switch-on-port-available.c index 8fd3c9e5f..c8e3d552b 100644 --- a/src/modules/module-switch-on-port-available.c +++ b/src/modules/module-switch-on-port-available.c @@ -80,7 +80,7 @@ static bool profile_good_for_output(pa_card_profile *profile, pa_device_port *po if (card->active_profile->max_source_channels != profile->max_source_channels) return false; - if (port == card->preferred_output_port) + if (port && port == card->preferred_output_port) return true; PA_IDXSET_FOREACH(sink, card->sinks, idx) { @@ -251,6 +251,42 @@ static void switch_to_port(pa_device_port *port) { pa_sink_set_port(pp.sink, port->name, false); } +static void deactivate_direction(pa_card *card, pa_direction_t direction) { + pa_card_profile *profile; + void *state; + pa_card_profile *best_profile = NULL; + const char *direction_str; + + PA_HASHMAP_FOREACH(profile, card->profiles, state) { + switch (direction) { + case PA_DIRECTION_OUTPUT: + if (profile->n_sinks != 0) + continue; + if (!profile_good_for_output(profile, NULL)) + continue; + break; + + case PA_DIRECTION_INPUT: + if (profile->n_sources != 0) + continue; + if (!profile_good_for_input(profile, NULL)) + continue; + break; + } + + if (!best_profile || profile->priority > best_profile->priority) + best_profile = profile; + } + + direction_str = direction == PA_DIRECTION_OUTPUT ? "output" : "input"; + + if (best_profile) { + pa_log_debug("Deactivating %s on card %s.", direction_str, card->name); + pa_card_set_profile(card, best_profile, false); + } else + pa_log_debug("Wanted to deactivate %s on card %s, but no suitable profile was found.", direction_str, card->name); +} + /* Switches away from a port, switching profiles if necessary or preferred */ static void switch_from_port(pa_device_port *port) { struct port_pointers pp = find_port_pointers(port); @@ -270,6 +306,8 @@ static void switch_from_port(pa_device_port *port) { if (best_port) switch_to_port(best_port); + else + deactivate_direction(port->card, port->direction); } -- 2.14.2