From a18d495b59e6b32a8d944b9e3d4bfb458f409f05 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 5 Oct 2023 16:08:01 +0200 Subject: [PATCH] impl-node: keep separate elapsed time Don't directly update the offset when not running. The running time is position - offset and stays constant when not running. Instead keep an extra elapsed variable that is updated when the state is running. The offset is then always posision - elapsed. This is more reliable and can compensate for jumps in the position timestamps. Fixes #3544 See #3189 --- src/pipewire/impl-node.c | 7 +++++-- src/pipewire/private.h | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/pipewire/impl-node.c b/src/pipewire/impl-node.c index 63f121321..18cd2a5c8 100644 --- a/src/pipewire/impl-node.c +++ b/src/pipewire/impl-node.c @@ -1322,6 +1322,7 @@ static void reset_position(struct pw_impl_node *this, struct spa_io_position *po this->target_rate = SPA_FRACTION(1, rate); this->target_quantum = quantum; + this->elapsed = 0; pos->clock.rate = pos->clock.target_rate = this->target_rate; pos->clock.duration = pos->clock.target_duration = this->target_quantum; @@ -1745,8 +1746,10 @@ static inline void update_position(struct pw_impl_node *node, int all_ready, uin if (all_ready) a->position.state = SPA_IO_POSITION_STATE_RUNNING; } - if (SPA_LIKELY(a->position.state != SPA_IO_POSITION_STATE_RUNNING)) - a->position.offset += a->position.clock.duration; + if (SPA_LIKELY(a->position.state == SPA_IO_POSITION_STATE_RUNNING)) + node->elapsed += a->position.clock.duration; + + a->position.offset = a->position.clock.position - node->elapsed; } /* Called from the data-loop and it is the starting point for driver nodes. diff --git a/src/pipewire/private.h b/src/pipewire/private.h index b753b9ebb..9a41e35f2 100644 --- a/src/pipewire/private.h +++ b/src/pipewire/private.h @@ -732,6 +732,7 @@ struct pw_impl_node { uint64_t target_quantum; uint64_t driver_start; + uint64_t elapsed; /* elapsed time in playing */ void *user_data; /**< extra user data */ };