From a821027fb88ee23643db4da21d200d22137ce2a3 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 25 Aug 2023 12:56:17 +0200 Subject: [PATCH] context: scan link groups in both directions Don't just stop scanning the link groups after we tried one direction, also try the other direction. Otherwise: source -> loopback1_in|loopback1_out -> loopback2_in|loopback2_out -> record will first scan from loopback2_out downstream and finds loopback2_in in the same group but without downstream links. Then when upstream scan is done, loopback2_out is already scanned and will be skipped and so loopback1 stays IDLE. We fix this by keeping track of the direction that we scanned a node in and only stop when we scanned it in the same direction twice. --- src/pipewire/context.c | 6 +++++- src/pipewire/private.h | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/pipewire/context.c b/src/pipewire/context.c index 9d9b629ae..ec02558d8 100644 --- a/src/pipewire/context.c +++ b/src/pipewire/context.c @@ -800,6 +800,8 @@ static inline int run_nodes(struct pw_context *context, struct pw_impl_node *nod pw_log_debug("node %p: '%s' direction:%s", node, node->name, pw_direction_as_string(direction)); + SPA_FLAG_SET(node->checked, 1u<input_ports, link) { spa_list_for_each(l, &p->links, input_link) { @@ -834,7 +836,8 @@ static inline int run_nodes(struct pw_context *context, struct pw_impl_node *nod * them. */ if (node->link_group != NULL) { spa_list_for_each(t, nodes, sort_link) { - if (t->exported || !t->active || t->runnable) + if (t->exported || !t->active || + SPA_FLAG_IS_SET(t->checked, 1u<link_group, node->link_group)) continue; @@ -1201,6 +1204,7 @@ again: /* clean up the flags first */ spa_list_for_each(n, &context->node_list, link) { n->visited = false; + n->checked = 0; n->runnable = n->always_process && n->active; } diff --git a/src/pipewire/private.h b/src/pipewire/private.h index 90993ba16..26dce7e76 100644 --- a/src/pipewire/private.h +++ b/src/pipewire/private.h @@ -676,6 +676,7 @@ struct pw_impl_node { unsigned int trigger:1; /**< has the TRIGGER property and needs an extra * trigger to start processing. */ unsigned int can_suspend:1; + unsigned int checked; /**< for sorting */ uint32_t port_user_data_size; /**< extra size for port user data */