diff options
author | Wim Taymans <wtaymans@redhat.com> | 2019-12-17 15:58:43 +0100 |
---|---|---|
committer | Wim Taymans <wtaymans@redhat.com> | 2019-12-17 15:58:43 +0100 |
commit | 59c92bddbaa1717956a9c006946af373fa94e6b6 (patch) | |
tree | 994f6b7eb7d0436c8d5db0b2114800384c3170f5 | |
parent | d67d0123625297e0dd9a25081ececed009b6d168 (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.c | 132 | ||||
-rw-r--r-- | src/examples/media-session/stream-endpoint.c | 2 |
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); } |