diff --git a/spa/include/spa/node/io.h b/spa/include/spa/node/io.h index 166529ac1..20934efd4 100644 --- a/spa/include/spa/node/io.h +++ b/spa/include/spa/node/io.h @@ -117,7 +117,7 @@ struct spa_io_clock { * is unique per clock and can be used to check if nodes * share the same clock. */ uint64_t nsec; /**< time in nanoseconds against monotonic clock */ - struct spa_fraction rate; /**< rate for position/duration/delay */ + struct spa_fraction rate; /**< rate for position/duration/delay/xrun */ uint64_t position; /**< current position */ uint64_t duration; /**< duration of current cycle */ int64_t delay; /**< delay between position and hardware, @@ -129,8 +129,8 @@ struct spa_io_clock { uint64_t target_duration; /**< target duration of next cycle */ uint32_t target_seq; /**< seq counter. must be equal at start and * end of read and lower bit must be 0 */ - - uint32_t padding[3]; + uint32_t padding; + uint64_t xrun; /**< estimated accumulated xrun duration */ }; /* the size of the video in this cycle */ diff --git a/spa/plugins/alsa/alsa-pcm.c b/spa/plugins/alsa/alsa-pcm.c index fdd40e80c..cddb0b64d 100644 --- a/spa/plugins/alsa/alsa-pcm.c +++ b/spa/plugins/alsa/alsa-pcm.c @@ -1931,14 +1931,18 @@ static int alsa_recover(struct state *state, int err) delay = SPA_TIMEVAL_TO_USEC(&diff); missing = delay * state->rate / SPA_USEC_PER_SEC; + if (missing == 0) + missing = state->threshold; spa_log_trace(state->log, "%p: xrun of %"PRIu64" usec %"PRIu64, state, delay, missing); + if (state->clock) + state->clock->xrun += missing; + state->sample_count += missing; + spa_node_call_xrun(&state->callbacks, SPA_TIMEVAL_TO_USEC(&trigger), delay, NULL); - - state->sample_count += missing ? missing : state->threshold; break; } case SND_PCM_STATE_SUSPENDED: