From 84acfbbda5b2a635a361f31f15907ab7dc28cf18 Mon Sep 17 00:00:00 2001 From: Konstantin Kharlamov Date: Sun, 13 Jun 2021 21:40:12 +0300 Subject: [PATCH] media-session: switch to the route when availability changed When a user plugs in headphones, they expect to hear an audio through them. Currently, that usecase might or might not work with pipewire depending on the user's luck, because pipewire instead uses port priorities, and those apparently rarely have sane default values. PulseAudio ignored priorities here, instead it made use of the port right away. This should better match user expectations (who plugged in headphones and is expecting to hear sound), so let's do the same in pipewire. Fixes: https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/1170 --- src/examples/media-session/default-routes.c | 28 ++++++++++++++++----- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/examples/media-session/default-routes.c b/src/examples/media-session/default-routes.c index 66f5c0e9d..ac13bbfc0 100644 --- a/src/examples/media-session/default-routes.c +++ b/src/examples/media-session/default-routes.c @@ -566,13 +566,29 @@ static int find_best_route(struct device *dev, uint32_t device_id, struct route parse_enum_route(p, device_id, &t) < 0) continue; - if (t.available == SPA_PARAM_AVAILABILITY_yes) { - if (best_avail.name == NULL || t.priority > best_avail.priority) + if (t.available == SPA_PARAM_AVAILABILITY_yes || t.available == SPA_PARAM_AVAILABILITY_unknown) { + struct route_info *ri; + if ((ri = find_route_info(dev, &t)) && ri->direction == SPA_DIRECTION_OUTPUT && + ri->available != ri->prev_available) { + /* If route availability changed, that means a user just + * plugged in something like headphones, and they probably + * expect to hear sound from it. Switch to it immediately. + * + * TODO: switch INPUT ports without source and the input + * ports their source->active_port is part of a group of + * ports (see module-switch-on-port-available.c in PulseAudio). + */ best_avail = t; - } - else if (t.available != SPA_PARAM_AVAILABILITY_no) { - if (best_unk.name == NULL || t.priority > best_unk.priority) - best_unk = t; + ri->save = true; + break; + } + else if (t.available == SPA_PARAM_AVAILABILITY_yes) { + if (best_avail.name == NULL || t.priority > best_avail.priority) + best_avail = t; + } else { // SPA_PARAM_AVAILABILITY_unknown + if (best_unk.name == NULL || t.priority > best_unk.priority) + best_unk = t; + } } } best = best_avail;