bluez5: cache a2dp volumes activation info

So we don't get a sudden boost on soft volumes when switching profile/codec.
This commit is contained in:
Huang-Huang Bao 2021-04-21 09:18:13 +08:00 committed by Wim Taymans
parent 51c3290d11
commit 0dde4f8774
2 changed files with 20 additions and 7 deletions

View file

@ -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_monitor *monitor = transport->monitor;
struct spa_bt_transport_volume * t_volume; struct spa_bt_transport_volume * t_volume;
int volume_id;
if (transport->profile & SPA_BT_PROFILE_A2DP_SINK) 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) 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 else
return; return;
t_volume = &transport->volumes[volume_id];
if (t_volume->hw_volume != t_volume->new_hw_volume) { if (t_volume->hw_volume != t_volume->new_hw_volume) {
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->volume = spa_bt_volume_hw_to_linear(t_volume->hw_volume,
t_volume->hw_volume_max); t_volume->hw_volume_max);
spa_log_debug(monitor->log, "transport %p: volume changed %d(%f) ", spa_log_debug(monitor->log, "transport %p: volume changed %d(%f) ",
transport, t_volume->new_hw_volume, t_volume->volume); 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); 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) { 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 = SPA_BT_VOLUME_INVALID;
transport->volumes[i].hw_volume_max = SPA_BT_VOLUME_A2DP_MAX; 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) if (is_new)
spa_list_append(&transport->device->transport_list, &transport->device_link); 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) { if (codec->validate_config) {
struct spa_audio_info info; struct spa_audio_info info;
if (codec->validate_config(codec, 0, if (codec->validate_config(codec, 0,

View file

@ -424,6 +424,10 @@ struct spa_bt_device {
int has_battery; int has_battery;
uint32_t hw_volume_profiles; 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; struct spa_hook_list listener_list;
bool added; bool added;