summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wtaymans@redhat.com>2019-12-17 15:58:43 +0100
committerWim Taymans <wtaymans@redhat.com>2019-12-17 15:58:43 +0100
commit59c92bddbaa1717956a9c006946af373fa94e6b6 (patch)
tree994f6b7eb7d0436c8d5db0b2114800384c3170f5
parentd67d0123625297e0dd9a25081ececed009b6d168 (diff)
policy-ep: allow linking to nodes
When the target node or target endpoint is specified, try to link to it.
-rw-r--r--src/examples/media-session/policy-ep.c132
-rw-r--r--src/examples/media-session/stream-endpoint.c2
2 files changed, 82 insertions, 52 deletions
diff --git a/src/examples/media-session/policy-ep.c b/src/examples/media-session/policy-ep.c
index fc3115e9..52b41c20 100644
--- a/src/examples/media-session/policy-ep.c
+++ b/src/examples/media-session/policy-ep.c
@@ -71,7 +71,7 @@ struct endpoint {
struct spa_list link; /**< link in impl endpoint_list */
enum pw_direction direction;
- struct endpoint *peer;
+ uint32_t linked;
uint32_t client_id;
int32_t priority;
@@ -251,7 +251,6 @@ static void session_remove(void *data, struct sm_object *object)
struct find_data {
struct impl *impl;
- uint32_t path_id;
struct endpoint *ep;
struct endpoint *endpoint;
bool exclusive;
@@ -272,23 +271,18 @@ static int find_endpoint(void *data, struct endpoint *endpoint)
if (!endpoint->enabled)
return 0;
- if (find->path_id != SPA_ID_INVALID && endpoint->id != find->path_id)
+ if (endpoint->direction == find->ep->direction) {
+ pw_log_debug(".. same direction");
+ return 0;
+ }
+ if (strcmp(endpoint->media, find->ep->media) != 0) {
+ pw_log_debug(".. incompatible media %s <-> %s", endpoint->media, find->ep->media);
return 0;
-
- if (find->path_id == SPA_ID_INVALID) {
- if (endpoint->direction == find->ep->direction) {
- pw_log_debug(".. same direction");
- return 0;
- }
- if (strcmp(endpoint->media, find->ep->media) != 0) {
- pw_log_debug(".. incompatible media %s <-> %s", endpoint->media, find->ep->media);
- return 0;
- }
-
- plugged = endpoint->plugged;
- priority = endpoint->priority;
}
+ plugged = endpoint->plugged;
+ priority = endpoint->priority;
+
if ((find->exclusive && endpoint->busy) || endpoint->exclusive) {
pw_log_debug(NAME " %p: endpoint '%d' in use", impl, endpoint->id);
return 0;
@@ -308,12 +302,12 @@ static int find_endpoint(void *data, struct endpoint *endpoint)
return 0;
}
-static int link_endpoints(struct endpoint *endpoint, enum pw_direction direction, struct endpoint *peer, int max)
+static int link_endpoints(struct endpoint *endpoint, struct endpoint *peer)
{
- struct impl *impl = peer->impl;
+ struct impl *impl = endpoint->impl;
struct pw_properties *props;
- pw_log_debug(NAME " %p: link endpoints %d %d %d", impl, max, endpoint->id, peer->id);
+ pw_log_debug(NAME " %p: link endpoints %d %d", impl, endpoint->id, peer->id);
if (endpoint->direction == PW_DIRECTION_INPUT) {
struct endpoint *t = endpoint;
@@ -333,8 +327,43 @@ static int link_endpoints(struct endpoint *endpoint, enum pw_direction direction
pw_properties_free(props);
- endpoint->peer = peer;
- peer->peer = endpoint;
+ endpoint->linked++;
+ peer->linked++;
+
+ return 0;
+}
+
+static int link_node(struct endpoint *endpoint, struct sm_node *peer)
+{
+ struct impl *impl = endpoint->impl;
+ struct pw_properties *props;
+
+ pw_log_debug(NAME " %p: link endpoint %d to node %d", impl, endpoint->id, peer->obj.id);
+
+ props = pw_properties_new(NULL, NULL);
+
+ if (endpoint->direction == PW_DIRECTION_INPUT) {
+ pw_properties_setf(props, PW_KEY_LINK_OUTPUT_NODE, "%d", peer->obj.id);
+ pw_properties_setf(props, PW_KEY_LINK_OUTPUT_PORT, "%d", -1);
+ pw_properties_setf(props, PW_KEY_ENDPOINT_LINK_INPUT_ENDPOINT, "%d", endpoint->id);
+ pw_properties_setf(props, PW_KEY_ENDPOINT_LINK_INPUT_STREAM, "%d", -1);
+ pw_log_debug(NAME " %p: node %d -> endpoint %d", impl,
+ peer->obj.id, endpoint->id);
+ } else {
+ pw_properties_setf(props, PW_KEY_ENDPOINT_LINK_OUTPUT_ENDPOINT, "%d", endpoint->id);
+ pw_properties_setf(props, PW_KEY_ENDPOINT_LINK_OUTPUT_STREAM, "%d", -1);
+ pw_properties_setf(props, PW_KEY_LINK_INPUT_NODE, "%d", peer->obj.id);
+ pw_properties_setf(props, PW_KEY_LINK_INPUT_PORT, "%d", -1);
+ pw_log_debug(NAME " %p: endpoint %d -> node %d", impl,
+ endpoint->id, peer->obj.id);
+ }
+
+ pw_endpoint_create_link((struct pw_endpoint*)endpoint->obj->obj.proxy,
+ &props->dict);
+
+ pw_properties_free(props);
+
+ endpoint->linked++;
return 0;
}
@@ -347,7 +376,8 @@ static int rescan_endpoint(struct impl *impl, struct endpoint *ep)
struct find_data find;
struct pw_endpoint_info *info;
struct endpoint *peer;
- enum pw_direction direction;
+ struct sm_object *obj;
+ struct sm_node *node;
if (ep->type == ENDPOINT_TYPE_DEVICE)
return 0;
@@ -357,8 +387,8 @@ static int rescan_endpoint(struct impl *impl, struct endpoint *ep)
return 0;
}
- if (ep->peer != NULL) {
- pw_log_debug(NAME " %p: endpoint %d already has peer", impl, ep->id);
+ if (ep->linked > 0) {
+ pw_log_debug(NAME " %p: endpoint %d is already linked", impl, ep->id);
return 0;
}
@@ -383,48 +413,44 @@ static int rescan_endpoint(struct impl *impl, struct endpoint *ep)
else
exclusive = false;
- str = spa_dict_lookup(props, PW_KEY_ENDPOINT_TARGET);
- if (str != NULL)
- find.path_id = atoi(str);
- else
- find.path_id = SPA_ID_INVALID;
-
- pw_log_info(NAME " %p: exclusive:%d target %d", impl, exclusive, find.path_id);
-
find.impl = impl;
find.ep = ep;
find.exclusive = exclusive;
- spa_list_for_each(peer, &impl->endpoint_list, link)
- find_endpoint(&find, peer);
-
- if (find.endpoint == NULL && find.path_id != SPA_ID_INVALID) {
- struct sm_object *obj;
- pw_log_debug(NAME " %p: no endpoint found for %d, try endpoint", impl, ep->id);
+ pw_log_info(NAME " %p: exclusive:%d", impl, exclusive);
- if ((obj = sm_media_session_find_object(impl->session, find.path_id)) != NULL) {
- if (obj->type == PW_TYPE_INTERFACE_Endpoint) {
+ str = spa_dict_lookup(props, PW_KEY_ENDPOINT_TARGET);
+ if (str == NULL)
+ str = spa_dict_lookup(props, PW_KEY_NODE_TARGET);
+ if (str != NULL) {
+ uint32_t path_id = atoi(str);
+ pw_log_info(NAME " %p: target:%d", impl, path_id);
+
+ if ((obj = sm_media_session_find_object(impl->session, path_id)) != NULL) {
+ switch (obj->type) {
+ case PW_TYPE_INTERFACE_Endpoint:
peer = sm_object_get_data(obj, SESSION_KEY);
goto do_link;
- }
- if (obj->type == PW_TYPE_INTERFACE_Node) {
- pw_log_debug(NAME " %p: target is node", impl);
- }
- }
- else {
- str = spa_dict_lookup(props, PW_KEY_NODE_DONT_RECONNECT);
- if (str != NULL && pw_properties_parse_bool(str)) {
-// pw_registry_destroy(impl->registry, ep->id);
- return -ENOENT;
+ case PW_TYPE_INTERFACE_Node:
+ node = (struct sm_node*)obj;
+ goto do_link_node;
}
}
}
+ spa_list_for_each(peer, &impl->endpoint_list, link)
+ find_endpoint(&find, peer);
+
if (find.endpoint == NULL) {
struct sm_object *obj;
pw_log_warn(NAME " %p: no endpoint found for %d", impl, ep->id);
+ str = spa_dict_lookup(props, PW_KEY_NODE_DONT_RECONNECT);
+ if (str != NULL && pw_properties_parse_bool(str)) {
+// pw_registry_destroy(impl->registry, ep->id);
+ }
+
obj = sm_media_session_find_object(impl->session, ep->client_id);
if (obj && obj->type == PW_TYPE_INTERFACE_Client) {
pw_client_error((struct pw_client*)obj->proxy,
@@ -445,8 +471,10 @@ static int rescan_endpoint(struct impl *impl, struct endpoint *ep)
peer->busy = true;
do_link:
- link_endpoints(ep, direction, peer, 1);
-
+ link_endpoints(ep, peer);
+ return 1;
+do_link_node:
+ link_node(ep, node);
return 1;
}
diff --git a/src/examples/media-session/stream-endpoint.c b/src/examples/media-session/stream-endpoint.c
index f019899e..5028d4b6 100644
--- a/src/examples/media-session/stream-endpoint.c
+++ b/src/examples/media-session/stream-endpoint.c
@@ -400,6 +400,8 @@ static struct endpoint *create_endpoint(struct node *node)
if ((str = spa_dict_lookup(dict, PW_KEY_NODE_AUTOCONNECT)) != NULL)
pw_properties_set(props, PW_KEY_ENDPOINT_AUTOCONNECT, str);
if ((str = spa_dict_lookup(dict, PW_KEY_NODE_TARGET)) != NULL)
+ pw_properties_set(props, PW_KEY_NODE_TARGET, str);
+ if ((str = spa_dict_lookup(dict, PW_KEY_ENDPOINT_TARGET)) != NULL)
pw_properties_set(props, PW_KEY_ENDPOINT_TARGET, str);
}