From 5071589aea35227440a75476c7c5f342e81a4ef6 Mon Sep 17 00:00:00 2001 From: Pauli Virtanen Date: Fri, 13 Aug 2021 19:31:00 +0300 Subject: [PATCH] bluez5: enable SBC-XQ codec by default, if allowed by quirks Enable SBC-XQ by default, and move it at the end of the codecs list, so that bluez does not connect to it automatically except when it is the codec used previously. When the codec is disabled by quirks, it won't appear in the codecs list, and so can't be selected by user (and so won't be connected automatically). However, since SelectConfiguration does not carry information which device is in question, we cannot prevent BlueZ connecting to the codec even if it's disabled for a specific device. If the "impossible" occurs regardless, we won't reject the connection and the profile will be shown as the generic "A2DP" one. If the sound is garbled, the user can select some other profile that works. --- spa/plugins/bluez5/a2dp-codec-sbc.c | 1 - spa/plugins/bluez5/a2dp-codecs.c | 2 +- spa/plugins/bluez5/a2dp-codecs.h | 2 -- spa/plugins/bluez5/bluez5-dbus.c | 19 +++++++++---------- .../media-session.d/bluez-hardware.conf | 1 - src/daemon/media-session.d/bluez-monitor.conf | 2 +- 6 files changed, 11 insertions(+), 16 deletions(-) diff --git a/spa/plugins/bluez5/a2dp-codec-sbc.c b/spa/plugins/bluez5/a2dp-codec-sbc.c index 45dc3ba52..64e16b8b2 100644 --- a/spa/plugins/bluez5/a2dp-codec-sbc.c +++ b/spa/plugins/bluez5/a2dp-codec-sbc.c @@ -681,5 +681,4 @@ const struct a2dp_codec a2dp_codec_sbc_xq = { .decode = codec_decode, .reduce_bitpool = codec_reduce_bitpool, .increase_bitpool = codec_increase_bitpool, - .feature_flag = "sbc-xq", }; diff --git a/spa/plugins/bluez5/a2dp-codecs.c b/spa/plugins/bluez5/a2dp-codecs.c index da169d451..11c77e017 100644 --- a/spa/plugins/bluez5/a2dp-codecs.c +++ b/spa/plugins/bluez5/a2dp-codecs.c @@ -148,8 +148,8 @@ static const struct a2dp_codec * const a2dp_codec_list[] = { #if ENABLE_MP3 &a2dp_codec_mpeg, #endif - &a2dp_codec_sbc_xq, &a2dp_codec_sbc, + &a2dp_codec_sbc_xq, NULL }; diff --git a/spa/plugins/bluez5/a2dp-codecs.h b/spa/plugins/bluez5/a2dp-codecs.h index 3120ca275..6673236e8 100644 --- a/spa/plugins/bluez5/a2dp-codecs.h +++ b/spa/plugins/bluez5/a2dp-codecs.h @@ -314,8 +314,6 @@ struct a2dp_codec { const size_t send_buf_size; - const char *feature_flag; - int (*fill_caps) (const struct a2dp_codec *codec, uint32_t flags, uint8_t caps[A2DP_MAX_CAPS_SIZE]); int (*select_config) (const struct a2dp_codec *codec, uint32_t flags, diff --git a/spa/plugins/bluez5/bluez5-dbus.c b/spa/plugins/bluez5/bluez5-dbus.c index 9b94fcbd8..dc1c9d909 100644 --- a/spa/plugins/bluez5/bluez5-dbus.c +++ b/spa/plugins/bluez5/bluez5-dbus.c @@ -91,7 +91,6 @@ struct spa_bt_monitor { struct spa_bt_quirks *quirks; - unsigned int enable_sbc_xq:1; unsigned int backend_native_registered:1; unsigned int backend_ofono_registered:1; unsigned int backend_hsphfpd_registered:1; @@ -440,10 +439,6 @@ static int a2dp_endpoint_to_profile(const char *endpoint) static bool is_a2dp_codec_enabled(struct spa_bt_monitor *monitor, const struct a2dp_codec *codec) { - if (!monitor->enable_sbc_xq && codec->feature_flag != NULL && - spa_streq(codec->feature_flag, "sbc-xq")) - return false; - return spa_dict_lookup(&monitor->enabled_codecs, codec->name) != NULL; } @@ -1384,6 +1379,7 @@ static int device_update_props(struct spa_bt_device *device, bool spa_bt_device_supports_a2dp_codec(struct spa_bt_device *device, const struct a2dp_codec *codec) { + struct spa_bt_monitor *monitor = device->monitor; struct spa_bt_remote_endpoint *ep; if (!is_a2dp_codec_enabled(device->monitor, codec)) @@ -1394,6 +1390,14 @@ bool spa_bt_device_supports_a2dp_codec(struct spa_bt_device *device, const struc return (codec->codec_id == A2DP_CODEC_SBC && spa_streq(codec->name, "sbc")); } + if (codec->id == SPA_BLUETOOTH_AUDIO_CODEC_SBC_XQ) { + uint32_t bt_features = (uint32_t)-1; + if (monitor->quirks) + spa_bt_quirks_get_features(monitor->quirks, device->adapter, device, &bt_features); + if (!(bt_features & SPA_BT_FEATURE_SBC_XQ)) + return false; + } + spa_list_for_each(ep, &device->remote_endpoint_list, device_link) { if (a2dp_codec_check_caps(codec, ep->codec, ep->capabilities, ep->capabilities_len, &ep->monitor->default_audio_info)) @@ -3861,7 +3865,6 @@ static int impl_clear(struct spa_handle *handle) monitor->objects_listed = false; monitor->connection_info_supported = false; - monitor->enable_sbc_xq = false; monitor->backend_native_registered = false; monitor->backend_ofono_registered = false; monitor->backend_hsphfpd_registered = false; @@ -4069,10 +4072,6 @@ impl_init(const struct spa_handle_factory *factory, if ((str = spa_dict_lookup(info, "bluez5.default.channels")) != NULL && ((tmp = atoi(str)) > 0)) this->default_audio_info.channels = tmp; - - if ((str = spa_dict_lookup(info, "bluez5.enable-sbc-xq")) != NULL && - spa_atob(str)) - this->enable_sbc_xq = true; } register_media_application(this); diff --git a/src/daemon/media-session.d/bluez-hardware.conf b/src/daemon/media-session.d/bluez-hardware.conf index ffe2ccd05..04e06989a 100644 --- a/src/daemon/media-session.d/bluez-hardware.conf +++ b/src/daemon/media-session.d/bluez-hardware.conf @@ -13,7 +13,6 @@ # hw-volume AVRCP and HSP/HFP hardware volume support # hw-volume-mic Functional HSP/HFP microphone volume support # sbc-xq "nonstandard" SBC codec setting with better sound quality -# (XXX: the SBC-XQ per-device setting doesn't have effect yet) # # Features are disabled with the key "no-features" whose value is an # array of strings in the match rule. diff --git a/src/daemon/media-session.d/bluez-monitor.conf b/src/daemon/media-session.d/bluez-monitor.conf index e610fd922..6dd591a3f 100644 --- a/src/daemon/media-session.d/bluez-monitor.conf +++ b/src/daemon/media-session.d/bluez-monitor.conf @@ -27,7 +27,7 @@ properties = { #bluez5.headset-roles = [ hsp_hs hsp_ag hfp_hf hfp_ag ] # Enabled A2DP codecs (default: all). - #bluez5.codecs = [ sbc aac ldac aptx aptx_hd ] + #bluez5.codecs = [ sbc aac ldac aptx aptx_hd sbc_xq ] # Properties for the A2DP codec configuration #bluez5.default.rate = 48000