bluez5: add a2dp-source plugin

This commit is contained in:
Julian Bouzas 2019-04-19 13:26:07 -04:00 committed by Wim Taymans
parent 29164a0f54
commit 674f3e197e
4 changed files with 1192 additions and 15 deletions

View file

@ -42,6 +42,7 @@
#define MAX_DEVICES 64
extern const struct spa_handle_factory spa_a2dp_source_factory;
extern const struct spa_handle_factory spa_a2dp_sink_factory;
static const char default_device[] = "";
@ -69,24 +70,76 @@ struct impl {
struct spa_bt_device *bt_dev;
};
static int emit_nodes(struct impl *this)
static int emit_source_node(struct impl *this)
{
struct spa_dict_item items[1];
struct spa_bt_transport *t;
struct spa_bt_device *device = this->bt_dev;
enum spa_bt_profile profile;
enum spa_bt_profile profile = SPA_BT_PROFILE_NULL;
if (device->connected_profiles & SPA_BT_PROFILE_A2DP_SINK)
profile = SPA_BT_PROFILE_A2DP_SINK;
else if (device->connected_profiles & SPA_BT_PROFILE_HSP_AG)
profile = SPA_BT_PROFILE_HSP_AG;
else if (device->connected_profiles & SPA_BT_PROFILE_HFP_AG)
profile = SPA_BT_PROFILE_HFP_AG;
else {
spa_log_warn(this->log, "no profile available");
if (device->connected_profiles & SPA_BT_PROFILE_A2DP_SOURCE) {
spa_log_info(this->log, "A2DP (source) profile found");
profile = SPA_BT_PROFILE_A2DP_SOURCE;
} else if (device->connected_profiles & SPA_BT_PROFILE_HSP_HS) {
spa_log_info(this->log, "HSP (source) profile found (Not implemented yet)");
profile = SPA_BT_PROFILE_HSP_HS;
return -ENODEV;
} else if (device->connected_profiles & SPA_BT_PROFILE_HFP_HF) {
spa_log_info(this->log, "HFP (source) profile found (Not implemented yet)");
profile = SPA_BT_PROFILE_HFP_HF;
return -ENODEV;
}
/* Return if no profiles are connected */
if (profile == SPA_BT_PROFILE_NULL)
return -ENODEV;
spa_list_for_each(t, &device->transport_list, device_link) {
if (t->profile == profile) {
struct spa_device_object_info info;
char transport[16];
snprintf(transport, 16, "%p", t);
items[0] = SPA_DICT_ITEM_INIT("bluez5.transport", transport);
info = SPA_DEVICE_OBJECT_INFO_INIT();
info.type = SPA_TYPE_INTERFACE_Node;
info.factory = &spa_a2dp_source_factory;
info.change_mask = SPA_DEVICE_OBJECT_CHANGE_MASK_PROPS;
info.props = &SPA_DICT_INIT_ARRAY(items);
spa_device_emit_object_info(&this->hooks, 0, &info);
break;
}
}
spa_log_info (this->log, "bluez5 source nodes emitted");
return 0;
}
static int emit_sink_node(struct impl *this)
{
struct spa_dict_item items[1];
struct spa_bt_transport *t;
struct spa_bt_device *device = this->bt_dev;
enum spa_bt_profile profile = SPA_BT_PROFILE_NULL;
if (device->connected_profiles & SPA_BT_PROFILE_A2DP_SINK) {
spa_log_info(this->log, "A2DP (sink) profile found");
profile = SPA_BT_PROFILE_A2DP_SINK;
} else if (device->connected_profiles & SPA_BT_PROFILE_HSP_AG) {
spa_log_info(this->log, "HSP (sink) profile found (Not implemented yet)");
profile = SPA_BT_PROFILE_HSP_AG;
return -ENODEV;
} else if (device->connected_profiles & SPA_BT_PROFILE_HFP_AG) {
spa_log_info(this->log, "HFP (sink) profile found (Not implemented yet)");
profile = SPA_BT_PROFILE_HFP_AG;
return -ENODEV;
}
/* Return if no profiles are connected */
if (profile == SPA_BT_PROFILE_NULL)
return -ENODEV;
spa_list_for_each(t, &device->transport_list, device_link) {
if (t->profile == profile) {
@ -107,9 +160,23 @@ static int emit_nodes(struct impl *this)
}
}
spa_log_info(this->log, "bluez5 sink nodes emitted");
return 0;
}
static int emit_nodes(struct impl *this)
{
int sink, src;
sink = emit_sink_node(this);
src = emit_source_node(this);
if (sink == -ENODEV && src == -ENODEV)
spa_log_warn(this->log, "no profile available");
return SPA_MAX(sink, src);
}
static const struct spa_dict_item info_items[] = {
{ "media.class", "Audio/Device" },
};