mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-12-17 08:56:49 -05:00
bluez5: fix device supported codec checks
Make supported codec checks to use profiles, not "is-a-sink" flag, to determine which codecs can be used. Fixes bluez5-device checking only source profiles, even when the local device is only a sink.
This commit is contained in:
parent
6abc6e6693
commit
186b730c9c
3 changed files with 59 additions and 66 deletions
|
|
@ -526,6 +526,26 @@ static enum spa_bt_profile get_codec_profile(const struct media_codec *codec,
|
|||
}
|
||||
}
|
||||
|
||||
static enum spa_bt_profile swap_profile(enum spa_bt_profile profile)
|
||||
{
|
||||
switch (profile) {
|
||||
case SPA_BT_PROFILE_A2DP_SOURCE:
|
||||
return SPA_BT_PROFILE_A2DP_SINK;
|
||||
case SPA_BT_PROFILE_A2DP_SINK:
|
||||
return SPA_BT_PROFILE_A2DP_SOURCE;
|
||||
case SPA_BT_PROFILE_BAP_SOURCE:
|
||||
return SPA_BT_PROFILE_BAP_SINK;
|
||||
case SPA_BT_PROFILE_BAP_SINK:
|
||||
return SPA_BT_PROFILE_BAP_SOURCE;
|
||||
case SPA_BT_PROFILE_BAP_BROADCAST_SOURCE:
|
||||
return SPA_BT_PROFILE_BAP_BROADCAST_SINK;
|
||||
case SPA_BT_PROFILE_BAP_BROADCAST_SINK:
|
||||
return SPA_BT_PROFILE_BAP_BROADCAST_SOURCE;
|
||||
default:
|
||||
return SPA_BT_PROFILE_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static bool endpoint_should_be_registered(struct spa_bt_monitor *monitor,
|
||||
const struct media_codec *codec,
|
||||
enum spa_bt_media_direction direction)
|
||||
|
|
@ -2230,11 +2250,11 @@ static bool device_props_ready(struct spa_bt_device *device)
|
|||
return device->adapter && device->address;
|
||||
}
|
||||
|
||||
bool spa_bt_device_supports_media_codec(struct spa_bt_device *device, const struct media_codec *codec, bool sink)
|
||||
bool spa_bt_device_supports_media_codec(struct spa_bt_device *device, const struct media_codec *codec, enum spa_bt_profile profile)
|
||||
{
|
||||
struct spa_bt_monitor *monitor = device->monitor;
|
||||
struct spa_bt_remote_endpoint *ep;
|
||||
enum spa_bt_profile codec_profile;
|
||||
enum spa_bt_profile codec_target_profile;
|
||||
struct spa_bt_transport *t;
|
||||
const struct { enum spa_bluetooth_audio_codec codec; uint32_t mask; } quirks[] = {
|
||||
{ SPA_BLUETOOTH_AUDIO_CODEC_SBC_XQ, SPA_BT_FEATURE_SBC_XQ },
|
||||
|
|
@ -2270,17 +2290,14 @@ bool spa_bt_device_supports_media_codec(struct spa_bt_device *device, const stru
|
|||
return false;
|
||||
}
|
||||
|
||||
spa_list_for_each(ep, &device->remote_endpoint_list, device_link) {
|
||||
enum spa_bt_profile profile = spa_bt_profile_from_uuid(ep->uuid);
|
||||
if (codec->bap) {
|
||||
if ((profile == SPA_BT_PROFILE_BAP_BROADCAST_SINK) || (profile == SPA_BT_PROFILE_BAP_BROADCAST_SOURCE))
|
||||
codec_profile = sink ? SPA_BT_PROFILE_BAP_BROADCAST_SINK : SPA_BT_PROFILE_BAP_BROADCAST_SOURCE;
|
||||
else
|
||||
codec_profile = sink ? SPA_BT_PROFILE_BAP_SINK : SPA_BT_PROFILE_BAP_SOURCE;
|
||||
} else
|
||||
codec_profile = sink ? SPA_BT_PROFILE_A2DP_SINK : SPA_BT_PROFILE_A2DP_SOURCE;
|
||||
for (i = 0, codec_target_profile = 0; i < (size_t)SPA_BT_MEDIA_DIRECTION_LAST; ++i)
|
||||
if (codec_has_direction(codec, i))
|
||||
codec_target_profile |= swap_profile(get_codec_profile(codec, i));
|
||||
|
||||
if (profile != codec_profile)
|
||||
spa_list_for_each(ep, &device->remote_endpoint_list, device_link) {
|
||||
enum spa_bt_profile ep_profile = spa_bt_profile_from_uuid(ep->uuid);
|
||||
|
||||
if (!(ep_profile & codec_target_profile & profile))
|
||||
continue;
|
||||
|
||||
if (media_codec_check_caps(codec, ep->codec, ep->capabilities, ep->capabilities_len,
|
||||
|
|
@ -2296,15 +2313,7 @@ bool spa_bt_device_supports_media_codec(struct spa_bt_device *device, const stru
|
|||
* can only know that the currently configured codec is supported.
|
||||
*/
|
||||
spa_list_for_each(t, &device->transport_list, device_link) {
|
||||
if (codec->bap) {
|
||||
if((t->profile == SPA_BT_PROFILE_BAP_BROADCAST_SINK) || (t->profile == SPA_BT_PROFILE_BAP_BROADCAST_SOURCE))
|
||||
codec_profile = sink ? SPA_BT_PROFILE_BAP_BROADCAST_SINK : SPA_BT_PROFILE_BAP_BROADCAST_SOURCE;
|
||||
else
|
||||
codec_profile = sink ? SPA_BT_PROFILE_BAP_SINK : SPA_BT_PROFILE_BAP_SOURCE;
|
||||
} else
|
||||
codec_profile = sink ? SPA_BT_PROFILE_A2DP_SINK : SPA_BT_PROFILE_A2DP_SOURCE;
|
||||
|
||||
if (t->profile != codec_profile)
|
||||
if (!(t->profile & codec_target_profile & profile))
|
||||
continue;
|
||||
|
||||
if (codec == t->media_codec)
|
||||
|
|
@ -2314,7 +2323,7 @@ bool spa_bt_device_supports_media_codec(struct spa_bt_device *device, const stru
|
|||
return false;
|
||||
}
|
||||
|
||||
const struct media_codec **spa_bt_device_get_supported_media_codecs(struct spa_bt_device *device, size_t *count, bool sink)
|
||||
const struct media_codec **spa_bt_device_get_supported_media_codecs(struct spa_bt_device *device, size_t *count)
|
||||
{
|
||||
struct spa_bt_monitor *monitor = device->monitor;
|
||||
const struct media_codec * const * const media_codecs = monitor->media_codecs;
|
||||
|
|
@ -2329,7 +2338,7 @@ const struct media_codec **spa_bt_device_get_supported_media_codecs(struct spa_b
|
|||
|
||||
j = 0;
|
||||
for (i = 0; media_codecs[i] != NULL; ++i) {
|
||||
if (spa_bt_device_supports_media_codec(device, media_codecs[i], sink)) {
|
||||
if (spa_bt_device_supports_media_codec(device, media_codecs[i], device->connected_profiles)) {
|
||||
supported_codecs[j] = media_codecs[i];
|
||||
++j;
|
||||
}
|
||||
|
|
@ -3048,29 +3057,9 @@ static int transport_update_props(struct spa_bt_transport *transport,
|
|||
spa_log_debug(monitor->log, "transport %p: %s=%s", transport, key, value);
|
||||
|
||||
if (spa_streq(key, "UUID")) {
|
||||
switch (spa_bt_profile_from_uuid(value)) {
|
||||
case SPA_BT_PROFILE_A2DP_SOURCE:
|
||||
transport->profile = SPA_BT_PROFILE_A2DP_SINK;
|
||||
break;
|
||||
case SPA_BT_PROFILE_A2DP_SINK:
|
||||
transport->profile = SPA_BT_PROFILE_A2DP_SOURCE;
|
||||
break;
|
||||
case SPA_BT_PROFILE_BAP_SOURCE:
|
||||
transport->profile = SPA_BT_PROFILE_BAP_SINK;
|
||||
break;
|
||||
case SPA_BT_PROFILE_BAP_SINK:
|
||||
transport->profile = SPA_BT_PROFILE_BAP_SOURCE;
|
||||
break;
|
||||
case SPA_BT_PROFILE_BAP_BROADCAST_SOURCE:
|
||||
transport->profile = SPA_BT_PROFILE_BAP_BROADCAST_SINK;
|
||||
break;
|
||||
case SPA_BT_PROFILE_BAP_BROADCAST_SINK:
|
||||
transport->profile = SPA_BT_PROFILE_BAP_BROADCAST_SOURCE;
|
||||
break;
|
||||
default:
|
||||
transport->profile = swap_profile(spa_bt_profile_from_uuid(value));
|
||||
if (transport->profile == SPA_BT_PROFILE_NULL)
|
||||
spa_log_warn(monitor->log, "unknown profile %s", value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (spa_streq(key, "State")) {
|
||||
enum spa_bt_transport_state state = spa_bt_transport_state_from_string(value);
|
||||
|
|
@ -4154,7 +4143,7 @@ int spa_bt_device_ensure_media_codec(struct spa_bt_device *device, const struct
|
|||
}
|
||||
|
||||
for (i = 0; codecs[i] != NULL; ++i) {
|
||||
if (spa_bt_device_supports_media_codec(device, codecs[i], true)) {
|
||||
if (spa_bt_device_supports_media_codec(device, codecs[i], device->connected_profiles)) {
|
||||
preferred_codec = codecs[i];
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue