diff --git a/audio/out/ao.h b/audio/out/ao.h index 78f21c9ed9..18c7cdc02f 100644 --- a/audio/out/ao.h +++ b/audio/out/ao.h @@ -98,7 +98,7 @@ void ao_set_gain(struct ao *ao, float gain); double ao_get_delay(struct ao *ao); void ao_reset(struct ao *ao); void ao_start(struct ao *ao); -void ao_set_paused(struct ao *ao, bool paused); +void ao_set_paused(struct ao *ao, bool paused, bool eof); void ao_drain(struct ao *ao); bool ao_is_playing(struct ao *ao); struct mp_async_queue; diff --git a/audio/out/buffer.c b/audio/out/buffer.c index 673ec7a84e..77506d8363 100644 --- a/audio/out/buffer.c +++ b/audio/out/buffer.c @@ -349,12 +349,17 @@ void ao_start(struct ao *ao) ao_wakeup_playthread(ao); } -void ao_set_paused(struct ao *ao, bool paused) +void ao_set_paused(struct ao *ao, bool paused, bool eof) { struct buffer_state *p = ao->buffer_state; bool wakeup = false; bool do_reset = false, do_start = false; + // If we are going to pause on eof and ao is still playing, + // be sure to drain the ao first for gapless. + if (eof && paused && ao_is_playing(ao)) + ao_drain(ao); + pthread_mutex_lock(&p->lock); if ((p->playing || !ao->driver->write) && !p->paused && paused) { diff --git a/player/audio.c b/player/audio.c index fbba8acd11..4ea2d09f94 100644 --- a/player/audio.c +++ b/player/audio.c @@ -486,7 +486,8 @@ static int reinit_audio_filters_and_output(struct MPContext *mpctx) ao_c->ao_resume_time = opts->audio_wait_open > 0 ? mp_time_sec() + opts->audio_wait_open : 0; - ao_set_paused(mpctx->ao, get_internal_paused(mpctx)); + bool eof = mpctx->audio_status == STATUS_EOF; + ao_set_paused(mpctx->ao, get_internal_paused(mpctx), eof); ao_chain_set_ao(ao_c, mpctx->ao); diff --git a/player/playloop.c b/player/playloop.c index 0df97943d6..02902f17cd 100644 --- a/player/playloop.c +++ b/player/playloop.c @@ -162,8 +162,10 @@ void set_pause_state(struct MPContext *mpctx, bool user_pause) if (internal_paused != mpctx->paused) { mpctx->paused = internal_paused; - if (mpctx->ao) - ao_set_paused(mpctx->ao, internal_paused); + if (mpctx->ao) { + bool eof = mpctx->audio_status == STATUS_EOF; + ao_set_paused(mpctx->ao, internal_paused, eof); + } if (mpctx->video_out) vo_set_paused(mpctx->video_out, internal_paused);