mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-04 13:30:12 -05:00
policy-node: implement move node
Move nodes to a new target when the metadata changes.
This commit is contained in:
parent
ff876bf58e
commit
7915bf5778
1 changed files with 55 additions and 3 deletions
|
|
@ -421,7 +421,7 @@ static int link_nodes(struct node *node, struct node *peer)
|
||||||
props = pw_properties_new(NULL, NULL);
|
props = pw_properties_new(NULL, NULL);
|
||||||
pw_properties_setf(props, PW_KEY_LINK_OUTPUT_NODE, "%d", node->id);
|
pw_properties_setf(props, PW_KEY_LINK_OUTPUT_NODE, "%d", node->id);
|
||||||
pw_properties_setf(props, PW_KEY_LINK_INPUT_NODE, "%d", peer->id);
|
pw_properties_setf(props, PW_KEY_LINK_INPUT_NODE, "%d", peer->id);
|
||||||
pw_log_info("linking node %d -> node %d", node->id, peer->id);
|
pw_log_info("linking node %d to node %d", node->id, peer->id);
|
||||||
|
|
||||||
sm_media_session_create_links(impl->session, &props->dict);
|
sm_media_session_create_links(impl->session, &props->dict);
|
||||||
|
|
||||||
|
|
@ -449,7 +449,7 @@ static int unlink_nodes(struct node *node, struct node *peer)
|
||||||
props = pw_properties_new(NULL, NULL);
|
props = pw_properties_new(NULL, NULL);
|
||||||
pw_properties_setf(props, PW_KEY_LINK_OUTPUT_NODE, "%d", node->id);
|
pw_properties_setf(props, PW_KEY_LINK_OUTPUT_NODE, "%d", node->id);
|
||||||
pw_properties_setf(props, PW_KEY_LINK_INPUT_NODE, "%d", peer->id);
|
pw_properties_setf(props, PW_KEY_LINK_INPUT_NODE, "%d", peer->id);
|
||||||
pw_log_info("unlinking node %d -> node %d", node->id, peer->id);
|
pw_log_info("unlinking node %d from peer node %d", node->id, peer->id);
|
||||||
|
|
||||||
sm_media_session_remove_links(impl->session, &props->dict);
|
sm_media_session_remove_links(impl->session, &props->dict);
|
||||||
|
|
||||||
|
|
@ -619,6 +619,16 @@ static const struct sm_media_session_events session_events = {
|
||||||
.destroy = session_destroy,
|
.destroy = session_destroy,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct node *find_node_by_id(struct impl *impl, uint32_t id)
|
||||||
|
{
|
||||||
|
struct node *node;
|
||||||
|
spa_list_for_each(node, &impl->node_list, link) {
|
||||||
|
if (node->id == id)
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static struct node *find_node_by_name(struct impl *impl, const char *name)
|
static struct node *find_node_by_name(struct impl *impl, const char *name)
|
||||||
{
|
{
|
||||||
const char *str;
|
const char *str;
|
||||||
|
|
@ -646,7 +656,7 @@ static int move_node(struct impl *impl, const char *source, const char *target)
|
||||||
if (src_node == dst_node)
|
if (src_node == dst_node)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
pw_log_info("move %d -> %d", src_node->obj->obj.id, dst_node->obj->obj.id);
|
pw_log_info("move %d -> %d", src_node->id, dst_node->id);
|
||||||
|
|
||||||
/* unlink all nodes from source and link to target */
|
/* unlink all nodes from source and link to target */
|
||||||
spa_list_for_each(n, &impl->node_list, link) {
|
spa_list_for_each(n, &impl->node_list, link) {
|
||||||
|
|
@ -668,11 +678,39 @@ static int move_node(struct impl *impl, const char *source, const char *target)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int handle_move(struct impl *impl, struct node *src_node, struct node *dst_node)
|
||||||
|
{
|
||||||
|
const char *str;
|
||||||
|
struct pw_node_info *info;
|
||||||
|
|
||||||
|
if ((info = src_node->obj->info) == NULL)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
if ((str = spa_dict_lookup(info->props, PW_KEY_NODE_DONT_RECONNECT)) != NULL &&
|
||||||
|
pw_properties_parse_bool(str)) {
|
||||||
|
pw_log_warn("can't reconnect node %d to %d", src_node->id,
|
||||||
|
dst_node->id);
|
||||||
|
return -EPERM;
|
||||||
|
}
|
||||||
|
|
||||||
|
pw_log_info("move node %d: from peer %d to %d", src_node->id,
|
||||||
|
src_node->peer ? src_node->peer->id : SPA_ID_INVALID,
|
||||||
|
dst_node->id);
|
||||||
|
|
||||||
|
if (src_node->peer)
|
||||||
|
unlink_nodes(src_node, src_node->peer);
|
||||||
|
link_nodes(src_node, dst_node);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int metadata_property(void *object, uint32_t subject,
|
static int metadata_property(void *object, uint32_t subject,
|
||||||
const char *key, const char *type, const char *value)
|
const char *key, const char *type, const char *value)
|
||||||
{
|
{
|
||||||
struct impl *impl = object;
|
struct impl *impl = object;
|
||||||
|
|
||||||
|
if (key == NULL || type == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (subject == PW_ID_CORE) {
|
if (subject == PW_ID_CORE) {
|
||||||
if (strcmp(key, "default.audio.sink.name") == 0) {
|
if (strcmp(key, "default.audio.sink.name") == 0) {
|
||||||
if (impl->default_audio_sink && value)
|
if (impl->default_audio_sink && value)
|
||||||
|
|
@ -686,7 +724,21 @@ static int metadata_property(void *object, uint32_t subject,
|
||||||
free(impl->default_audio_source);
|
free(impl->default_audio_source);
|
||||||
impl->default_audio_source = value ? strdup(value) : NULL;
|
impl->default_audio_source = value ? strdup(value) : NULL;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
struct node *src_node, *dst_node = NULL;
|
||||||
|
|
||||||
|
src_node = find_node_by_id(impl, subject);
|
||||||
|
|
||||||
|
if (strcmp(key, "target.node") == 0 && value != NULL) {
|
||||||
|
dst_node = find_node_by_id(impl, atoi(value));
|
||||||
|
}
|
||||||
|
else if (strcmp(key, "target.node.name") == 0 && value != NULL) {
|
||||||
|
dst_node = find_node_by_name(impl, value);
|
||||||
|
}
|
||||||
|
if (src_node && dst_node)
|
||||||
|
handle_move(impl, src_node, dst_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue