diff --git a/player/screenshot.c b/player/screenshot.c index 7d1c743e40..2a1aaf6746 100644 --- a/player/screenshot.c +++ b/player/screenshot.c @@ -326,37 +326,38 @@ static void screenshot_save(struct MPContext *mpctx, struct mp_image *image) static struct mp_image *screenshot_get(struct MPContext *mpctx, int mode) { struct mp_image *image = NULL; - if (mpctx->video_out && mpctx->video_out->config_ok) { - if (mode == MODE_SUBTITLES && osd_get_render_subs_in_filter(mpctx->osd)) - mode = 0; + if (mode == MODE_SUBTITLES && osd_get_render_subs_in_filter(mpctx->osd)) + mode = 0; - struct voctrl_screenshot_args args = - { .full_window = (mode == MODE_FULL_WINDOW) }; + // vf_screenshot + if (mpctx->d_video && mpctx->d_video->vfilter) + vf_control_any(mpctx->d_video->vfilter, VFCTRL_SCREENSHOT, &image); - if (mpctx->d_video && mpctx->d_video->vfilter) - vf_control_any(mpctx->d_video->vfilter, VFCTRL_SCREENSHOT, &args); + if (!image && mpctx->video_out && mpctx->video_out->config_ok) { + vo_wait_frame(mpctx->video_out); // important for each-frame mode - if (!args.out_image) { - vo_wait_frame(mpctx->video_out); // important for each-frame mode - vo_control(mpctx->video_out, VOCTRL_SCREENSHOT, &args); - } - - image = args.out_image; - if (image) { - if (mpctx->d_video && mpctx->d_video->hwdec_info) { - struct mp_hwdec_ctx *ctx = mpctx->d_video->hwdec_info->hwctx; - struct mp_image *nimage = NULL; - if (ctx && ctx->download_image) - nimage = ctx->download_image(ctx, image, NULL); - if (nimage) { - talloc_free(image); - image = nimage; - } - } - if (mode == MODE_SUBTITLES && !args.has_osd) - add_subs(mpctx, image); + if (mode != MODE_FULL_WINDOW) + vo_control(mpctx->video_out, VOCTRL_SCREENSHOT, &image); + if (!image) { + vo_control(mpctx->video_out, VOCTRL_SCREENSHOT_WIN, &image); + mode = MODE_FULL_WINDOW; } } + + if (image && mpctx->d_video && mpctx->d_video->hwdec_info) { + struct mp_hwdec_ctx *ctx = mpctx->d_video->hwdec_info->hwctx; + struct mp_image *nimage = NULL; + if (ctx && ctx->download_image) + nimage = ctx->download_image(ctx, image, NULL); + if (nimage) { + talloc_free(image); + image = nimage; + } + } + + if (image && mode == MODE_SUBTITLES) + add_subs(mpctx, image); + return image; } diff --git a/video/filter/vf.h b/video/filter/vf.h index 07f38d680b..3362320eb8 100644 --- a/video/filter/vf.h +++ b/video/filter/vf.h @@ -144,7 +144,7 @@ enum vf_ctrl { VFCTRL_SEEK_RESET = 1, // reset on picture and PTS discontinuities VFCTRL_SET_EQUALIZER, // set color options (brightness,contrast etc) VFCTRL_GET_EQUALIZER, // get color options (brightness,contrast etc) - VFCTRL_SCREENSHOT, // Take screenshot, arg is voctrl_screenshot_args + VFCTRL_SCREENSHOT, // Take screenshot, arg is mp_image** VFCTRL_INIT_OSD, // Filter OSD renderer present? VFCTRL_SET_DEINTERLACE, // Set deinterlacing status VFCTRL_GET_DEINTERLACE, // Get deinterlacing status diff --git a/video/filter/vf_screenshot.c b/video/filter/vf_screenshot.c index d60271acc4..562a1d03f5 100644 --- a/video/filter/vf_screenshot.c +++ b/video/filter/vf_screenshot.c @@ -46,8 +46,7 @@ static struct mp_image *filter(struct vf_instance *vf, struct mp_image *mpi) static int control (vf_instance_t *vf, int request, void *data) { if (request == VFCTRL_SCREENSHOT && vf->priv->current) { - struct voctrl_screenshot_args *args = data; - args->out_image = mp_image_new_ref(vf->priv->current); + *(struct mp_image **)data = mp_image_new_ref(vf->priv->current); return CONTROL_TRUE; } return CONTROL_UNKNOWN; diff --git a/video/out/vo.h b/video/out/vo.h index 281152352d..9ae489e2cd 100644 --- a/video/out/vo.h +++ b/video/out/vo.h @@ -97,7 +97,10 @@ enum mp_voctrl { // imgfmt/w/h/d_w/d_h can be omitted for convenience. VOCTRL_GET_COLORSPACE, // struct mp_image_params* - VOCTRL_SCREENSHOT, // struct voctrl_screenshot_args* + // Retrieve original image. + VOCTRL_SCREENSHOT, // struct mp_image** + // Retrieve window contents. + VOCTRL_SCREENSHOT_WIN, // struct mp_image** VOCTRL_SET_COMMAND_LINE, // char** @@ -120,25 +123,6 @@ struct voctrl_get_equalizer_args { int *valueptr; }; -// VOCTRL_SCREENSHOT -struct voctrl_screenshot_args { - // 0: Save image of the currently displayed video frame, in original - // resolution. - // 1: Save full screenshot of the window. Should contain OSD, EOSD, and the - // scaled video. - // The value of this variable can be ignored if only a single method is - // implemented. - int full_window; - // Will be set to a newly allocated image, that contains the screenshot. - // The caller has to free the image with talloc_free(). - // It is not specified whether the image data is a copy or references the - // image data directly. - // Can be NULL on failure. - struct mp_image *out_image; - // Whether the VO rendered OSD/subtitles into out_image - bool has_osd; -}; - // VOCTRL_GET_WIN_STATE #define VO_WIN_STATE_MINIMIZED 1 diff --git a/video/out/vo_direct3d.c b/video/out/vo_direct3d.c index 293eff55fe..5b4fb7856a 100644 --- a/video/out/vo_direct3d.c +++ b/video/out/vo_direct3d.c @@ -1260,14 +1260,12 @@ static int control(struct vo *vo, uint32_t request, void *data) return VO_TRUE; case VOCTRL_GET_PANSCAN: return VO_TRUE; - case VOCTRL_SCREENSHOT: { - struct voctrl_screenshot_args *args = data; - if (args->full_window) - args->out_image = get_window_screenshot(priv); - else - args->out_image = get_screenshot(priv); - return !!args->out_image; - } + case VOCTRL_SCREENSHOT: + *(struct mp_image **)data = get_screenshot(priv); + return VO_TRUE; + case VOCTRL_SCREENSHOT_WIN: + *(struct mp_image **)data = get_window_screenshot(priv); + return VO_TRUE; } int events = 0; diff --git a/video/out/vo_opengl.c b/video/out/vo_opengl.c index 6a2a48fb47..618ed90aff 100644 --- a/video/out/vo_opengl.c +++ b/video/out/vo_opengl.c @@ -348,13 +348,13 @@ static int control(struct vo *vo, uint32_t request, void *data) gl_video_get_colorspace(p->renderer, data); mpgl_unlock(p->glctx); return VO_TRUE; - case VOCTRL_SCREENSHOT: { - struct voctrl_screenshot_args *args = data; + case VOCTRL_SCREENSHOT_WIN: + case VOCTRL_SCREENSHOT: + { mpgl_lock(p->glctx); - if (args->full_window) - args->out_image = glGetWindowScreenshot(p->gl); - else - args->out_image = gl_video_download_image(p->renderer); + *(struct mp_image **)data = request == VOCTRL_SCREENSHOT + ? gl_video_download_image(p->renderer) + : glGetWindowScreenshot(p->gl); mpgl_unlock(p->glctx); return true; } diff --git a/video/out/vo_opengl_cb.c b/video/out/vo_opengl_cb.c index 091a376dfa..a974305b85 100644 --- a/video/out/vo_opengl_cb.c +++ b/video/out/vo_opengl_cb.c @@ -489,9 +489,8 @@ static int control(struct vo *vo, uint32_t request, void *data) pthread_mutex_unlock(&p->ctx->lock); return VO_TRUE; case VOCTRL_SCREENSHOT: { - struct voctrl_screenshot_args *args = data; pthread_mutex_lock(&p->ctx->lock); - args->out_image = mp_image_new_ref(p->ctx->displayed_frame); + *(struct mp_image **)data = mp_image_new_ref(p->ctx->displayed_frame); pthread_mutex_unlock(&p->ctx->lock); return VO_TRUE; } diff --git a/video/out/vo_sdl.c b/video/out/vo_sdl.c index bc5ddda5c6..9b7605643a 100644 --- a/video/out/vo_sdl.c +++ b/video/out/vo_sdl.c @@ -1018,14 +1018,12 @@ static int control(struct vo *vo, uint32_t request, void *data) struct voctrl_get_equalizer_args *args = data; return get_eq(vo, args->name, args->valueptr); } - case VOCTRL_SCREENSHOT: { - struct voctrl_screenshot_args *args = data; - if (args->full_window) - args->out_image = get_window_screenshot(vo); - else - args->out_image = get_screenshot(vo); + case VOCTRL_SCREENSHOT: + *(struct mp_image **)data = get_screenshot(vo); + return true; + case VOCTRL_SCREENSHOT_WIN: + *(struct mp_image **)data = get_window_screenshot(vo); return true; - } case VOCTRL_SET_CURSOR_VISIBILITY: SDL_ShowCursor(*(bool *)data); return true; diff --git a/video/out/vo_vaapi.c b/video/out/vo_vaapi.c index 06c7b3c9f4..1c4b016e6b 100644 --- a/video/out/vo_vaapi.c +++ b/video/out/vo_vaapi.c @@ -541,11 +541,9 @@ static int control(struct vo *vo, uint32_t request, void *data) p->output_surface = p->visible_surface; draw_osd(vo); return true; - case VOCTRL_SCREENSHOT: { - struct voctrl_screenshot_args *args = data; - args->out_image = get_screenshot(p); + case VOCTRL_SCREENSHOT: + *(struct mp_image **)data = get_screenshot(p); return true; - } case VOCTRL_GET_PANSCAN: return VO_TRUE; case VOCTRL_SET_PANSCAN: diff --git a/video/out/vo_vdpau.c b/video/out/vo_vdpau.c index 7b98b84243..1a1287c1d7 100644 --- a/video/out/vo_vdpau.c +++ b/video/out/vo_vdpau.c @@ -1048,14 +1048,15 @@ static int control(struct vo *vo, uint32_t request, void *data) case VOCTRL_RESET: forget_frames(vo, true); return true; - case VOCTRL_SCREENSHOT: { + case VOCTRL_SCREENSHOT_WIN: + case VOCTRL_SCREENSHOT: + { if (!status_ok(vo)) return false; - struct voctrl_screenshot_args *args = data; - if (args->full_window) { - args->out_image = get_window_screenshot(vo); + if (request == VOCTRL_SCREENSHOT_WIN) { + *(struct mp_image **)data = get_window_screenshot(vo); } else { - args->out_image = + *(struct mp_image **)data = vc->current_image ? mp_image_new_ref(vc->current_image) : NULL; } return true; diff --git a/video/out/vo_wayland.c b/video/out/vo_wayland.c index 770142ae9d..ed23f8af3d 100644 --- a/video/out/vo_wayland.c +++ b/video/out/vo_wayland.c @@ -690,11 +690,8 @@ static int control(struct vo *vo, uint32_t request, void *data) case VOCTRL_REDRAW_FRAME: return redraw_frame(p); case VOCTRL_SCREENSHOT: - { - struct voctrl_screenshot_args *args = data; - args->out_image = get_screenshot(p); - return VO_TRUE; - } + *(struct mp_image **)data = get_screenshot(p); + return true; case VOCTRL_GET_RECENT_FLIP_TIME: { *(int64_t*) data = p->recent_flip_time; diff --git a/video/out/vo_x11.c b/video/out/vo_x11.c index 13fa0a3c9f..32d9b731fd 100644 --- a/video/out/vo_x11.c +++ b/video/out/vo_x11.c @@ -619,12 +619,10 @@ static int control(struct vo *vo, uint32_t request, void *data) case VOCTRL_REDRAW_FRAME: draw_image(vo, p->original_image); return true; - case VOCTRL_SCREENSHOT: { - struct voctrl_screenshot_args *args = data; - args->out_image = get_screenshot(vo); + case VOCTRL_SCREENSHOT: + *(struct mp_image **)data = get_screenshot(vo); return true; } - } int events = 0; int r = vo_x11_control(vo, &events, request, data); diff --git a/video/out/vo_xv.c b/video/out/vo_xv.c index 202ba13735..e506fc9359 100644 --- a/video/out/vo_xv.c +++ b/video/out/vo_xv.c @@ -839,12 +839,10 @@ static int control(struct vo *vo, uint32_t request, void *data) case VOCTRL_REDRAW_FRAME: draw_image(vo, ctx->original_image); return true; - case VOCTRL_SCREENSHOT: { - struct voctrl_screenshot_args *args = data; - args->out_image = get_screenshot(vo); + case VOCTRL_SCREENSHOT: + *(struct mp_image **)data = get_screenshot(vo); return true; } - } int events = 0; int r = vo_x11_control(vo, &events, request, data); if (events & (VO_EVENT_EXPOSE | VO_EVENT_RESIZE))