module-ffado: implement freewheeling

When freewheeling starts, pause the streaming and resume when
freewheeling stops. Also make sure we don't try to do any IO or
timeouts.
This commit is contained in:
Wim Taymans 2024-08-01 17:17:05 +02:00
parent 3bd1217a02
commit 3e5a85b3bc

View file

@ -253,6 +253,7 @@ struct impl {
unsigned int do_disconnect:1;
unsigned int fix_midi:1;
unsigned int started:1;
unsigned int freewheel:1;
pthread_t thread;
@ -683,10 +684,28 @@ static void stream_io_changed(void *data, void *port_data, uint32_t id, void *ar
{
struct stream *s = data;
struct impl *impl = s->impl;
bool freewheel;
if (port_data == NULL) {
switch (id) {
case SPA_IO_Position:
impl->position = area;
freewheel = impl->position != NULL &&
SPA_FLAG_IS_SET(impl->position->clock.flags, SPA_IO_CLOCK_FLAG_FREEWHEEL);
if (impl->freewheel != freewheel) {
pw_log_info("freewheel: %d -> %d", impl->freewheel, freewheel);
impl->freewheel = freewheel;
if (impl->started) {
if (freewheel) {
set_timeout(impl, 0);
ffado_streaming_stop(impl->dev);
} else {
ffado_streaming_start(impl->dev);
impl->rt.done = true;
set_timeout(impl, get_time_ns(impl));
}
}
}
break;
default:
break;
@ -991,6 +1010,9 @@ static void on_ffado_timeout(void *data, uint64_t expirations)
pw_log_trace_fp("wakeup %d", impl->rt.done);
if (impl->freewheel)
return;
if (!impl->rt.done) {
impl->rt.pw_xrun++;
impl->rt.new_xrun = true;