diff --git a/audio/out/ao.c b/audio/out/ao.c index 55fcac1a24..313f4f7554 100644 --- a/audio/out/ao.c +++ b/audio/out/ao.c @@ -327,6 +327,11 @@ void ao_drain(struct ao *ao) } } +bool ao_eof_reached(struct ao *ao) +{ + return ao_get_delay(ao) < AO_EOF_DELAY; +} + bool ao_chmap_sel_adjust(struct ao *ao, const struct mp_chmap_sel *s, struct mp_chmap *map) { diff --git a/audio/out/ao.h b/audio/out/ao.h index 056cdf7295..59de0c08b1 100644 --- a/audio/out/ao.h +++ b/audio/out/ao.h @@ -49,11 +49,6 @@ typedef struct ao_control_vol { float right; } ao_control_vol_t; -// If ao_get_delay() reaches this value after ao_play() was called with the -// AOPLAY_FINAL_CHUNK flag set, the playback core expects that the audio has -// all been played. -#define AO_EOF_DELAY 0.05 - struct ao; struct mpv_global; struct input_ctx; @@ -77,5 +72,6 @@ void ao_reset(struct ao *ao); void ao_pause(struct ao *ao); void ao_resume(struct ao *ao); void ao_drain(struct ao *ao); +bool ao_eof_reached(struct ao *ao); #endif /* MPLAYER_AUDIO_OUT_H */ diff --git a/audio/out/internal.h b/audio/out/internal.h index 4214c6c1d6..cc3abb14f5 100644 --- a/audio/out/internal.h +++ b/audio/out/internal.h @@ -27,6 +27,11 @@ // Minimum buffer size in seconds. #define MIN_BUFFER 0.2 +// If ao_get_delay() reaches this value after ao_play() was called with the +// AOPLAY_FINAL_CHUNK flag set, the playback core expects that the audio has +// all been played. +#define AO_EOF_DELAY 0.05 + /* global data used by ao.c and ao drivers */ struct ao { int samplerate; diff --git a/player/playloop.c b/player/playloop.c index 61a2ac0c20..9ad9debfe1 100644 --- a/player/playloop.c +++ b/player/playloop.c @@ -961,7 +961,6 @@ void run_playloop(struct MPContext *mpctx) handle_cursor_autohide(mpctx); } - double buffered_audio = -1; while (mpctx->d_video) { // never loops, for "break;" only struct vo *vo = mpctx->video_out; update_fps(mpctx); @@ -1032,7 +1031,7 @@ void run_playloop(struct MPContext *mpctx) mpctx->time_frame -= get_relative_time(mpctx); double audio_pts = playing_audio_pts(mpctx); if (full_audio_buffers && !mpctx->restart_playback) { - buffered_audio = ao_get_delay(mpctx->ao); + double buffered_audio = ao_get_delay(mpctx->ao); MP_TRACE(mpctx, "audio delay=%f\n", buffered_audio); if (opts->autosync) { @@ -1184,17 +1183,13 @@ void run_playloop(struct MPContext *mpctx) } if (!video_left) mpctx->restart_playback = false; - if (mpctx->d_audio && buffered_audio == -1) - buffered_audio = mpctx->paused ? 0 : ao_get_delay(mpctx->ao); update_osd_msg(mpctx); if (!video_left && (!mpctx->paused || was_restart)) { double a_pos = 0; - if (mpctx->d_audio) { - a_pos = (written_audio_pts(mpctx) - - mpctx->opts->playback_speed * buffered_audio); - } + if (mpctx->d_audio) + a_pos = playing_audio_pts(mpctx); mpctx->playback_pts = a_pos; if (was_restart) mp_notify(mpctx, MPV_EVENT_PLAYBACK_RESTART, NULL); @@ -1219,7 +1214,7 @@ void run_playloop(struct MPContext *mpctx) * buffered. */ if ((mpctx->d_audio || mpctx->d_video) && !audio_left && !video_left - && (opts->gapless_audio || buffered_audio < AO_EOF_DELAY) + && (opts->gapless_audio || (mpctx->d_audio && ao_eof_reached(mpctx->ao))) && (!mpctx->paused || was_restart)) { if (end_is_chapter) { mp_seek(mpctx, (struct seek_params){