From 5e9f7916674c4640707727eac80c659290492bad Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 23 Jan 2015 22:06:12 +0100 Subject: [PATCH] video: separate screenshot modes Use different VOCTRLs for "window" and normal screenshot modes. The normal one will probably be removed, and replaced by generic code in vo.c, and this commit is preparation for this. (Doing it the other way around would be slightly simpler, but I haven't decided yet about the second one, and touching every VO is needed anyway in order to remove the unneeded crap. E.g. has_osd has been unused for a long time.) --- player/screenshot.c | 53 ++++++++++++++++++------------------ video/filter/vf.h | 2 +- video/filter/vf_screenshot.c | 3 +- video/out/vo.h | 24 +++------------- video/out/vo_direct3d.c | 14 ++++------ video/out/vo_opengl.c | 12 ++++---- video/out/vo_opengl_cb.c | 3 +- video/out/vo_sdl.c | 12 ++++---- video/out/vo_vaapi.c | 6 ++-- video/out/vo_vdpau.c | 11 ++++---- video/out/vo_wayland.c | 7 ++--- video/out/vo_x11.c | 6 ++-- video/out/vo_xv.c | 6 ++-- 13 files changed, 65 insertions(+), 94 deletions(-) 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))