More session manager work

pulseaudio card is mapped to device
pulseaudio sink/source is mapped to an endpoint
prepare to map streams to card profiles
Add Route param to implement the endpoint routing later (ports)
Create an alsa endpoint for each device
Create one stream for each endpoint (Playback/Capture)

Implement create_link on the endpoint. The idea is to call
create link on the peer endpoint to complete the link. Remove
create_link on the session.

Add stream-monitor to turn pw_stream nodes into endpoints

Add a policy manager that tries to link endpoints

Use enum pw_direction for the endpoint direction. We can use the
media_class to determine if this is a pw_stream or not but it should
not really matter, you can link any output to any input.

Add autoconnect property for endpoints to make the policy connect.
This commit is contained in:
Wim Taymans 2019-11-13 09:38:40 +01:00
parent edd011605d
commit 3f3dfbc67e
27 changed files with 2338 additions and 439 deletions

View file

@ -52,14 +52,18 @@ struct alsa_object;
struct alsa_node {
struct monitor *monitor;
enum pw_direction direction;
struct alsa_object *object;
struct spa_list link;
uint32_t id;
struct pw_properties *props;
struct pw_proxy *proxy;
struct spa_node *node;
struct pw_proxy *proxy;
struct spa_hook listener;
struct pw_node_info *info;
};
struct alsa_object {
@ -106,6 +110,17 @@ static void alsa_update_node(struct alsa_object *obj, struct alsa_node *node,
pw_properties_update(node->props, info->props);
}
static void node_event_info(void *object, const struct pw_node_info *info)
{
struct alsa_node *node = object;
node->info = pw_node_info_update(node->info, info);
}
static const struct pw_node_proxy_events node_events = {
PW_VERSION_NODE_PROXY_EVENTS,
.info = node_event_info,
};
static struct alsa_node *alsa_create_node(struct alsa_object *obj, uint32_t id,
const struct spa_device_object_info *info)
{
@ -142,6 +157,11 @@ static struct alsa_node *alsa_create_node(struct alsa_object *obj, uint32_t id,
if ((stream = pw_properties_get(node->props, SPA_KEY_API_ALSA_PCM_STREAM)) == NULL)
stream = "unknown";
if (!strcmp(stream, "capture"))
node->direction = PW_DIRECTION_OUTPUT;
else
node->direction = PW_DIRECTION_INPUT;
if (obj->first) {
if (atol(dev) != 0)
obj->priority -= 256;
@ -160,7 +180,7 @@ static struct alsa_node *alsa_create_node(struct alsa_object *obj, uint32_t id,
}
if (pw_properties_get(node->props, SPA_KEY_MEDIA_CLASS) == NULL) {
if (!strcmp(stream, "capture"))
if (node->direction == PW_DIRECTION_OUTPUT)
pw_properties_setf(node->props, SPA_KEY_MEDIA_CLASS, "Audio/Source");
else
pw_properties_setf(node->props, SPA_KEY_MEDIA_CLASS, "Audio/Sink");
@ -209,6 +229,7 @@ static struct alsa_node *alsa_create_node(struct alsa_object *obj, uint32_t id,
res = -errno;
goto clean_node;
}
pw_proxy_add_object_listener(node->proxy, &node->listener, &node_events, node);
spa_list_append(&obj->node_list, &node->link);