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

File diff suppressed because it is too large Load diff

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" },
};

View file

@ -45,8 +45,6 @@
#include <spa/utils/type.h>
#include <spa/debug/mem.h>
#undef ENABLE_AAC
#include "a2dp-codecs.h"
#include "defs.h"
@ -1221,8 +1219,25 @@ static int register_a2dp_endpoint(struct spa_bt_monitor *monitor,
profile_path = "/A2DP/SBC/Source";
break;
case A2DP_CODEC_MPEG24:
profile_path = "/A2DP/MPEG24/Source";
/* We don't support MPEG24 for now */
return -ENOTSUP;
/* profile_path = "/A2DP/MPEG24/Source";
break; */
default:
return -ENOTSUP;
}
break;
case SPA_BT_PROFILE_A2DP_SINK:
switch (codec) {
case A2DP_CODEC_SBC:
profile_path = "/A2DP/SBC/Sink";
break;
case A2DP_CODEC_MPEG24:
/* We don't support MPEG24 for now */
return -ENOTSUP;
/* profile_path = "/A2DP/MPEG24/Sink";
break; */
default:
return -ENOTSUP;
}
@ -1291,18 +1306,30 @@ static int adapter_register_endpoints(struct spa_bt_adapter *a)
{
struct spa_bt_monitor *monitor = a->monitor;
#ifdef ENABLE_AAC
/* We don't support MPEG24 for now */
/*
register_a2dp_endpoint(monitor, a->path,
SPA_BT_UUID_A2DP_SOURCE,
SPA_BT_PROFILE_A2DP_SOURCE,
A2DP_CODEC_MPEG24,
&bluez_a2dp_aac, sizeof(bluez_a2dp_aac));
#endif
register_a2dp_endpoint(monitor, a->path,
SPA_BT_UUID_A2DP_SINK,
SPA_BT_PROFILE_A2DP_SINK,
A2DP_CODEC_MPEG24,
&bluez_a2dp_aac, sizeof(bluez_a2dp_aac));
*/
register_a2dp_endpoint(monitor, a->path,
SPA_BT_UUID_A2DP_SOURCE,
SPA_BT_PROFILE_A2DP_SOURCE,
A2DP_CODEC_SBC,
&bluez_a2dp_sbc, sizeof(bluez_a2dp_sbc));
register_a2dp_endpoint(monitor, a->path,
SPA_BT_UUID_A2DP_SINK,
SPA_BT_PROFILE_A2DP_SINK,
A2DP_CODEC_SBC,
&bluez_a2dp_sbc, sizeof(bluez_a2dp_sbc));
return 0;
}

View file

@ -1,6 +1,7 @@
bluez5_sources = ['plugin.c',
'a2dp-sink.c',
'a2dp-source.c',
'bluez5-device.c',
'bluez5-monitor.c']