bluez5: account for driver clock rate difference in rate matching

The rate matching calculations are done in the system clock domain.  If
the driver ticks at a different rate, the correction factor needs to be
adjusted by the rate_diff.

This fixes ISO streams getting out of sync with each other when target
delay changes. This happens because typically one of them is the driver
and the other follower. Driver adjust clock rate, and follower does its
own adjustment *on top of that* so it rate matches more or less at
double speed.  (The DLL of the follower to some degree corrects for
this, but can't do that when hitting RATE_CTL_DIFF_MAX and moreover it
acts with a delay.)
This commit is contained in:
Pauli Virtanen 2025-07-11 15:11:38 +03:00 committed by Wim Taymans
parent ddc023b883
commit 30047f232b

View file

@ -678,6 +678,13 @@ static int setup_matching(struct impl *this)
if (port->rate_match) {
port->rate_match->rate = 1 / port->ratectl.corr;
/* We rate match in the system clock domain. If driver ticks at a
* different rate, we as follower must compensate.
*/
if (this->following && SPA_LIKELY(this->position &&
this->position->clock.rate_diff))
port->rate_match->rate /= this->position->clock.rate_diff;
SPA_FLAG_UPDATE(port->rate_match->flags, SPA_IO_RATE_MATCH_FLAG_ACTIVE, this->following);
}