bluez5: handle sink vs. source correctly in get_supported_codecs

Make a distinction between sink and source endpoints when determining
supported codecs.
This commit is contained in:
Pauli Virtanen 2022-06-12 19:09:29 +03:00 committed by Wim Taymans
parent 889d507e9c
commit 0dc8255057
3 changed files with 15 additions and 8 deletions

View file

@ -1552,7 +1552,7 @@ static bool device_props_ready(struct spa_bt_device *device)
return device->adapter && device->address; return device->adapter && device->address;
} }
bool spa_bt_device_supports_a2dp_codec(struct spa_bt_device *device, const struct a2dp_codec *codec) bool spa_bt_device_supports_a2dp_codec(struct spa_bt_device *device, const struct a2dp_codec *codec, bool sink)
{ {
struct spa_bt_monitor *monitor = device->monitor; struct spa_bt_monitor *monitor = device->monitor;
struct spa_bt_remote_endpoint *ep; struct spa_bt_remote_endpoint *ep;
@ -1588,6 +1588,13 @@ bool spa_bt_device_supports_a2dp_codec(struct spa_bt_device *device, const struc
} }
spa_list_for_each(ep, &device->remote_endpoint_list, device_link) { spa_list_for_each(ep, &device->remote_endpoint_list, device_link) {
const enum spa_bt_profile profile = spa_bt_profile_from_uuid(ep->uuid);
const enum spa_bt_profile expected = sink ?
SPA_BT_PROFILE_A2DP_SINK : SPA_BT_PROFILE_A2DP_SOURCE;
if (profile != expected)
continue;
if (a2dp_codec_check_caps(codec, ep->codec, ep->capabilities, ep->capabilities_len, if (a2dp_codec_check_caps(codec, ep->codec, ep->capabilities, ep->capabilities_len,
&ep->monitor->default_audio_info, &monitor->global_settings)) &ep->monitor->default_audio_info, &monitor->global_settings))
return true; return true;
@ -1596,7 +1603,7 @@ bool spa_bt_device_supports_a2dp_codec(struct spa_bt_device *device, const struc
return false; return false;
} }
const struct a2dp_codec **spa_bt_device_get_supported_a2dp_codecs(struct spa_bt_device *device, size_t *count) const struct a2dp_codec **spa_bt_device_get_supported_a2dp_codecs(struct spa_bt_device *device, size_t *count, bool sink)
{ {
struct spa_bt_monitor *monitor = device->monitor; struct spa_bt_monitor *monitor = device->monitor;
const struct a2dp_codec * const * const a2dp_codecs = monitor->a2dp_codecs; const struct a2dp_codec * const * const a2dp_codecs = monitor->a2dp_codecs;
@ -1612,7 +1619,7 @@ const struct a2dp_codec **spa_bt_device_get_supported_a2dp_codecs(struct spa_bt_
j = 0; j = 0;
for (i = 0; a2dp_codecs[i] != NULL; ++i) { for (i = 0; a2dp_codecs[i] != NULL; ++i) {
if (spa_bt_device_supports_a2dp_codec(device, a2dp_codecs[i])) { if (spa_bt_device_supports_a2dp_codec(device, a2dp_codecs[i], sink)) {
supported_codecs[j] = a2dp_codecs[i]; supported_codecs[j] = a2dp_codecs[i];
++j; ++j;
} }
@ -2933,7 +2940,7 @@ int spa_bt_device_ensure_a2dp_codec(struct spa_bt_device *device, const struct a
} }
for (i = 0; codecs[i] != NULL; ++i) { for (i = 0; codecs[i] != NULL; ++i) {
if (spa_bt_device_supports_a2dp_codec(device, codecs[i])) { if (spa_bt_device_supports_a2dp_codec(device, codecs[i], true)) {
preferred_codec = codecs[i]; preferred_codec = codecs[i];
break; break;
} }

View file

@ -915,7 +915,7 @@ static void profiles_changed(void *userdata, uint32_t prev_profiles, uint32_t pr
if (this->bt_dev->connected_profiles & SPA_BT_PROFILE_A2DP_SINK) { if (this->bt_dev->connected_profiles & SPA_BT_PROFILE_A2DP_SINK) {
free(this->supported_codecs); free(this->supported_codecs);
this->supported_codecs = spa_bt_device_get_supported_a2dp_codecs( this->supported_codecs = spa_bt_device_get_supported_a2dp_codecs(
this->bt_dev, &this->supported_codec_count); this->bt_dev, &this->supported_codec_count, true);
} }
switch (this->profile) { switch (this->profile) {
@ -1130,7 +1130,7 @@ static void set_initial_profile(struct impl *this)
if (this->supported_codecs) if (this->supported_codecs)
free(this->supported_codecs); free(this->supported_codecs);
this->supported_codecs = spa_bt_device_get_supported_a2dp_codecs( this->supported_codecs = spa_bt_device_get_supported_a2dp_codecs(
this->bt_dev, &this->supported_codec_count); this->bt_dev, &this->supported_codec_count, true);
/* Prefer A2DP, then HFP, then null, but select AG if the device /* Prefer A2DP, then HFP, then null, but select AG if the device
appears not to have A2DP_SINK or any HEAD_UNIT profile */ appears not to have A2DP_SINK or any HEAD_UNIT profile */

View file

@ -490,8 +490,8 @@ int spa_bt_device_add_profile(struct spa_bt_device *device, enum spa_bt_profile
int spa_bt_device_connect_profile(struct spa_bt_device *device, enum spa_bt_profile profile); int spa_bt_device_connect_profile(struct spa_bt_device *device, enum spa_bt_profile profile);
int spa_bt_device_check_profiles(struct spa_bt_device *device, bool force); int spa_bt_device_check_profiles(struct spa_bt_device *device, bool force);
int spa_bt_device_ensure_a2dp_codec(struct spa_bt_device *device, const struct a2dp_codec * const *codecs); int spa_bt_device_ensure_a2dp_codec(struct spa_bt_device *device, const struct a2dp_codec * const *codecs);
bool spa_bt_device_supports_a2dp_codec(struct spa_bt_device *device, const struct a2dp_codec *codec); bool spa_bt_device_supports_a2dp_codec(struct spa_bt_device *device, const struct a2dp_codec *codec, bool sink);
const struct a2dp_codec **spa_bt_device_get_supported_a2dp_codecs(struct spa_bt_device *device, size_t *count); const struct a2dp_codec **spa_bt_device_get_supported_a2dp_codecs(struct spa_bt_device *device, size_t *count, bool sink);
int spa_bt_device_ensure_hfp_codec(struct spa_bt_device *device, unsigned int codec); int spa_bt_device_ensure_hfp_codec(struct spa_bt_device *device, unsigned int codec);
int spa_bt_device_supports_hfp_codec(struct spa_bt_device *device, unsigned int codec); int spa_bt_device_supports_hfp_codec(struct spa_bt_device *device, unsigned int codec);
int spa_bt_device_release_transports(struct spa_bt_device *device); int spa_bt_device_release_transports(struct spa_bt_device *device);