As an extra, I broke try_to_switch_profile() into smaller functions, because the two levels of loops with continue statements inside both were a bit hard to follow. --- src/modules/module-switch-on-port-available.c | 76 ++++++++++++++++--------- 1 file changed, 49 insertions(+), 27 deletions(-) diff --git a/src/modules/module-switch-on-port-available.c b/src/modules/module-switch-on-port-available.c index bcb5a4c..f83b7aa 100644 --- a/src/modules/module-switch-on-port-available.c +++ b/src/modules/module-switch-on-port-available.c @@ -49,6 +49,42 @@ static pa_device_port* find_best_port(pa_hashmap *ports) { return result; } +static pa_bool_t profile_good_for_output(pa_card_profile *profile) { + pa_sink *sink; + uint32_t idx; + + pa_assert(profile); + + if (profile->card->active_profile->n_sources != profile->n_sources) + return FALSE; + + if (profile->card->active_profile->max_source_channels != profile->max_source_channels) + return FALSE; + + /* Try not to switch to HDMI sinks from analog when HDMI is becoming available */ + PA_IDXSET_FOREACH(sink, profile->card->sinks, idx) { + if (!sink->active_port) + continue; + + if (sink->active_port->available != PA_PORT_AVAILABLE_NO) + return FALSE; + } + + return TRUE; +} + +static pa_bool_t profile_good_for_input(pa_card_profile *profile) { + pa_assert(profile); + + if (profile->card->active_profile->n_sinks != profile->n_sinks) + return FALSE; + + if (profile->card->active_profile->max_sink_channels != profile->max_sink_channels) + return FALSE; + + return TRUE; +} + static pa_bool_t try_to_switch_profile(pa_card *card, pa_device_port *port) { pa_card_profile *best_profile = NULL, *profile; void *state; @@ -56,6 +92,8 @@ 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; @@ -65,35 +103,19 @@ 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 */ - if (!port->is_input) { - if (card->active_profile->n_sources != profile->n_sources) - continue; - - if (card->active_profile->max_source_channels != profile->max_source_channels) - continue; - } - - if (!port->is_output) { - if (card->active_profile->n_sinks != profile->n_sinks) - continue; - - if (card->active_profile->max_sink_channels != profile->max_sink_channels) - continue; - } + switch (direction) { + case PA_DIRECTION_OUTPUT: + if (!profile_good_for_output(profile)) + continue; + break; - if (port->is_output) { - /* Try not to switch to HDMI sinks from analog when HDMI is becoming available */ - uint32_t state2; - pa_sink *sink; - pa_bool_t found_active_port = FALSE; - PA_IDXSET_FOREACH(sink, card->sinks, state2) { - if (!sink->active_port) + case PA_DIRECTION_INPUT: + if (!profile_good_for_input(profile)) continue; - if (sink->active_port->available != PA_PORT_AVAILABLE_NO) - found_active_port = TRUE; - } - if (found_active_port) - continue; + break; + + default: + pa_assert_not_reached(); } best_profile = profile; -- 1.7.10