node: add a clock XRUN_RECOVER flag

Make a new flag that is set when the process function is called because
of a recover from a graph xrun.

Use this flag in the freewheel driver to detect a recover and to avoid
scheduling a new timeout. We should schedule a new timeout only when the
process function was called after completion.

This fixes export in ardour some more when the initial driver timeout
didn't complete (when, for example, some nodes were still starting up).
This commit is contained in:
Wim Taymans 2024-07-12 12:21:59 +02:00
parent 73d41308b1
commit 42096de3cc
3 changed files with 6 additions and 2 deletions

View file

@ -125,7 +125,8 @@ struct spa_io_range {
* \ref spa_io_position.clock.id in \ref SPA_IO_Position are the same. * \ref spa_io_position.clock.id in \ref SPA_IO_Position are the same.
*/ */
struct spa_io_clock { struct spa_io_clock {
#define SPA_IO_CLOCK_FLAG_FREEWHEEL (1u<<0) #define SPA_IO_CLOCK_FLAG_FREEWHEEL (1u<<0) /* graph is freewheeling */
#define SPA_IO_CLOCK_FLAG_XRUN_RECOVER (1u<<1) /* recovering from xrun */
uint32_t flags; /**< Clock flags */ uint32_t flags; /**< Clock flags */
uint32_t id; /**< Unique clock id, set by host application */ uint32_t id; /**< Unique clock id, set by host application */
char name[64]; /**< Clock name prefixed with API, set by node when it receives char name[64]; /**< Clock name prefixed with API, set by node when it receives

View file

@ -524,7 +524,8 @@ static int impl_node_process(void *object)
spa_return_val_if_fail(this != NULL, -EINVAL); spa_return_val_if_fail(this != NULL, -EINVAL);
spa_log_trace(this->log, "process %d", this->props.freewheel); spa_log_trace(this->log, "process %d", this->props.freewheel);
if (this->props.freewheel) { if (this->props.freewheel &&
!SPA_FLAG_IS_SET(this->position->clock.flags, SPA_IO_CLOCK_FLAG_XRUN_RECOVER)) {
this->next_time = gettime_nsec(this, this->timer_clockid); this->next_time = gettime_nsec(this, this->timer_clockid);
set_timeout(this, this->next_time); set_timeout(this, this->next_time);
} }

View file

@ -2034,7 +2034,9 @@ static int node_ready(void *data, int status)
old_status = SPA_ATOMIC_LOAD(a->status); old_status = SPA_ATOMIC_LOAD(a->status);
if (old_status != PW_NODE_ACTIVATION_FINISHED) { if (old_status != PW_NODE_ACTIVATION_FINISHED) {
SPA_ATOMIC_STORE(a->status, PW_NODE_ACTIVATION_TRIGGERED); SPA_ATOMIC_STORE(a->status, PW_NODE_ACTIVATION_TRIGGERED);
SPA_FLAG_SET(cl->flags, SPA_IO_CLOCK_FLAG_XRUN_RECOVER);
process_node(node, nsec); process_node(node, nsec);
SPA_FLAG_CLEAR(cl->flags, SPA_IO_CLOCK_FLAG_XRUN_RECOVER);
debug_xrun_graph(node, nsec); debug_xrun_graph(node, nsec);
} }
} }