From 89bf8b856692ef734f8289ba1adee8b3e0592f9f Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 8 Aug 2024 15:20:38 +0200 Subject: [PATCH] impl-node: improve driver activation counter calculation Don't schedule nodes that didn't receive us as the driver node yet because they will not be able to signal us when they complete and leave us xrun. Also only count the nodes that we will actually schedule and expect a signal from, set this in the pending activation counter. This can be less when some nodes are still starting or receiving the driver activation record. This eleminates some errors when adding and removing nodes. See #4182 --- src/pipewire/impl-node.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/pipewire/impl-node.c b/src/pipewire/impl-node.c index 2d431fd85..d32a3f5d1 100644 --- a/src/pipewire/impl-node.c +++ b/src/pipewire/impl-node.c @@ -2080,6 +2080,7 @@ again: all_ready = sync_type == SYNC_CHECK; update_sync = !all_ready; target_sync = sync_type == SYNC_START ? true : false; + pending = 0; spa_list_for_each(t, &driver->rt.target_list, link) { struct pw_node_activation *ta = t->activation; @@ -2088,6 +2089,10 @@ again: ta->driver_id = driver->info.id; retry_status: pw_node_activation_state_reset(&ta->state[0]); + + if (ta->active_driver_id != ta->driver_id) + continue; + /* we don't change the state of inactive nodes and don't use them * for reposition. The pending will be at least 1 and they might * get decremented to 0 but since the status is inactive, we don't @@ -2101,6 +2106,8 @@ retry_status: if (SPA_UNLIKELY(!SPA_ATOMIC_CAS(ta->status, old_status, PW_NODE_ACTIVATION_NOT_TRIGGERED))) goto retry_status; + pending++; + if (old_status == PW_NODE_ACTIVATION_TRIGGERED || old_status == PW_NODE_ACTIVATION_AWAKE) { update_xrun_stats(ta, 1, nsec / 1000, 0); @@ -2139,6 +2146,7 @@ retry_status: reposition_target = NULL; goto again; } + state->pending = pending; update_position(node, all_ready, nsec);