On 28.12.2017 16:14, Tanu Kaskinen wrote: > 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. > --- I am not sure if changing the profile is a good idea. There is no code which restores the profile when the cable gets plugged again. Can't you fire a hook when a sink or source is suspended due to PA_SUSPEND_UNAVAILABLE and let module-rescue-stream handle the case? Further comment below. > > 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)) Should this not be profile_good_for_input()? > + continue; > + break; > + > + case PA_DIRECTION_INPUT: > + if (profile->n_sources != 0) > + continue; > + if (!profile_good_for_input(profile, NULL)) ... and this one profile_good_for_output()? > + 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); > } > >