From 0dde4f8774af4f9e5236c87276d5413d6f4910eb Mon Sep 17 00:00:00 2001 From: Huang-Huang Bao Date: Wed, 21 Apr 2021 09:18:13 +0800 Subject: [PATCH] bluez5: cache a2dp volumes activation info So we don't get a sudden boost on soft volumes when switching profile/codec. --- spa/plugins/bluez5/bluez5-dbus.c | 23 ++++++++++++++++------- spa/plugins/bluez5/defs.h | 4 ++++ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/spa/plugins/bluez5/bluez5-dbus.c b/spa/plugins/bluez5/bluez5-dbus.c index 5b24137b2..68f8eda30 100644 --- a/spa/plugins/bluez5/bluez5-dbus.c +++ b/spa/plugins/bluez5/bluez5-dbus.c @@ -1690,22 +1690,27 @@ static void spa_bt_transport_volume_changed(struct spa_bt_transport *transport) { struct spa_bt_monitor *monitor = transport->monitor; struct spa_bt_transport_volume * t_volume; + int volume_id; if (transport->profile & SPA_BT_PROFILE_A2DP_SINK) - t_volume = &transport->volumes[SPA_BT_VOLUME_ID_TX]; + volume_id = SPA_BT_VOLUME_ID_TX; else if (transport->profile & SPA_BT_PROFILE_A2DP_SOURCE) - t_volume = &transport->volumes[SPA_BT_VOLUME_ID_RX]; + volume_id = SPA_BT_VOLUME_ID_RX; else return; + t_volume = &transport->volumes[volume_id]; + if (t_volume->hw_volume != t_volume->new_hw_volume) { t_volume->hw_volume = t_volume->new_hw_volume; t_volume->volume = spa_bt_volume_hw_to_linear(t_volume->hw_volume, t_volume->hw_volume_max); spa_log_debug(monitor->log, "transport %p: volume changed %d(%f) ", transport, t_volume->new_hw_volume, t_volume->volume); - if (spa_bt_transport_volume_enabled(transport)) + if (spa_bt_transport_volume_enabled(transport)) { + transport->device->a2dp_volume_active[volume_id] = true; spa_bt_transport_emit_volume_changed(transport); + } } } @@ -2537,10 +2542,6 @@ static DBusHandlerResult endpoint_set_configuration(DBusConnection *conn, } } - /* PW is the rendering device so it's responsible for reporting hardware volume. */ - if (profile & SPA_BT_PROFILE_A2DP_SOURCE) { - transport->volumes[SPA_BT_VOLUME_ID_RX].active = true; - } for (int i = 0; i < SPA_BT_VOLUME_ID_TERM; ++i) { transport->volumes[i].hw_volume = SPA_BT_VOLUME_INVALID; transport->volumes[i].hw_volume_max = SPA_BT_VOLUME_A2DP_MAX; @@ -2556,6 +2557,14 @@ static DBusHandlerResult endpoint_set_configuration(DBusConnection *conn, if (is_new) spa_list_append(&transport->device->transport_list, &transport->device_link); + if (profile & SPA_BT_PROFILE_A2DP_SOURCE) { + /* PW is the rendering device so it's responsible for reporting hardware volume. */ + transport->volumes[SPA_BT_VOLUME_ID_RX].active = true; + } else if (profile & SPA_BT_PROFILE_A2DP_SINK) { + transport->volumes[SPA_BT_VOLUME_ID_TX].active + |= transport->device->a2dp_volume_active[SPA_BT_VOLUME_ID_TX]; + } + if (codec->validate_config) { struct spa_audio_info info; if (codec->validate_config(codec, 0, diff --git a/spa/plugins/bluez5/defs.h b/spa/plugins/bluez5/defs.h index 131a319ad..5bc5adbe7 100644 --- a/spa/plugins/bluez5/defs.h +++ b/spa/plugins/bluez5/defs.h @@ -424,6 +424,10 @@ struct spa_bt_device { int has_battery; uint32_t hw_volume_profiles; + /* Even tought A2DP volume is exposed on transport interface, the + * volume activation info would not be variate between transports + * under same device. So it's safe to cache activation info here. */ + bool a2dp_volume_active[2]; struct spa_hook_list listener_list; bool added;