From ca4192e2df7bcfdb9e18461f19e1bd2dd0ee3c7a Mon Sep 17 00:00:00 2001 From: Dudemanguy Date: Sat, 15 Jul 2023 21:38:59 -0500 Subject: [PATCH] player/video: check for forced eof It's a bit of an edge case, but since we now allow the disabling of the software fallback it's possible to have a situation where hwdec completely fails and the mpv window is still lingering from the previous item in the playlist. What needs to happen is simply that the vo_chain should uninit itself and handle force_window if needed. In order to do that, a new VDCTRL is added that checks vd_lavc if force_eof was set. player/video will then start the uninit process if needed after getting this. --- filters/f_decoder_wrapper.h | 1 + player/video.c | 15 +++++++++++++++ video/decode/vd_lavc.c | 4 ++++ 3 files changed, 20 insertions(+) diff --git a/filters/f_decoder_wrapper.h b/filters/f_decoder_wrapper.h index 9fa1a4f010..3100e6836b 100644 --- a/filters/f_decoder_wrapper.h +++ b/filters/f_decoder_wrapper.h @@ -77,6 +77,7 @@ enum dec_ctrl { VDCTRL_GET_BFRAMES, // framedrop mode: 0=none, 1=standard, 2=hrseek VDCTRL_SET_FRAMEDROP, + VDCTRL_CHECK_FORCED_EOF, }; int mp_decoder_wrapper_control(struct mp_decoder_wrapper *d, diff --git a/player/video.c b/player/video.c index 547f67c9de..0161929c46 100644 --- a/player/video.c +++ b/player/video.c @@ -573,6 +573,16 @@ static bool check_for_hwdec_fallback(struct MPContext *mpctx) return true; } +static bool check_for_forced_eof(struct MPContext *mpctx) +{ + struct vo_chain *vo_c = mpctx->vo_chain; + struct mp_decoder_wrapper *dec = vo_c->track->dec; + + bool forced_eof = false; + mp_decoder_wrapper_control(dec, VDCTRL_CHECK_FORCED_EOF, &forced_eof); + return forced_eof; +} + /* Update avsync before a new video frame is displayed. Actually, this can be * called arbitrarily often before the actual display. * This adjusts the time of the next video frame */ @@ -1041,6 +1051,11 @@ void write_video(struct MPContext *mpctx) if (r == VD_EOF) { if (check_for_hwdec_fallback(mpctx)) return; + if (check_for_forced_eof(mpctx)) { + uninit_video_chain(mpctx); + handle_force_window(mpctx, true); + return; + } if (vo_c->filter->failed_output_conversion) goto error; diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c index 1cd8ba4438..2106dcb56e 100644 --- a/video/decode/vd_lavc.c +++ b/video/decode/vd_lavc.c @@ -1325,6 +1325,10 @@ static int control(struct mp_filter *vd, enum dec_ctrl cmd, void *arg) case VDCTRL_SET_FRAMEDROP: ctx->framedrop_flags = *(int *)arg; return CONTROL_TRUE; + case VDCTRL_CHECK_FORCED_EOF: { + *(bool *)arg = ctx->force_eof; + return CONTROL_TRUE; + } case VDCTRL_GET_BFRAMES: { AVCodecContext *avctx = ctx->avctx; if (!avctx)