diff --git a/src/modules/module-client-node/remote-node.c b/src/modules/module-client-node/remote-node.c index f276a9de4..a76307caa 100644 --- a/src/modules/module-client-node/remote-node.c +++ b/src/modules/module-client-node/remote-node.c @@ -1210,8 +1210,8 @@ static struct pw_proxy *node_export(struct pw_core *core, void *object, bool do_ /* the node might have been registered and added to a driver. When we export, * we will be assigned a new driver target from the server and we can forget our * local ones. */ - pw_impl_node_remove_target(node, &node->rt.driver_target); - pw_impl_node_remove_target(node->driver_node, &node->rt.target); + pw_node_peer_unref(spa_steal_ptr(node->from_driver_peer)); + pw_node_peer_unref(spa_steal_ptr(node->to_driver_peer)); data->allow_mlock = pw_properties_get_bool(node->properties, "mem.allow-mlock", data->context->settings.mem_allow_mlock); diff --git a/src/modules/module-profiler.c b/src/modules/module-profiler.c index 535b7244c..8d2cfc15d 100644 --- a/src/modules/module-profiler.c +++ b/src/modules/module-profiler.c @@ -225,7 +225,7 @@ static void context_do_profile(void *data) struct pw_node_activation *na; struct spa_fraction latency; - if (t->id == id || t->flags & PW_NODE_TARGET_PEER) + if (t->id == id) continue; if (n != NULL) { diff --git a/src/pipewire/impl-link.c b/src/pipewire/impl-link.c index 1baf74033..a6426f833 100644 --- a/src/pipewire/impl-link.c +++ b/src/pipewire/impl-link.c @@ -52,7 +52,8 @@ struct impl { /** \endcond */ -static struct pw_node_peer *pw_node_peer_ref(struct pw_impl_node *onode, struct pw_impl_node *inode) +SPA_EXPORT +struct pw_node_peer *pw_node_peer_ref(struct pw_impl_node *onode, struct pw_impl_node *inode) { struct pw_node_peer *peer; @@ -70,7 +71,6 @@ static struct pw_node_peer *pw_node_peer_ref(struct pw_impl_node *onode, struct peer->ref = 1; peer->output = onode; copy_target(&peer->target, &inode->rt.target); - peer->target.flags = PW_NODE_TARGET_PEER; spa_list_append(&onode->peer_list, &peer->link); pw_log_debug("new peer %p from %p to %p", peer, onode, inode); @@ -79,9 +79,10 @@ static struct pw_node_peer *pw_node_peer_ref(struct pw_impl_node *onode, struct return peer; } -static void pw_node_peer_unref(struct pw_node_peer *peer) +SPA_EXPORT +void pw_node_peer_unref(struct pw_node_peer *peer) { - if (--peer->ref > 0) + if (peer == NULL || --peer->ref > 0) return; spa_list_remove(&peer->link); pw_log_debug("remove peer %p from %p to %p", peer, peer->output, peer->target.node); diff --git a/src/pipewire/impl-node.c b/src/pipewire/impl-node.c index f539c8ee8..f41e37659 100644 --- a/src/pipewire/impl-node.c +++ b/src/pipewire/impl-node.c @@ -899,9 +899,8 @@ int pw_impl_node_register(struct pw_impl_node *this, this->rt.target.id = this->info.id; this->rt.target.activation->position.clock.id = this->global->id; - copy_target(&this->rt.driver_target, &this->rt.target); - pw_impl_node_add_target(this, &this->rt.driver_target); - pw_impl_node_add_target(this, &this->rt.target); + this->from_driver_peer = pw_node_peer_ref(this, this); + this->to_driver_peer = pw_node_peer_ref(this, this); pw_properties_setf(this->properties, PW_KEY_OBJECT_ID, "%d", this->global->id); pw_properties_setf(this->properties, PW_KEY_OBJECT_SERIAL, "%"PRIu64, @@ -983,18 +982,16 @@ int pw_impl_node_set_driver(struct pw_impl_node *node, struct pw_impl_node *driv old->name, old->info.id, driver->name, driver->info.id); /* make sure the old driver doesn't trigger the node anymore */ - pw_impl_node_remove_target(old, &node->rt.target); + pw_node_peer_unref(spa_steal_ptr(node->from_driver_peer)); /* make sure the node doesn't trigger the old driver anymore */ - pw_impl_node_remove_target(node, &node->rt.driver_target); - spa_zero(node->rt.driver_target); + pw_node_peer_unref(spa_steal_ptr(node->to_driver_peer)); node->driver_node = driver; node->moved = true; /* first send new driver target to node, the node is not yet being * scheduled so it won't trigger yet */ - copy_target(&node->rt.driver_target, &driver->rt.target); - pw_impl_node_add_target(node, &node->rt.driver_target); + node->to_driver_peer = pw_node_peer_ref(node, driver); /* then set the new driver node activation */ pw_impl_node_set_io(node, SPA_IO_Position, @@ -1002,7 +999,7 @@ int pw_impl_node_set_driver(struct pw_impl_node *node, struct pw_impl_node *driv sizeof(struct spa_io_position)); /* and then make the driver trigger the node */ - pw_impl_node_add_target(driver, &node->rt.target); + node->from_driver_peer = pw_node_peer_ref(driver, node); pw_impl_node_emit_driver_changed(node, old, driver); @@ -2117,7 +2114,6 @@ static int node_xrun(void *data, uint64_t trigger, uint64_t delay, struct spa_po { struct pw_impl_node *this = data; struct pw_node_activation *a = this->rt.target.activation; - struct pw_node_activation *da = this->rt.driver_target.activation; struct spa_system *data_system = this->rt.target.system; uint64_t nsec = get_time_ns(data_system); int suppressed; @@ -2126,8 +2122,8 @@ static int node_xrun(void *data, uint64_t trigger, uint64_t delay, struct spa_po if ((suppressed = spa_ratelimit_test(&this->rt.rate_limit, nsec)) >= 0) { struct spa_fraction rate; - if (da) { - struct spa_io_clock *cl = &da->position.clock; + if (a) { + struct spa_io_clock *cl = &a->position.clock; rate.num = cl->rate.num * cl->duration; rate.denom = cl->rate.denom; } else { @@ -2303,8 +2299,8 @@ void pw_impl_node_destroy(struct pw_impl_node *node) /* remove ourself as a follower from the driver node */ spa_list_remove(&node->follower_link); - pw_impl_node_remove_target(node, &node->rt.driver_target); - pw_impl_node_remove_target(node->driver_node, &node->rt.target); + pw_node_peer_unref(spa_steal_ptr(node->from_driver_peer)); + pw_node_peer_unref(spa_steal_ptr(node->to_driver_peer)); remove_segment_owner(node->driver_node, node->info.id); spa_list_consume(follower, &node->follower_list, follower_link) { diff --git a/src/pipewire/private.h b/src/pipewire/private.h index 8f32d7761..9bfd88498 100644 --- a/src/pipewire/private.h +++ b/src/pipewire/private.h @@ -532,8 +532,6 @@ static inline void pw_node_activation_state_reset(struct pw_node_activation_stat struct pw_node_target { struct spa_list link; -#define PW_NODE_TARGET_NONE 0 -#define PW_NODE_TARGET_PEER 1 uint32_t flags; uint32_t id; char name[128]; @@ -661,6 +659,16 @@ static inline void trigger_target(struct pw_node_target *t, uint64_t nsec) wake_target(t, nsec); } +struct pw_node_peer { + int ref; + struct spa_list link; /**< link in peer list */ + struct pw_impl_node *output; /**< the output node */ + struct pw_node_target target; /**< target of the input node */ +}; + +struct pw_node_peer *pw_node_peer_ref(struct pw_impl_node *onode, struct pw_impl_node *inode); +void pw_node_peer_unref(struct pw_node_peer *peer); + #define pw_impl_node_emit(o,m,v,...) spa_hook_list_call(&o->listener_list, struct pw_impl_node_events, m, v, ##__VA_ARGS__) #define pw_impl_node_emit_destroy(n) pw_impl_node_emit(n, destroy, 0) #define pw_impl_node_emit_free(n) pw_impl_node_emit(n, free, 0) @@ -779,7 +787,6 @@ struct pw_impl_node { struct spa_list target_list; /* list of targets to signal after * this node */ - struct pw_node_target driver_target; /* driver target that we signal */ struct spa_list input_mix; /* our input ports (and mixers) */ struct spa_list output_mix; /* output ports (and mixers) */ @@ -791,6 +798,8 @@ struct pw_impl_node { bool prepared; /**< the node was added to loop */ } rt; + struct pw_node_peer *to_driver_peer; /* node -> driver */ + struct pw_node_peer *from_driver_peer; /* driver -> node */ struct spa_fraction target_rate; uint64_t target_quantum; @@ -936,13 +945,6 @@ struct pw_control_link { unsigned int valid:1; }; -struct pw_node_peer { - int ref; - struct spa_list link; /**< link in peer list */ - struct pw_impl_node *output; /**< the output node */ - struct pw_node_target target; /**< target of the input node */ -}; - #define pw_impl_link_emit(o,m,v,...) spa_hook_list_call(&o->listener_list, struct pw_impl_link_events, m, v, ##__VA_ARGS__) #define pw_impl_link_emit_destroy(l) pw_impl_link_emit(l, destroy, 0) #define pw_impl_link_emit_free(l) pw_impl_link_emit(l, free, 0)