From 2e199eba4374acc6e96e002d4d0166a1a665639d Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 7 Dec 2021 18:28:57 +0100 Subject: [PATCH] node: update quantum and rate at beginning of cycle Don't directly update the quantum and rate in the driver position when recalculating the graph or else clients might see different values during one cycle. Instead update another variable and copy this into the position when we start a new cycle. --- src/pipewire/context.c | 12 ++++++------ src/pipewire/impl-node.c | 10 ++++++++-- src/pipewire/private.h | 2 ++ 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/pipewire/context.c b/src/pipewire/context.c index 422e8cf83..f726e779e 100644 --- a/src/pipewire/context.c +++ b/src/pipewire/context.c @@ -1189,7 +1189,7 @@ again: if (force_rate) lock_rate = false; - current_rate = n->rt.position->clock.rate.denom; + current_rate = n->current_rate.denom; if (target_rate != current_rate && lock_rate) target_rate = current_rate; else if (target_rate != current_rate && !force_rate && @@ -1200,7 +1200,7 @@ again: pw_log_info("(%s-%u) state:%s new rate:%u->%u", n->name, n->info.id, pw_node_state_as_string(n->info.state), - n->rt.position->clock.rate.denom, + n->current_rate.denom, target_rate); if (force_rate) { @@ -1210,7 +1210,7 @@ again: if (n->info.state >= PW_NODE_STATE_IDLE) suspend_driver(context, n); } - n->rt.position->clock.rate = SPA_FRACTION(1, target_rate); + n->current_rate = SPA_FRACTION(1, target_rate); current_rate = target_rate; /* we might be suspended now and the links need to be prepared again */ goto again; @@ -1236,12 +1236,12 @@ again: if (context->settings.clock_power_of_two_quantum) quantum = flp2(quantum); - if (running && quantum != n->rt.position->clock.duration && !lock_quantum) { + if (running && quantum != n->current_quantum && !lock_quantum) { pw_log_info("(%s-%u) new quantum:%"PRIu64"->%u", n->name, n->info.id, - n->rt.position->clock.duration, + n->current_quantum, quantum); - n->rt.position->clock.duration = quantum; + n->current_quantum = quantum; } pw_log_debug("%p: driving %p running:%d passive:%d quantum:%u '%s'", diff --git a/src/pipewire/impl-node.c b/src/pipewire/impl-node.c index 7a4ed8c5f..7f94fed2e 100644 --- a/src/pipewire/impl-node.c +++ b/src/pipewire/impl-node.c @@ -1124,8 +1124,11 @@ static void reset_position(struct pw_impl_node *this, struct spa_io_position *po uint32_t quantum = s->clock_force_quantum == 0 ? s->clock_quantum : s->clock_force_quantum; uint32_t rate = s->clock_force_rate == 0 ? s->clock_rate : s->clock_force_rate; - pos->clock.rate = SPA_FRACTION(1, rate); - pos->clock.duration = quantum; + this->current_rate = SPA_FRACTION(1, rate); + this->current_quantum = quantum; + + pos->clock.rate = this->current_rate; + pos->clock.duration = this->current_quantum; pos->video.flags = SPA_IO_VIDEO_SIZE_VALID; pos->video.size = s->video_size; pos->video.stride = pos->video.size.width * 16; @@ -1579,6 +1582,9 @@ static int node_ready(void *data, int status) node->rt.target.signal(node->rt.target.data); } + node->rt.position->clock.duration = node->current_quantum; + node->rt.position->clock.rate = node->current_rate; + sync_type = check_updates(node, &reposition_owner); owner[0] = ATOMIC_LOAD(a->segment_owner[0]); owner[1] = ATOMIC_LOAD(a->segment_owner[1]); diff --git a/src/pipewire/private.h b/src/pipewire/private.h index ab131508c..e0d74cccb 100644 --- a/src/pipewire/private.h +++ b/src/pipewire/private.h @@ -728,6 +728,8 @@ struct pw_impl_node { struct ratelimit rate_limit; } rt; + struct spa_fraction current_rate; + uint64_t current_quantum; void *user_data; /**< extra user data */ };