mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
bluez5: update a2dp codec list when remote endpoints change
This commit is contained in:
parent
6b5b56bcc7
commit
51b0248d09
2 changed files with 36 additions and 12 deletions
|
|
@ -2924,6 +2924,7 @@ static void interface_added(struct spa_bt_monitor *monitor,
|
||||||
}
|
}
|
||||||
else if (strcmp(interface_name, BLUEZ_MEDIA_ENDPOINT_INTERFACE) == 0) {
|
else if (strcmp(interface_name, BLUEZ_MEDIA_ENDPOINT_INTERFACE) == 0) {
|
||||||
struct spa_bt_remote_endpoint *ep;
|
struct spa_bt_remote_endpoint *ep;
|
||||||
|
struct spa_bt_device *d;
|
||||||
|
|
||||||
ep = remote_endpoint_find(monitor, object_path);
|
ep = remote_endpoint_find(monitor, object_path);
|
||||||
if (ep == NULL) {
|
if (ep == NULL) {
|
||||||
|
|
@ -2935,6 +2936,10 @@ static void interface_added(struct spa_bt_monitor *monitor,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
remote_endpoint_update_props(ep, props_iter, NULL);
|
remote_endpoint_update_props(ep, props_iter, NULL);
|
||||||
|
|
||||||
|
d = ep->device;
|
||||||
|
if (d)
|
||||||
|
spa_bt_device_emit_profiles_changed(d, d->profiles, d->connected_profiles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2992,8 +2997,12 @@ static void interfaces_removed(struct spa_bt_monitor *monitor, DBusMessageIter *
|
||||||
} else if (strcmp(interface_name, BLUEZ_MEDIA_ENDPOINT_INTERFACE) == 0) {
|
} else if (strcmp(interface_name, BLUEZ_MEDIA_ENDPOINT_INTERFACE) == 0) {
|
||||||
struct spa_bt_remote_endpoint *ep;
|
struct spa_bt_remote_endpoint *ep;
|
||||||
ep = remote_endpoint_find(monitor, object_path);
|
ep = remote_endpoint_find(monitor, object_path);
|
||||||
if (ep != NULL)
|
if (ep != NULL) {
|
||||||
|
struct spa_bt_device *d = ep->device;
|
||||||
remote_endpoint_free(ep);
|
remote_endpoint_free(ep);
|
||||||
|
if (d)
|
||||||
|
spa_bt_device_emit_profiles_changed(d, d->profiles, d->connected_profiles);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dbus_message_iter_next(&it);
|
dbus_message_iter_next(&it);
|
||||||
|
|
@ -3234,6 +3243,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us
|
||||||
}
|
}
|
||||||
else if (strcmp(iface, BLUEZ_MEDIA_ENDPOINT_INTERFACE) == 0) {
|
else if (strcmp(iface, BLUEZ_MEDIA_ENDPOINT_INTERFACE) == 0) {
|
||||||
struct spa_bt_remote_endpoint *ep;
|
struct spa_bt_remote_endpoint *ep;
|
||||||
|
struct spa_bt_device *d;
|
||||||
|
|
||||||
ep = remote_endpoint_find(monitor, path);
|
ep = remote_endpoint_find(monitor, path);
|
||||||
if (ep == NULL) {
|
if (ep == NULL) {
|
||||||
|
|
@ -3244,6 +3254,10 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us
|
||||||
spa_log_debug(monitor->log, "Properties changed in remote endpoint %s", path);
|
spa_log_debug(monitor->log, "Properties changed in remote endpoint %s", path);
|
||||||
|
|
||||||
remote_endpoint_update_props(ep, &it[1], NULL);
|
remote_endpoint_update_props(ep, &it[1], NULL);
|
||||||
|
|
||||||
|
d = ep->device;
|
||||||
|
if (d)
|
||||||
|
spa_bt_device_emit_profiles_changed(d, d->profiles, d->connected_profiles);
|
||||||
}
|
}
|
||||||
else if (strcmp(iface, BLUEZ_MEDIA_TRANSPORT_INTERFACE) == 0) {
|
else if (strcmp(iface, BLUEZ_MEDIA_TRANSPORT_INTERFACE) == 0) {
|
||||||
struct spa_bt_transport *transport;
|
struct spa_bt_transport *transport;
|
||||||
|
|
|
||||||
|
|
@ -157,6 +157,16 @@ static const struct a2dp_codec *get_a2dp_codec(enum spa_bluetooth_audio_codec id
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct a2dp_codec *get_supported_a2dp_codec(struct impl *this, enum spa_bluetooth_audio_codec id)
|
||||||
|
{
|
||||||
|
const struct a2dp_codec *a2dp_codec = NULL;
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < this->supported_codec_count; ++i)
|
||||||
|
if (this->supported_codecs[i]->id == id)
|
||||||
|
a2dp_codec = this->supported_codecs[i];
|
||||||
|
return a2dp_codec;
|
||||||
|
}
|
||||||
|
|
||||||
static unsigned int get_hfp_codec(enum spa_bluetooth_audio_codec id)
|
static unsigned int get_hfp_codec(enum spa_bluetooth_audio_codec id)
|
||||||
{
|
{
|
||||||
switch (id) {
|
switch (id) {
|
||||||
|
|
@ -572,6 +582,12 @@ static void profiles_changed(void *userdata, uint32_t prev_profiles, uint32_t pr
|
||||||
if (this->switching_codec)
|
if (this->switching_codec)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (this->bt_dev->connected_profiles & SPA_BT_PROFILE_A2DP_SINK) {
|
||||||
|
free(this->supported_codecs);
|
||||||
|
this->supported_codecs = spa_bt_device_get_supported_a2dp_codecs(
|
||||||
|
this->bt_dev, &this->supported_codec_count);
|
||||||
|
}
|
||||||
|
|
||||||
switch (this->profile) {
|
switch (this->profile) {
|
||||||
case DEVICE_PROFILE_OFF:
|
case DEVICE_PROFILE_OFF:
|
||||||
/* Noop */
|
/* Noop */
|
||||||
|
|
@ -584,12 +600,16 @@ static void profiles_changed(void *userdata, uint32_t prev_profiles, uint32_t pr
|
||||||
nodes_changed);
|
nodes_changed);
|
||||||
break;
|
break;
|
||||||
case DEVICE_PROFILE_A2DP:
|
case DEVICE_PROFILE_A2DP:
|
||||||
|
if (get_supported_a2dp_codec(this, this->props.codec) == NULL)
|
||||||
|
this->props.codec = 0;
|
||||||
nodes_changed = (connected_change & (SPA_BT_PROFILE_A2DP_SINK |
|
nodes_changed = (connected_change & (SPA_BT_PROFILE_A2DP_SINK |
|
||||||
SPA_BT_PROFILE_A2DP_SOURCE));
|
SPA_BT_PROFILE_A2DP_SOURCE));
|
||||||
spa_log_debug(this->log, NAME": profiles changed: A2DP nodes changed: %d",
|
spa_log_debug(this->log, NAME": profiles changed: A2DP nodes changed: %d",
|
||||||
nodes_changed);
|
nodes_changed);
|
||||||
break;
|
break;
|
||||||
case DEVICE_PROFILE_HSP_HFP:
|
case DEVICE_PROFILE_HSP_HFP:
|
||||||
|
if (spa_bt_device_supports_hfp_codec(this->bt_dev, get_hfp_codec(this->props.codec)) == 0)
|
||||||
|
this->props.codec = 0;
|
||||||
nodes_changed = (connected_change & SPA_BT_PROFILE_HEADSET_HEAD_UNIT);
|
nodes_changed = (connected_change & SPA_BT_PROFILE_HEADSET_HEAD_UNIT);
|
||||||
spa_log_debug(this->log, NAME": profiles changed: HSP/HFP nodes changed: %d",
|
spa_log_debug(this->log, NAME": profiles changed: HSP/HFP nodes changed: %d",
|
||||||
nodes_changed);
|
nodes_changed);
|
||||||
|
|
@ -601,12 +621,6 @@ static void profiles_changed(void *userdata, uint32_t prev_profiles, uint32_t pr
|
||||||
emit_nodes(this);
|
emit_nodes(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (connected_change & SPA_BT_PROFILE_A2DP_SINK) {
|
|
||||||
free(this->supported_codecs);
|
|
||||||
this->supported_codecs = spa_bt_device_get_supported_a2dp_codecs(
|
|
||||||
this->bt_dev, &this->supported_codec_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
this->info.change_mask |= SPA_DEVICE_CHANGE_MASK_PARAMS;
|
this->info.change_mask |= SPA_DEVICE_CHANGE_MASK_PARAMS;
|
||||||
this->params[IDX_Profile].flags ^= SPA_PARAM_INFO_SERIAL;
|
this->params[IDX_Profile].flags ^= SPA_PARAM_INFO_SERIAL;
|
||||||
this->params[IDX_EnumProfile].flags ^= SPA_PARAM_INFO_SERIAL;
|
this->params[IDX_EnumProfile].flags ^= SPA_PARAM_INFO_SERIAL;
|
||||||
|
|
@ -834,11 +848,7 @@ static struct spa_pod *build_profile(struct impl *this, struct spa_pod_builder *
|
||||||
name = spa_bt_profile_name(profile);
|
name = spa_bt_profile_name(profile);
|
||||||
n_sink++;
|
n_sink++;
|
||||||
if (codec) {
|
if (codec) {
|
||||||
uint32_t i;
|
const struct a2dp_codec *a2dp_codec = get_supported_a2dp_codec(this, codec);
|
||||||
const struct a2dp_codec *a2dp_codec = NULL;
|
|
||||||
for (i = 0; i < this->supported_codec_count; ++i)
|
|
||||||
if (codec == this->supported_codecs[i]->id)
|
|
||||||
a2dp_codec = this->supported_codecs[i];
|
|
||||||
if (a2dp_codec == NULL) {
|
if (a2dp_codec == NULL) {
|
||||||
errno = -EINVAL;
|
errno = -EINVAL;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue