From d16c59096cbebd230f3a7aaf6aa1072eefbfd27c Mon Sep 17 00:00:00 2001 From: Dudemanguy Date: Wed, 19 Jul 2023 12:51:53 -0500 Subject: [PATCH] screenshot: implement screenshot-window in sw for most VOs mpv already has a bunch of software scaling utils. Instead of forcing every VO to implement this, we can just grab the frame and scale it in software in one central place. Fixes #11968. --- player/screenshot.c | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/player/screenshot.c b/player/screenshot.c index ab4cc8877a..7956c58131 100644 --- a/player/screenshot.c +++ b/player/screenshot.c @@ -326,11 +326,17 @@ static char *gen_fname(struct mp_cmd_ctx *cmd, const char *file_ext) static void add_osd(struct MPContext *mpctx, struct mp_image *image, int mode) { - struct mp_osd_res res = osd_res_from_image_params(&image->params); - if (mode == MODE_SUBTITLES) { + bool window = mode == MODE_FULL_WINDOW; + struct mp_osd_res res = window ? osd_get_vo_res(mpctx->video_out->osd) : + osd_res_from_image_params(&image->params); + if (mode == MODE_SUBTITLES || window) { osd_draw_on_image(mpctx->osd, res, mpctx->video_pts, OSD_DRAW_SUB_ONLY, image); } + if (window) { + osd_draw_on_image(mpctx->osd, res, mpctx->video_pts, + OSD_DRAW_OSD_ONLY, image); + } } static struct mp_image *screenshot_get(struct MPContext *mpctx, int mode, @@ -368,11 +374,8 @@ static struct mp_image *screenshot_get(struct MPContext *mpctx, int mode, image = vo_get_current_frame(mpctx->video_out); } - if (!image) - return NULL; - // vo_get_current_frame() can return a hardware frame, which we have to download first. - if (image->fmt.flags & MP_IMGFLAG_HWACCEL) { + if (image && image->fmt.flags & MP_IMGFLAG_HWACCEL) { struct mp_image *nimage = mp_image_hw_download(image, NULL); talloc_free(image); if (!nimage) @@ -380,6 +383,26 @@ static struct mp_image *screenshot_get(struct MPContext *mpctx, int mode, image = nimage; } + if (use_sw && image && window) { + struct mp_osd_res res = osd_get_vo_res(mpctx->video_out->osd); + struct mp_osd_res image_res = osd_res_from_image_params(&image->params); + if (!osd_res_equals(res, image_res)) { + struct mp_image *nimage = mp_image_alloc(image->imgfmt, res.w, res.h); + if (!nimage) { + talloc_free(image); + return NULL; + } + struct mp_sws_context *sws = mp_sws_alloc(NULL); + mp_sws_scale(sws, nimage, image); + talloc_free(image); + talloc_free(sws); + image = nimage; + } + } + + if (!image) + return NULL; + if (use_sw && mode != 0) add_osd(mpctx, image, mode); mp_image_params_guess_csp(&image->params);