mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
bluez5: add a2dp-source plugin
This commit is contained in:
parent
29164a0f54
commit
674f3e197e
4 changed files with 1192 additions and 15 deletions
1082
spa/plugins/bluez5/a2dp-source.c
Normal file
1082
spa/plugins/bluez5/a2dp-source.c
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -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" },
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
bluez5_sources = ['plugin.c',
|
||||
'a2dp-sink.c',
|
||||
'a2dp-source.c',
|
||||
'bluez5-device.c',
|
||||
'bluez5-monitor.c']
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue