media-session: only restore best profile when something changed

Keep track of the best profile. Only try to switch away from the
saved profile when something changed and the saved profile is not
available.

This makes it possible to select an unavailable profile but when
something is changed, it will switch away from it.
This commit is contained in:
Wim Taymans 2021-03-11 09:32:17 +01:00
parent 485bae5eb0
commit d295d97160

View file

@ -75,6 +75,7 @@ struct device {
struct spa_hook listener; struct spa_hook listener;
uint32_t saved_profile; uint32_t saved_profile;
uint32_t best_profile;
uint32_t active_profile; uint32_t active_profile;
}; };
@ -284,45 +285,50 @@ static int handle_active_profile(struct device *dev)
static int handle_profile_switch(struct device *dev) static int handle_profile_switch(struct device *dev)
{ {
struct profile pr; struct profile saved, best;
int res; int res;
bool changed = false;
/* try to find the next best profile */
res = find_best_profile(dev, &best);
if (res < 0) {
pw_log_info("device '%s': can't find best profile: %s",
dev->name, spa_strerror(res));
best.index = SPA_ID_INVALID;
} else {
if (dev->best_profile != best.index)
changed = true;
dev->best_profile = best.index;
pw_log_info("device '%s': found best profile '%s' changed:%d",
dev->name, best.name, changed);
}
/* try to restore our saved profile */ /* try to restore our saved profile */
res = find_saved_profile(dev, &pr); res = find_saved_profile(dev, &saved);
if (res >= 0) { if (res >= 0) {
/* we found a saved profile */ /* we found a saved profile */
if (pr.available == SPA_PARAM_AVAILABILITY_no) { if (saved.available == SPA_PARAM_AVAILABILITY_no && changed) {
pw_log_info("device '%s': saved profile '%s' unavailable", pw_log_info("device '%s': saved profile '%s' unavailable",
dev->name, pr.name); dev->name, saved.name);
res = -ENOENT;
} else { } else {
pw_log_info("device '%s': found saved profile '%s'", pw_log_info("device '%s': found saved profile '%s'",
dev->name, pr.name); dev->name, saved.name);
/* make sure we save again */ /* make sure we save again */
pr.save = true; saved.save = true;
best = saved;
} }
} else { } else {
pw_log_info("device '%s': no saved profile: %s", pw_log_info("device '%s': no saved profile: %s",
dev->name, spa_strerror(res)); dev->name, spa_strerror(res));
} }
if (res < 0) { if (best.index != SPA_ID_INVALID) {
/* try to find the next best profile */ if (dev->active_profile == best.index) {
res = find_best_profile(dev, &pr);
if (res < 0)
pw_log_info("device '%s': can't find best profile: %s",
dev->name, spa_strerror(res));
else
pw_log_info("device '%s': found best profile '%s'",
dev->name, pr.name);
}
if (res >= 0) {
if (dev->active_profile == pr.index) {
pw_log_info("device '%s': best profile '%s' is already active", pw_log_info("device '%s': best profile '%s' is already active",
dev->name, pr.name); dev->name, best.name);
} else { } else {
pw_log_info("device '%s': restore best profile '%s' index %d", pw_log_info("device '%s': restore best profile '%s' index %d",
dev->name, pr.name, pr.index); dev->name, best.name, best.index);
set_profile(dev, &pr); set_profile(dev, &best);
} }
} else { } else {
pw_log_warn("device '%s': can't restore profile: %s", dev->name, pw_log_warn("device '%s': can't restore profile: %s", dev->name,
@ -386,6 +392,7 @@ static void session_create(void *data, struct sm_object *object)
dev->key = spa_aprintf(PREFIX"%s", name); dev->key = spa_aprintf(PREFIX"%s", name);
dev->active_profile = SPA_ID_INVALID; dev->active_profile = SPA_ID_INVALID;
dev->saved_profile = SPA_ID_INVALID; dev->saved_profile = SPA_ID_INVALID;
dev->best_profile = SPA_ID_INVALID;
dev->obj->obj.mask |= SM_DEVICE_CHANGE_MASK_PARAMS; dev->obj->obj.mask |= SM_DEVICE_CHANGE_MASK_PARAMS;
sm_object_add_listener(&dev->obj->obj, &dev->listener, &object_events, dev); sm_object_add_listener(&dev->obj->obj, &dev->listener, &object_events, dev);