mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-12-16 08:56:45 -05:00
bluez5: select BAP audio locations in SelectProperties
Do BAP audio location selection properly in SelectProperties, now that BlueZ provides the supported locations there. Remove a previous workaround. The audio location in SelectProperties determines the audio channel allocation, which determines the channel positions.
This commit is contained in:
parent
815501cc1f
commit
420f7cb48e
3 changed files with 97 additions and 117 deletions
|
|
@ -39,8 +39,6 @@
|
|||
#include "iso-io.h"
|
||||
#include "defs.h"
|
||||
|
||||
#include "bap-codec-caps.h"
|
||||
|
||||
static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.bluez5");
|
||||
#undef SPA_LOG_TOPIC_DEFAULT
|
||||
#define SPA_LOG_TOPIC_DEFAULT &log_topic
|
||||
|
|
@ -632,10 +630,14 @@ static DBusHandlerResult endpoint_select_properties(DBusConnection *conn, DBusMe
|
|||
const struct media_codec *codec;
|
||||
bool sink;
|
||||
const char *err_msg = "Unknown error";
|
||||
struct spa_dict settings;
|
||||
struct spa_dict_item setting_items[SPA_N_ELEMENTS(monitor->global_setting_items) + 1];
|
||||
int i;
|
||||
|
||||
const char *endpoint_path = NULL;
|
||||
uint8_t caps[A2DP_MAX_CAPS_SIZE];
|
||||
uint8_t config[A2DP_MAX_CAPS_SIZE];
|
||||
char locations[64] = {0};
|
||||
int caps_size = 0;
|
||||
int conf_size;
|
||||
DBusMessageIter dict;
|
||||
|
|
@ -751,6 +753,8 @@ static DBusHandlerResult endpoint_select_properties(DBusConnection *conn, DBusMe
|
|||
endpoint_qos.preferred_delay_min = v;
|
||||
else if (spa_streq(key, "PreferredMaximumDelay"))
|
||||
endpoint_qos.preferred_delay_max = v;
|
||||
else if (spa_streq(key, "Location"))
|
||||
spa_scnprintf(locations, sizeof(locations), "%"PRIu32, v);
|
||||
else
|
||||
spa_log_info(monitor->log, "Unknown property %s", key);
|
||||
} else {
|
||||
|
|
@ -775,10 +779,12 @@ static DBusHandlerResult endpoint_select_properties(DBusConnection *conn, DBusMe
|
|||
ep->acceptor = true;
|
||||
}
|
||||
|
||||
/* TODO: determine which device the SelectConfiguration() call is associated
|
||||
* with; it's known here based on the remote endpoint.
|
||||
*/
|
||||
conf_size = codec->select_config(codec, 0, caps, caps_size, &monitor->default_audio_info, NULL, config);
|
||||
for (i = 0; i < (int)monitor->global_settings.n_items; ++i)
|
||||
setting_items[i] = monitor->global_settings.items[i];
|
||||
setting_items[i] = SPA_DICT_ITEM_INIT("bluez5.bap.locations", locations);
|
||||
settings = SPA_DICT_INIT(setting_items, monitor->global_settings.n_items + 1);
|
||||
|
||||
conf_size = codec->select_config(codec, 0, caps, caps_size, &monitor->default_audio_info, &settings, config);
|
||||
if (conf_size < 0) {
|
||||
spa_log_error(monitor->log, "can't select config: %d (%s)",
|
||||
conf_size, spa_strerror(conf_size));
|
||||
|
|
@ -3189,16 +3195,6 @@ static int transport_update_props(struct spa_bt_transport *transport,
|
|||
else
|
||||
transport->bap_cis = value;
|
||||
}
|
||||
else if (spa_streq(key, "Location")) {
|
||||
uint32_t value;
|
||||
|
||||
if (type != DBUS_TYPE_UINT32)
|
||||
goto next;
|
||||
dbus_message_iter_get_basic(&it[1], &value);
|
||||
|
||||
spa_log_debug(monitor->log, "transport %p: %s=%d", transport, key, (int)value);
|
||||
transport->bap_location = value;
|
||||
}
|
||||
next:
|
||||
dbus_message_iter_next(props_iter);
|
||||
}
|
||||
|
|
@ -4187,64 +4183,6 @@ int spa_bt_device_supports_hfp_codec(struct spa_bt_device *device, unsigned int
|
|||
return spa_bt_backend_supports_codec(monitor->backend, device, codec);
|
||||
}
|
||||
|
||||
static void bap_update_codec_location(struct spa_bt_transport *t)
|
||||
{
|
||||
uint8_t *data = t->configuration;
|
||||
size_t size = t->configuration_len;
|
||||
struct ltv *ltv;
|
||||
uint32_t location;
|
||||
int i;
|
||||
|
||||
if (!t->bap_location)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Append channel location from BAP transport location, if no channel
|
||||
* configuration is present in the configuration.
|
||||
*
|
||||
* XXX: The codec select_configuration should set the location
|
||||
* XXX: for mono channels from the device location. We have to do
|
||||
* XXX: this here because transport location is not know
|
||||
* XXX: in SelectProperties (TODO: should be fixed in bluez).
|
||||
*/
|
||||
|
||||
while (size > 0) {
|
||||
ltv = (struct ltv *)data;
|
||||
|
||||
if (ltv->len < sizeof(struct ltv) || ltv->len >= size)
|
||||
return;
|
||||
|
||||
if (ltv->type == LC3_TYPE_CHAN)
|
||||
return; /* already has the channel info */
|
||||
|
||||
size -= ltv->len + 1;
|
||||
data += ltv->len + 1;
|
||||
}
|
||||
|
||||
/* Pick the first location bit set */
|
||||
location = t->bap_location;
|
||||
for (i = 0; i < 32; ++i) {
|
||||
if (location & (1 << i)) {
|
||||
location = (1 << i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Append LTV value to transport configuration */
|
||||
size = t->configuration_len + sizeof(struct ltv) + sizeof(uint32_t);
|
||||
data = realloc(t->configuration, size);
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
ltv = SPA_PTROFF(data, t->configuration_len, struct ltv);
|
||||
ltv->len = 5;
|
||||
ltv->type = LC3_TYPE_CHAN;
|
||||
memcpy(ltv->value, &location, sizeof(uint32_t));
|
||||
|
||||
t->configuration = data;
|
||||
t->configuration_len = size;
|
||||
}
|
||||
|
||||
static DBusHandlerResult endpoint_set_configuration(DBusConnection *conn,
|
||||
const char *path, DBusMessage *m, void *userdata)
|
||||
{
|
||||
|
|
@ -4329,9 +4267,6 @@ static DBusHandlerResult endpoint_set_configuration(DBusConnection *conn,
|
|||
|= transport->device->a2dp_volume_active[SPA_BT_VOLUME_ID_TX];
|
||||
}
|
||||
|
||||
if (codec->bap)
|
||||
bap_update_codec_location(transport);
|
||||
|
||||
if (codec->validate_config) {
|
||||
struct spa_audio_info info;
|
||||
if (codec->validate_config(codec, sink ? MEDIA_CODEC_FLAG_SINK : 0,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue