diff --git a/src/pipewire/context.c b/src/pipewire/context.c index 7b6d426ab..8956c9c03 100644 --- a/src/pipewire/context.c +++ b/src/pipewire/context.c @@ -1101,11 +1101,25 @@ static int collect_nodes(struct pw_context *context, struct pw_impl_node *node, pw_log_debug(" next node %p: '%s' runnable:%u %p %p %p", n, n->name, n->runnable, n->groups, n->link_groups, sync); } - spa_list_for_each(n, collect, sort_link) - if (!n->driving && n->runnable) { + /* All non-driver runnable nodes (ie. reachable with a non-passive link) now make + * all linked nodes up and downstream runnable as well */ + spa_list_for_each(n, collect, sort_link) { + if (!n->driver && n->runnable) { run_nodes(context, n, collect, PW_DIRECTION_OUTPUT, 0); run_nodes(context, n, collect, PW_DIRECTION_INPUT, 0); } + } + /* now we might have made a driver runnable, if the node is not runnable at this point + * it means it was linked to the driver with passives links and some other node + * made the driver active. If the node is a leaf it can not be activated in any other + * way and we will also make it, and all its peers, runnable */ + spa_list_for_each(n, collect, sort_link) { + if (!n->driver && n->driver_node->runnable && !n->runnable && n->leaf) { + n->runnable = true; + run_nodes(context, n, collect, PW_DIRECTION_OUTPUT, 0); + run_nodes(context, n, collect, PW_DIRECTION_INPUT, 0); + } + } return 0; } diff --git a/src/pipewire/impl-node.c b/src/pipewire/impl-node.c index 75e945617..87fbe58e2 100644 --- a/src/pipewire/impl-node.c +++ b/src/pipewire/impl-node.c @@ -1309,6 +1309,10 @@ static void check_properties(struct pw_impl_node *node) } } node->lock_rate = pw_properties_get_bool(node->properties, PW_KEY_NODE_LOCK_RATE, false); + /* the leaf node is one that only produces/consumes the data. We can deduce this from the + * absence of a link-group and the fact that it has no output/input ports. */ + node->leaf = node->link_groups == NULL && + (node->info.max_input_ports == 0 || node->info.max_output_ports == 0); value = pw_properties_get_uint32(node->properties, PW_KEY_NODE_FORCE_RATE, SPA_ID_INVALID); if (value == 0) diff --git a/src/pipewire/private.h b/src/pipewire/private.h index 072eac596..ebe0c6d5d 100644 --- a/src/pipewire/private.h +++ b/src/pipewire/private.h @@ -784,6 +784,7 @@ struct pw_impl_node { 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 */ + unsigned int leaf:1; /**< node only produces/consumes data */ uint32_t transport; /**< latest transport request */