mirror of
https://github.com/mpv-player/mpv
synced 2024-12-26 00:42:57 +00:00
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:
parent
4a1a0e98d8
commit
5e9f791667
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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))
|
||||
|
Loading…
Reference in New Issue
Block a user