diff --git a/audio/out/ao.c b/audio/out/ao.c index a4d6ad5db6..71c17e03b0 100644 --- a/audio/out/ao.c +++ b/audio/out/ao.c @@ -469,10 +469,7 @@ void ao_hotplug_event(struct ao *ao) // Returns whether this call actually set a new underrun flag. bool ao_underrun_event(struct ao *ao) { - bool new_underrun = ao_add_events(ao, AO_EVENT_UNDERRUN); - if (new_underrun) - MP_WARN(ao, "Device underrun detected.\n"); - return new_underrun; + return ao_add_events(ao, AO_EVENT_UNDERRUN); } bool ao_chmap_sel_adjust(struct ao *ao, const struct mp_chmap_sel *s, diff --git a/audio/out/pull.c b/audio/out/pull.c index a3d4b024b1..fe8204e01b 100644 --- a/audio/out/pull.c +++ b/audio/out/pull.c @@ -83,23 +83,10 @@ static void set_state(struct ao *ao, int new_state) } } -static void report_underruns(struct ao *ao) -{ - struct ao_pull_state *p = ao->api_priv; - - int underflow = atomic_fetch_and(&p->underflow, 0); - if (underflow) { - if (ao_underrun_event(ao)) - MP_VERBOSE(ao, "Audio underrun by %d samples.\n", underflow); - } -} - static int get_space(struct ao *ao) { struct ao_pull_state *p = ao->api_priv; - report_underruns(ao); - // Since the reader will read the last plane last, its free space is the // minimum free space across all planes. return mp_ring_available(p->buffers[ao->num_planes - 1]) / ao->sstride; @@ -133,7 +120,9 @@ static int play(struct ao *ao, void **data, int samples, int flags) bool draining = write_samples == samples && (flags & AOPLAY_FINAL_CHUNK); atomic_store(&p->draining, draining); - report_underruns(ao); + int underflow = atomic_fetch_and(&p->underflow, 0); + if (underflow) + MP_DBG(ao, "Audio underrun by %d samples.\n", underflow); return write_samples; } @@ -165,8 +154,10 @@ int ao_read_data(struct ao *ao, void **data, int samples, int64_t out_time_us) int buffered_bytes = mp_ring_buffered(p->buffers[0]); bytes = MPMIN(buffered_bytes, full_bytes); - if (full_bytes > bytes && !atomic_load(&p->draining)) + if (full_bytes > bytes && !atomic_load(&p->draining)) { atomic_fetch_add(&p->underflow, (full_bytes - bytes) / ao->sstride); + ao_underrun_event(ao); + } if (bytes > 0) atomic_store(&p->end_time_us, out_time_us); diff --git a/player/audio.c b/player/audio.c index 4f4b1992ae..fdc07fbf2b 100644 --- a/player/audio.c +++ b/player/audio.c @@ -859,8 +859,11 @@ void fill_audio_out_buffers(struct MPContext *mpctx) int playsize = ao_get_space(mpctx->ao); - if (ao_query_and_reset_events(mpctx->ao, AO_EVENT_UNDERRUN)) + if (ao_query_and_reset_events(mpctx->ao, AO_EVENT_UNDERRUN)) { + if (!ao_c->underrun) + MP_WARN(mpctx, "Audio device underrun detected.\n"); ao_c->underrun = true; + } // Stop feeding data if an underrun happened. Something else needs to // "unblock" audio after underrun. handle_update_cache() does this and can