From 6305eada809eb88554791bd9bcf19baa1837475b Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 16 Sep 2025 13:41:11 +0200 Subject: [PATCH] impl-port: add port.exclusive flag Add a port.exclusive flag and inherit the value from the node.exclusive flag if not otherwise specified. Make it so that exclusive ports can only be linked once. This is important for explicit sync where there can be only one producer and one consumer in order to signal the timeline objects correctly. --- src/pipewire/impl-node.c | 1 + src/pipewire/impl-port.c | 4 ++++ src/pipewire/keys.h | 1 + src/pipewire/private.h | 2 ++ 4 files changed, 8 insertions(+) diff --git a/src/pipewire/impl-node.c b/src/pipewire/impl-node.c index 14f76b9e7..754dbe602 100644 --- a/src/pipewire/impl-node.c +++ b/src/pipewire/impl-node.c @@ -1159,6 +1159,7 @@ static void check_properties(struct pw_impl_node *node) node->transport_sync = pw_properties_get_bool(node->properties, PW_KEY_NODE_TRANSPORT_SYNC, false); impl->cache_params = pw_properties_get_bool(node->properties, PW_KEY_NODE_CACHE_PARAMS, true); driver = pw_properties_get_bool(node->properties, PW_KEY_NODE_DRIVER, false); + node->exclusive = pw_properties_get_bool(node->properties, PW_KEY_NODE_EXCLUSIVE, false); if (node->driver != driver) { pw_log_debug("%p: driver %d -> %d", node, node->driver, driver); diff --git a/src/pipewire/impl-port.c b/src/pipewire/impl-port.c index 9c8744ff4..c85b05b88 100644 --- a/src/pipewire/impl-port.c +++ b/src/pipewire/impl-port.c @@ -370,6 +370,9 @@ int pw_impl_port_init_mix(struct pw_impl_port *port, struct pw_impl_port_mix *mi uint32_t port_id; int res = 0; + if (port->exclusive && port->n_mix != 0) + return -EBUSY; + port_id = pw_map_insert_new(&port->mix_port_map, mix); if (port_id == SPA_ID_INVALID) return -errno; @@ -1236,6 +1239,7 @@ int pw_impl_port_add(struct pw_impl_port *port, struct pw_impl_node *node) is_monitor = pw_properties_get_bool(port->properties, PW_KEY_PORT_MONITOR, false); port->ignore_latency = pw_properties_get_bool(port->properties, PW_KEY_PORT_IGNORE_LATENCY, false); + port->exclusive = pw_properties_get_bool(port->properties, PW_KEY_PORT_EXCLUSIVE, node->exclusive); is_control = PW_IMPL_PORT_IS_CONTROL(port); if (is_control) { diff --git a/src/pipewire/keys.h b/src/pipewire/keys.h index ae7df2372..88b549d89 100644 --- a/src/pipewire/keys.h +++ b/src/pipewire/keys.h @@ -245,6 +245,7 @@ extern "C" { #define PW_KEY_PORT_PASSIVE "port.passive" /**< the ports wants passive links, since 0.3.67 */ #define PW_KEY_PORT_IGNORE_LATENCY "port.ignore-latency" /**< latency ignored by peers, since 0.3.71 */ #define PW_KEY_PORT_GROUP "port.group" /**< the port group of the port 1.2.0 */ +#define PW_KEY_PORT_EXCLUSIVE "port.exclusive" /**< link port only once 1.6.0 */ /** link properties */ #define PW_KEY_LINK_ID "link.id" /**< a link id */ diff --git a/src/pipewire/private.h b/src/pipewire/private.h index 74624c9e3..e886f54e1 100644 --- a/src/pipewire/private.h +++ b/src/pipewire/private.h @@ -782,6 +782,7 @@ struct pw_impl_node { unsigned int sync:1; /**< the sync-groups are active */ unsigned int async:1; /**< async processing, one cycle latency */ unsigned int lazy:1; /**< the graph is lazy scheduling */ + unsigned int exclusive:1; /**< ports can only be linked once */ uint32_t transport; /**< latest transport request */ @@ -964,6 +965,7 @@ struct pw_impl_port { unsigned int have_latency_param:1; unsigned int ignore_latency:1; unsigned int have_latency:1; + unsigned int exclusive:1; /**< port can only be linked once */ unsigned int have_tag_param:1; struct spa_pod *tag[2]; /**< tags */