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.
This commit is contained in:
Wim Taymans 2023-08-25 12:56:17 +02:00
parent d416ac9f18
commit a821027fb8
2 changed files with 6 additions and 1 deletions

View file

@ -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<<direction);
if (direction == PW_DIRECTION_INPUT) {
spa_list_for_each(p, &node->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<<direction))
continue;
if (!spa_streq(t->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;
}

View file

@ -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 */