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.
This commit is contained in:
Wim Taymans 2021-12-07 18:28:57 +01:00
parent c14e89a578
commit 2e199eba43
3 changed files with 16 additions and 8 deletions

View file

@ -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'",

View file

@ -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]);

View file

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