support: fix freewheel timeout in node-driver

When freewheeling we will immediately schedule a new graph cycle when we
get a process call because the graph completed.

When the process call is not done, because of some xrun or
because some node was removed that causes the graph to fail completion,
The next cycle will happen after a timeout.

This timeout was calculated as the ideal wakeup time (after a quantum of
time) and would accumulate for each timeout. The result is that the
timeout ended up far in the future and would stall the freewheel driver
for a long time.

Fix this by always setting the next timeout to wakeup time + freewheel.timeout
seconds. Also add a config property for the timeout (10 seconds, like
jack2 by default).
This commit is contained in:
Wim Taymans 2024-01-10 11:59:10 +01:00
parent c7519c73ac
commit 15908328d1

View file

@ -30,6 +30,7 @@
#define NAME "driver"
#define DEFAULT_FREEWHEEL false
#define DEFAULT_FREEWHEEL_WAIT 10
#define DEFAULT_CLOCK_PREFIX "clock.system"
#define DEFAULT_CLOCK_ID CLOCK_MONOTONIC
@ -44,6 +45,7 @@ struct props {
bool freewheel;
char clock_name[64];
clockid_t clock_id;
uint32_t freewheel_wait;
};
struct impl {
@ -86,6 +88,7 @@ static void reset_props(struct props *props)
props->freewheel = DEFAULT_FREEWHEEL;
spa_zero(props->clock_name);
props->clock_id = CLOCK_MONOTONIC;
props->freewheel_wait = DEFAULT_FREEWHEEL_WAIT;
}
static const struct clock_info {
@ -262,7 +265,10 @@ static void on_timeout(struct spa_source *source)
duration = 1024;
rate = 48000;
}
nsec = this->next_time;
if (this->props.freewheel)
nsec = gettime_nsec(this, this->props.clock_id);
else
nsec = this->next_time;
if (this->tracking)
/* we are actually following another clock */
@ -293,7 +299,10 @@ static void on_timeout(struct spa_source *source)
this->last_time = current_time;
if (this->tracking) {
if (this->props.freewheel) {
corr = 1.0;
this->next_time = nsec + this->props.freewheel_wait * SPA_NSEC_PER_SEC;
} else if (this->tracking) {
corr = spa_dll_update(&this->dll, err);
this->next_time = nsec + duration / corr * 1e9 / rate;
} else {
@ -610,6 +619,8 @@ impl_init(const struct spa_handle_factory *factory,
} else {
this->props.clock_id = FD_TO_CLOCKID(this->clock_fd);
}
} else if (spa_streq(k, "freewheel.wait")) {
this->props.freewheel_wait = atoi(s);
}
}
if (this->props.clock_name[0] == '\0') {