diff --git a/src/pipewire/context.c b/src/pipewire/context.c index f3e1b4d76..e30a2ce73 100644 --- a/src/pipewire/context.c +++ b/src/pipewire/context.c @@ -1637,6 +1637,7 @@ again: uint64_t quantum_stamp = 0, rate_stamp = 0; bool force_rate, force_quantum, restore_rate = false, restore_quantum = false; bool do_reconfigure = false, need_resume, was_target_pending; + bool have_request = false; const uint32_t *node_rates; uint32_t node_n_rates, node_def_rate; uint32_t node_max_quantum, node_min_quantum, node_def_quantum, node_rate_quantum; @@ -1705,6 +1706,9 @@ again: context, s, running, s->runnable, rate.num, rate.denom, latency.num, latency.denom, s->name); + if (running && s != n && s->supports_request > 0) + have_request = true; + s->moved = false; } @@ -1861,6 +1865,9 @@ again: n->target_rate = n->rt.position->clock.target_rate; } + SPA_FLAG_UPDATE(n->rt.position->clock.flags, + SPA_IO_CLOCK_FLAG_LAZY, have_request && n->supports_lazy > 0); + pw_log_debug("%p: driver %p running:%d runnable:%d quantum:%u rate:%u (%"PRIu64"/%u)'%s'", context, n, running, n->runnable, target_quantum, target_rate, n->rt.position->clock.target_duration, diff --git a/src/pipewire/impl-node.c b/src/pipewire/impl-node.c index 8a03d7250..c1e79cb66 100644 --- a/src/pipewire/impl-node.c +++ b/src/pipewire/impl-node.c @@ -324,6 +324,9 @@ static int start_node(struct pw_impl_node *this) pw_log_debug("%p: start node driving:%d driver:%d prepared:%d", this, this->driving, this->driver, this->rt.prepared); + this->lazy = this->rt.position && SPA_FLAG_IS_SET(this->rt.position->clock.flags, + SPA_IO_CLOCK_FLAG_LAZY); + if (!(this->driving && this->driver)) { impl->pending_play = true; res = spa_node_send_command(this->node, @@ -758,6 +761,14 @@ static inline void insert_driver(struct pw_context *context, struct pw_impl_node spa_list_for_each_safe(n, t, &context->driver_list, driver_link) { if (n->priority_driver < node->priority_driver) break; + if (n->priority_driver == 0 && node->priority_driver == 0) { + /* no priority is set, we prefer the driver that does + * lazy scheduling. */ + if (n->supports_request > 0 && node->supports_lazy > 0) { + if (n->supports_request <= node->supports_lazy) + break; + } + } } spa_list_append(&n->driver_link, &node->driver_link); pw_context_emit_driver_added(context, node); diff --git a/src/pipewire/private.h b/src/pipewire/private.h index e14d79f42..fa9fa8dea 100644 --- a/src/pipewire/private.h +++ b/src/pipewire/private.h @@ -782,6 +782,7 @@ struct pw_impl_node { unsigned int sync:1; /**< the sync-groups are active */ unsigned int transport:1; /**< the transport is active */ unsigned int async:1; /**< async processing, one cycle latency */ + unsigned int lazy:1; /**< the graph is lazy scheduling */ uint32_t port_user_data_size; /**< extra size for port user data */