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.)
This commit is contained in:
wm4 2015-01-23 22:06:12 +01:00
parent 4a1a0e98d8
commit 5e9f791667
13 changed files with 65 additions and 94 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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:

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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))